/* 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) noexcept { return static_cast &&>(v); } /* forward */ template static inline constexpr T && forward(RemoveReference &v) noexcept { return static_cast(v); } template static inline constexpr T && forward(RemoveReference &&v) noexcept { return static_cast(v); } /* declval */ template AddRvalueReference declval(); /* swap */ template void swap(T &a, T &b) noexcept( IsNothrowMoveConstructible::value && IsNothrowMoveAssignable::value ) { T c(move(a)); 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() noexcept( IsNothrowDefaultConstructible::value && IsNothrowDefaultConstructible::value ) = default; ~Pair() = default; Pair(const Pair &) noexcept( IsNothrowCopyConstructible::value && IsNothrowCopyConstructible::value ) = default; Pair(Pair &&) noexcept( IsNothrowMoveConstructible::value && IsNothrowMoveConstructible::value ) = default; Pair(const T &x, const U &y) noexcept( IsNothrowCopyConstructible::value && IsNothrowCopyConstructible::value ): first(x), second(y) {} template Pair(TT &&x, UU &&y): first(forward(x)), second(forward(y)) {} template Pair(const Pair &v) noexcept( IsNothrowCopyConstructible::value && IsNothrowCopyConstructible::value ): first(v.first), second(v.second) {} template Pair(Pair &&v) noexcept( IsNothrowMoveConstructible::value && IsNothrowMoveConstructible::value ): first(move(v.first)), second(move(v.second)) {} Pair &operator=(const Pair &v) noexcept( IsNothrowCopyAssignable::value && IsNothrowCopyAssignable::value ) { first = v.first; second = v.second; return *this; } template Pair &operator=(const Pair &v) noexcept( IsNothrowCopyAssignable::value && IsNothrowCopyAssignable::value ) { 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