]> git.saurik.com Git - apple/xnu.git/blame - libkern/os/cpp_util.h
xnu-7195.101.1.tar.gz
[apple/xnu.git] / libkern / os / cpp_util.h
CommitLineData
cb323159
A
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
f427ee49
A
14void* operator new(size_t, void*);
15
cb323159
A
16namespace os {
17#if OS_HAS_NULLPTR
18typedef decltype(nullptr) nullptr_t;
19#endif
20
21/*
22 * Reference removal
23 */
24
25template <class _T> struct remove_reference {typedef _T type;};
26template <class _T> struct remove_reference<_T&> {typedef _T type;};
27template <class _T> struct remove_reference<_T &&> {typedef _T type;};
28template <class _T> using remove_reference_t = typename remove_reference<_T>::type;
29
30/*
31 * Const removal
32 */
33
34template <class _T> struct remove_const {typedef _T type;};
35template <class _T> struct remove_const<const _T> {typedef _T type;};
36template <class _T> using remove_const_t = typename remove_const<_T>::type;
37
f427ee49
A
38template <class T> struct is_lvalue_reference { static constexpr bool value = false; };
39template <class T> struct is_lvalue_reference<T&> { static constexpr bool value = true; };
40
cb323159
A
41/*
42 * Move
43 */
44
45template <class _T>
46inline typename remove_reference<_T>::type &&
47move(_T && _t)
48{
49 typedef typename os::remove_reference<_T>::type _U;
50 return static_cast<_U &&>(_t);
51}
f427ee49
A
52
53template <class T>
54T*
55move(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
63template <class T>
64constexpr T && forward(os::remove_reference_t<T>&t) noexcept {
65 return static_cast<T &&>(t);
66}
67
68template <class T>
69constexpr 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]
78template <class T>
79T*
80move_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
88template <class T>
89T*
90uninitialized_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
98template <class T>
99void
100destroy(T* first, T* last)
101{
102 for (; first != last; ++first) {
103 first->~T();
104 }
105}
106
107template <class T>
108void
109uninitialized_value_construct(T* first, T* last)
110{
111 for (; first != last; ++first) {
112 ::new (static_cast<void*>(first)) T();
113 }
114}
cb323159
A
115}
116
117#endif /* _OS_CPP_UTIL_H */