Embedded Template Library 1.0
utility.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2016 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_UTILITY_INCLUDED
32#define ETL_UTILITY_INCLUDED
33
34#include "platform.h"
35#include "type_traits.h"
36
37#if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL
38 #if ETL_USING_CPP11
39 #include <utility>
40 #else
41 #include <algorithm>
42 #endif
43#endif
44
47
48namespace etl
49{
50#if ETL_USING_CPP11
51 //******************************************************************************
52 template <typename T>
53 constexpr typename etl::remove_reference<T>::type&& move(T&& t) ETL_NOEXCEPT
54 {
55 return static_cast<typename etl::remove_reference<T>::type&&>(t);
56 }
57
58 //******************************************************************************
59 template <typename T>
60 constexpr T&& forward(typename etl::remove_reference<T>::type& t) ETL_NOEXCEPT
61 {
62 return static_cast<T&&>(t);
63 }
64
65 template <typename T>
66 constexpr T&& forward(typename etl::remove_reference<T>::type&& t) ETL_NOEXCEPT
67 {
68 ETL_STATIC_ASSERT(!etl::is_lvalue_reference<T>::value, "Invalid rvalue to lvalue conversion");
69 return static_cast<T&&>(t);
70 }
71
72 //******************************************************************************
78 //******************************************************************************
79 //***********************************
81 //***********************************
82 template <typename T, typename U>
83 ETL_NODISCARD
84 ETL_CONSTEXPR
85 etl::enable_if_t<etl::is_const<etl::remove_reference_t<T>>::value && etl::is_lvalue_reference<T>::value, const etl::remove_reference_t<U>&>
86 forward_like(U&& u) ETL_NOEXCEPT
87 {
88 return static_cast<const etl::remove_reference_t<U>&>(u);
89 }
90
91 //***********************************
93 //***********************************
94 template <typename T, typename U>
95 ETL_NODISCARD
96 ETL_CONSTEXPR
97 etl::enable_if_t<etl::is_const<etl::remove_reference_t<T>>::value && !etl::is_lvalue_reference<T>::value, const etl::remove_reference_t<U>&&>
98 forward_like(U&& u) ETL_NOEXCEPT
99 {
100 return static_cast<const etl::remove_reference_t<U>&&>(u);
101 }
102
103 //***********************************
105 //***********************************
106 template <typename T, typename U>
107 ETL_NODISCARD
108 ETL_CONSTEXPR
109 etl::enable_if_t<!etl::is_const<etl::remove_reference_t<T>>::value && etl::is_lvalue_reference<T>::value, etl::remove_reference_t<U>&>
110 forward_like(U&& u) ETL_NOEXCEPT
111 {
112 return static_cast<etl::remove_reference_t<U>&>(u);
113 }
114
115 //***********************************
117 //***********************************
118 template <typename T, typename U>
119 ETL_NODISCARD
120 ETL_CONSTEXPR
121 etl::enable_if_t<!etl::is_const<etl::remove_reference_t<T>>::value && !etl::is_lvalue_reference<T>::value, etl::remove_reference_t<U>&&>
122 forward_like(U&& u) ETL_NOEXCEPT
123 {
124 return static_cast<etl::remove_reference_t<U>&&>(u);
125 }
126
127 //***********************************
128 // Defines the type that forward_like would cast to.
129 //***********************************
130 template <typename T, typename U>
131 using forward_like_t = decltype(etl::forward_like<T>(etl::declval<U&>()));
132#endif
133
134 // We can't have std::swap and etl::swap templates coexisting in the unit tests
135 // as the compiler will be unable to decide of which one to use, due to ADL.
136#if ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST)
137 //***************************************************************************
138 // swap
139 template <typename T>
140 ETL_CONSTEXPR14 void swap(T& a, T& b) ETL_NOEXCEPT
141 {
142 T temp(ETL_MOVE(a));
143 a = ETL_MOVE(b);
144 b = ETL_MOVE(temp);
145 }
146
147 template< class T, size_t N >
148 ETL_CONSTEXPR14 void swap(T(&a)[N], T(&b)[N]) ETL_NOEXCEPT
149 {
150 for (size_t i = 0UL; i < N; ++i)
151 {
152 swap(a[i], b[i]);
153 }
154 }
155#endif
156
157 //***************************************************************************
161 //***************************************************************************
162 template <typename T1, typename T2>
163 struct pair
164 {
165 typedef T1 first_type;
166 typedef T2 second_type;
167
168 T1 first;
170
171 //***************************************************************************
175 //***************************************************************************
176 ETL_CONSTEXPR pair()
177 : first(T1())
178 , second(T2())
179 {
180 }
181
182 //***************************************************************************
186 //***************************************************************************
187 ETL_CONSTEXPR14 pair(const T1& a, const T2& b)
188 : first(a)
189 , second(b)
190 {
191 }
192
193#if ETL_USING_CPP11
194 //***************************************************************************
196 //***************************************************************************
197 template <typename U1, typename U2>
198 ETL_CONSTEXPR14 pair(U1&& a, U2&& b)
199 : first(etl::forward<U1>(a))
200 , second(etl::forward<U2>(b))
201 {
202 }
203#endif
204
205 //***************************************************************************
209 //***************************************************************************
210 template <typename U1, typename U2>
211 ETL_CONSTEXPR14 pair(const pair<U1, U2>& other)
212 : first(other.first)
213 , second(other.second)
214 {
215 }
216
218 pair(const pair<T1, T2>& other)
219 : first(other.first)
220 , second(other.second)
221 {
222 }
223
224#if ETL_USING_CPP11
226 template <typename U1, typename U2>
227 ETL_CONSTEXPR14 pair(pair<U1, U2>&& other)
228 : first(etl::forward<U1>(other.first))
229 , second(etl::forward<U2>(other.second))
230 {
231 }
232#endif
233
234#if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL
236 template <typename U1, typename U2>
237 operator std::pair<U1, U2>()
238 {
239 return std::make_pair(first, second);
240 }
241
243 template <typename U1, typename U2>
244 pair(const std::pair<U1, U2>& other)
245 : first(other.first)
246 , second(other.second)
247 {
248 }
249
250#if ETL_USING_CPP11
252 template <typename U1, typename U2>
253 pair(std::pair<U1, U2>&& other)
254 : first(etl::forward<U1>(other.first))
255 , second(etl::forward<U2>(other.second))
256 {
257 }
258#endif
259#endif
260
261 void swap(pair<T1, T2>& other)
262 {
263 using ETL_OR_STD::swap;
264
265 swap(first, other.first);
266 swap(second, other.second);
267 }
268
269 pair<T1, T2>& operator =(const pair<T1, T2>& other)
270 {
271 first = other.first;
272 second = other.second;
273
274 return *this;
275 }
276
277 template <typename U1, typename U2>
278 pair<U1, U2>& operator =(const pair<U1, U2>& other)
279 {
280 first = other.first;
281 second = other.second;
282
283 return *this;
284 }
285
286#if ETL_USING_CPP11
287 pair<T1, T2>& operator =(pair<T1, T2>&& other)
288 {
289 first = etl::forward<T1>(other.first);
290 second = etl::forward<T2>(other.second);
291
292 return *this;
293 }
294
295 template <typename U1, typename U2>
296 pair<U1, U2>& operator =(pair<U1, U2>&& other)
297 {
298 first = etl::forward<U1>(other.first);
299 second = etl::forward<U2>(other.second);
300
301 return *this;
302 }
303#endif
304 };
305
306 //***************************************************************************
313 //***************************************************************************
314#if ETL_USING_CPP11
315 template <typename T1, typename T2>
316 inline pair<T1, T2> make_pair(T1&& a, T2&& b)
317 {
318 return pair<T1, T2>(etl::forward<T1>(a), etl::forward<T2>(b));
319 }
320#else
321 template <typename T1, typename T2>
322 inline pair<T1, T2> make_pair(T1 a, T2 b)
323 {
324 return pair<T1, T2>(a, b);
325 }
326#endif
327
328 //******************************************************************************
329 template <typename T1, typename T2>
330 inline void swap(pair<T1, T2>& a, pair<T1, T2>& b)
331 {
332 a.swap(b);
333 }
334
336 template <typename T1, typename T2>
337 inline bool operator ==(const pair<T1, T2>& a, const pair<T1, T2>& b)
338 {
339 return (a.first == b.first) && (a.second == b.second);
340 }
341
343 template <typename T1, typename T2>
344 inline bool operator !=(const pair<T1, T2>& a, const pair<T1, T2>& b)
345 {
346 return !(a == b);
347 }
348
349 template <typename T1, typename T2>
350 inline bool operator <(const pair<T1, T2>& a, const pair<T1, T2>& b)
351 {
352 return (a.first < b.first) ||
353 (!(b.first < a.first) && (a.second < b.second));
354 }
355
357 template <typename T1, typename T2>
358 inline bool operator >(const pair<T1, T2>& a, const pair<T1, T2>& b)
359 {
360 return (b < a);
361 }
362
364 template <typename T1, typename T2>
365 inline bool operator <=(const pair<T1, T2>& a, const pair<T1, T2>& b)
366 {
367 return !(b < a);
368 }
369
371 template <typename T1, typename T2>
372 inline bool operator >=(const pair<T1, T2>& a, const pair<T1, T2>& b)
373 {
374 return !(a < b);
375 }
376
377 //***************************************************************************
388 //***************************************************************************
389 template <typename TPair>
391 {
392 typedef typename TPair::first_type type;
393
394 //***************************************************************************
397 //***************************************************************************
398 type& operator()(TPair& p) const
399 {
400 return p.first;
401 }
402
403 //***************************************************************************
405 //
406 const type& operator()(const TPair& p) const
407 {
408 return p.first;
409 }
410 };
411
412 //***************************************************************************
423 //***************************************************************************
424 template <typename TPair>
426 {
427 typedef typename TPair::second_type type;
428
429 //***************************************************************************
432 //***************************************************************************
433 type& operator()(TPair& p) const
434 {
435 return p.second;
436 }
437
438 //***************************************************************************
440 //***************************************************************************
441 const type& operator()(const TPair& p) const
442 {
443 return p.second;
444 }
445 };
446
447#if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED
448 //***************************************************************************
450 //***************************************************************************
451 template <typename T>
452 T exchange(T& object, const T& new_value)
453 {
454 T old_value = object;
455 object = new_value;
456 return old_value;
457 }
458
459 template <typename T, typename U>
460 T exchange(T& object, const U& new_value)
461 {
462 T old_value = object;
463 object = new_value;
464 return old_value;
465 }
466#else
467 //***************************************************************************
469 //***************************************************************************
470 template <typename T, typename U = T>
471 T exchange(T& object, const U& new_value)
472 {
473 return std::exchange(object, new_value);
474 }
475#endif
476
477 //***************************************************************************
479 //***************************************************************************
480 template <typename T>
481 typename etl::add_const<T>::type& as_const(T& t)
482 {
483 return t;
484 }
485
486 //***************************************************************************
488 //***************************************************************************
489#if ETL_USING_CPP11
490 template <typename T, T... Integers>
491 class integer_sequence
492 {
493 public:
494
495 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Integral types only");
496
497 typedef T value_type;
498
499 static ETL_CONSTEXPR size_t size() ETL_NOEXCEPT
500 {
501 return sizeof...(Integers);
502 }
503 };
504
505 namespace private_integer_sequence
506 {
507 template <size_t N, typename IndexSeq>
508 struct make_index_sequence;
509
510 template <size_t N, size_t... Indices>
511 struct make_index_sequence<N, etl::integer_sequence<size_t, Indices...>>
512 {
513 typedef typename make_index_sequence<N - 1, etl::integer_sequence<size_t, N - 1, Indices...>>::type type;
514 };
515
516 template <size_t... Indices>
517 struct make_index_sequence<0, etl::integer_sequence<size_t, Indices...>>
518 {
519 typedef etl::integer_sequence<size_t, Indices...> type;
520 };
521 }
522
523 //***********************************
524 template <size_t N>
525 using make_index_sequence = typename private_integer_sequence::make_index_sequence<N, etl::integer_sequence<size_t>>::type;
526
527 //***********************************
528 template <size_t... Indices>
529 using index_sequence = etl::integer_sequence<size_t, Indices...>;
530#endif
531
532 //***************************************************************************
534 //***************************************************************************
535 template <typename T>
537 {
539 : x(T(0))
540 , y(T(0))
541 {
542 }
543
544 coordinate_2d(T x_, T y_)
545 : x(x_)
546 , y(y_)
547 {
548 }
549
550 friend bool operator ==(const coordinate_2d& lhs, const coordinate_2d& rhs)
551 {
552 return (lhs.x == rhs.x) && (lhs.y == rhs.y);
553 }
554
555 friend bool operator !=(const coordinate_2d& lhs, const coordinate_2d& rhs)
556 {
557 return !(lhs == rhs);
558 }
559
560 T x;
561 T y;
562 };
563
564 //***************************************************************************
566 //***************************************************************************
567
568 //*************************
570 {
571 explicit ETL_CONSTEXPR in_place_t() {}
572 };
573
574#if ETL_USING_CPP17
575 inline constexpr in_place_t in_place{};
576#endif
577
578 //*************************
579 template <typename T> struct in_place_type_t
580 {
581 explicit ETL_CONSTEXPR in_place_type_t() {};
582 };
583
584#if ETL_USING_CPP17
585 template <typename T>
586 inline constexpr in_place_type_t<T> in_place_type{};
587#endif
588
589 //*************************
590 template <size_t I> struct in_place_index_t
591 {
592 explicit ETL_CONSTEXPR in_place_index_t() {}
593 };
594
595#if ETL_USING_CPP17
596 template <size_t I>
597 inline constexpr in_place_index_t<I> in_place_index{};
598#endif
599
600#if ETL_USING_CPP11
601 //*************************************************************************
603 //*************************************************************************
604 template <typename TReturn, typename... TParams>
605 class functor
606 {
607 public:
608
609 //*********************************
611 //*********************************
612 constexpr functor(TReturn(*ptr_)(TParams...))
613 : ptr(ptr_)
614 {
615 }
616
617 //*********************************
619 //*********************************
620 constexpr TReturn operator()(TParams... args) const
621 {
622 return ptr(etl::forward<TParams>(args)...);
623 }
624
625 private:
626
628 TReturn(*ptr)(TParams...);
629 };
630#endif
631
632#if ETL_USING_CPP11
633 //*****************************************************************************
634 // A wrapper for a member function
635 // Creates a static member function that calls the specified member function.
636 //*****************************************************************************
637 template <typename T>
638 class member_function_wrapper;
639
640 template <typename TReturn, typename... TParams>
641 class member_function_wrapper<TReturn(TParams...)>
642 {
643 public:
644
645 template <typename T, T& Instance, TReturn(T::* Method)(TParams...)>
646 static constexpr TReturn function(TParams... params)
647 {
648 return (Instance.*Method)(etl::forward<TParams>(params)...);
649 }
650 };
651#endif
652
653#if ETL_USING_CPP11
654 //*****************************************************************************
655 // A wrapper for a functor
656 // Creates a static member function that calls the specified functor.
657 //*****************************************************************************
658 template <typename T>
659 class functor_wrapper;
660
661 template <typename TReturn, typename... TParams>
662 class functor_wrapper<TReturn(TParams...)>
663 {
664 public:
665
666 template <typename TFunctor, TFunctor& Instance>
667 static constexpr TReturn function(TParams... params)
668 {
669 return Instance(etl::forward<TParams>(params)...);
670 }
671 };
672#endif
673}
674
675#endif
is_integral
Definition: type_traits_generator.h:1001
is_lvalue_reference
Definition: type_traits_generator.h:1121
bitset_ext
Definition: absolute.h:38
pair< T1, T2 > make_pair(T1 a, T2 b)
A convenience wrapper for creating a pair from two objects.
Definition: utility.h:322
T exchange(T &object, const T &new_value)
exchange (const)
Definition: utility.h:452
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:684
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:696
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:645
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition: array.h:621
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:633
etl::add_const< T >::type & as_const(T &t)
as_const
Definition: utility.h:481
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:657
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:672
integer_sequence
Definition: utility.h:537
Definition: utility.h:591
in_place disambiguation tags.
Definition: utility.h:570
Definition: utility.h:580
pair holds two objects of arbitrary type
Definition: utility.h:164
T1 first_type
first_type is the first bound type
Definition: utility.h:165
pair(const std::pair< U1, U2 > &other)
Constructing from std::pair.
Definition: utility.h:244
T1 first
first is a copy of the first object
Definition: utility.h:168
ETL_CONSTEXPR pair()
Default constructor.
Definition: utility.h:176
pair(const pair< T1, T2 > &other)
Copy constructor.
Definition: utility.h:218
T2 second
second is a copy of the second object
Definition: utility.h:169
T2 second_type
second_type is the second bound type
Definition: utility.h:166
Functor to select pair::first.
Definition: utility.h:391
type & operator()(TPair &p) const
Function call that return p.first.
Definition: utility.h:398
const type & operator()(const TPair &p) const
Function call that return p.first.
Definition: utility.h:406
TPair::first_type type
type of member pair::first.
Definition: utility.h:392
Functor to select pair::second.
Definition: utility.h:426
type & operator()(TPair &p) const
Function call. The return value is p.second.
Definition: utility.h:433
const type & operator()(const TPair &p) const
Function call. The return value is p.second.
Definition: utility.h:441
TPair::second_type type
type of member pair::second.
Definition: utility.h:427