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