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 ETL_CONSTEXPR 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 ETL_CONSTEXPR 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 ETL_CONSTEXPR 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);
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 #if ETL_CPP11_NOT_SUPPORTED
494 //***************************************************************************
496 //***************************************************************************
497 template <typename T>
498 T exchange(T& object, const T& new_value)
499 {
500 T old_value = object;
501 object = new_value;
502 return old_value;
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 ETL_CONSTEXPR14 T exchange(T& object, U&& new_value)
517 ETL_NOEXCEPT_IF((etl::is_nothrow_move_constructible<T>::value && etl::is_nothrow_assignable<T&, U>::value))
518 {
519 T old_value = etl::move(object);
520 object = etl::forward<U>(new_value);
521 return old_value;
522 }
523 #endif // ETL_CPP11_NOT_SUPPORTED
524#else
525 //***************************************************************************
527 //***************************************************************************
528 template <typename T, typename U = T>
529 ETL_CONSTEXPR14 T exchange(T& object, U&& new_value)
530 ETL_NOEXCEPT_IF((etl::is_nothrow_move_constructible<T>::value && etl::is_nothrow_assignable<T&, U>::value))
531 {
532 return std::exchange(object, etl::forward<U>(new_value));
533 }
534#endif // ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED
535
536 //***************************************************************************
538 //***************************************************************************
539 template <typename T>
540 typename etl::add_const<T>::type& as_const(T& t)
541 {
542 return t;
543 }
544
545 //***************************************************************************
547 //***************************************************************************
548#if ETL_USING_CPP11
549 template <typename T, T... Integers>
550 class integer_sequence
551 {
552 public:
553
554 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Integral types only");
555
556 typedef T value_type;
557
558 static ETL_CONSTEXPR size_t size() ETL_NOEXCEPT
559 {
560 return sizeof...(Integers);
561 }
562 };
563
564 namespace private_integer_sequence
565 {
566 template <size_t Count, typename IndexSeq>
567 struct make_index_sequence;
568
569 template <size_t Count, size_t... Indices>
570 struct make_index_sequence<Count, etl::integer_sequence<size_t, Indices...>>
571 {
572 using type = typename make_index_sequence< Count - 1, etl::integer_sequence<size_t, Count - 1, Indices...>>::type;
573 };
574
575 template <size_t... Indices>
576 struct make_index_sequence<0, etl::integer_sequence<size_t, Indices...>>
577 {
578 using type = etl::integer_sequence<size_t, Indices...>;
579 };
580
581 template <size_t Offset, typename IndexSeq>
582 struct offset_index_sequence;
583
584 template <size_t Offset, size_t... Indices>
585 struct offset_index_sequence<Offset, etl::integer_sequence<size_t, Indices...>>
586 {
587 using type = etl::integer_sequence<size_t, (Offset + Indices)...>;
588 };
589 } // namespace private_integer_sequence
590
591 //***********************************
593 //***********************************
594 template <size_t Count>
595 using make_index_sequence = typename private_integer_sequence::make_index_sequence< Count, etl::integer_sequence<size_t>>::type;
596
597 //***********************************
599 //***********************************
600 template <size_t Offset, size_t Count>
601 using make_index_sequence_with_offset = typename private_integer_sequence::offset_index_sequence< Offset, etl::make_index_sequence<Count>>::type;
602
603 //***********************************
604 // Helper to support both parameter packs and etl::type_list<T...>
605 // Forward declare etl::type_list to allow use without including type_list.h
606 template <typename... TTypes>
607 struct type_list;
608
609 namespace private_make_index_sequence_for
610 {
611 // Generic pack form
612 template <typename... TTypes>
613 struct impl
614 {
615 using type = typename private_integer_sequence::make_index_sequence< sizeof...(TTypes), etl::integer_sequence<size_t>>::type;
616 };
617
618 // etl::type_list form
619 template <typename... TTypes>
620 struct impl<etl::type_list<TTypes...>> : impl<TTypes...>
621 {
622 };
623 } // namespace private_make_index_sequence_for
624
625 //***********************************
629 //***********************************
630 template <typename... TTypes>
631 using make_index_sequence_for = typename private_make_index_sequence_for::impl<TTypes...>::type;
632
633 //***********************************
635 //***********************************
636 template <size_t... Indices>
637 using index_sequence = etl::integer_sequence<size_t, Indices...>;
638
639 //************************************
641 //************************************
642 template <typename... TTypes>
643 using index_sequence_for = typename etl::make_index_sequence_for<TTypes...>;
644
645 //************************************
647 //************************************
648 template <typename TIndexSequence1, typename TIndexSequence2>
649 struct index_sequence_cat;
650
651 template <size_t... Indices1, size_t... Indices2>
652 struct index_sequence_cat<etl::index_sequence<Indices1...>, etl::index_sequence<Indices2...>>
653 {
654 using type = etl::index_sequence<Indices1..., Indices2...>;
655 };
656
657 template <typename TIndexSequence1, typename TIndexSequence2>
658 using index_sequence_cat_t = typename index_sequence_cat<TIndexSequence1, TIndexSequence2>::type;
659
660 //************************************
662 //************************************
663 template <typename TIndexSequence, size_t Index>
664 struct index_sequence_push_front;
665
666 template <size_t... Indices, size_t Index>
667 struct index_sequence_push_front<etl::index_sequence<Indices...>, Index>
668 {
669 // Adds the new index to the front of the sequence.
670 using type = etl::index_sequence<Index, Indices...>;
671 };
672
673 template <typename TIndexSequence, size_t Index>
674 using index_sequence_push_front_t = typename index_sequence_push_front<TIndexSequence, Index>::type;
675
676 //************************************
678 //************************************
679 template <typename TIndexSequence>
680 struct index_sequence_pop_front;
681
682 template <>
683 struct index_sequence_pop_front<etl::index_sequence<>>
684 {
685 using type = etl::index_sequence<>;
686 };
687
688 template <size_t Index, size_t... Indices>
689 struct index_sequence_pop_front<etl::index_sequence<Index, Indices...>>
690 {
691 // Removes the front index by declaring the type to be the tail of the
692 // sequence.
693 using type = etl::index_sequence<Indices...>;
694 };
695
696 template <typename TIndexSequence>
697 using index_sequence_pop_front_t = typename index_sequence_pop_front<TIndexSequence>::type;
698
699 //************************************
701 //************************************
702 template <typename TIndexSequence, size_t Index>
703 struct index_sequence_push_back;
704
705 template <size_t... Indices, size_t Index>
706 struct index_sequence_push_back<etl::index_sequence<Indices...>, Index>
707 {
708 // Adds the new index to the back of the sequence by concatenating the new
709 // index with the sequence.
710 using type = etl::index_sequence<Indices..., Index>;
711 };
712
713 template <typename TIndexSequence, size_t Index>
714 using index_sequence_push_back_t = typename index_sequence_push_back<TIndexSequence, Index>::type;
715
716 //************************************
718 //************************************
719 template <typename TIndexSequence>
720 struct index_sequence_pop_back;
721
722 // Pop back of and empty sequence is an empty sequence.
723 template <>
724 struct index_sequence_pop_back<etl::index_sequence<>>
725 {
726 using type = etl::index_sequence<>;
727 };
728
729 // Pop back of a single element sequence is an empty sequence.
730 // The single element is never added to the result, so is effectively removed.
731 // This is the terminating specialisation for the general case.
732 template <size_t Index>
733 struct index_sequence_pop_back<etl::index_sequence<Index>>
734 {
735 using type = etl::index_sequence<>;
736 };
737
738 // Multi element sequence. Pop back is the front element concatenated with the
739 // pop back of the tail.
740 template <size_t Index, size_t... Indices>
741 struct index_sequence_pop_back<etl::index_sequence<Index, Indices...>>
742 {
743 // Removes the last index by concatenating the front index with the pop back
744 // of the tail. The last index is never added to the result, so is
745 // effectively removed.
746 using type = etl::index_sequence_cat_t< etl::index_sequence<Index>, typename index_sequence_pop_back<etl::index_sequence<Indices...>>::type>;
747 };
748
749 template <typename TIndexSequence>
750 using index_sequence_pop_back_t = typename index_sequence_pop_back<TIndexSequence>::type;
751
752 //************************************
754 //************************************
755 template <typename TIndexSequence, size_t Nth>
756 struct index_sequence_at;
757
758 template <size_t Nth>
759 struct index_sequence_at<etl::index_sequence<>, Nth>
760 {
761 template <size_t>
762 struct dependent_false : etl::false_type
763 {
764 };
765
766 static_assert(dependent_false<Nth>::value, "Nth out of range for index_sequence_at");
767 };
768
769 // When Nth is 0, the index at the Nth position is the front index of the
770 // sequence.
771 template <size_t Index, size_t... Indices>
772 struct index_sequence_at<etl::index_sequence<Index, Indices...>, 0>
773 {
774 static constexpr size_t value = Index;
775 };
776
777 // When Nth is greater than 0, recurse with the tail of the sequence and Nth
778 // - 1.
779 template <size_t Index, size_t... Indices, size_t Nth>
780 struct index_sequence_at<etl::index_sequence<Index, Indices...>, Nth>
781 {
782 static_assert(Nth < sizeof...(Indices) + 1U, "Nth out of range for index_sequence_at");
783
784 static constexpr size_t value = index_sequence_at<etl::index_sequence<Indices...>, Nth - 1U>::value;
785 };
786
787 #if ETL_USING_CPP17
788 template <typename TIndexSequence, size_t Nth>
789 inline constexpr size_t index_sequence_at_v = index_sequence_at<TIndexSequence, Nth>::value;
790 #endif
791
792 //************************************
794 //************************************
795 template <typename TIndexSequence, size_t Value>
796 struct index_sequence_contains;
797
798 // An empty sequence does not contain any value.
799 template <size_t Value>
800 struct index_sequence_contains<etl::index_sequence<>, Value> : etl::false_type
801 {
802 };
803
804 // When the front index of the sequence is the value, the sequence contains
805 // the value. When the front index of the sequence is not the value, recurse
806 // with the tail of the sequence.
807 template <size_t Index, size_t... Indices, size_t Value>
808 struct index_sequence_contains<etl::index_sequence<Index, Indices...>, Value>
809 : etl::integral_constant< bool, (Index == Value) || index_sequence_contains<etl::index_sequence<Indices...>, Value>::value>
810 {
811 };
812
813 #if ETL_USING_CPP17
814 template <typename TIndexSequence, size_t Value>
815 inline constexpr bool index_sequence_contains_v = index_sequence_contains<TIndexSequence, Value>::value;
816 #endif
817
818 //***************************************************************************
821 //***************************************************************************
822 namespace private_index_sequence
823 {
824 template <typename TIndexSequence, typename TUniqueIndices>
825 struct type_index_sequence_impl;
826
827 // When the front index of the sequence is not in the unique sequence, add
828 // it to the back of the unique sequence and recurse with the tail of the
829 // sequence.
830 template <size_t Index, size_t... Indices, size_t... UniqueIndices>
831 struct type_index_sequence_impl<etl::index_sequence<Index, Indices...>, etl::index_sequence<UniqueIndices...>>
832 {
833 // If the index is already in the unique sequence, do not add it again.
834 // Otherwise, add it to the back of the unique sequence.
835 using type =
836 typename etl::conditional_t< etl::index_sequence_contains<etl::index_sequence<UniqueIndices...>, Index>::value,
837 type_index_sequence_impl<etl::index_sequence<Indices...>, etl::index_sequence<UniqueIndices...>>,
838 type_index_sequence_impl< etl::index_sequence<Indices...>,
839 etl::index_sequence_push_back_t<etl::index_sequence<UniqueIndices...>, Index>>>::type;
840 };
841
842 // When the sequence is empty, the unique sequence is the result.
843 template <size_t... UniqueIndices>
844 struct type_index_sequence_impl<etl::index_sequence<>, etl::index_sequence<UniqueIndices...>>
845 {
846 using type = etl::index_sequence<UniqueIndices...>;
847 };
848 } // namespace private_index_sequence
849
850 template <typename T>
851 struct index_sequence_unique;
852
853 template <size_t... Indices>
854 struct index_sequence_unique<etl::index_sequence<Indices...>>
855 {
856 using type = typename private_index_sequence::type_index_sequence_impl< etl::index_sequence<Indices...>, etl::index_sequence<>>::type;
857 };
858
859 #if ETL_USING_CPP11
860 template <typename TIndexSequence>
861 using index_sequence_unique_t = typename etl::index_sequence_unique<TIndexSequence>::type;
862 #endif
863
864 //***************************************************************************
866 //***************************************************************************
867 template <typename T>
868 struct index_sequence_is_unique;
869
870 template <size_t... Indices>
871 struct index_sequence_is_unique<etl::index_sequence<Indices...>>
872 : etl::bool_constant< etl::is_same< etl::index_sequence<Indices...>, etl::index_sequence_unique_t<etl::index_sequence<Indices...>>>::value>
873 {
874 };
875
876 #if ETL_USING_CPP17
877 template <typename TIndexSequence>
878 inline constexpr bool index_sequence_is_unique_v = index_sequence_is_unique<TIndexSequence>::type::value;
879 #endif
880
881 //***************************************************************************
883 //***************************************************************************
884 template <typename T>
885 struct index_sequence_is_empty;
886
887 template <>
888 struct index_sequence_is_empty<etl::index_sequence<>> : etl::true_type
889 {
890 };
891
892 template <size_t... Indices>
893 struct index_sequence_is_empty<etl::index_sequence<Indices...>> : etl::false_type
894 {
895 };
896
897 #if ETL_USING_CPP17
898 template <typename... TTypes>
899 inline constexpr bool index_sequence_is_empty_v = index_sequence_is_empty<TTypes...>::value;
900 #endif
901#endif
902
903 //***************************************************************************
905 //***************************************************************************
906 template <typename T>
907 struct coordinate_2d
908 {
909 ETL_CONSTEXPR coordinate_2d()
910 : x(T(0))
911 , y(T(0))
912 {
913 }
914
915 ETL_CONSTEXPR coordinate_2d(T x_, T y_)
916 : x(x_)
917 , y(y_)
918 {
919 }
920
921 friend bool operator==(const coordinate_2d& lhs, const coordinate_2d& rhs)
922 {
923 return (lhs.x == rhs.x) && (lhs.y == rhs.y);
924 }
925
926 friend bool operator!=(const coordinate_2d& lhs, const coordinate_2d& rhs)
927 {
928 return !(lhs == rhs);
929 }
930
931 T x;
932 T y;
933 };
934
935 //***************************************************************************
937 //***************************************************************************
938
939 //*************************
940 struct in_place_t
941 {
942 explicit ETL_CONSTEXPR in_place_t() {}
943 };
944
945#if ETL_USING_CPP17
946 inline constexpr in_place_t in_place{};
947#endif
948
949 //*************************
950 template <typename T>
951 struct in_place_type_t
952 {
953 explicit ETL_CONSTEXPR in_place_type_t() {}
954 };
955
956#if ETL_USING_CPP17
957 template <typename T>
958 inline constexpr in_place_type_t<T> in_place_type{};
959#endif
960
961 //*************************
962 template <size_t Index>
963 struct in_place_index_t
964 {
965 explicit ETL_CONSTEXPR in_place_index_t() {}
966 };
967
968#if ETL_USING_CPP17
969 template <size_t Index>
970 inline constexpr in_place_index_t<Index> in_place_index{};
971#endif
972
973#if ETL_USING_CPP11
974 //*************************************************************************
975 // A function wrapper for free/global functions.
976 // Deprecated.
977 // See etl::function_ptr_as_functor for a runtime time wrapper option.
978 // See etl::function_as_functor for a compile time wrapper option.
979 //*************************************************************************
980 template <typename TReturn, typename... TParams>
981 class ETL_DEPRECATED functor
982 {
983 public:
984
985 //*********************************
987 //*********************************
988 constexpr functor(TReturn (*ptr_)(TParams...))
989 : ptr(ptr_)
990 {
991 }
992
993 //*********************************
995 //*********************************
996 constexpr TReturn operator()(TParams... args) const
997 {
998 return ptr(etl::forward<TParams>(args)...);
999 }
1000
1001 private:
1002
1004 TReturn (*ptr)(TParams...);
1005 };
1006
1007 //*****************************************************************************
1008 // Wrap a member function with a static free function.
1009 // Creates a static member function that calls the specified member function.
1010 // Deprecated
1011 // See etl::member_function_as_static
1012 //*****************************************************************************
1013 template <typename T>
1014 class member_function_wrapper;
1015
1016 template <typename TReturn, typename... TParams>
1017 class ETL_DEPRECATED member_function_wrapper<TReturn(TParams...)>
1018 {
1019 public:
1020
1021 template <typename T, T& Instance, TReturn (T::*Method)(TParams...)>
1022 static constexpr TReturn function(TParams... params)
1023 {
1024 return (Instance.*Method)(etl::forward<TParams>(params)...);
1025 }
1026 };
1027
1028 //*****************************************************************************
1029 // Wrap a functor with a static free function.
1030 // Creates a static member function that calls the specified functor.
1031 // Deprecated
1032 // See etl::functor_as_static
1033 //*****************************************************************************
1034 template <typename T>
1035 class functor_wrapper;
1036
1037 template <typename TReturn, typename... TParams>
1038 class functor_wrapper<TReturn(TParams...)>
1039 {
1040 public:
1041
1042 template <typename TFunctor, TFunctor& Instance>
1043 static constexpr TReturn function(TParams... params)
1044 {
1045 return Instance(etl::forward<TParams>(params)...);
1046 }
1047 };
1048#endif
1049
1050#if ETL_USING_CPP17
1051 //*****************************************************************************
1052 // Wraps a functor with a static free function at compile time.
1053 // Creates a static member 'call' that calls the specified functor.
1054 //*****************************************************************************
1055 template <auto& Instance>
1056 struct functor_as_static
1057 {
1058 template <typename... TArgs>
1059 static constexpr auto call(TArgs&&... args)
1060 {
1061 return (Instance.operator())(etl::forward<TArgs>(args)...);
1062 }
1063 };
1064
1065 //*****************************************************************************
1066 // Wraps a member function with a static free function at compile time.
1067 // Creates a static member 'call' that calls the specified member function.
1068 //*****************************************************************************
1069 template <auto Method, auto& Instance>
1070 struct member_function_as_static
1071 {
1072 template <typename... TArgs>
1073 static constexpr auto call(TArgs&&... args)
1074 {
1075 return (Instance.*Method)(etl::forward<TArgs>(args)...);
1076 }
1077 };
1078
1079 //*****************************************************************************
1080 // Wraps a member function with a functor at compile time.
1081 // Creates a functor that calls the specified member function.
1082 //*****************************************************************************
1083 template <auto Method, auto& Instance>
1084 class member_function_as_functor
1085 {
1086 public:
1087
1088 template <typename... TArgs>
1089 constexpr auto operator()(TArgs&&... args) const -> decltype((Instance.*Method)(etl::forward<TArgs>(args)...))
1090 {
1091 return (Instance.*Method)(etl::forward<TArgs>(args)...);
1092 }
1093 };
1094
1095 //*****************************************************************************
1096 // Wraps a function with a functor at compile time.
1097 // Creates a functor that calls the specified free function.
1098 //*****************************************************************************
1099 template <auto Function>
1100 class function_as_functor
1101 {
1102 public:
1103
1104 template <typename... TArgs>
1105 constexpr auto operator()(TArgs&&... args) const -> decltype(Function(etl::forward<TArgs>(args)...))
1106 {
1107 return Function(etl::forward<TArgs>(args)...);
1108 }
1109 };
1110#endif
1111
1112#if ETL_USING_CPP11
1113 //*****************************************************************************
1114 // Wraps a function pointer with a functor at run time.
1115 // Creates a functor that calls the specified free function.
1116 //*****************************************************************************
1117 template <typename T>
1118 class function_ptr_as_functor;
1119
1120 template <typename TReturn, typename... TArgs>
1121 class function_ptr_as_functor<TReturn(TArgs...)>
1122 {
1123 public:
1124
1125 //*********************************
1127 //*********************************
1128 constexpr function_ptr_as_functor(TReturn (*ptr_)(TArgs...))
1129 : ptr(ptr_)
1130 {
1131 }
1132
1133 //*********************************
1135 //*********************************
1136 constexpr TReturn operator()(TArgs... args) const
1137 {
1138 return ptr(etl::forward<TArgs>(args)...);
1139 }
1140
1141 private:
1142
1144 TReturn (*ptr)(TArgs...);
1145 };
1146#endif
1147
1148#if ETL_USING_CPP17 && !defined(ETL_FORCE_CPP11_NONTYPE)
1149 //*****************************************************************************
1150 // Wraps a non-type template parameter as a type.
1151 //*****************************************************************************
1152 template <auto Value>
1153 struct nontype_t
1154 {
1155 static constexpr decltype(Value) value = Value;
1156 };
1157#elif ETL_USING_CPP11
1158 //*****************************************************************************
1159 // Wraps a non-type template parameter as a type.
1160 //*****************************************************************************
1161 template <typename T, T Value>
1162 struct nontype_t
1163 {
1164 static constexpr T value = Value;
1165 };
1166#endif
1167} // namespace etl
1168
1169#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.
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:1078
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:498
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1130
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:1144
ETL_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1090
etl::add_const< T >::type & as_const(T &t)
as_const
Definition utility.h:540
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1103
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1117
Definition utility.h:964
in_place disambiguation tags.
Definition utility.h:941
Definition utility.h:952
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
T1 first
first is a copy of the first object
Definition utility.h:180
ETL_CONSTEXPR pair(const pair< T1, T2 > &other)
Copy constructor.
Definition utility.h:231
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
ETL_CONSTEXPR pair(const std::pair< U1, U2 > &other)
Constructing from std::pair.
Definition utility.h:257
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