source: mainline/uspace/lib/cpp/include/impl/utility.hpp@ e5cf551

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e5cf551 was de53138, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: revamped c header wrappers, now only include standard symbols, others are in std::hel, fixed some bugs

  • Property mode set to 100644
File size: 6.9 KB
Line 
1/*
2 * Copyright (c) 2017 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_UTILITY
30#define LIBCPP_UTILITY
31
32#include <cstdint>
33#include <type_traits>
34
35namespace std
36{
37 /**
38 * 20.2.1, operators:
39 */
40
41 namespace rel_ops
42 {
43 template<typename T>
44 bool operator!=(const T& lhs, const T& rhs)
45 {
46 return !(lhs == rhs);
47 }
48
49 template<typename T>
50 bool operator>(const T& lhs, const T& rhs)
51 {
52 return (rhs < lhs);
53 }
54
55 template<typename T>
56 bool operator<=(const T& lhs, const T& rhs)
57 {
58 return !(rhs < lhs);
59 }
60
61 template<typename T>
62 bool operator>=(const T& lhs, const T& rhs)
63 {
64 return !(lhs < rhs);
65 }
66 }
67
68 /**
69 * 20.2.4, forward/move helpers:
70 */
71
72 template<class T>
73 constexpr T&& forward(remove_reference_t<T>& t) noexcept
74 {
75 return static_cast<T&&>(t);
76 }
77
78 template<class T>
79 constexpr T&& forward(remove_reference_t<T>&& t) noexcept
80 {
81 return static_cast<T&&>(t);
82 }
83
84 template<class T>
85 constexpr remove_reference_t<T>&& move(T&& t) noexcept
86 {
87 return static_cast<remove_reference_t<T>&&>(t);
88 }
89
90 /**
91 * 20.2.2, swap:
92 */
93
94 template<class T>
95 void swap(T& x, T& y)
96 /* noexcept(is_nothrow_move_constructible<T>::value && */
97 /* is_nothrow_move_assignable<T>::value) */
98 {
99 T tmp{move(x)};
100 x = move(y);
101 y = move(tmp);
102 }
103
104 template<class T, size_t N>
105 void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)))
106 {
107 // TODO: Use swap_ranges(a, a + N, b); when implemented.
108 }
109
110 /**
111 * 20.2.3, exchange:
112 */
113
114 template<class T, class U = T>
115 T exchange(T& obj, U&& new_val)
116 {
117 T old_val = move(obj);
118 obj = forward<U>(new_val);
119
120 return old_val;
121 }
122
123 /**
124 * 20.2.5, function template declval:
125 * Note: This function only needs declaration, not
126 * implementation.
127 */
128
129 template<class T>
130 add_rvalue_reference_t<T> declval() noexcept;
131
132 /**
133 * 20.3, pairs:
134 */
135
136 struct piecewise_construct_t
137 {
138 explicit piecewise_construct_t() = default;
139 };
140
141 template<typename T1, typename T2>
142 struct pair
143 {
144 using first_type = T1;
145 using second_type = T2;
146
147 T1 first;
148 T2 second;
149
150 pair(const pair&) = default;
151 pair(pair&&) = default;
152
153 constexpr pair()
154 : first{}, second{}
155 { /* DUMMY BODY */ }
156
157 constexpr pair(const T1& x, const T2& y)
158 : first{x}, second{y}
159 { /* DUMMY BODY */ }
160
161 template<typename U, typename V>
162 constexpr pair(U&& x, V&& y)
163 : first(x), second(y)
164 { /* DUMMY BODY */ }
165
166 template<typename U, typename V>
167 constexpr pair(const pair<U, V>& other)
168 : first(other.first), second(other.second)
169 { /* DUMMY BODY */ }
170
171 template<typename U, typename V>
172 constexpr pair(pair<U, V>&& other)
173 : first(forward<first_type>(other.first)),
174 second(forward<second_type>(other.second))
175 { /* DUMMY BODY */ }
176
177 /* TODO: need tuple, piecewise_construct_t
178 template<class... Args1, class... Args2>
179 pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args)
180 {
181 // TODO:
182 }
183 */
184
185 pair& operator=(const pair& other)
186 {
187 first = other.first;
188 second = other.second;
189
190 return *this;
191 }
192
193 template<typename U, typename V>
194 pair& operator=(const pair<U, V>& other)
195 {
196 first = other.first;
197 second = other.second;
198
199 return *this;
200 }
201
202 pair& operator=(pair&& other) noexcept
203 {
204 first = forward<first_type>(other.first);
205 second = forward<second_type>(other.second);
206
207 return *this;
208 }
209 };
210
211 /**
212 * 20.5.2, class template integer_sequence:
213 */
214
215 template<class T, T... Is>
216 struct integer_sequence
217 {
218 using value_type = T;
219
220 static constexpr size_t size() noexcept
221 {
222 return sizeof...(Is);
223 }
224
225 using next = integer_sequence<T, Is..., sizeof...(Is)>;
226 };
227
228 template<std::size_t... Is>
229 using index_sequence = integer_sequence<std::size_t, Is...>;
230
231 /**
232 * 20.5.3, alias template make_integer_sequence:
233 */
234
235 namespace aux
236 {
237 template<class T, uintmax_t N>
238 struct make_integer_sequence
239 {
240 /**
241 * Recursive to the bottom case below, appends sizeof...(Is) in
242 * every next "call", building the sequence.
243 */
244 using type = typename make_integer_sequence<T, N - 1>::type::next;
245 };
246
247 template<class T>
248 struct make_integer_sequence<T, std::uintmax_t(0)>
249 {
250 using type = integer_sequence<T>;
251 };
252 }
253
254
255 /**
256 * Problem: We can't specialize the N parameter because it is a value parameter
257 * depending on a type parameter.
258 * Solution: According to the standard: if N is negative, the program is ill-formed,
259 * so we just recast it to uintmax_t :)
260 */
261 template<class T, T N>
262 using make_integer_sequence = typename aux::make_integer_sequence<T, std::uintmax_t(N)>::type;
263
264 template<size_t N>
265 using make_index_sequence = make_integer_sequence<std::size_t, N>;
266}
267
268#endif
Note: See TracBrowser for help on using the repository browser.