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

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

cpp: added the rest of pair specialized algorithms

  • Property mode set to 100644
File size: 8.7 KB
RevLine 
[b1cd380c]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
[de53138]32#include <cstdint>
[7a666789]33#include <internal/type_transformation.hpp>
[2084bfcd]34#include <type_traits>
35
[b1cd380c]36namespace std
37{
38 /**
39 * 20.2.1, operators:
40 */
[aab972f]41
[f041811]42 namespace rel_ops
[b1cd380c]43 {
[f041811]44 template<typename T>
45 bool operator!=(const T& lhs, const T& rhs)
46 {
47 return !(lhs == rhs);
48 }
[b1cd380c]49
[f041811]50 template<typename T>
51 bool operator>(const T& lhs, const T& rhs)
52 {
53 return (rhs < lhs);
54 }
[b1cd380c]55
[f041811]56 template<typename T>
57 bool operator<=(const T& lhs, const T& rhs)
58 {
59 return !(rhs < lhs);
60 }
[b1cd380c]61
[f041811]62 template<typename T>
63 bool operator>=(const T& lhs, const T& rhs)
64 {
65 return !(lhs < rhs);
66 }
[b1cd380c]67 }
68
[add816c7]69 /**
70 * 20.2.4, forward/move helpers:
71 */
72
73 template<class T>
[79f35d40]74 constexpr T&& forward(remove_reference_t<T>& t) noexcept
[add816c7]75 {
76 return static_cast<T&&>(t);
77 }
78
79 template<class T>
[79f35d40]80 constexpr T&& forward(remove_reference_t<T>&& t) noexcept
[add816c7]81 {
82 return static_cast<T&&>(t);
83 }
84
85 template<class T>
[79f35d40]86 constexpr remove_reference_t<T>&& move(T&& t) noexcept
[add816c7]87 {
88 return static_cast<remove_reference_t<T>&&>(t);
89 }
90
[5abc7fd]91 /**
92 * 20.2.2, swap:
93 */
94
95 template<class T>
96 void swap(T& x, T& y)
[18944e0]97 /* noexcept(is_nothrow_move_constructible<T>::value && */
98 /* is_nothrow_move_assignable<T>::value) */
[5abc7fd]99 {
[add816c7]100 T tmp{move(x)};
101 x = move(y);
102 y = move(tmp);
[5abc7fd]103 }
104
105 template<class T, size_t N>
106 void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)))
107 {
108 // TODO: Use swap_ranges(a, a + N, b); when implemented.
109 }
110
111 /**
112 * 20.2.3, exchange:
113 */
114
115 template<class T, class U = T>
116 T exchange(T& obj, U&& new_val)
117 {
[add816c7]118 T old_val = move(obj);
119 obj = forward<U>(new_val);
[5abc7fd]120
121 return old_val;
122 }
[b1cd380c]123
124 /**
125 * 20.2.5, function template declval:
126 * Note: This function only needs declaration, not
127 * implementation.
128 */
129
130 template<class T>
131 add_rvalue_reference_t<T> declval() noexcept;
132
133 /**
134 * 20.3, pairs:
135 */
136
137 struct piecewise_construct_t
138 {
139 explicit piecewise_construct_t() = default;
140 };
141
142 template<typename T1, typename T2>
143 struct pair
144 {
145 using first_type = T1;
146 using second_type = T2;
147
148 T1 first;
149 T2 second;
150
151 pair(const pair&) = default;
152 pair(pair&&) = default;
153
154 constexpr pair()
155 : first{}, second{}
156 { /* DUMMY BODY */ }
157
158 constexpr pair(const T1& x, const T2& y)
159 : first{x}, second{y}
160 { /* DUMMY BODY */ }
161
162 template<typename U, typename V>
163 constexpr pair(U&& x, V&& y)
164 : first(x), second(y)
165 { /* DUMMY BODY */ }
166
167 template<typename U, typename V>
168 constexpr pair(const pair<U, V>& other)
169 : first(other.first), second(other.second)
170 { /* DUMMY BODY */ }
171
172 template<typename U, typename V>
173 constexpr pair(pair<U, V>&& other)
174 : first(forward<first_type>(other.first)),
175 second(forward<second_type>(other.second))
176 { /* DUMMY BODY */ }
177
178 /* TODO: need tuple, piecewise_construct_t
179 template<class... Args1, class... Args2>
180 pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args)
181 {
182 // TODO:
183 }
184 */
185
186 pair& operator=(const pair& other)
187 {
188 first = other.first;
189 second = other.second;
190
191 return *this;
192 }
193
194 template<typename U, typename V>
195 pair& operator=(const pair<U, V>& other)
196 {
197 first = other.first;
198 second = other.second;
199
200 return *this;
201 }
202
203 pair& operator=(pair&& other) noexcept
204 {
205 first = forward<first_type>(other.first);
206 second = forward<second_type>(other.second);
207
208 return *this;
209 }
210 };
[82ef902]211
[7a666789]212 /**
213 * 20.3.3, specialized algorithms:
214 */
215
[82d256e]216 template<class T1, class T2>
217 constexpr bool operator==(const pair<T1, T2>& lhs,
218 const pair<T1, T2>& rhs)
219 {
220 return lhs.first == rhs.first && lhs.second == rhs.second;
221 }
222
223 template<class T1, class T2>
224 constexpr bool operator<(const pair<T1, T2>& lhs,
225 const pair<T1, T2>& rhs)
226 {
227 return lhs.first < rhs.first ||
228 (!(rhs.first < lhs.first) && lhs.second < rhs.second);
229 }
230
231 template<class T1, class T2>
232 constexpr bool operator!=(const pair<T1, T2>& lhs,
233 const pair<T1, T2>& rhs)
234 {
235 return !(lhs == rhs);
236 }
237
238 template<class T1, class T2>
239 constexpr bool operator>(const pair<T1, T2>& lhs,
240 const pair<T1, T2>& rhs)
241 {
242 return rhs < lhs;
243 }
244
245 template<class T1, class T2>
246 constexpr bool operator>=(const pair<T1, T2>& lhs,
247 const pair<T1, T2>& rhs)
248 {
249 return !(lhs < rhs);
250 }
251
252 template<class T1, class T2>
253 constexpr bool operator<=(const pair<T1, T2>& lhs,
254 const pair<T1, T2>& rhs)
255 {
256 return !(rhs < lhs);
257 }
258
259 template<class T1, class T2>
260 constexpr void swap(pair<T1, T2>& lhs, pair<T1, T2>& rhs)
261 noexcept(noexcept(lhs.swap(rhs)))
262 {
263 lhs.swap(rhs);
264 }
[7a666789]265
266 template<class T1, class T2>
267 constexpr auto make_pair(T1&& t1, T2&& t2)
268 {
269 return pair<
270 aux::transform_tuple_types_t<T1>,
271 aux::transform_tuple_types_t<T2>
272 >{
273 forward<T1>(t1), forward<T2>(t2)
274 };
275 }
276
277 /**
278 * 20.3.4, tuple-like access to pair:
279 */
280
281 // TODO: implement
282
[82ef902]283 /**
284 * 20.5.2, class template integer_sequence:
285 */
286
287 template<class T, T... Is>
288 struct integer_sequence
289 {
290 using value_type = T;
291
292 static constexpr size_t size() noexcept
293 {
294 return sizeof...(Is);
295 }
296
297 using next = integer_sequence<T, Is..., sizeof...(Is)>;
298 };
299
300 template<std::size_t... Is>
301 using index_sequence = integer_sequence<std::size_t, Is...>;
302
303 /**
304 * 20.5.3, alias template make_integer_sequence:
305 */
306
307 namespace aux
308 {
[de53138]309 template<class T, uintmax_t N>
[82ef902]310 struct make_integer_sequence
311 {
312 /**
313 * Recursive to the bottom case below, appends sizeof...(Is) in
314 * every next "call", building the sequence.
315 */
316 using type = typename make_integer_sequence<T, N - 1>::type::next;
317 };
318
319 template<class T>
320 struct make_integer_sequence<T, std::uintmax_t(0)>
321 {
322 using type = integer_sequence<T>;
323 };
324 }
325
326
327 /**
328 * Problem: We can't specialize the N parameter because it is a value parameter
329 * depending on a type parameter.
330 * Solution: According to the standard: if N is negative, the program is ill-formed,
331 * so we just recast it to uintmax_t :)
332 */
333 template<class T, T N>
334 using make_integer_sequence = typename aux::make_integer_sequence<T, std::uintmax_t(N)>::type;
335
336 template<size_t N>
337 using make_index_sequence = make_integer_sequence<std::size_t, N>;
[b1cd380c]338}
339
340#endif
Note: See TracBrowser for help on using the repository browser.