www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Detect if a struct is a 3-float vector

reply JN <666total wp.pl> writes:
I'm looking for a way to test a struct for these conditions:

1. has members named x, y and z
2. these members are floating point type

This works, but feels kinda verbose, is there some shorter way? 
Can I somehow avoid the hasMember/getMember calls?

```d
import std.traits;

struct Vector3f
{
     float x, y, z;
}

struct Vector2f
{
     float x, y;
}

struct Vector3i
{
     int x, y, z;
}

bool isVector3fType(T)()
{
     static if (__traits(hasMember, T, "x") && __traits(hasMember, 
T, "y") && __traits(hasMember, T, "z"))
     {
         static if (isFloatingPoint!(typeof(__traits(getMember, T, 
"x")))
         && isFloatingPoint!(typeof(__traits(getMember, T, 
"y")))&& isFloatingPoint!(typeof(__traits(getMember, T, "z")))) {
             return true;
         }
     }
     return false;
}

void main()
{
     static assert(isVector3fType!Vector3f);
     static assert(!isVector3fType!Vector2f);
     static assert(!isVector3fType!Vector3i);
}
```
Jun 23 2021
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/23/21 6:36 PM, JN wrote:
 I'm looking for a way to test a struct for these conditions:
 
 1. has members named x, y and z
 2. these members are floating point type
 
 This works, but feels kinda verbose, is there some shorter way? Can I 
 somehow avoid the hasMember/getMember calls?
 
 ```d
 import std.traits;
 
 struct Vector3f
 {
      float x, y, z;
 }
 
 struct Vector2f
 {
      float x, y;
 }
 
 struct Vector3i
 {
      int x, y, z;
 }
 
 bool isVector3fType(T)()
 {
      static if (__traits(hasMember, T, "x") && __traits(hasMember, T, 
 "y") && __traits(hasMember, T, "z"))
      {
          static if (isFloatingPoint!(typeof(__traits(getMember, T,
"x")))
          && isFloatingPoint!(typeof(__traits(getMember, T, "y")))&& 
 isFloatingPoint!(typeof(__traits(getMember, T, "z")))) {
              return true;
          }
      }
      return false;
 }
 
 void main()
 {
      static assert(isVector3fType!Vector3f);
      static assert(!isVector3fType!Vector2f);
      static assert(!isVector3fType!Vector3i);
 }
 ```
Hm.. what about: ```d enum isVector3fType(T) = FieldNameTuple!T.length == 3 && FieldNameTuple!T == AliasSeq!("x", "y", "z") && allSatisfy!(isFloatingPoint, Fields!T); ``` (the length thing was required, otherwise the thing complained for Vector2f) -Steve
Jun 23 2021