Base type for arrays

Meta via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Jun 17 19:39:38 PDT 2015


On Wednesday, 17 June 2015 at 19:53:07 UTC, jmh530 wrote:
> I want to write a function template that works for any array of 
> a particular type, but not the base type, so real[], real[][], 
> etc, but not real. I was using ForeachType to do some testing, 
> but it doesn't really get the base type. It just takes one of 
> the [] off and returns the remaining type (see code below). 
> ElementType from std.range seems to operate in a similar way. 
> There are also ways to do this for associative arrays, but they 
> don't apply here either.
>
> How do I go about just getting the actual base type of an array?
>
> import std.stdio;
> import std.traits;
>
> void main() {
> 	real[2] x;
> 	x[0] = 0;
> 	x[1] = 1;
> 	
> 	writeln(is(ForeachType!(typeof(x)) == real)); //prints true
>
> 	real[2][2] xx;
> 	xx[0][0] = 0;
> 	xx[1][0] = 1;
> 	xx[0][1] = 2;
> 	xx[1][1] = 3;
> 	
> 	writeln(is(ForeachType!(typeof(xx)) == real));  //prints false
> 	writeln(typeid(ForeachType!(typeof(xx)));       //prints 
> real[2]
> }

Here is another solution which is more general in that it can be 
used with any input range.

import std.range: isInputRange;
import std.array;

template FlattenedType(R, int depth = int.max)
if (isInputRange!R && depth >= 0)
{
	static if (depth == 0)
	{
		alias FlattenedType = R;
	}
	else
	{
		alias FrontType = typeof(R.init.front);
		static if (isInputRange!FrontType)
		{
			alias FlattenedType = FlattenedType!(FrontType, depth - 1);
		}
		else
		{
			alias FlattenedType = R;
		}
	}
}

alias ArrayBaseType(T: U[], U) = 
typeof(FlattenedType!T.init.front);

void main()
{
	assert(is(FlattenedType!(int[][][]) == int[]));
	assert(is(ArrayBaseType!(int[][][]) == int));
}


More information about the Digitalmars-d-learn mailing list