Embedded Template Library 1.0
Loading...
Searching...
No Matches
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
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
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
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
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 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
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)
214 {
215 }
216
219 : first(other.first)
221 {
222 }
223
224#if ETL_USING_CPP11
226 template <typename U1, typename U2>
227 ETL_CONSTEXPR14 pair(pair<U1, U2>&& other)
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)
247 {
248 }
249
250#if ETL_USING_CPP11
252 template <typename U1, typename U2>
253 pair(std::pair<U1, U2>&& other)
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;
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;
282
283 return *this;
284 }
285
286#if ETL_USING_CPP11
287 pair<T1, T2>& operator =(pair<T1, T2>&& other)
288 {
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 {
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>
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 {
340 return (a.first == b.first) && !(a.second < b.second) && !(a.second > b.second);
342 }
343
345 template <typename T1, typename T2>
346 inline bool operator !=(const pair<T1, T2>& a, const pair<T1, T2>& b)
347 {
348 return !(a == b);
349 }
350
351 template <typename T1, typename T2>
352 inline bool operator <(const pair<T1, T2>& a, const pair<T1, T2>& b)
353 {
354 return (a.first < b.first) ||
355 (!(b.first < a.first) && (a.second < b.second));
356 }
357
359 template <typename T1, typename T2>
360 inline bool operator >(const pair<T1, T2>& a, const pair<T1, T2>& b)
361 {
362 return (b < a);
363 }
364
366 template <typename T1, typename T2>
367 inline bool operator <=(const pair<T1, T2>& a, const pair<T1, T2>& b)
368 {
369 return !(b < a);
370 }
371
373 template <typename T1, typename T2>
374 inline bool operator >=(const pair<T1, T2>& a, const pair<T1, T2>& b)
375 {
376 return !(a < b);
377 }
378
379 //***************************************************************************
390 //***************************************************************************
391 template <typename TPair>
393 {
394 typedef typename TPair::first_type type;
395
396 //***************************************************************************
399 //***************************************************************************
401 {
402 return p.first;
403 }
404
405 //***************************************************************************
407 //
408 const type& operator()(const TPair& p) const
409 {
410 return p.first;
411 }
412 };
413
414 //***************************************************************************
425 //***************************************************************************
426 template <typename TPair>
428 {
429 typedef typename TPair::second_type type;
430
431 //***************************************************************************
434 //***************************************************************************
436 {
437 return p.second;
438 }
439
440 //***************************************************************************
442 //***************************************************************************
443 const type& operator()(const TPair& p) const
444 {
445 return p.second;
446 }
447 };
448
449#if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED
450 //***************************************************************************
452 //***************************************************************************
453 template <typename T>
454 T exchange(T& object, const T& new_value)
455 {
456 T old_value = object;
457 object = new_value;
458 return old_value;
459 }
460
461 template <typename T, typename U>
462 T exchange(T& object, const U& new_value)
463 {
464 T old_value = object;
465 object = new_value;
466 return old_value;
467 }
468#else
469 //***************************************************************************
471 //***************************************************************************
472 template <typename T, typename U = T>
473 T exchange(T& object, const U& new_value)
474 {
475 return std::exchange(object, new_value);
476 }
477#endif
478
479 //***************************************************************************
481 //***************************************************************************
482 template <typename T>
484 {
485 return t;
486 }
487
488 //***************************************************************************
490 //***************************************************************************
491#if ETL_USING_CPP11
492 template <typename T, T... Integers>
493 class integer_sequence
494 {
495 public:
496
497 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Integral types only");
498
499 typedef T value_type;
500
501 static ETL_CONSTEXPR size_t size() ETL_NOEXCEPT
502 {
503 return sizeof...(Integers);
504 }
505 };
506
507 namespace private_integer_sequence
508 {
509 template <size_t N, typename IndexSeq>
510 struct make_index_sequence;
511
512 template <size_t N, size_t... Indices>
513 struct make_index_sequence<N, etl::integer_sequence<size_t, Indices...>>
514 {
515 typedef typename make_index_sequence<N - 1, etl::integer_sequence<size_t, N - 1, Indices...>>::type type;
516 };
517
518 template <size_t... Indices>
519 struct make_index_sequence<0, etl::integer_sequence<size_t, Indices...>>
520 {
521 typedef etl::integer_sequence<size_t, Indices...> type;
522 };
523 }
524
525 //***********************************
526 template <size_t N>
527 using make_index_sequence = typename private_integer_sequence::make_index_sequence<N, etl::integer_sequence<size_t>>::type;
528
529 //***********************************
530 template <size_t... Indices>
531 using index_sequence = etl::integer_sequence<size_t, Indices...>;
532#endif
533
534 //***************************************************************************
536 //***************************************************************************
537 template <typename T>
539 {
541 : x(T(0))
542 , y(T(0))
543 {
544 }
545
547 : x(x_)
548 , y(y_)
549 {
550 }
551
552 friend bool operator ==(const coordinate_2d& lhs, const coordinate_2d& rhs)
553 {
554 return (lhs.x == rhs.x) && (lhs.y == rhs.y);
555 }
556
557 friend bool operator !=(const coordinate_2d& lhs, const coordinate_2d& rhs)
558 {
559 return !(lhs == rhs);
560 }
561
562 T x;
563 T y;
564 };
565
566 //***************************************************************************
568 //***************************************************************************
569
570 //*************************
572 {
573 explicit ETL_CONSTEXPR in_place_t() {}
574 };
575
576#if ETL_USING_CPP17
577 inline constexpr in_place_t in_place{};
578#endif
579
580 //*************************
581 template <typename T> struct in_place_type_t
582 {
583 explicit ETL_CONSTEXPR in_place_type_t() {}
584 };
585
586#if ETL_USING_CPP17
587 template <typename T>
588 inline constexpr in_place_type_t<T> in_place_type{};
589#endif
590
591 //*************************
592 template <size_t I> struct in_place_index_t
593 {
594 explicit ETL_CONSTEXPR in_place_index_t() {}
595 };
596
597#if ETL_USING_CPP17
598 template <size_t I>
599 inline constexpr in_place_index_t<I> in_place_index{};
600#endif
601
602#if ETL_USING_CPP11
603 //*************************************************************************
605 //*************************************************************************
606 template <typename TReturn, typename... TParams>
607 class functor
608 {
609 public:
610
611 //*********************************
613 //*********************************
614 constexpr functor(TReturn(*ptr_)(TParams...))
615 : ptr(ptr_)
616 {
617 }
618
619 //*********************************
621 //*********************************
622 constexpr TReturn operator()(TParams... args) const
623 {
624 return ptr(etl::forward<TParams>(args)...);
625 }
626
627 private:
628
630 TReturn(*ptr)(TParams...);
631 };
632#endif
633
634#if ETL_USING_CPP11
635 //*****************************************************************************
636 // A wrapper for a member function
637 // Creates a static member function that calls the specified member function.
638 //*****************************************************************************
639 template <typename T>
640 class member_function_wrapper;
641
642 template <typename TReturn, typename... TParams>
643 class member_function_wrapper<TReturn(TParams...)>
644 {
645 public:
646
647 template <typename T, T& Instance, TReturn(T::* Method)(TParams...)>
649 {
651 }
652 };
653#endif
654
655#if ETL_USING_CPP11
656 //*****************************************************************************
657 // A wrapper for a functor
658 // Creates a static member function that calls the specified functor.
659 //*****************************************************************************
660 template <typename T>
661 class functor_wrapper;
662
663 template <typename TReturn, typename... TParams>
664 class functor_wrapper<TReturn(TParams...)>
665 {
666 public:
667
668 template <typename TFunctor, TFunctor& Instance>
669 static constexpr TReturn function(TParams... params)
670 {
672 }
673 };
674#endif
675}
676
677#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:454
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:693
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:705
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:654
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition array.h:630
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1187
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:642
etl::add_const< T >::type & as_const(T &t)
as_const
Definition utility.h:483
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:666
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:681
integer_sequence
Definition utility.h:539
Definition utility.h:593
in_place disambiguation tags.
Definition utility.h:572
Definition utility.h:582
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
ETL_CONSTEXPR14 pair(const T1 &a, const T2 &b)
Constructor from parameters.
Definition utility.h:187
operator std::pair< U1, U2 >()
Converting to std::pair.
Definition utility.h:237
ETL_CONSTEXPR14 pair(const pair< U1, U2 > &other)
Copy constructor.
Definition utility.h:211
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:393
type & operator()(TPair &p) const
Function call that return p.first.
Definition utility.h:400
const type & operator()(const TPair &p) const
Function call that return p.first.
Definition utility.h:408
TPair::first_type type
type of member pair::first.
Definition utility.h:394
Functor to select pair::second.
Definition utility.h:428
type & operator()(TPair &p) const
Function call. The return value is p.second.
Definition utility.h:435
const type & operator()(const TPair &p) const
Function call. The return value is p.second.
Definition utility.h:443
TPair::second_type type
type of member pair::second.
Definition utility.h:429