diff --git a/octa/utility.h b/octa/utility.h index 2a1bc82..bcb74e8 100644 --- a/octa/utility.h +++ b/octa/utility.h @@ -11,12 +11,16 @@ #include "octa/type_traits.h" namespace octa { + /* move */ + template static inline constexpr RemoveReference && move(T &&v) noexcept { return static_cast &&>(v); } + /* forward */ + template static inline constexpr T && forward(RemoveReference &v) noexcept { @@ -29,8 +33,12 @@ namespace octa { return static_cast(v); } + /* declval */ + template AddRvalueReference declval(); + /* swap */ + template void swap(T &a, T &b) noexcept(IsNothrowMoveConstructible::value && IsNothrowMoveAssignable::value) { @@ -38,12 +46,80 @@ namespace octa { a = move(b); b = move(c); } + template void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b))) { for (size_t i = 0; i < N; ++i) { swap(a[i], b[i]); } } + + /* pair */ + + template + struct Pair { + T first; + U second; + + Pair() = default; + ~Pair() = default; + + Pair(const Pair &) = default; + Pair(Pair &&) = default; + + Pair(const T &x, const U &y): first(x), second(y) {} + + template + Pair(TT &&x, UU &&y): first(forward(x)), second(forward(y)) {} + + template + Pair(const Pair &v): first(v.first), second(v.second) {} + + template + Pair(Pair &&v): first(move(v.first)), second(move(v.second)) {} + + Pair &operator=(const Pair &v) { + first = v.first; + second = v.second; + return *this; + } + + template + Pair &operator=(const Pair &v) { + first = v.first; + second = v.second; + return *this; + } + + Pair &operator=(Pair &&v) noexcept( + IsNothrowMoveAssignable::value + && IsNothrowMoveAssignable::value + ) { + first = move(v.first); + second = move(v.second); + return *this; + } + + template + Pair &operator=(Pair &&v) { + first = forward(v.first); + second = forward(v.second); + return *this; + } + + void swap(Pair &v) noexcept( + noexcept(octa::swap(first, v.first)) + && noexcept(octa::swap(second, v.second)) + ) { + octa::swap(first, v.first); + octa::swap(second, v.second); + } + }; + + template + void swap(Pair &a, Pair &b) noexcept(noexcept(a.swap(b))) { + a.swap(b); + } } #endif \ No newline at end of file