1#ifndef _OS_CPP_UTIL_H
2#define _OS_CPP_UTIL_H
3
4#include <sys/cdefs.h>
5#include <sys/_types/_size_t.h>
6
7#if __has_feature(cxx_nullptr) && __has_feature(cxx_decltype)
8# define OS_HAS_NULLPTR 1
9#endif
10
11#if __has_feature(cxx_rvalue_references) || __has_extension(cxx_rvalue_references)
12# define OS_HAS_RVALUE_REFERENCES 1
13#endif
14
15#if (defined(__has_include) && __has_include(<__xnu_libcxx_sentinel.h>) && __has_include(<new>))
16#include <new>
17#else
18void* operator new(size_t, void*) noexcept; // forward declaration needed for placement-new
19#endif
20
21namespace os {
22#if OS_HAS_NULLPTR
23typedef decltype(nullptr) nullptr_t;
24#endif
25
26/*
27 * Reference removal
28 */
29
30template <class _T> struct remove_reference {typedef _T type;};
31template <class _T> struct remove_reference<_T&> {typedef _T type;};
32template <class _T> struct remove_reference<_T &&> {typedef _T type;};
33template <class _T> using remove_reference_t = typename remove_reference<_T>::type;
34
35/*
36 * Pointer removal
37 */
38
39template <class _T> struct remove_pointer {typedef _T type;};
40template <class _T> struct remove_pointer<_T*> {typedef _T type;};
41template <class _T> struct remove_pointer<_T* const> {typedef _T type;};
42template <class _T> struct remove_pointer<_T* volatile> {typedef _T type;};
43template <class _T> struct remove_pointer<_T* const volatile> {typedef _T type;};
44template <class _T> using remove_pointer_t = typename remove_pointer<_T>::type;
45
46/*
47 * Const removal
48 */
49
50template <class _T> struct remove_const {typedef _T type;};
51template <class _T> struct remove_const<const _T> {typedef _T type;};
52template <class _T> using remove_const_t = typename remove_const<_T>::type;
53
54/*
55 * Volatile removal
56 */
57
58template <class _T> struct remove_volatile {typedef _T type;};
59template <class _T> struct remove_volatile<volatile _T> {typedef _T type;};
60template <class _T> using remove_volatile_t = typename remove_volatile<_T>::type;
61
62/*
63 * Extent removal
64 */
65
66template<class _T> struct remove_extent { typedef _T type; };
67template<class _T> struct remove_extent<_T[]> { typedef _T type; };
68template<class _T, size_t N> struct remove_extent<_T[N]> { typedef _T type; };
69template <class _T> using remove_extent_t = typename remove_extent<_T>::type;
70
71
72template <class T> struct is_lvalue_reference { static constexpr bool value = false; };
73template <class T> struct is_lvalue_reference<T&> { static constexpr bool value = true; };
74
75/*
76 * is_same
77 */
78
79template<class T, class U> struct is_same { static constexpr bool value = false; };
80template<class T> struct is_same<T, T> { static constexpr bool value = true; };
81
82/*
83 * Move
84 */
85
86template <class _T>
87inline typename remove_reference<_T>::type &&
88move(_T && _t)
89{
90 typedef typename os::remove_reference<_T>::type _U;
91 return static_cast<_U &&>(_t);
92}
93
94template <class T>
95T*
96move(T* first, T* last, T* d_first)
97{
98 for (; first != last; ++d_first, (void)++first) {
99 *d_first = os::move(*first);
100 }
101 return d_first;
102}
103
104template <class T>
105constexpr T && forward(os::remove_reference_t<T>&t) noexcept {
106 return static_cast<T &&>(t);
107}
108
109template <class T>
110constexpr T && forward(os::remove_reference_t<T>&& t) noexcept {
111 static_assert(!os::is_lvalue_reference<T>::value,
112 "can not forward an rvalue as an lvalue");
113 return static_cast<T &&>(t);
114}
115
116// Moves [first, last) into the range ending at d_last,
117// proceeding backwards (from last to first)
118// UB if d_last is within (first, last]
119template <class T>
120T*
121move_backward(T* first, T* last, T* d_last)
122{
123 while (first != last) {
124 *(--d_last) = os::move(*(--last));
125 }
126 return d_last;
127}
128
129template <class T>
130T*
131uninitialized_move(T* first, T* last, T* d_first)
132{
133 for (; first != last; ++d_first, (void) ++first) {
134 ::new (static_cast<void*>(d_first)) T(os::move(*first));
135 }
136 return first;
137}
138
139template <class T>
140void
141destroy(T* first, T* last)
142{
143 for (; first != last; ++first) {
144 first->~T();
145 }
146}
147
148template <class T>
149void
150uninitialized_value_construct(T* first, T* last)
151{
152 for (; first != last; ++first) {
153 ::new (static_cast<void*>(first)) T();
154 }
155}
156}
157
158#endif /* _OS_CPP_UTIL_H */
159