Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
February 22, 2018 PackedAliasSeq? | ||||
---|---|---|---|---|
| ||||
After coding https://github.com/dlang/phobos/pull/6192 with AliasSeq, the experience has been quite pleasurable. However, in places the AliasSeq tends to expand too eagerly, leading to a need to "keep it together" e.g. when you need to pass two of those to a template. I worked around the issue by nesting templates like this: template Merge(T...) { template With(U...) { static if (T.length == 0) alias With = U; else static if (U.length == 0) alias With = T; else static if (T[0] < U[0] || T[0] == U[0] && T[1].stringof <= U[1].stringof) alias With = AliasSeq!(T[0], T[1], Merge!(T[2 .. $]).With!U); else alias With = AliasSeq!(U[0], U[1], Merge!T.With!(U[2 .. $])); } } So instead of the unworkable Merge!(AliasSeq!(...), AliasSeq!(...)), one would write Merge!(AliasSeq!(...)).With!(AliasSeq!(...)). The problem remains for other use cases, so I was thinking of adding to std.meta this simple artifact: template PackedAliasSeq!(T...) { alias expand = AliasSeq!T; } That way, everything stays together and can be expanded on demand. Andrei |
February 22, 2018 Re: PackedAliasSeq? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 22 February 2018 at 19:26:54 UTC, Andrei Alexandrescu wrote: > After coding https://github.com/dlang/phobos/pull/6192 with AliasSeq, the experience has been quite pleasurable. However, in places the AliasSeq tends to expand too eagerly, leading to a need to "keep it together" e.g. when you need to pass two of those to a template. > > [...] You could also extend the existing `Pack` template: https://github.com/dlang/phobos/blob/master/std/meta.d#L1704 |
February 24, 2018 Re: PackedAliasSeq? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 22 February 2018 at 19:26:54 UTC, Andrei Alexandrescu wrote:
> After coding https://github.com/dlang/phobos/pull/6192 with AliasSeq, the experience has been quite pleasurable. However, in places the AliasSeq tends to expand too eagerly, leading to a need to "keep it together" e.g. when you need to pass two of those to a template.
>
> I worked around the issue by nesting templates like this:
>
> template Merge(T...)
> {
> template With(U...)
> {
> static if (T.length == 0)
> alias With = U;
> else static if (U.length == 0)
> alias With = T;
> else static if (T[0] < U[0]
> || T[0] == U[0] && T[1].stringof <= U[1].stringof)
> alias With =
> AliasSeq!(T[0], T[1], Merge!(T[2 .. $]).With!U);
> else
> alias With =
> AliasSeq!(U[0], U[1], Merge!T.With!(U[2 .. $]));
> }
> }
>
> So instead of the unworkable Merge!(AliasSeq!(...), AliasSeq!(...)), one would write Merge!(AliasSeq!(...)).With!(AliasSeq!(...)).
>
> The problem remains for other use cases, so I was thinking of adding to std.meta this simple artifact:
>
> template PackedAliasSeq!(T...)
> {
> alias expand = AliasSeq!T;
> }
>
> That way, everything stays together and can be expanded on demand.
>
>
> Andrei
Isn't a packed AliasSeq just a tuple ?
|
February 24, 2018 Re: PackedAliasSeq? | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On Saturday, 24 February 2018 at 06:14:52 UTC, deadalnix wrote:
> On Thursday, 22 February 2018 at 19:26:54 UTC, Andrei Alexandrescu wrote:
>> After coding https://github.com/dlang/phobos/pull/6192 with AliasSeq, the experience has been quite pleasurable. However, in places the AliasSeq tends to expand too eagerly, leading to a need to "keep it together" e.g. when you need to pass two of those to a template.
>>
>> I worked around the issue by nesting templates like this:
>>
>> template Merge(T...)
>> {
>> template With(U...)
>> {
>> static if (T.length == 0)
>> alias With = U;
>> else static if (U.length == 0)
>> alias With = T;
>> else static if (T[0] < U[0]
>> || T[0] == U[0] && T[1].stringof <= U[1].stringof)
>> alias With =
>> AliasSeq!(T[0], T[1], Merge!(T[2 .. $]).With!U);
>> else
>> alias With =
>> AliasSeq!(U[0], U[1], Merge!T.With!(U[2 .. $]));
>> }
>> }
>>
>> So instead of the unworkable Merge!(AliasSeq!(...), AliasSeq!(...)), one would write Merge!(AliasSeq!(...)).With!(AliasSeq!(...)).
>>
>> The problem remains for other use cases, so I was thinking of adding to std.meta this simple artifact:
>>
>> template PackedAliasSeq!(T...)
>> {
>> alias expand = AliasSeq!T;
>> }
>>
>> That way, everything stays together and can be expanded on demand.
>>
>>
>> Andrei
>
> Isn't a packed AliasSeq just a tuple ?
It is not a tuple (in the `std.typecons.Tuple` sense) if it can contain values, types and other kinds of symbols. I think a more appropriate name would be AliasTuple - an AliasSeq that doesn't auto-expand.
|
February 24, 2018 Re: PackedAliasSeq? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 22 February 2018 at 19:26:54 UTC, Andrei Alexandrescu wrote: > After coding https://github.com/dlang/phobos/pull/6192 with AliasSeq, the experience has been quite pleasurable. However, in places the AliasSeq tends to expand too eagerly, leading to a need to "keep it together" e.g. when you need to pass two of those to a template. > > I worked around the issue by nesting templates like this: > > template Merge(T...) > { > template With(U...) > { > static if (T.length == 0) > alias With = U; > else static if (U.length == 0) > alias With = T; > else static if (T[0] < U[0] > || T[0] == U[0] && T[1].stringof <= U[1].stringof) > alias With = > AliasSeq!(T[0], T[1], Merge!(T[2 .. $]).With!U); > else > alias With = > AliasSeq!(U[0], U[1], Merge!T.With!(U[2 .. $])); > } > } > > So instead of the unworkable Merge!(AliasSeq!(...), AliasSeq!(...)), one would write Merge!(AliasSeq!(...)).With!(AliasSeq!(...)). > > The problem remains for other use cases, so I was thinking of adding to std.meta this simple artifact: > > template PackedAliasSeq!(T...) > { > alias expand = AliasSeq!T; > } > > That way, everything stays together and can be expanded on demand. > > > Andrei Yes, I love this stuff, lots of possibilities. E.g. import std.traits : isInstanceOf; import std.meta : allSatisfy, AliasSeq, staticMap, Alias; template Pack(T ...) { alias expand = T; enum length = expand.length; } enum isPack(alias T) = isInstanceOf!(Pack, T); template Head(alias P) if (isPack!P) { alias Head = Alias!(P.expand[0]); } template Tail(alias P) if (isPack!P) { alias Tail = Pack!(P.expand[1 .. $]); } template staticZip(Seqs ...) if (Seqs.length >= 2 && allSatisfy!(isPack, Seqs)) { enum len = Seqs[0].length; static foreach (Seq; Seqs[1 .. $]) static assert(Seq.length == len, "All arguments to staticZip must have the same length"); static if (len == 0) alias staticZip = AliasSeq!(); else alias staticZip = AliasSeq!(Pack!(staticMap!(Head, Seqs)), staticZip!(staticMap!(Tail, Seqs))); } |
February 26, 2018 Re: PackedAliasSeq? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 22 February 2018 at 19:26:54 UTC, Andrei Alexandrescu wrote: > template PackedAliasSeq!(T...) > { > alias expand = AliasSeq!T; > } I started playing around with this a few days ago, and came up with another interesting abstraction - NamedPack: alias foo = NamedPack!("Type", int, "name", "foo"); assert(is(foo.Type == int)); assert(foo.name == "foo"); assert(foo.equals!(NamedPack!("Type", int, "name", "foo"))); And for good measure, a helper to define your own 'compile-time structs', for want of a better word: alias Field = DefinePack!("Type", Type, "name", string, "offset", int); alias field1 = Field!(int, "a", 0); assert(is(field1.Type == int)); assert(field1.name == "a"); assert(field1.offset == 0); assert(field1.equals!(NamedPack!("Type", int, "name", "a", "offset", 0))); One benefit over regular structs being of course that these will never end up in the binary. The more structured nature of this construct over the simple Pack template makes it useful where information would otherwise be encoded in the order of elements, as e.g. in pull #6192. Implementation and some more documentation: https://gist.github.com/Biotronic/8a2664c050f01aed5e0c45950509022b -- Simen |
Copyright © 1999-2021 by the D Language Foundation