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
38#include "private/tuple_size.h"
39
40#if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL
41 #if ETL_USING_CPP11
42 #include <utility>
43 #else
44 #include <algorithm>
45 #endif
46#endif
47
50
51namespace etl
52{
53#if ETL_USING_CPP11
54 //******************************************************************************
55 template <typename T>
56 constexpr typename etl::remove_reference<T>::type&& move(T&& t) ETL_NOEXCEPT
57 {
58 return static_cast<typename etl::remove_reference<T>::type&&>(t);
59 }
60
61 //******************************************************************************
62 template <typename T>
63 constexpr T&& forward(typename etl::remove_reference<T>::type& t) ETL_NOEXCEPT
64 {
65 return static_cast<T&&>(t);
66 }
67
68 template <typename T>
69 constexpr T&& forward(typename etl::remove_reference<T>::type&& t) ETL_NOEXCEPT
70 {
71 ETL_STATIC_ASSERT(!etl::is_lvalue_reference<T>::value, "Invalid rvalue to lvalue conversion");
72 return static_cast<T&&>(t);
73 }
74
75 //******************************************************************************
84 //******************************************************************************
85 //***********************************
87 //***********************************
88 template <typename T, typename U>
89 ETL_NODISCARD
90 ETL_CONSTEXPR etl::enable_if_t<etl::is_const<etl::remove_reference_t<T>>::value && etl::is_lvalue_reference<T>::value,
91 const etl::remove_reference_t<U>&> forward_like(U&& u) ETL_NOEXCEPT
92 {
93 return static_cast<const etl::remove_reference_t<U>&>(u);
94 }
95
96 //***********************************
98 //***********************************
99 template <typename T, typename U>
100 ETL_NODISCARD
101 ETL_CONSTEXPR etl::enable_if_t<etl::is_const<etl::remove_reference_t<T>>::value && !etl::is_lvalue_reference<T>::value,
102 const etl::remove_reference_t<U>&&> forward_like(U&& u) ETL_NOEXCEPT
103 {
104 return static_cast<const etl::remove_reference_t<U>&&>(u);
105 }
106
107 //***********************************
109 //***********************************
110 template <typename T, typename U>
111 ETL_NODISCARD
112 ETL_CONSTEXPR etl::enable_if_t<!etl::is_const<etl::remove_reference_t<T>>::value && etl::is_lvalue_reference<T>::value, etl::remove_reference_t<U>&>
113 forward_like(U&& u) ETL_NOEXCEPT
114 {
115 return static_cast<etl::remove_reference_t<U>&>(u);
116 }
117
118 //***********************************
120 //***********************************
121 template <typename T, typename U>
122 ETL_NODISCARD
123 ETL_CONSTEXPR etl::enable_if_t<!etl::is_const<etl::remove_reference_t<T>>::value && !etl::is_lvalue_reference<T>::value, etl::remove_reference_t<U>&&>
124 forward_like(U&& u) ETL_NOEXCEPT
125 {
126 return static_cast<etl::remove_reference_t<U>&&>(u);
127 }
128
129 //***********************************
130 // Defines the type that forward_like would cast to.
131 //***********************************
132 template <typename T, typename U>
133 using forward_like_t = decltype(etl::forward_like<T>(etl::declval<U&>()));
134#endif
135
136 //***********************************
137 // Gets the underlying type of an enum.
138 //***********************************
139 template <typename T>
140 ETL_CONSTEXPR typename underlying_type<T>::type to_underlying(T value) ETL_NOEXCEPT
141 {
142 return static_cast<typename underlying_type<T>::type>(value);
143 }
144
145 // We can't have std::swap and etl::swap templates coexisting in the unit
146 // tests as the compiler will be unable to decide which one to use, due to
147 // ADL.
148#if ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST)
149 //***************************************************************************
150 // swap
151 template <typename T>
152 ETL_CONSTEXPR14 void swap(T& a, T& b) ETL_NOEXCEPT
153 {
154 T temp(ETL_MOVE(a));
155 a = ETL_MOVE(b);
156 b = ETL_MOVE(temp);
157 }
158
159 template < class T, size_t Size >
160 ETL_CONSTEXPR14 void swap(T (&a)[Size], T (&b)[Size]) ETL_NOEXCEPT
161 {
162 for (size_t i = 0UL; i < Size; ++i)
163 {
164 swap(a[i], b[i]);
165 }
166 }
167#endif
168
169 //***************************************************************************
173 //***************************************************************************
174 template <typename T1, typename T2>
175 struct pair
176 {
177 typedef T1 first_type;
178 typedef T2 second_type;
179
180 T1 first;
182
183 //***************************************************************************
188 //***************************************************************************
189 ETL_CONSTEXPR pair()
190 : first(T1())
191 , second(T2())
192 {
193 }
194
195 //***************************************************************************
199 //***************************************************************************
200 ETL_CONSTEXPR14 pair(const T1& a, const T2& b)
201 : first(a)
202 , second(b)
203 {
204 }
205
206#if ETL_USING_CPP11
207 //***************************************************************************
209 //***************************************************************************
210 template <typename U1, typename U2>
211 ETL_CONSTEXPR14 pair(U1&& a, U2&& b)
212 : first(etl::forward<U1>(a))
213 , second(etl::forward<U2>(b))
214 {
215 }
216#endif
217
218 //***************************************************************************
222 //***************************************************************************
223 template <typename U1, typename U2>
224 ETL_CONSTEXPR14 pair(const pair<U1, U2>& other)
225 : first(other.first)
226 , second(other.second)
227 {
228 }
229
231 pair(const pair<T1, T2>& other)
232 : first(other.first)
233 , second(other.second)
234 {
235 }
236
237#if ETL_USING_CPP11
239 template <typename U1, typename U2>
240 ETL_CONSTEXPR14 pair(pair<U1, U2>&& other)
241 : first(etl::forward<U1>(other.first))
242 , second(etl::forward<U2>(other.second))
243 {
244 }
245#endif
246
247#if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL
249 template <typename U1, typename U2>
250 operator std::pair<U1, U2>()
251 {
252 return std::make_pair(first, second);
253 }
254
256 template <typename U1, typename U2>
257 pair(const std::pair<U1, U2>& other)
258 : first(other.first)
259 , second(other.second)
260 {
261 }
262
263 #if ETL_USING_CPP11
265 template <typename U1, typename U2>
266 pair(std::pair<U1, U2>&& other)
267 : first(etl::forward<U1>(other.first))
268 , second(etl::forward<U2>(other.second))
269 {
270 }
271 #endif
272#endif
273
274 void swap(pair<T1, T2>& other)
275 {
276 using ETL_OR_STD::swap;
277
278 swap(first, other.first);
279 swap(second, other.second);
280 }
281
282 pair<T1, T2>& operator=(const pair<T1, T2>& other)
283 {
284 first = other.first;
285 second = other.second;
286
287 return *this;
288 }
289
290 template <typename U1, typename U2>
291 pair<U1, U2>& operator=(const pair<U1, U2>& other)
292 {
293 first = other.first;
294 second = other.second;
295
296 return *this;
297 }
298
299#if ETL_USING_CPP11
300 pair<T1, T2>& operator=(pair<T1, T2>&& other)
301 {
302 first = etl::forward<T1>(other.first);
303 second = etl::forward<T2>(other.second);
304
305 return *this;
306 }
307
308 template <typename U1, typename U2>
309 pair<U1, U2>& operator=(pair<U1, U2>&& other)
310 {
311 first = etl::forward<U1>(other.first);
312 second = etl::forward<U2>(other.second);
313
314 return *this;
315 }
316#endif
317 };
318
319 //***************************************************************************
326 //***************************************************************************
327#if ETL_USING_CPP11
328 template <typename T1, typename T2>
329 inline pair<T1, T2> make_pair(T1&& a, T2&& b)
330 {
331 return pair<T1, T2>(etl::forward<T1>(a), etl::forward<T2>(b));
332 }
333#else
334 template <typename T1, typename T2>
335 inline pair<T1, T2> make_pair(T1 a, T2 b)
336 {
337 return pair<T1, T2>(a, b);
338 }
339#endif
340
341#if ETL_USING_CPP11
342 //******************************************************************************
343 template <size_t Index, typename T1, typename T2>
344 struct tuple_element<Index, ETL_OR_STD::pair<T1, T2> >
345 {
346 ETL_STATIC_ASSERT(Index < 2U, "pair has only 2 elements");
347 };
348
349 template <typename T1, typename T2>
350 struct tuple_element<0U, ETL_OR_STD::pair<T1, T2> >
351 {
352 typedef T1 type;
353 };
354
355 template <typename T1, typename T2>
356 struct tuple_element<1U, ETL_OR_STD::pair<T1, T2> >
357 {
358 typedef T2 type;
359 };
360
361 //******************************************************************************
362 template <typename T1, typename T2>
363 struct tuple_size<ETL_OR_STD::pair<T1, T2>> : public etl::integral_constant<size_t, 2U>
364 {
365 };
366#endif
367
368 //******************************************************************************
369 template <typename T1, typename T2>
370 inline void swap(pair<T1, T2>& a, pair<T1, T2>& b)
371 {
372 a.swap(b);
373 }
374
376 template <typename T1, typename T2>
377 inline bool operator==(const pair<T1, T2>& a, const pair<T1, T2>& b)
378 {
380 return (a.first == b.first) && !(a.second < b.second) && !(a.second > b.second);
382 }
383
385 template <typename T1, typename T2>
386 inline bool operator!=(const pair<T1, T2>& a, const pair<T1, T2>& b)
387 {
388 return !(a == b);
389 }
390
391 template <typename T1, typename T2>
392 inline bool operator<(const pair<T1, T2>& a, const pair<T1, T2>& b)
393 {
394 return (a.first < b.first) || (!(b.first < a.first) && (a.second < b.second));
395 }
396
398 template <typename T1, typename T2>
399 inline bool operator>(const pair<T1, T2>& a, const pair<T1, T2>& b)
400 {
401 return (b < a);
402 }
403
405 template <typename T1, typename T2>
406 inline bool operator<=(const pair<T1, T2>& a, const pair<T1, T2>& b)
407 {
408 return !(b < a);
409 }
410
412 template <typename T1, typename T2>
413 inline bool operator>=(const pair<T1, T2>& a, const pair<T1, T2>& b)
414 {
415 return !(a < b);
416 }
417
418 //***************************************************************************
431 //***************************************************************************
432 template <typename TPair>
434 {
435 typedef typename TPair::first_type type;
436
437 //***************************************************************************
440 //***************************************************************************
441 type& operator()(TPair& p) const
442 {
443 return p.first;
444 }
445
446 //***************************************************************************
448 //
449 const type& operator()(const TPair& p) const
450 {
451 return p.first;
452 }
453 };
454
455 //***************************************************************************
468 //***************************************************************************
469 template <typename TPair>
471 {
472 typedef typename TPair::second_type type;
473
474 //***************************************************************************
477 //***************************************************************************
478 type& operator()(TPair& p) const
479 {
480 return p.second;
481 }
482
483 //***************************************************************************
485 //***************************************************************************
486 const type& operator()(const TPair& p) const
487 {
488 return p.second;
489 }
490 };
491
492#if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED
493 //***************************************************************************
495 //***************************************************************************
496 template <typename T>
497 T exchange(T& object, const T& new_value)
498 {
499 T old_value = object;
500 object = new_value;
501 return old_value;
502 }
503
504 template <typename T, typename U>
505 T exchange(T& object, const U& new_value)
506 {
507 T old_value = object;
508 object = new_value;
509 return old_value;
510 }
511#else
512 //***************************************************************************
514 //***************************************************************************
515 template <typename T, typename U = T>
516 T exchange(T& object, const U& new_value)
517 {
518 return std::exchange(object, new_value);
519 }
520#endif
521
522 //***************************************************************************
524 //***************************************************************************
525 template <typename T>
526 typename etl::add_const<T>::type& as_const(T& t)
527 {
528 return t;
529 }
530
531 //***************************************************************************
533 //***************************************************************************
534#if ETL_USING_CPP11
535 template <typename T, T... Integers>
536 class integer_sequence
537 {
538 public:
539
540 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Integral types only");
541
542 typedef T value_type;
543
544 static ETL_CONSTEXPR size_t size() ETL_NOEXCEPT
545 {
546 return sizeof...(Integers);
547 }
548 };
549
550 namespace private_integer_sequence
551 {
552 template <size_t Count, typename IndexSeq>
553 struct make_index_sequence;
554
555 template <size_t Count, size_t... Indices>
556 struct make_index_sequence<Count, etl::integer_sequence<size_t, Indices...>>
557 {
558 using type = typename make_index_sequence< Count - 1, etl::integer_sequence<size_t, Count - 1, Indices...>>::type;
559 };
560
561 template <size_t... Indices>
562 struct make_index_sequence<0, etl::integer_sequence<size_t, Indices...>>
563 {
564 using type = etl::integer_sequence<size_t, Indices...>;
565 };
566
567 template <size_t Offset, typename IndexSeq>
568 struct offset_index_sequence;
569
570 template <size_t Offset, size_t... Indices>
571 struct offset_index_sequence<Offset, etl::integer_sequence<size_t, Indices...>>
572 {
573 using type = etl::integer_sequence<size_t, (Offset + Indices)...>;
574 };
575 } // namespace private_integer_sequence
576
577 //***********************************
579 //***********************************
580 template <size_t Count>
581 using make_index_sequence = typename private_integer_sequence::make_index_sequence< Count, etl::integer_sequence<size_t>>::type;
582
583 //***********************************
585 //***********************************
586 template <size_t Offset, size_t Count>
587 using make_index_sequence_with_offset = typename private_integer_sequence::offset_index_sequence< Offset, etl::make_index_sequence<Count>>::type;
588
589 //***********************************
590 // Helper to support both parameter packs and etl::type_list<T...>
591 // Forward declare etl::type_list to allow use without including type_list.h
592 template <typename... TTypes>
593 struct type_list;
594
595 namespace private_make_index_sequence_for
596 {
597 // Generic pack form
598 template <typename... TTypes>
599 struct impl
600 {
601 using type = typename private_integer_sequence::make_index_sequence< sizeof...(TTypes), etl::integer_sequence<size_t>>::type;
602 };
603
604 // etl::type_list form
605 template <typename... TTypes>
606 struct impl<etl::type_list<TTypes...>> : impl<TTypes...>
607 {
608 };
609 } // namespace private_make_index_sequence_for
610
611 //***********************************
615 //***********************************
616 template <typename... TTypes>
617 using make_index_sequence_for = typename private_make_index_sequence_for::impl<TTypes...>::type;
618
619 //***********************************
621 //***********************************
622 template <size_t... Indices>
623 using index_sequence = etl::integer_sequence<size_t, Indices...>;
624
625 //************************************
627 //************************************
628 template <typename... TTypes>
629 using index_sequence_for = typename etl::make_index_sequence_for<TTypes...>;
630
631 //************************************
633 //************************************
634 template <typename TIndexSequence1, typename TIndexSequence2>
635 struct index_sequence_cat;
636
637 template <size_t... Indices1, size_t... Indices2>
638 struct index_sequence_cat<etl::index_sequence<Indices1...>, etl::index_sequence<Indices2...>>
639 {
640 using type = etl::index_sequence<Indices1..., Indices2...>;
641 };
642
643 template <typename TIndexSequence1, typename TIndexSequence2>
644 using index_sequence_cat_t = typename index_sequence_cat<TIndexSequence1, TIndexSequence2>::type;
645
646 //************************************
648 //************************************
649 template <typename TIndexSequence, size_t Index>
650 struct index_sequence_push_front;
651
652 template <size_t... Indices, size_t Index>
653 struct index_sequence_push_front<etl::index_sequence<Indices...>, Index>
654 {
655 // Adds the new index to the front of the sequence.
656 using type = etl::index_sequence<Index, Indices...>;
657 };
658
659 template <typename TIndexSequence, size_t Index>
660 using index_sequence_push_front_t = typename index_sequence_push_front<TIndexSequence, Index>::type;
661
662 //************************************
664 //************************************
665 template <typename TIndexSequence>
666 struct index_sequence_pop_front;
667
668 template <>
669 struct index_sequence_pop_front<etl::index_sequence<>>
670 {
671 using type = etl::index_sequence<>;
672 };
673
674 template <size_t Index, size_t... Indices>
675 struct index_sequence_pop_front<etl::index_sequence<Index, Indices...>>
676 {
677 // Removes the front index by declaring the type to be the tail of the
678 // sequence.
679 using type = etl::index_sequence<Indices...>;
680 };
681
682 template <typename TIndexSequence>
683 using index_sequence_pop_front_t = typename index_sequence_pop_front<TIndexSequence>::type;
684
685 //************************************
687 //************************************
688 template <typename TIndexSequence, size_t Index>
689 struct index_sequence_push_back;
690
691 template <size_t... Indices, size_t Index>
692 struct index_sequence_push_back<etl::index_sequence<Indices...>, Index>
693 {
694 // Adds the new index to the back of the sequence by concatenating the new
695 // index with the sequence.
696 using type = etl::index_sequence<Indices..., Index>;
697 };
698
699 template <typename TIndexSequence, size_t Index>
700 using index_sequence_push_back_t = typename index_sequence_push_back<TIndexSequence, Index>::type;
701
702 //************************************
704 //************************************
705 template <typename TIndexSequence>
706 struct index_sequence_pop_back;
707
708 // Pop back of and empty sequence is an empty sequence.
709 template <>
710 struct index_sequence_pop_back<etl::index_sequence<>>
711 {
712 using type = etl::index_sequence<>;
713 };
714
715 // Pop back of a single element sequence is an empty sequence.
716 // The single element is never added to the result, so is effectively removed.
717 // This is the terminating specialisation for the general case.
718 template <size_t Index>
719 struct index_sequence_pop_back<etl::index_sequence<Index>>
720 {
721 using type = etl::index_sequence<>;
722 };
723
724 // Multi element sequence. Pop back is the front element concatenated with the
725 // pop back of the tail.
726 template <size_t Index, size_t... Indices>
727 struct index_sequence_pop_back<etl::index_sequence<Index, Indices...>>
728 {
729 // Removes the last index by concatenating the front index with the pop back
730 // of the tail. The last index is never added to the result, so is
731 // effectively removed.
732 using type = etl::index_sequence_cat_t< etl::index_sequence<Index>, typename index_sequence_pop_back<etl::index_sequence<Indices...>>::type>;
733 };
734
735 template <typename TIndexSequence>
736 using index_sequence_pop_back_t = typename index_sequence_pop_back<TIndexSequence>::type;
737
738 //************************************
740 //************************************
741 template <typename TIndexSequence, size_t Nth>
742 struct index_sequence_at;
743
744 template <size_t Nth>
745 struct index_sequence_at<etl::index_sequence<>, Nth>
746 {
747 template <size_t>
748 struct dependent_false : etl::false_type
749 {
750 };
751
752 static_assert(dependent_false<Nth>::value, "Nth out of range for index_sequence_at");
753 };
754
755 // When Nth is 0, the index at the Nth position is the front index of the
756 // sequence.
757 template <size_t Index, size_t... Indices>
758 struct index_sequence_at<etl::index_sequence<Index, Indices...>, 0>
759 {
760 static constexpr size_t value = Index;
761 };
762
763 // When Nth is greater than 0, recurse with the tail of the sequence and Nth
764 // - 1.
765 template <size_t Index, size_t... Indices, size_t Nth>
766 struct index_sequence_at<etl::index_sequence<Index, Indices...>, Nth>
767 {
768 static_assert(Nth < sizeof...(Indices) + 1U, "Nth out of range for index_sequence_at");
769
770 static constexpr size_t value = index_sequence_at<etl::index_sequence<Indices...>, Nth - 1U>::value;
771 };
772
773 #if ETL_USING_CPP17
774 template <typename TIndexSequence, size_t Nth>
775 inline constexpr size_t index_sequence_at_v = index_sequence_at<TIndexSequence, Nth>::value;
776 #endif
777
778 //************************************
780 //************************************
781 template <typename TIndexSequence, size_t Value>
782 struct index_sequence_contains;
783
784 // An empty sequence does not contain any value.
785 template <size_t Value>
786 struct index_sequence_contains<etl::index_sequence<>, Value> : etl::false_type
787 {
788 };
789
790 // When the front index of the sequence is the value, the sequence contains
791 // the value. When the front index of the sequence is not the value, recurse
792 // with the tail of the sequence.
793 template <size_t Index, size_t... Indices, size_t Value>
794 struct index_sequence_contains<etl::index_sequence<Index, Indices...>, Value>
795 : etl::integral_constant< bool, (Index == Value) || index_sequence_contains<etl::index_sequence<Indices...>, Value>::value>
796 {
797 };
798
799 #if ETL_USING_CPP17
800 template <typename TIndexSequence, size_t Value>
801 inline constexpr bool index_sequence_contains_v = index_sequence_contains<TIndexSequence, Value>::value;
802 #endif
803
804 //***************************************************************************
807 //***************************************************************************
808 namespace private_index_sequence
809 {
810 template <typename TIndexSequence, typename TUniqueIndices>
811 struct type_index_sequence_impl;
812
813 // When the front index of the sequence is not in the unique sequence, add
814 // it to the back of the unique sequence and recurse with the tail of the
815 // sequence.
816 template <size_t Index, size_t... Indices, size_t... UniqueIndices>
817 struct type_index_sequence_impl<etl::index_sequence<Index, Indices...>, etl::index_sequence<UniqueIndices...>>
818 {
819 // If the index is already in the unique sequence, do not add it again.
820 // Otherwise, add it to the back of the unique sequence.
821 using type =
822 typename etl::conditional_t< etl::index_sequence_contains<etl::index_sequence<UniqueIndices...>, Index>::value,
823 type_index_sequence_impl<etl::index_sequence<Indices...>, etl::index_sequence<UniqueIndices...>>,
824 type_index_sequence_impl< etl::index_sequence<Indices...>,
825 etl::index_sequence_push_back_t<etl::index_sequence<UniqueIndices...>, Index>>>::type;
826 };
827
828 // When the sequence is empty, the unique sequence is the result.
829 template <size_t... UniqueIndices>
830 struct type_index_sequence_impl<etl::index_sequence<>, etl::index_sequence<UniqueIndices...>>
831 {
832 using type = etl::index_sequence<UniqueIndices...>;
833 };
834 } // namespace private_index_sequence
835
836 template <typename T>
837 struct index_sequence_unique;
838
839 template <size_t... Indices>
840 struct index_sequence_unique<etl::index_sequence<Indices...>>
841 {
842 using type = typename private_index_sequence::type_index_sequence_impl< etl::index_sequence<Indices...>, etl::index_sequence<>>::type;
843 };
844
845 #if ETL_USING_CPP11
846 template <typename TIndexSequence>
847 using index_sequence_unique_t = typename etl::index_sequence_unique<TIndexSequence>::type;
848 #endif
849
850 //***************************************************************************
852 //***************************************************************************
853 template <typename T>
854 struct index_sequence_is_unique;
855
856 template <size_t... Indices>
857 struct index_sequence_is_unique<etl::index_sequence<Indices...>>
858 : etl::bool_constant< etl::is_same< etl::index_sequence<Indices...>, etl::index_sequence_unique_t<etl::index_sequence<Indices...>>>::value>
859 {
860 };
861
862 #if ETL_USING_CPP17
863 template <typename TIndexSequence>
864 inline constexpr bool index_sequence_is_unique_v = index_sequence_is_unique<TIndexSequence>::type::value;
865 #endif
866
867 //***************************************************************************
869 //***************************************************************************
870 template <typename T>
871 struct index_sequence_is_empty;
872
873 template <>
874 struct index_sequence_is_empty<etl::index_sequence<>> : etl::true_type
875 {
876 };
877
878 template <size_t... Indices>
879 struct index_sequence_is_empty<etl::index_sequence<Indices...>> : etl::false_type
880 {
881 };
882
883 #if ETL_USING_CPP17
884 template <typename... TTypes>
885 inline constexpr bool index_sequence_is_empty_v = index_sequence_is_empty<TTypes...>::value;
886 #endif
887#endif
888
889 //***************************************************************************
891 //***************************************************************************
892 template <typename T>
893 struct coordinate_2d
894 {
895 coordinate_2d()
896 : x(T(0))
897 , y(T(0))
898 {
899 }
900
901 coordinate_2d(T x_, T y_)
902 : x(x_)
903 , y(y_)
904 {
905 }
906
907 friend bool operator==(const coordinate_2d& lhs, const coordinate_2d& rhs)
908 {
909 return (lhs.x == rhs.x) && (lhs.y == rhs.y);
910 }
911
912 friend bool operator!=(const coordinate_2d& lhs, const coordinate_2d& rhs)
913 {
914 return !(lhs == rhs);
915 }
916
917 T x;
918 T y;
919 };
920
921 //***************************************************************************
923 //***************************************************************************
924
925 //*************************
926 struct in_place_t
927 {
928 explicit ETL_CONSTEXPR in_place_t() {}
929 };
930
931#if ETL_USING_CPP17
932 inline constexpr in_place_t in_place{};
933#endif
934
935 //*************************
936 template <typename T>
937 struct in_place_type_t
938 {
939 explicit ETL_CONSTEXPR in_place_type_t() {}
940 };
941
942#if ETL_USING_CPP17
943 template <typename T>
944 inline constexpr in_place_type_t<T> in_place_type{};
945#endif
946
947 //*************************
948 template <size_t Index>
949 struct in_place_index_t
950 {
951 explicit ETL_CONSTEXPR in_place_index_t() {}
952 };
953
954#if ETL_USING_CPP17
955 template <size_t Index>
956 inline constexpr in_place_index_t<Index> in_place_index{};
957#endif
958
959#if ETL_USING_CPP11
960 //*************************************************************************
961 // A function wrapper for free/global functions.
962 // Deprecated.
963 // See etl::function_ptr_as_functor for a runtime time wrapper option.
964 // See etl::function_as_functor for a compile time wrapper option.
965 //*************************************************************************
966 template <typename TReturn, typename... TParams>
967 class ETL_DEPRECATED functor
968 {
969 public:
970
971 //*********************************
973 //*********************************
974 constexpr functor(TReturn (*ptr_)(TParams...))
975 : ptr(ptr_)
976 {
977 }
978
979 //*********************************
981 //*********************************
982 constexpr TReturn operator()(TParams... args) const
983 {
984 return ptr(etl::forward<TParams>(args)...);
985 }
986
987 private:
988
990 TReturn (*ptr)(TParams...);
991 };
992
993 //*****************************************************************************
994 // Wrap a member function with a static free function.
995 // Creates a static member function that calls the specified member function.
996 // Deprecated
997 // See etl::member_function_as_static
998 //*****************************************************************************
999 template <typename T>
1000 class member_function_wrapper;
1001
1002 template <typename TReturn, typename... TParams>
1003 class ETL_DEPRECATED member_function_wrapper<TReturn(TParams...)>
1004 {
1005 public:
1006
1007 template <typename T, T& Instance, TReturn (T::*Method)(TParams...)>
1008 static constexpr TReturn function(TParams... params)
1009 {
1010 return (Instance.*Method)(etl::forward<TParams>(params)...);
1011 }
1012 };
1013
1014 //*****************************************************************************
1015 // Wrap a functor with a static free function.
1016 // Creates a static member function that calls the specified functor.
1017 // Deprecated
1018 // See etl::functor_as_static
1019 //*****************************************************************************
1020 template <typename T>
1021 class functor_wrapper;
1022
1023 template <typename TReturn, typename... TParams>
1024 class functor_wrapper<TReturn(TParams...)>
1025 {
1026 public:
1027
1028 template <typename TFunctor, TFunctor& Instance>
1029 static constexpr TReturn function(TParams... params)
1030 {
1031 return Instance(etl::forward<TParams>(params)...);
1032 }
1033 };
1034#endif
1035
1036#if ETL_USING_CPP17
1037 //*****************************************************************************
1038 // Wraps a functor with a static free function at compile time.
1039 // Creates a static member 'call' that calls the specified functor.
1040 //*****************************************************************************
1041 template <auto& Instance>
1042 struct functor_as_static
1043 {
1044 template <typename... TArgs>
1045 static constexpr auto call(TArgs&&... args)
1046 {
1047 return (Instance.operator())(etl::forward<TArgs>(args)...);
1048 }
1049 };
1050
1051 //*****************************************************************************
1052 // Wraps a member function with a static free function at compile time.
1053 // Creates a static member 'call' that calls the specified member function.
1054 //*****************************************************************************
1055 template <auto Method, auto& Instance>
1056 struct member_function_as_static
1057 {
1058 template <typename... TArgs>
1059 static constexpr auto call(TArgs&&... args)
1060 {
1061 return (Instance.*Method)(etl::forward<TArgs>(args)...);
1062 }
1063 };
1064
1065 //*****************************************************************************
1066 // Wraps a member function with a functor at compile time.
1067 // Creates a functor that calls the specified member function.
1068 //*****************************************************************************
1069 template <auto Method, auto& Instance>
1070 class member_function_as_functor
1071 {
1072 public:
1073
1074 template <typename... TArgs>
1075 constexpr auto operator()(TArgs&&... args) const -> decltype((Instance.*Method)(etl::forward<TArgs>(args)...))
1076 {
1077 return (Instance.*Method)(etl::forward<TArgs>(args)...);
1078 }
1079 };
1080
1081 //*****************************************************************************
1082 // Wraps a function with a functor at compile time.
1083 // Creates a functor that calls the specified free function.
1084 //*****************************************************************************
1085 template <auto Function>
1086 class function_as_functor
1087 {
1088 public:
1089
1090 template <typename... TArgs>
1091 constexpr auto operator()(TArgs&&... args) const -> decltype(Function(etl::forward<TArgs>(args)...))
1092 {
1093 return Function(etl::forward<TArgs>(args)...);
1094 }
1095 };
1096#endif
1097
1098#if ETL_USING_CPP11
1099 //*****************************************************************************
1100 // Wraps a function pointer with a functor at run time.
1101 // Creates a functor that calls the specified free function.
1102 //*****************************************************************************
1103 template <typename T>
1104 class function_ptr_as_functor;
1105
1106 template <typename TReturn, typename... TArgs>
1107 class function_ptr_as_functor<TReturn(TArgs...)>
1108 {
1109 public:
1110
1111 //*********************************
1113 //*********************************
1114 constexpr function_ptr_as_functor(TReturn (*ptr_)(TArgs...))
1115 : ptr(ptr_)
1116 {
1117 }
1118
1119 //*********************************
1121 //*********************************
1122 constexpr TReturn operator()(TArgs... args) const
1123 {
1124 return ptr(etl::forward<TArgs>(args)...);
1125 }
1126
1127 private:
1128
1130 TReturn (*ptr)(TArgs...);
1131 };
1132#endif
1133
1134#if ETL_USING_CPP17 && !defined(ETL_FORCE_CPP11_NONTYPE)
1135 //*****************************************************************************
1136 // Wraps a non-type template parameter as a type.
1137 //*****************************************************************************
1138 template <auto Value>
1139 struct nontype_t
1140 {
1141 static constexpr decltype(Value) value = Value;
1142 };
1143#elif ETL_USING_CPP11
1144 //*****************************************************************************
1145 // Wraps a non-type template parameter as a type.
1146 //*****************************************************************************
1147 template <typename T, T Value>
1148 struct nontype_t
1149 {
1150 static constexpr T value = Value;
1151 };
1152#endif
1153} // namespace etl
1154
1155#endif
void swap(etl::array_view< T > &lhs, etl::array_view< T > &rhs) ETL_NOEXCEPT
Swaps the values.
Definition array_view.h:692
Two pairs of the same type are equal if their members are equal.
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR14 void swap(etl::typed_storage_ext< T > &lhs, etl::typed_storage_ext< T > &rhs) ETL_NOEXCEPT
Swap two etl::typed_storage_ext.
Definition alignment.h:856
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1081
pair< T1, T2 > make_pair(T1 a, T2 b)
A convenience wrapper for creating a pair from two objects.
Definition utility.h:335
T exchange(T &object, const T &new_value)
exchange (const)
Definition utility.h:497
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1133
integral_constant< bool, false > false_type
integral_constant specialisations
Definition type_traits.h:80
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1147
ETL_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1093
etl::add_const< T >::type & as_const(T &t)
as_const
Definition utility.h:526
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1106
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1120
Definition utility.h:950
in_place disambiguation tags.
Definition utility.h:927
Definition utility.h:938
pair holds two objects of arbitrary type
Definition utility.h:176
T1 first_type
first_type is the first bound type
Definition utility.h:177
pair(const std::pair< U1, U2 > &other)
Constructing from std::pair.
Definition utility.h:257
T1 first
first is a copy of the first object
Definition utility.h:180
ETL_CONSTEXPR pair()
Default constructor.
Definition utility.h:189
ETL_CONSTEXPR14 pair(const T1 &a, const T2 &b)
Constructor from parameters.
Definition utility.h:200
ETL_CONSTEXPR14 pair(const pair< U1, U2 > &other)
Copy constructor.
Definition utility.h:224
pair(const pair< T1, T2 > &other)
Copy constructor.
Definition utility.h:231
T2 second
second is a copy of the second object
Definition utility.h:181
T2 second_type
second_type is the second bound type
Definition utility.h:178
Functor to select pair::first.
Definition utility.h:434
type & operator()(TPair &p) const
Function call that return p.first.
Definition utility.h:441
const type & operator()(const TPair &p) const
Function call that return p.first.
Definition utility.h:449
TPair::first_type type
type of member pair::first.
Definition utility.h:435
Functor to select pair::second.
Definition utility.h:471
type & operator()(TPair &p) const
Function call. The return value is p.second.
Definition utility.h:478
const type & operator()(const TPair &p) const
Function call. The return value is p.second.
Definition utility.h:486
TPair::second_type type
type of member pair::second.
Definition utility.h:472
Definition tuple_size.h:38