Orange/include/Orange/Math/Swizzle.h

190 lines
4.1 KiB
C++

#pragma once
#include <Orange/Core/Array.h>
namespace orange
{
template <typename T, size_t Alignment, size_t Size>
struct alignas(Alignment) Swizzle
{
Array<T, Size> data;
// TODO: Deduplicate these constructors... somehow
constexpr Swizzle()
: data{ } {}
constexpr explicit Swizzle(T splat)
{
Fill(data.begin(), data.end(), splat);
}
constexpr Swizzle(const T components[Size])
{
Copy(&components[0], &components[Size], data.begin());
}
};
template <typename T, size_t Alignment>
struct alignas(Alignment) Swizzle<T, Alignment, 1>
{
union
{
Array<T, 1> data;
struct
{
float x;
};
struct
{
float r;
};
};
constexpr Swizzle()
: data{ } {}
constexpr explicit Swizzle(T splat)
{
Fill(data.begin(), data.end(), splat);
}
constexpr Swizzle(const T components[1])
{
Copy(&components[0], &components[1], data.begin());
}
constexpr Swizzle(const Swizzle& other) = default;
};
template <typename T, size_t Alignment>
struct alignas(Alignment) Swizzle<T, Alignment, 2>
{
union
{
Array<T, 2> data;
struct
{
float x;
float y;
};
struct
{
float r;
float g;
};
};
constexpr Swizzle()
: data{ } {}
constexpr explicit Swizzle(T splat)
{
Fill(data.begin(), data.end(), splat);
}
constexpr Swizzle(const T components[2])
{
copy(&components[0], &components[2], data.begin());
}
template <typename... Args>
constexpr Swizzle(const Args&... args)
: data {{ args... }}
{
static_assert(sizeof...(Args) == 2);
}
constexpr Swizzle(const Swizzle& other) = default;
};
template <typename T, size_t Alignment>
struct alignas(Alignment) Swizzle<T, Alignment, 3>
{
union
{
Array<T, 3> data;
struct
{
float x;
float y;
float z;
};
struct
{
float r;
float g;
float b;
};
};
constexpr Swizzle()
: data{ } {}
constexpr explicit Swizzle(T splat)
{
Fill(data.begin(), data.end(), splat);
}
constexpr Swizzle(const T components[3])
{
copy(&components[0], &components[3], data.begin());
}
template <typename... Args>
constexpr Swizzle(const Args&... args)
: data {{ args... }}
{
static_assert(sizeof...(Args) == 3);
}
constexpr Swizzle(const Swizzle& other) = default;
};
template <typename T, size_t Alignment>
struct alignas(Alignment) Swizzle<T, Alignment, 4>
{
union
{
Array<T, 4> data;
struct
{
float x;
float y;
float z;
float w;
};
struct
{
float r;
float g;
float b;
float a;
};
};
constexpr Swizzle()
: data{ } {}
constexpr explicit Swizzle(T splat)
{
Fill(data.begin(), data.end(), splat);
}
constexpr Swizzle(const T components[4])
{
copy(&components[0], &components[4], data.begin());
}
template <typename... Args>
constexpr Swizzle(const Args&... args)
: data {{ args... }}
{
static_assert(sizeof...(Args) == 4);
}
constexpr Swizzle(const Swizzle& other) = default;
};
}