www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to get element type of a slice?

reply Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
Hello folks,

Hope everyone is doing fine. Considering the following code, in 
the first condition, I am extracting the type Point from the 
slice Point[]. I searched in the std.traits, and could not find a 
neater solution something like ElementTypeOf!T. Is there any 
neater solution for it? Thanks in advance.

```d
     static if (isArray!VecPoint){
         VecPoint dummy;
         alias Point = typeof(dummy[0]);
     } else static if (isRandomAccessRange!VecPoint){
         alias ASeq2 = TemplateArgsOf!VecPoint;
         alias Point = ASeq2[0];
     } else
         static assert(0, typeof(VecPoint).stringof ~ " type is 
not supported");
```

Ferhat
Aug 17 2021
next sibling parent reply jfondren <julian.fondren gmail.com> writes:
On Tuesday, 17 August 2021 at 12:21:31 UTC, Ferhat Kurtulmuş 
wrote:
 Hello folks,

 Hope everyone is doing fine. Considering the following code, in 
 the first condition, I am extracting the type Point from the 
 slice Point[]. I searched in the std.traits, and could not find 
 a neater solution something like ElementTypeOf!T. Is there any 
 neater solution for it? Thanks in advance.

 ```d
     static if (isArray!VecPoint){
         VecPoint dummy;
         alias Point = typeof(dummy[0]);
     } else static if (isRandomAccessRange!VecPoint){
         alias ASeq2 = TemplateArgsOf!VecPoint;
         alias Point = ASeq2[0];
     } else
         static assert(0, typeof(VecPoint).stringof ~ " type is 
 not supported");
 ```

 Ferhat
This one's not in std.traits: ```d import std.range : ElementType; struct Point { int x, y; } unittest { Point[] points; assert(is(ElementType!(typeof(points)) == Point)); } ```
Aug 17 2021
next sibling parent Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
On Tuesday, 17 August 2021 at 12:26:36 UTC, jfondren wrote:
 On Tuesday, 17 August 2021 at 12:21:31 UTC, Ferhat Kurtulmuş 
 wrote:
 [...]
This one's not in std.traits: ```d import std.range : ElementType; struct Point { int x, y; } unittest { Point[] points; assert(is(ElementType!(typeof(points)) == Point)); } ```
Awesome! Have a great day.
Aug 17 2021
prev sibling parent reply Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
On Tuesday, 17 August 2021 at 12:26:36 UTC, jfondren wrote:
 On Tuesday, 17 August 2021 at 12:21:31 UTC, Ferhat Kurtulmuş 
 wrote:
 [...]
This one's not in std.traits: ```d import std.range : ElementType; struct Point { int x, y; } unittest { Point[] points; assert(is(ElementType!(typeof(points)) == Point)); } ```
Hey, thank you again but, I don't want an instance of Point[] I need: alias T = Point[]; alias ElementOfPointSlice = .... // element type of T
Aug 17 2021
parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Tuesday, 17 August 2021 at 12:33:03 UTC, Ferhat Kurtulmuş 
wrote:
 On Tuesday, 17 August 2021 at 12:26:36 UTC, jfondren wrote:
 On Tuesday, 17 August 2021 at 12:21:31 UTC, Ferhat Kurtulmuş 
 wrote:
 [...]
