#pragma once namespace Rush { template struct Tuple2 { T x, y; T* begin() { return &x; } T* end() { return &y + 1; } const T* begin() const { return &x; } const T* end() const { return &y + 1; } static size_t size() { return 2; } bool operator==(const Tuple2& rhs) const { return x == rhs.x && y == rhs.y; } bool operator!=(const Tuple2& rhs) const { return x != rhs.x || y != rhs.y; } }; template struct Tuple3 { T x, y, z; T* begin() { return &x; } T* end() { return &z + 1; } const T* begin() const { return &x; } const T* end() const { return &z + 1; } static size_t size() { return 3; } bool operator==(const Tuple3& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z; } bool operator!=(const Tuple3& rhs) const { return x != rhs.x || y != rhs.y || z != rhs.z; } }; template struct Tuple4 { T x, y, z, w; T* begin() { return &x; } T* end() { return &w + 1; } const T* begin() const { return &x; } const T* end() const { return &w + 1; } static size_t size() { return 4; } bool operator==(const Tuple4& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w; } bool operator!=(const Tuple4& rhs) const { return x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w; } }; typedef Tuple2 Tuple2f; typedef Tuple3 Tuple3f; typedef Tuple4 Tuple4f; typedef Tuple2 Tuple2i; typedef Tuple3 Tuple3i; typedef Tuple4 Tuple4i; typedef Tuple2 Tuple2u; typedef Tuple3 Tuple3u; typedef Tuple4 Tuple4u; typedef Tuple2 Tuple2b; typedef Tuple3 Tuple3b; typedef Tuple4 Tuple4b; }