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