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