/* Utilities for OctaSTD. * * This file is part of OctaSTD. See COPYING.md for futher information. */ #ifndef OCTA_UTILITY_H #define OCTA_UTILITY_H #include /* must be in std namespace otherwise the compiler won't know about it */ namespace std { template class initializer_list { const T *p_buf; size_t p_len; initializer_list(const T *v, size_t n): p_buf(v), p_len(n) {} public: struct type { typedef T value; typedef T &reference; typedef const T &const_reference; typedef T *pointer; typedef const T *const_pointer; typedef size_t size; typedef ptrdiff_t difference; }; initializer_list(): p_buf(nullptr), p_len(0) {} size_t length() const { return p_len; } const T *get() const { return p_buf; } }; } namespace octa { template using InitializerList = std::initializer_list; template void swap(T &a, T &b) { T c(move(a)); a = move(b); b = move(c); } template void swap(T (&a)[N], T (&b)[N]) { for (size_t i = 0; i < N; ++i) { swap(a[i], b[i]); } } /* aliased in traits.h later */ namespace internal { template struct RemoveReference { typedef T type; }; template struct RemoveReference { typedef T type; }; template struct RemoveReference { typedef T type; }; template struct AddRvalueReference { typedef T &&type; }; template struct AddRvalueReference { typedef T &&type; }; template struct AddRvalueReference { typedef T &&type; }; template<> struct AddRvalueReference { typedef void type; }; template<> struct AddRvalueReference { typedef const void type; }; template<> struct AddRvalueReference { typedef volatile void type; }; template<> struct AddRvalueReference { typedef const volatile void type; }; } template static inline constexpr typename internal::RemoveReference::type && move(T &&v) noexcept { return static_cast::type &&>(v); } template static inline constexpr T && forward(typename internal::RemoveReference::type &v) noexcept { return static_cast(v); } template static inline constexpr T && forward(typename internal::RemoveReference::type &&v) noexcept { return static_cast(v); } template typename internal::AddRvalueReference::type declval(); namespace internal { template struct MemTypes; template struct MemTypes { typedef R result; typedef T argument; }; template struct MemTypes { typedef R result; typedef T argument; typedef T first; typedef A second; }; template struct MemTypes { typedef R result; typedef const T argument; }; template struct MemTypes { typedef R result; typedef const T argument; typedef const T first; typedef A second; }; template class MemFn { R T::*p_ptr; public: struct type: MemTypes {}; MemFn(R T::*ptr): p_ptr(ptr) {} template auto operator()(T &obj, A &&...args) -> decltype(((obj).*(p_ptr))(args...)) { return ((obj).*(p_ptr))(args...); } template auto operator()(const T &obj, A &&...args) -> decltype(((obj).*(p_ptr))(args...)) const { return ((obj).*(p_ptr))(args...); } template auto operator()(T *obj, A &&...args) -> decltype(((obj)->*(p_ptr))(args...)) { return ((obj)->*(p_ptr))(args...); } template auto operator()(const T *obj, A &&...args) -> decltype(((obj)->*(p_ptr))(args...)) const { return ((obj)->*(p_ptr))(args...); } }; } template internal::MemFn mem_fn(R T:: *ptr) { return internal::MemFn(ptr); } } #endif