#include <iostream>
template<typename T, size_t D>
struct VectorBase;
template<typename T>
struct VectorBase<T, 2>
{
constexpr VectorBase() : v{} {}
union {
T v[2];
struct { T x, y; };
};
};
template<typename T>
struct VectorBase<T, 3>
{
constexpr VectorBase() : v{} {}
union {
T v[3];
struct { T x, y, z; };
};
};
template<typename T>
struct VectorBase<T, 4>
{
constexpr VectorBase() : v{} {}
union {
T v[4];
struct { T x, y, z, w; };
};
};
template<typename T, size_t D>
struct Vector : public VectorBase<T, D>
{
using VectorBase<T, D>::v;
using size_type = decltype(D);
using value_type = T;
constexpr Vector() : VectorBase<T,D>{} {}
constexpr Vector(T scalar) {
std::fill(std::begin(v), std::end(v), scalar);
}
constexpr T& operator[](size_type i) const noexcept { return v[i]; }
constexpr const T& operator[](size_type i) noexcept { return v[i]; }
constexpr size_type size() const noexcept { return D; }
constexpr T* data() noexcept { return &v[0]; }
constexpr const T* data() const noexcept { return &v[0]; }
};
template<typename T>
using Vector2 = Vector<T, 2>;
template<typename T>
using Vector3 = Vector<T, 3>;
template<typename T>
using Vector4 = Vector<T, 4>;
int main() {
Vector3<int> v{1};
std::cout << v[0] << ", " << v.z << "\n";
return 0;
}
CSNpbmNsdWRlIDxpb3N0cmVhbT4KCQoJdGVtcGxhdGU8dHlwZW5hbWUgVCwgc2l6ZV90IEQ+CglzdHJ1Y3QgVmVjdG9yQmFzZTsKCQoJdGVtcGxhdGU8dHlwZW5hbWUgVD4KCXN0cnVjdCBWZWN0b3JCYXNlPFQsIDI+Cgl7CgkJY29uc3RleHByIFZlY3RvckJhc2UoKSA6IHZ7fSB7fQoJCXVuaW9uIHsKCQkJVCB2WzJdOwoJCQlzdHJ1Y3QgeyBUIHgsIHk7IH07CgkJfTsKCX07CgkKCXRlbXBsYXRlPHR5cGVuYW1lIFQ+CglzdHJ1Y3QgVmVjdG9yQmFzZTxULCAzPgoJewoJCWNvbnN0ZXhwciBWZWN0b3JCYXNlKCkgOiB2e30ge30KCQl1bmlvbiB7CgkJCVQgdlszXTsKCQkJc3RydWN0IHsgVCB4LCB5LCB6OyB9OwoJCX07Cgl9OwoJCgl0ZW1wbGF0ZTx0eXBlbmFtZSBUPgoJc3RydWN0IFZlY3RvckJhc2U8VCwgND4KCXsKCQljb25zdGV4cHIgVmVjdG9yQmFzZSgpIDogdnt9IHt9CgkJdW5pb24gewoJCQlUIHZbNF07CgkJCXN0cnVjdCB7IFQgeCwgeSwgeiwgdzsgfTsKCQl9OwoJfTsKCQoJdGVtcGxhdGU8dHlwZW5hbWUgVCwgc2l6ZV90IEQ+CglzdHJ1Y3QgVmVjdG9yIDogcHVibGljIFZlY3RvckJhc2U8VCwgRD4KCXsKCQl1c2luZyBWZWN0b3JCYXNlPFQsIEQ+Ojp2OwoJCXVzaW5nIHNpemVfdHlwZSA9IGRlY2x0eXBlKEQpOwoJCXVzaW5nIHZhbHVlX3R5cGUgPSBUOwoJCgkJY29uc3RleHByIFZlY3RvcigpIDogVmVjdG9yQmFzZTxULEQ+e30ge30KCQljb25zdGV4cHIgVmVjdG9yKFQgc2NhbGFyKSB7CgkJCXN0ZDo6ZmlsbChzdGQ6OmJlZ2luKHYpLCBzdGQ6OmVuZCh2KSwgc2NhbGFyKTsKCQl9CgkJCgkJY29uc3RleHByIFQmIG9wZXJhdG9yW10oc2l6ZV90eXBlIGkpIGNvbnN0IG5vZXhjZXB0IHsgcmV0dXJuIHZbaV07IH0KCQljb25zdGV4cHIgY29uc3QgVCYgb3BlcmF0b3JbXShzaXplX3R5cGUgaSkgbm9leGNlcHQgeyByZXR1cm4gdltpXTsgfQoJCQoJCWNvbnN0ZXhwciBzaXplX3R5cGUgc2l6ZSgpIGNvbnN0IG5vZXhjZXB0IHsgcmV0dXJuIEQ7IH0KCQkKCQljb25zdGV4cHIgVCogZGF0YSgpIG5vZXhjZXB0IHsgcmV0dXJuICZ2WzBdOyB9CgkJY29uc3RleHByIGNvbnN0IFQqIGRhdGEoKSBjb25zdCBub2V4Y2VwdCB7IHJldHVybiAmdlswXTsgfQoJfTsKCQogICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICAgIHVzaW5nIFZlY3RvcjIgPSBWZWN0b3I8VCwgMj47CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgogICAgdXNpbmcgVmVjdG9yMyA9IFZlY3RvcjxULCAzPjsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgICB1c2luZyBWZWN0b3I0ID0gVmVjdG9yPFQsIDQ+OwoJCglpbnQgbWFpbigpIHsKCQlWZWN0b3IzPGludD4gdnsxfTsKCQkKCQlzdGQ6OmNvdXQgPDwgdlswXSA8PCAiLCAiIDw8IHYueiA8PCAiXG4iOwoJCXJldHVybiAwOwoJfQoK