Changing Template Static Ifs to Recursion
jmh530 via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Jun 1 13:51:25 PDT 2017
On Wednesday, 31 May 2017 at 21:02:07 UTC, jmh530 wrote:
> On Wednesday, 31 May 2017 at 19:22:18 UTC, Stefan Koch wrote:
>>
>> You could also use string mixins.
>> Which will be more efficient then recursion.
>
> I try to avoid string mixins unless I can't help it.
> Nevertheless, I made an effort to try to get it to work and
> below seems to be working. I still have to use some recursion
> to generate the string.
>
> The downside is that this version can't be @nogc, correct?
>
One advantage of the mixin version is that I don't have to
explicitly get the type of the result. In ag0aep6g's example, it
works easily enough for arrays, but if the indexing is more
complicated, then it becomes a pain to get the correct types.
I struggled a little to get it @nogc, but eventually got it there
by changing the helper code to free-standing functions that use
enums to force CTFE. The code is below:
private
{
const(char[]) opIndex_i(size_t i)() @nogc
{
return "this.underlying[" ~ i.stringof ~ "][slices[" ~
i.stringof ~ "]]";
}
const(char[]) GenResult(alias f, T...)() @nogc
{
const(char[]) GenParens(U...)() @nogc
{
static if (U.length > 0)
{
static if (U.length == 1)
{
enum result = f!(U.length - 1);
}
else static if (U.length > 1)
{
enum result = GenParens!(U[0 .. $ - 1]) ~ ", " ~ f!(U.length
- 1);
}
return result;
}
}
enum parens = GenParens!(T);
return "foo!(Names)(" ~ parens ~ ")";
}
}
struct Foo(T...)
{
alias U = Tuple!T;
U underlying;
alias underlying this;
alias Names = U.fieldNames;
alias Types = U.Types;
/// Alternate access to tuple
auto index(size_t dimension)() const @property
{
return underlying[dimension];
}
auto ref opIndex(Slices...)(Slices slices) @nogc
if (Slices.length == Types.length)
{
return mixin(GenResult!(opIndex_i, Slices));
}
}
More information about the Digitalmars-d-learn
mailing list