June 23, 2021

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?

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);
}
June 23, 2021

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?

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:

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