1 #ifndef _OS_CPP_UTIL_H 2 #define _OS_CPP_UTIL_H 3 4 #include <sys/cdefs.h> 5 6 #if __has_feature(cxx_nullptr) && __has_feature(cxx_decltype) 7 # define OS_HAS_NULLPTR 1 8 #endif 9 10 #if __has_feature(cxx_rvalue_references) || __has_extension(cxx_rvalue_references) 11 # define OS_HAS_RVALUE_REFERENCES 1 12 #endif 13 14 void* operator new(size_t, void*) noexcept; 15 16 namespace os { 17 #if OS_HAS_NULLPTR 18 typedef decltype(nullptr) nullptr_t; 19 #endif 20 21 /* 22 * Reference removal 23 */ 24 25 template <class _T> struct remove_reference {typedef _T type;}; 26 template <class _T> struct remove_reference<_T&> {typedef _T type;}; 27 template <class _T> struct remove_reference<_T &&> {typedef _T type;}; 28 template <class _T> using remove_reference_t = typename remove_reference<_T>::type; 29 30 /* 31 * Const removal 32 */ 33 34 template <class _T> struct remove_const {typedef _T type;}; 35 template <class _T> struct remove_const<const _T> {typedef _T type;}; 36 template <class _T> using remove_const_t = typename remove_const<_T>::type; 37 38 template <class T> struct is_lvalue_reference { static constexpr bool value = false; }; 39 template <class T> struct is_lvalue_reference<T&> { static constexpr bool value = true; }; 40 41 /* 42 * Move 43 */ 44 45 template <class _T> 46 inline typename remove_reference<_T>::type && 47 move(_T && _t) 48 { 49 typedef typename os::remove_reference<_T>::type _U; 50 return static_cast<_U &&>(_t); 51 } 52 53 template <class T> 54 T* 55 move(T* first, T* last, T* d_first) 56 { 57 for (; first != last; ++d_first, (void)++first) { 58 *d_first = os::move(*first); 59 } 60 return d_first; 61 } 62 63 template <class T> 64 constexpr T && forward(os::remove_reference_t<T>&t) noexcept { 65 return static_cast<T &&>(t); 66 } 67 68 template <class T> 69 constexpr T && forward(os::remove_reference_t<T>&& t) noexcept { 70 static_assert(!os::is_lvalue_reference<T>::value, 71 "can not forward an rvalue as an lvalue"); 72 return static_cast<T &&>(t); 73 } 74 75 // Moves [first, last) into the range ending at d_last, 76 // proceeding backwards (from last to first) 77 // UB if d_last is within (first, last] 78 template <class T> 79 T* 80 move_backward(T* first, T* last, T* d_last) 81 { 82 while (first != last) { 83 *(--d_last) = os::move(*(--last)); 84 } 85 return d_last; 86 } 87 88 template <class T> 89 T* 90 uninitialized_move(T* first, T* last, T* d_first) 91 { 92 for (; first != last; ++d_first, (void) ++first) { 93 ::new (static_cast<void*>(d_first)) T(os::move(*first)); 94 } 95 return first; 96 } 97 98 template <class T> 99 void 100 destroy(T* first, T* last) 101 { 102 for (; first != last; ++first) { 103 first->~T(); 104 } 105 } 106 107 template <class T> 108 void 109 uninitialized_value_construct(T* first, T* last) 110 { 111 for (; first != last; ++first) { 112 ::new (static_cast<void*>(first)) T(); 113 } 114 } 115 } 116 117 #endif /* _OS_CPP_UTIL_H */ 118