This one's not in std.traits: ```d import std.range : ElementType; struct Point { int x, y; } unittest { Point[] points; assert(is(ElementType!(typeof(points)) == Point)); } ```
Hey, thank you again but, I don't want an instance of Point[] I need: alias T = Point[]; alias ElementOfPointSlice = .... // element type of T
``` alias T = Point[]; unittest { Point[] points; assert(is(ElementType!(typeof(points)) == Point)); }
Aug 18 2021
parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Thursday, 19 August 2021 at 03:29:03 UTC, Jesse Phillips wrote:
 On Tuesday, 17 August 2021 at 12:33:03 UTC, Ferhat Kurtulmuş 
 wrote:
 On Tuesday, 17 August 2021 at 12:26:36 UTC, jfondren wrote:
 On Tuesday, 17 August 2021 at 12:21:31 UTC, Ferhat Kurtulmuş 
 wrote:
 [...]
This one's not in std.traits: ```d import std.range : ElementType; struct Point { int x, y; } unittest { Point[] points; assert(is(ElementType!(typeof(points)) == Point)); } ```
Hey, thank you again but, I don't want an instance of Point[] I need: alias T = Point[]; alias ElementOfPointSlice = .... // element type of T
Sorry last post was not complete. Not tested. ``` alias T = Point[]; alias ElementOfPointSlice = ElementType!(T); unittest { assert(is(ElementOfPointSlice == Point)); } ```
Aug 18 2021
parent reply jfondren <julian.fondren gmail.com> writes:
On Thursday, 19 August 2021 at 03:32:47 UTC, Jesse Phillips wrote:
 On Thursday, 19 August 2021 at 03:29:03 UTC, Jesse Phillips 
 wrote:
 On Tuesday, 17 August 2021 at 12:33:03 UTC, Ferhat Kurtulmuş 
 wrote:
 On Tuesday, 17 August 2021 at 12:26:36 UTC, jfondren wrote:
 On Tuesday, 17 August 2021 at 12:21:31 UTC, Ferhat Kurtulmuş 
 wrote:
 [...]
This one's not in std.traits: ```d import std.range : ElementType; struct Point { int x, y; } unittest { Point[] points; assert(is(ElementType!(typeof(points)) == Point)); } ```
Hey, thank you again but, I don't want an instance of Point[] I need: alias T = Point[]; alias ElementOfPointSlice = .... // element type of T
Sorry last post was not complete. Not tested. ``` alias T = Point[]; alias ElementOfPointSlice = ElementType!(T); unittest { assert(is(ElementOfPointSlice == Point)); } ```
so, what's the problem? This passes tests: ```d import std.range : ElementType; struct Point { int x, y; } alias T = Point[]; alias ElementOfPointSlice = ElementType!(T); unittest { assert(is(ElementOfPointSlice == Point)); } ```
Aug 18 2021
parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Thursday, 19 August 2021 at 04:03:31 UTC, jfondren wrote:
 On Thursday, 19 August 2021 at 03:32:47 UTC, Jesse Phillips 
 wrote:
 On Tuesday, 17 August 2021 at 12:33:03 UTC, Ferhat Kurtulmuş 
 wrote:
 Hey, thank you again but, I don't want an instance of 
 Point[] I need:

 alias T = Point[];

 alias ElementOfPointSlice = .... // element type of T
so, what's the problem? This passes tests: ```d import std.range : ElementType; struct Point { int x, y; } alias T = Point[]; alias ElementOfPointSlice = ElementType!(T); unittest { assert(is(ElementOfPointSlice == Point)); } ```
No issue just trying to give Ferhat a final answer to his question.
Aug 20 2021
parent Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
On Saturday, 21 August 2021 at 02:59:39 UTC, Jesse Phillips wrote:
 On Thursday, 19 August 2021 at 04:03:31 UTC, jfondren wrote:
 On Thursday, 19 August 2021 at 03:32:47 UTC, Jesse Phillips 
 wrote:
 On Tuesday, 17 August 2021 at 12:33:03 UTC, Ferhat Kurtulmuş 
 wrote:
 Hey, thank you again but, I don't want an instance of 
 Point[] I need:

 alias T = Point[];

 alias ElementOfPointSlice = .... // element type of T
so, what's the problem? This passes tests: ```d import std.range : ElementType; struct Point { int x, y; } alias T = Point[]; alias ElementOfPointSlice = ElementType!(T); unittest { assert(is(ElementOfPointSlice == Point)); } ```
 No issue just trying to give Ferhat a final answer to his 
 question.
Thank you. I appreciate it.
Aug 23 2021
prev sibling next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 17 August 2021 at 12:21:31 UTC, Ferhat Kurtulmuş 
wrote:
 Hello folks,

 Hope everyone is doing fine. Considering the following code, in 
 the first condition, I am extracting the type Point from the 
 slice Point[]. I searched in the std.traits, and could not find 
 a neater solution something like ElementTypeOf!T. Is there any 
 neater solution for it? Thanks in advance.
`typeof(T.init[0])` Note that `std.range.ElementType` will probably not give the result you expect for character arrays (such as `char[]` and `wchar[]`), due to autodecoding.
Aug 17 2021
parent Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
On Tuesday, 17 August 2021 at 12:32:45 UTC, Paul Backus wrote:
 On Tuesday, 17 August 2021 at 12:21:31 UTC, Ferhat Kurtulmuş 
 wrote:
 Hello folks,

 Hope everyone is doing fine. Considering the following code, 
 in the first condition, I am extracting the type Point from 
 the slice Point[]. I searched in the std.traits, and could not 
 find a neater solution something like ElementTypeOf!T. Is 
 there any neater solution for it? Thanks in advance.
`typeof(T.init[0])` Note that `std.range.ElementType` will probably not give the result you expect for character arrays (such as `char[]` and `wchar[]`), due to autodecoding.
Thank you. This one looks better.
Aug 17 2021
prev sibling next sibling parent reply drug <drug2004 bk.ru> writes:
17.08.2021 15:21, Ferhat Kurtulmuş пишет:
 Hello folks,
 
 Hope everyone is doing fine. Considering the following code, in the 
 first condition, I am extracting the type Point from the slice Point[]. 
 I searched in the std.traits, and could not find a neater solution 
 something like ElementTypeOf!T. Is there any neater solution for it? 
 Thanks in advance.
 
 ```d
      static if (isArray!VecPoint){
          VecPoint dummy;
          alias Point = typeof(dummy[0]);
      } else static if (isRandomAccessRange!VecPoint){
          alias ASeq2 = TemplateArgsOf!VecPoint;
          alias Point = ASeq2[0];
      } else
          static assert(0, typeof(VecPoint).stringof ~ " type is not 
 supported");
 ```
 
 Ferhat
https://dlang.org/library/std/range/primitives/element_type.html
Aug 17 2021
parent Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
On Tuesday, 17 August 2021 at 12:49:02 UTC, drug wrote:
 17.08.2021 15:21, Ferhat Kurtulmuş пишет:
 [...]
https://dlang.org/library/std/range/primitives/element_type.html
Yes, that is neat. Thank you.
Aug 17 2021
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/17/21 8:21 AM, Ferhat Kurtulmuş wrote:
 Hello folks,
 
 Hope everyone is doing fine. Considering the following code, in the 
 first condition, I am extracting the type Point from the slice Point[]. 
 I searched in the std.traits, and could not find a neater solution 
 something like ElementTypeOf!T. Is there any neater solution for it? 
 Thanks in advance.
 
 ```d
      static if (isArray!VecPoint){
          VecPoint dummy;
          alias Point = typeof(dummy[0]);
      } else static if (isRandomAccessRange!VecPoint){
          alias ASeq2 = TemplateArgsOf!VecPoint;
          alias Point = ASeq2[0];
      } else
          static assert(0, typeof(VecPoint).stringof ~ " type is not 
 supported");
 ```
If you want the element type of a range (i.e. the thing returned by `range.front`), you can use `ElementType!T` (from std.range.primitives). This returns the element type of the range, which for every array *except* character arrays, gives you the element type of the array. If you want always the element type of the array, even for auto-decoded ranges, use `ElementEncodingType!T`. If you know it's an array, you can just use Paul's solution. Your `isRandomAccessRange` branch seems very suspect. -Steve
Aug 17 2021
parent reply Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
On Tuesday, 17 August 2021 at 13:14:44 UTC, Steven Schveighoffer 
wrote:
 On 8/17/21 8:21 AM, Ferhat Kurtulmuş wrote:
 Hello folks,
 
 Hope everyone is doing fine. Considering the following code, 
 in the first condition, I am extracting the type Point from 
 the slice Point[]. I searched in the std.traits, and could not 
 find a neater solution something like ElementTypeOf!T. Is 
 there any neater solution for it? Thanks in advance.
 
 ```d
      static if (isArray!VecPoint){
          VecPoint dummy;
          alias Point = typeof(dummy[0]);
      } else static if (isRandomAccessRange!VecPoint){
          alias ASeq2 = TemplateArgsOf!VecPoint;
          alias Point = ASeq2[0];
      } else
          static assert(0, typeof(VecPoint).stringof ~ " type 
 is not supported");
 ```
If you want the element type of a range (i.e. the thing returned by `range.front`), you can use `ElementType!T` (from std.range.primitives). This returns the element type of the range, which for every array *except* character arrays, gives you the element type of the array. If you want always the element type of the array, even for auto-decoded ranges, use `ElementEncodingType!T`. If you know it's an array, you can just use Paul's solution. Your `isRandomAccessRange` branch seems very suspect. -Steve
Very informative, thanks. My code is lying here[1]. I want my struct to accept 2d static arrays, random access ranges, and "std.container.Array". I could achieve it with its present form, and I will probably slightly modify it based on your comments. [1]: https://github.com/aferust/earcut-d/blob/master/source/earcutd.d#L34
Aug 17 2021
parent jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 17 August 2021 at 14:40:20 UTC, Ferhat Kurtulmuş 
wrote:
 [snip]

 Very informative, thanks. My code is lying here[1]. I want my 
 struct to accept 2d static arrays, random access ranges, and 
 "std.container.Array". I could achieve it with its present 
 form, and I will probably slightly modify it based on your 
 comments.

 [1]: 
 https://github.com/aferust/earcut-d/blob/master/source/earcutd.d#L34
If it would only accept dynamic arrays, you could use something like below ```d import std.traits: isDynamicArray; template DynamicArrayOf(T : U[], U) if (isDynamicArray!T) { alias DynamicArrayOf = U; } struct Point {} void main() { static assert(is(DynamicArrayOf!(int[]) == int)); static assert(is(DynamicArrayOf!(Point[]) == Point)); } ```
Aug 18 2021