tuple slicing operator

Meta via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Aug 9 12:26:45 PDT 2014


On Saturday, 9 August 2014 at 16:39:34 UTC, Vlad Levenfeld wrote:
> I may be misunderstanding the intended semantics of the [] 
> operator but I've come to interpret x[] to mean "give me x as a 
> range" and this is the meaning I intend when I overload it in 
> my own structs.
>
> But -
>
> auto z = tuple (1,1,1);
> pragma (msg, typeof(z)); // Tuple!(int, int, int)
> pragma (msg, typeof(z[])); // (int, int, int)

Tuples are special. Tuple internally keeps a compiler tuple that 
it aliases to itself. Compiler tuples have a built-in "static 
slice" operator that no other type has. Since Tuple aliases a 
compiler tuple to itself internally, doing `z[]` actually 
forwards to the compiler tuple's static slice operator (which is 
why z[] gives you a type of (int, int, int) instead of 
Tuple!(int, int, int)). It is a bit confusing, but tuples are a 
messy part of the D language.

Other than that, thinking of `x[]` as "give me x as a range" is 
not really correct. For one thing, any type can overload the [] 
operator, so x[] can mean anything. Second, it's more correct to 
think of x[] as meaning "give me a *slice* of x", since [] is the 
slice operator. Usually slices *are* ranges, but they don't have 
to be, and it's not a good assumption to make.


> In generic code I tend to use [] to make sure a variable is a 
> range before I use it (like static arrays, or structs following 
> my interpretation of []). So now whenever tuples might come 
> into the mix I have to pass the argument through an overloaded 
> convenience function that can tell a range or tuple type from 
> one-element variadic argument.
>
> I've got a lot of difficulty with that last part so I am 
> wondering, is there a better way to do this?

In generic code, you should always use template constraints and 
static if along with the appropriate traits to check facts about 
a type. Take a look at std.traits and std.range, which have 
templates that can tell you whether a type T is an input range, 
forward range, etc., an array, etc.


More information about the Digitalmars-d-learn mailing list