Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 25, 2020 How to get the element type of an array? | ||||
---|---|---|---|---|
| ||||
What's the best way to get the element type of an array at compile time? Something like std.range.ElementType except that works on any array type. There is std.traits.ForeachType, but it wasn't clear if that was the right thing. --Jon |
August 25, 2020 Re: How to get the element type of an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jon Degenhardt | On Tuesday, 25 August 2020 at 03:41:06 UTC, Jon Degenhardt wrote:
> What's the best way to get the element type of an array at compile time?
>
> Something like std.range.ElementType except that works on any array type. There is std.traits.ForeachType, but it wasn't clear if that was the right thing.
>
> --Jon
One way (maybe not the best way) is to use the type of the array's ptr property when dereferenced, e.g.
import std.traits : isArray;
template ArrayElementOf (Array)
if (isArray!Array)
{
alias ArrayElementOf = typeof(*Array.init.ptr);
}
|
August 24, 2020 Re: How to get the element type of an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jon Degenhardt | On Tue, Aug 25, 2020 at 03:41:06AM +0000, Jon Degenhardt via Digitalmars-d-learn wrote: > What's the best way to get the element type of an array at compile time? > > Something like std.range.ElementType except that works on any array type. There is std.traits.ForeachType, but it wasn't clear if that was the right thing. [...] alias T = ... /* the type to inspect */ static if (is(T : E[], E)) { ... /* in this block, E is the element type */ } Or if you need to use it in another expression: template ArrayElemType(T) { static if (is(T : E[], E)) { alias ArrayElemType = E; } else alias ArrayElemType = void; // or static assert(0) if it should be an error } int[] myArr; pragma(msg, ArrayElemType!(typeof(myArr))); // int string myStr; pragma(msg, ArrayElemType!(typeof(myStr))); // immutable(char) T -- The best way to destroy a cause is to defend it poorly. |
August 25, 2020 Re: How to get the element type of an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Tuesday, 25 August 2020 at 04:36:56 UTC, H. S. Teoh wrote:
> [...]
Harry Gillanders, H.S. Teoh,
Thank you both for the quick replies. Both methods address my needs. Very much appreciated, I was having trouble figuring this one out.
--Jon
|
August 25, 2020 Re: How to get the element type of an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jon Degenhardt | On Tuesday, 25 August 2020 at 03:41:06 UTC, Jon Degenhardt wrote:
> What's the best way to get the element type of an array at compile time?
>
> Something like std.range.ElementType except that works on any array type. There is std.traits.ForeachType, but it wasn't clear if that was the right thing.
>
> --Jon
I'm curious to know what are the array types that were not accepted by ElementType ( or ElementEncodingType ) ?
|
August 25, 2020 Re: How to get the element type of an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | On Tuesday, 25 August 2020 at 05:02:46 UTC, Basile B. wrote: > On Tuesday, 25 August 2020 at 03:41:06 UTC, Jon Degenhardt wrote: >> What's the best way to get the element type of an array at compile time? >> >> Something like std.range.ElementType except that works on any array type. There is std.traits.ForeachType, but it wasn't clear if that was the right thing. >> >> --Jon > > I'm curious to know what are the array types that were not accepted by ElementType ( or ElementEncodingType ) ? Interesting. I need to test static arrays. In fact 'ElementType' does work with static arrays. Which is likely what you expected. I assumed ElementType would not work, because static arrays don't satisfy 'isInputRange', and the documentation for ElementType says: > The element type is determined as the type yielded by r.front for an object r of type R. [...] If R doesn't have front, ElementType!R is void. But, if std.range is imported, a static array does indeed get a 'front' member. It doesn't satisfy isInputRange, but it does have a 'front' element. The situation is still confusing though. If only 'std.range.ElementType' is imported, a static array does not have a 'front' member, but ElementType still gets the correct type. (This is where the documentation says it'll return void.) --- Import std.range --- @safe unittest { import std.range; ubyte[10] staticArray; ubyte[] dynamicArray = new ubyte[](10); static assert(is(ElementType!(typeof(staticArray)) == ubyte)); static assert(is(ElementType!(typeof(dynamicArray)) == ubyte)); // front is available static assert(__traits(compiles, staticArray.front)); static assert(__traits(compiles, dynamicArray.front)); static assert(is(typeof(staticArray.front) == ubyte)); static assert(is(typeof(dynamicArray.front) == ubyte)); } --- Import std.range.ElementType --- @safe unittest { import std.range : ElementType; ubyte[10] staticArray; ubyte[] dynamicArray = new ubyte[](10); static assert(is(ElementType!(typeof(staticArray)) == ubyte)); static assert(is(ElementType!(typeof(dynamicArray)) == ubyte)); // front is not available static assert(!__traits(compiles, staticArray.front)); static assert(!__traits(compiles, dynamicArray.front)); static assert(!is(typeof(staticArray.front) == ubyte)); static assert(!is(typeof(dynamicArray.front) == ubyte)); } This suggests the documentation for ElementType not quite correct. |
August 25, 2020 Re: How to get the element type of an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jon Degenhardt | On 8/25/20 4:38 AM, Jon Degenhardt wrote: > On Tuesday, 25 August 2020 at 05:02:46 UTC, Basile B. wrote: >> On Tuesday, 25 August 2020 at 03:41:06 UTC, Jon Degenhardt wrote: >>> What's the best way to get the element type of an array at compile time? >>> >>> Something like std.range.ElementType except that works on any array type. There is std.traits.ForeachType, but it wasn't clear if that was the right thing. >>> >>> --Jon >> >> I'm curious to know what are the array types that were not accepted by ElementType ( or ElementEncodingType ) ? > > Interesting. I need to test static arrays. In fact 'ElementType' does work with static arrays. Which is likely what you expected. Also note that due to autodecoding, ElementType says `dchar` for strings. ElementEncodingType should be the choice if you are looking for the array element type. But you could also use the techniques specified here (and might be less confusing). > But, if std.range is imported, a static array does indeed get a 'front' member. It doesn't satisfy isInputRange, but it does have a 'front' element. Because you can't pop the front of a static array. front works because a static array automatically casts to a normal array (there is no specialized overload for static arrays). > The situation is still confusing though. If only 'std.range.ElementType' is imported, a static array does not have a 'front' member, but ElementType still gets the correct type. (This is where the documentation says it'll return void.) You are maybe thinking of how C works? D imports are different, the code is defined the same no matter how it is imported. *your* module cannot see std.range.primitives.front, but the range module itself can see that UFCS function. This is also why ElementType will fail on types that have UFCS front defined, but not imported directly from std.range.primitives. -Steve |
August 25, 2020 Re: How to get the element type of an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jon Degenhardt | On Tuesday, 25 August 2020 at 03:41:06 UTC, Jon Degenhardt wrote:
> What's the best way to get the element type of an array at compile time?
>
> Something like std.range.ElementType except that works on any array type. There is std.traits.ForeachType, but it wasn't clear if that was the right thing.
>
> --Jon
Why not just use typeof(a[0])
It does not matter if array is empty or not. Typeof does not actually evaluate its expression, just the type.
|
August 25, 2020 Re: How to get the element type of an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to FreeSlave | On Tue, Aug 25, 2020 at 03:02:14PM +0000, FreeSlave via Digitalmars-d-learn wrote: > On Tuesday, 25 August 2020 at 03:41:06 UTC, Jon Degenhardt wrote: > > What's the best way to get the element type of an array at compile time? > > > > Something like std.range.ElementType except that works on any array type. There is std.traits.ForeachType, but it wasn't clear if that was the right thing. > > > > --Jon > > Why not just use typeof(a[0]) > > It does not matter if array is empty or not. Typeof does not actually evaluate its expression, just the type. +1, why didn't I think of this before. :-D T -- Political correctness: socially-sanctioned hypocrisy. |
August 25, 2020 Re: How to get the element type of an array? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Tuesday, 25 August 2020 at 12:50:35 UTC, Steven Schveighoffer wrote:
>> The situation is still confusing though. If only 'std.range.ElementType' is imported, a static array does not have a 'front' member, but ElementType still gets the correct type. (This is where the documentation says it'll return void.)
>
> You are maybe thinking of how C works? D imports are different, the code is defined the same no matter how it is imported. *your* module cannot see std.range.primitives.front, but the range module itself can see that UFCS function.
This is a good characteristic. But the reason it surprised me was that I expected to be able to manually expand the ElementType (or ElementEncodingType) template see the results of the expressions it uses.
template ElementType(R)
{
static if (is(typeof(R.init.front.init) T))
alias ElementType = T;
else
alias ElementType = void;
}
So, yes, I was expecting this to behave like an inline code expansion.
Yesterday I was doing that for 'hasSlicing', which has a more complicated set of tests. I wanted to see exactly which expression in 'hasSlicing' was causing it to return false for a struct I wrote. (Turned out to be a test for 'length'.)
I'll have to be more careful about this.
|
Copyright © 1999-2021 by the D Language Foundation