/* Utilities for OctaSTD. * * This file is part of OctaSTD. See COPYING.md for futher information. */ #ifndef OCTA_UTILITY_H #define OCTA_UTILITY_H #include #include "octa/type_traits.h" namespace octa { /* move */ template static inline constexpr RemoveReference &&move(T &&v) { return static_cast &&>(v); } /* forward */ template static inline constexpr T &&forward(RemoveReference &v) { return static_cast(v); } template static inline constexpr T &&forward(RemoveReference &&v) { return static_cast(v); } /* declval */ template AddRvalueReference declval(); /* swap */ template struct __OctaSwapTest { template struct __OctaTest {}; template static char __octa_test(__OctaTest *); template static int __octa_test(...); static constexpr bool value = (sizeof(__octa_test(0)) == sizeof(char)); }; template inline void __octa_swap(T &a, T &b, EnableIf< __OctaSwapTest::value, bool > = true) { a.swap(b); } template inline void __octa_swap(T &a, T &b, EnableIf< !__OctaSwapTest::value, bool > = true) { T c(move(a)); a = move(b); b = move(c); } template void swap(T &a, T &b) { __octa_swap(a, b); } template void swap(T (&a)[N], T (&b)[N]) { 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) { 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) { octa::swap(first, v.first); octa::swap(second, v.second); } }; } #endif