Embedded Template Library 1.0
Loading...
Searching...
No Matches
algorithm.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
10Documentation: https://www.etlcpp.com/algorithm.html
11
12Copyright(c) 2014 John Wellbelove
13
14Permission is hereby granted, free of charge, to any person obtaining a copy
15of this software and associated documentation files(the "Software"), to deal
16in the Software without restriction, including without limitation the rights
17to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
18copies of the Software, and to permit persons to whom the Software is
19furnished to do so, subject to the following conditions :
20
21The above copyright notice and this permission notice shall be included in all
22copies or substantial portions of the Software.
23
24THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
27AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30SOFTWARE.
31******************************************************************************/
32
33#ifndef ETL_ALGORITHM_INCLUDED
34#define ETL_ALGORITHM_INCLUDED
35
40
41#include "platform.h"
42#include "type_traits.h"
43#include "iterator.h"
44#include "functional.h"
45#include "utility.h"
46#include "largest.h"
47#include "gcd.h"
48#include "error_handler.h"
49#include "exception.h"
50
51#include <stdint.h>
52#include <string.h>
53
54#include "private/minmax_push.h"
55
56#if ETL_USING_STL
57 #include <algorithm>
58 #include <utility>
59 #include <iterator>
60 #include <functional>
61 #include <numeric>
62#endif
63
64namespace etl
65{
66 // Declare prototypes of the ETL's sort functions
67 template <typename TIterator>
68#if ETL_USING_STD_NAMESPACE
69 ETL_CONSTEXPR20
70#else
71 ETL_CONSTEXPR14
72#endif
73 void shell_sort(TIterator first, TIterator last);
74
75 template <typename TIterator, typename TCompare>
76#if ETL_USING_STD_NAMESPACE
77 ETL_CONSTEXPR20
78#else
79 ETL_CONSTEXPR14
80#endif
81 void shell_sort(TIterator first, TIterator last, TCompare compare);
82
83 template <typename TIterator>
84 ETL_CONSTEXPR14 void insertion_sort(TIterator first, TIterator last);
85
86 template <typename TIterator, typename TCompare>
87 ETL_CONSTEXPR14 void insertion_sort(TIterator first, TIterator last, TCompare compare);
88
90 {
91 public:
92
93 algorithm_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
95 {
96 }
97 };
98
100 {
101 public:
102
103 algorithm_error(string_type file_name_, numeric_type line_number_)
104 : algorithm_exception(ETL_ERROR_TEXT("algorithm:error", ETL_ALGORITHM_FILE_ID"A"), file_name_, line_number_)
105 {
106 }
107 };
108
109}
110
111//*****************************************************************************
112// Algorithms defined by the ETL
113//*****************************************************************************
114namespace etl
115{
116 namespace private_algorithm
117 {
118 template <bool use_swap>
119 struct swap_impl;
120
121 // Generic swap
122 template <>
123 struct swap_impl<false>
124 {
125 template <typename TIterator1, typename TIterator2>
126 static void do_swap(TIterator1 a, TIterator2 b)
127 {
128 typename etl::iterator_traits<TIterator1>::value_type tmp = *a;
129 *a = *b;
130 *b = tmp;
131 }
132 };
133
134 // Specialised swap
135 template <>
136 struct swap_impl<true>
137 {
138 template <typename TIterator1, typename TIterator2>
139 static void do_swap(TIterator1 a, TIterator2 b)
140 {
141 using ETL_OR_STD::swap; // Allow ADL
142 swap(*a, *b);
143 }
144 };
145 }
146
147 //***************************************************************************
148 // iter_swap
149 //***************************************************************************
150 template <typename TIterator1, typename TIterator2>
151#if ETL_USING_STD_NAMESPACE
152 ETL_CONSTEXPR20
153#else
154 ETL_CONSTEXPR14
155#endif
156 void iter_swap(TIterator1 a, TIterator2 b)
157 {
160
161 typedef typename traits1::value_type v1;
162 typedef typename traits2::value_type v2;
163
164 typedef typename traits1::reference r1;
165 typedef typename traits2::reference r2;
166
170
172 }
173
174 //***************************************************************************
175 // swap_ranges
176 //***************************************************************************
177 template <typename TIterator1, typename TIterator2>
178#if ETL_USING_STD_NAMESPACE
179 ETL_CONSTEXPR20
180#else
181 ETL_CONSTEXPR14
182#endif
183 TIterator2 swap_ranges(TIterator1 first1,
186 {
187 while (first1 != last1)
188 {
189 iter_swap(first1, first2);
190 ++first1;
191 ++first2;
192 }
193
194 return first2;
195 }
196
197 //***************************************************************************
198 // generate
199 template <typename TIterator, typename TFunction>
200 ETL_CONSTEXPR14
201 void generate(TIterator db, TIterator de, TFunction funct)
202 {
203 while (db != de)
204 {
205 *db++ = funct();
206 }
207 }
208
209 //***************************************************************************
210 // copy
211#if ETL_USING_STL && ETL_USING_CPP20
212 // Use the STL constexpr implementation.
213 template <typename TIterator1, typename TIterator2>
215 {
216 return std::copy(sb, se, db);
217 }
218#else
219 // Non-pointer or not trivially copyable or not using builtin memcpy.
220 template <typename TIterator1, typename TIterator2>
221 ETL_CONSTEXPR14 TIterator2 copy(TIterator1 sb, TIterator1 se, TIterator2 db)
222 {
223 while (sb != se)
224 {
225 *db = *sb;
226 ++db;
227 ++sb;
228 }
229
230 return db;
231 }
232#endif
233
234 //***************************************************************************
235 // reverse_copy
236#if ETL_USING_STL && ETL_USING_CPP20
237 template <typename TIterator1, typename TIterator2>
238 constexpr TIterator2 reverse_copy(TIterator1 sb, TIterator1 se, TIterator2 db)
239 {
240 return std::reverse_copy(sb, se, db);
241 }
242#else
243 template <typename TIterator1, typename TIterator2>
244 ETL_CONSTEXPR14
246 {
247 while (sb != se)
248 {
249 *db = *--se;
250 ++db;
251 }
252
253 return db;
254 }
255#endif
256
257 //***************************************************************************
258 // copy_n
259#if ETL_USING_STL && ETL_USING_CPP20
260 // Use the STL implementation
261 template <typename TIterator1, typename TSize, typename TIterator2>
262 constexpr TIterator2 copy_n(TIterator1 sb, TSize count, TIterator2 db)
263 {
264 return std::copy_n(sb, count, db);
265 }
266#else
267 // Non-pointer or not trivially copyable or not using builtin memcpy.
268 template <typename TIterator1, typename TSize, typename TIterator2>
269 ETL_CONSTEXPR14 TIterator2 copy_n(TIterator1 sb, TSize count, TIterator2 db)
270 {
271 while (count != 0)
272 {
273 *db = *sb;
274 ++db;
275 ++sb;
276 --count;
277 }
278
279 return db;
280 }
281#endif
282
283 //***************************************************************************
284 // copy_backward
285#if ETL_USING_STL && ETL_USING_CPP20
286 template <typename TIterator1, typename TIterator2>
287 constexpr TIterator2 copy_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
288 {
289 return std::copy_backward(sb, se, de);
290 }
291#else
292 template <typename TIterator1, typename TIterator2>
293 ETL_CONSTEXPR14 TIterator2 copy_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
294 {
295 while (se != sb)
296 {
297 *(--de) = *(--se);
298 }
299
300 return de;
301 }
302#endif
303
304 //***************************************************************************
305 // move
306#if ETL_USING_STL && ETL_USING_CPP20
307 template <typename TIterator1, typename TIterator2>
309 {
310 return std::move(sb, se, db);
311 }
312#elif ETL_USING_CPP11
313 // For C++11
314 template <typename TIterator1, typename TIterator2>
315 ETL_CONSTEXPR14 TIterator2 move(TIterator1 sb, TIterator1 se, TIterator2 db)
316 {
317 while (sb != se)
318 {
319 *db = etl::move(*sb);
320 ++db;
321 ++sb;
322 }
323
324 return db;
325 }
326#else
327 // For C++03
328 template <typename TIterator1, typename TIterator2>
329 ETL_CONSTEXPR14 TIterator2 move(TIterator1 sb, TIterator1 se, TIterator2 db)
330 {
331 return copy(sb, se, db);
332 }
333#endif
334
335 //***************************************************************************
336 // move_backward
337#if ETL_USING_STL && ETL_USING_CPP20
338 template <typename TIterator1, typename TIterator2>
339 ETL_CONSTEXPR20 TIterator2 move_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
340 {
341 return std::move_backward(sb, se, de);
342 }
343#elif ETL_USING_CPP11
344 // For C++11
345 template <typename TIterator1, typename TIterator2>
346 ETL_CONSTEXPR14 TIterator2 move_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
347 {
348 while (sb != se)
349 {
350 *(--de) = etl::move(*(--se));
351 }
352
353 return de;
354 }
355#else
356 // For C++03
357 template <typename TIterator1, typename TIterator2>
358 ETL_CONSTEXPR14 TIterator2 move_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
359 {
360 return etl::copy_backward(sb, se, de);
361 }
362#endif
363
364 //***************************************************************************
365 // reverse
366 //***************************************************************************
367 // Pointers
368 template <typename TIterator>
369 ETL_CONSTEXPR14
371 reverse(TIterator b, TIterator e)
372 {
373 if (b != e)
374 {
375 while (b < --e)
376 {
377 etl::iter_swap(b, e);
378 ++b;
379 }
380 }
381 }
382
383 // Non-pointers
384 template <typename TIterator>
385 ETL_CONSTEXPR14
387 reverse(TIterator b, TIterator e)
388 {
389 while ((b != e) && (b != --e))
390 {
391 etl::iter_swap(b++, e);
392 }
393 }
394
395 //***************************************************************************
396 // lower_bound
397 //***************************************************************************
398 template<typename TIterator, typename TValue, typename TCompare>
399 ETL_NODISCARD
400 ETL_CONSTEXPR14
401 TIterator lower_bound(TIterator first, TIterator last, const TValue& value, TCompare compare)
402 {
403 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
404
405 difference_t count = etl::distance(first, last);
406
407 while (count > 0)
408 {
409 TIterator itr = first;
410 difference_t step = count / 2;
411
412 etl::advance(itr, step);
413
414 if (compare(*itr, value))
415 {
416 first = ++itr;
417 count -= step + 1;
418 }
419 else
420 {
421 count = step;
422 }
423 }
424
425 return first;
426 }
427
428 template<typename TIterator, typename TValue>
429 ETL_NODISCARD
430 ETL_CONSTEXPR14
431 TIterator lower_bound(TIterator first, TIterator last, const TValue& value)
432 {
434
435 return etl::lower_bound(first, last, value, compare());
436 }
437
438 //***************************************************************************
439 // upper_bound
440 //***************************************************************************
441 template<typename TIterator, typename TValue, typename TCompare>
442 ETL_NODISCARD
443 ETL_CONSTEXPR14
444 TIterator upper_bound(TIterator first, TIterator last, const TValue& value, TCompare compare)
445 {
446 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
447
448 difference_t count = etl::distance(first, last);
449
450 while (count > 0)
451 {
452 TIterator itr = first;
453 difference_t step = count / 2;
454
455 etl::advance(itr, step);
456
457 if (!compare(value, *itr))
458 {
459 first = ++itr;
460 count -= step + 1;
461 }
462 else
463 {
464 count = step;
465 }
466 }
467
468 return first;
469 }
470
471 template<typename TIterator, typename TValue>
472 ETL_NODISCARD
473 ETL_CONSTEXPR14
474 TIterator upper_bound(TIterator first, TIterator last, const TValue& value)
475 {
477
478 return etl::upper_bound(first, last, value, compare());
479 }
480
481 //***************************************************************************
482 // equal_range
483 //***************************************************************************
484 template<typename TIterator, typename TValue, typename TCompare>
485 ETL_NODISCARD
486 ETL_CONSTEXPR14
487 ETL_OR_STD::pair<TIterator, TIterator> equal_range(TIterator first, TIterator last, const TValue& value, TCompare compare)
488 {
489 return ETL_OR_STD::make_pair(etl::lower_bound(first, last, value, compare),
490 etl::upper_bound(first, last, value, compare));
491 }
492
493 template<typename TIterator, typename TValue>
494 ETL_NODISCARD
495 ETL_OR_STD::pair<TIterator, TIterator> equal_range(TIterator first, TIterator last, const TValue& value)
496 {
498
499 return ETL_OR_STD::make_pair(etl::lower_bound(first, last, value, compare()),
500 etl::upper_bound(first, last, value, compare()));
501 }
502
503 //***************************************************************************
504 // binary_search
505 //***************************************************************************
506 template <typename TIterator, typename T, typename Compare>
507 ETL_NODISCARD
508 bool binary_search(TIterator first, TIterator last, const T& value, Compare compare)
509 {
510 first = etl::lower_bound(first, last, value, compare);
511
512 return (!(first == last) && !(compare(value, *first)));
513 }
514
515 template <typename TIterator, typename T>
516 ETL_NODISCARD
517 bool binary_search(TIterator first, TIterator last, const T& value)
518 {
520
521 return binary_search(first, last, value, compare());
522 }
523
524 //***************************************************************************
525 // find_if
526 //***************************************************************************
527 template <typename TIterator, typename TUnaryPredicate>
528 ETL_NODISCARD
529 ETL_CONSTEXPR14
531 {
532 while (first != last)
533 {
534 if (predicate(*first))
535 {
536 return first;
537 }
538
539 ++first;
540 }
541
542 return last;
543 }
544
545 //***************************************************************************
546 // find
547 //***************************************************************************
548 template <typename TIterator, typename T>
549 ETL_NODISCARD
550 ETL_CONSTEXPR14
551 TIterator find(TIterator first, TIterator last, const T& value)
552 {
553 while (first != last)
554 {
555 if (*first == value)
556 {
557 return first;
558 }
559
560 ++first;
561 }
562
563 return last;
564 }
565
566 //***************************************************************************
567 // fill
568#if ETL_USING_STL && ETL_USING_CPP20
569 template<typename TIterator, typename TValue>
570 constexpr void fill(TIterator first, TIterator last, const TValue& value)
571 {
572 std::fill(first, last, value);
573 }
574#else
575 template<typename TIterator, typename TValue>
576 ETL_CONSTEXPR14 void fill(TIterator first, TIterator last, const TValue& value)
577 {
578 while (first != last)
579 {
580 *first = value;
581 ++first;
582 }
583 }
584#endif
585
586 //***************************************************************************
587 // fill_n
588#if ETL_USING_STL && ETL_USING_CPP20
589 template<typename TIterator, typename TSize, typename TValue>
590 constexpr TIterator fill_n(TIterator first, TSize count, const TValue& value)
591 {
592 return std::fill_n(first, count, value);
593 }
594#else
595 template<typename TIterator, typename TSize, typename TValue>
596 ETL_CONSTEXPR14 TIterator fill_n(TIterator first, TSize count, const TValue& value)
597 {
598 while (count != 0)
599 {
600 *first++ = value;
601 --count;
602 }
603
604 return first;
605 }
606#endif
607
608 //***************************************************************************
609 // count
610 //***************************************************************************
611 template <typename TIterator, typename T>
612 ETL_NODISCARD
613 ETL_CONSTEXPR14
614 typename etl::iterator_traits<TIterator>::difference_type count(TIterator first, TIterator last, const T& value)
615 {
616 typename iterator_traits<TIterator>::difference_type n = 0;
617
618 while (first != last)
619 {
620 if (*first == value)
621 {
622 ++n;
623 }
624
625 ++first;
626 }
627
628 return n;
629 }
630
631 //***************************************************************************
632 // count_if
633 //***************************************************************************
634 template <typename TIterator, typename TUnaryPredicate>
635 ETL_NODISCARD
636 ETL_CONSTEXPR14
637 typename etl::iterator_traits<TIterator>::difference_type
638 count_if(TIterator first, TIterator last, TUnaryPredicate predicate)
639 {
640 typename iterator_traits<TIterator>::difference_type n = 0;
641
642 while (first != last)
643 {
644 if (predicate(*first))
645 {
646 ++n;
647 }
648
649 ++first;
650 }
651
652 return n;
653 }
654
655 //***************************************************************************
656 // equal
657#if ETL_USING_STL && ETL_USING_CPP20
658 // Three parameter
659 template <typename TIterator1, typename TIterator2>
660 [[nodiscard]]
661 constexpr
663 {
664 return std::equal(first1, last1, first2);
665 }
666
667 // Three parameter + predicate
668 template <typename TIterator1, typename TIterator2, typename TPredicate>
669 [[nodiscard]]
670 constexpr
672 {
673 return std::equal(first1, last1, first2, predicate);
674 }
675
676 // Four parameter
677 template <typename TIterator1, typename TIterator2>
678 [[nodiscard]]
679 constexpr
681 {
682 return std::equal(first1, last1, first2, last2);
683 }
684
685 // Four parameter + Predicate
686 template <typename TIterator1, typename TIterator2, typename TPredicate>
687 [[nodiscard]]
688 constexpr
690 {
691 return std::equal(first1, last1, first2, last2, predicate);
692 }
693
694#else
695
696 template <typename TIterator1, typename TIterator2>
697 ETL_NODISCARD
698 ETL_CONSTEXPR14
700 {
701 while (first1 != last1)
702 {
703 if (*first1 != *first2)
704 {
705 return false;
706 }
707
708 ++first1;
709 ++first2;
710 }
711
712 return true;
713 }
714
715 // Predicate
716 template <typename TIterator1, typename TIterator2, typename TPredicate>
717 ETL_NODISCARD
718 ETL_CONSTEXPR14
720 {
721 while (first1 != last1)
722 {
723 if (!predicate(*first1, *first2))
724 {
725 return false;
726 }
727
728 ++first1;
729 ++first2;
730 }
731
732 return true;
733 }
734
735 // Four parameter
736 template <typename TIterator1, typename TIterator2>
737 ETL_NODISCARD
738 ETL_CONSTEXPR14
740 {
741 while ((first1 != last1) && (first2 != last2))
742 {
743 if (*first1 != *first2)
744 {
745 return false;
746 }
747
748 ++first1;
749 ++first2;
750 }
751
752 return (first1 == last1) && (first2 == last2);
753 }
754
755 // Four parameter, Predicate
756 template <typename TIterator1, typename TIterator2, typename TPredicate>
757 ETL_NODISCARD
758 ETL_CONSTEXPR14
760 {
761 while ((first1 != last1) && (first2 != last2))
762 {
763 if (!predicate(*first1 , *first2))
764 {
765 return false;
766 }
767
768 ++first1;
769 ++first2;
770 }
771
772 return (first1 == last1) && (first2 == last2);
773 }
774#endif
775
776 //***************************************************************************
777 // lexicographical_compare
778 //***************************************************************************
779 template <typename TIterator1, typename TIterator2, typename TCompare>
780 ETL_NODISCARD
781 ETL_CONSTEXPR14
782 bool lexicographical_compare(TIterator1 first1, TIterator1 last1,
784 TCompare compare)
785 {
786 while ((first1 != last1) && (first2 != last2))
787 {
788 if (compare(*first1, *first2))
789 {
790 return true;
791 }
792
793 if (compare(*first2, *first1))
794 {
795 return false;
796 }
797
798 ++first1;
799 ++first2;
800 }
801
802 return (first1 == last1) && (first2 != last2);
803 }
804
805 // lexicographical_compare
806 template <typename TIterator1, typename TIterator2>
807 ETL_NODISCARD
808 ETL_CONSTEXPR14
809 bool lexicographical_compare(TIterator1 first1, TIterator1 last1,
811 {
813
814 return etl::lexicographical_compare(first1, last1, first2, last2, compare());
815 }
816
817 //***************************************************************************
818 // min
819 //***************************************************************************
820 template <typename T, typename TCompare>
821 ETL_NODISCARD
822 ETL_CONSTEXPR
823 const T& min(const T& a, const T& b, TCompare compare)
824 {
825 return (compare(a, b)) ? a : b;
826 }
827
828 template <typename T>
829 ETL_NODISCARD
830 ETL_CONSTEXPR
831 const T& min(const T& a, const T& b)
832 {
833 typedef etl::less<T> compare;
834
835 return etl::min(a, b, compare());
836 }
837
838 //***************************************************************************
839 // max
840 //***************************************************************************
841 template <typename T, typename TCompare>
842 ETL_NODISCARD
843 ETL_CONSTEXPR
844 const T& max(const T& a, const T& b, TCompare compare)
845 {
846 return (compare(a, b)) ? b : a;
847 }
848
849 template <typename T>
850 ETL_NODISCARD
851 ETL_CONSTEXPR
852 const T& max(const T& a, const T& b)
853 {
854 typedef etl::less<T> compare;
855
856 return etl::max(a, b, compare());
857 }
858
859 //***************************************************************************
860 // for_each
861 //***************************************************************************
862 template <typename TIterator, typename TUnaryOperation>
863 ETL_CONSTEXPR14
865 {
866 while (first != last)
867 {
868 unary_operation(*first);
869 ++first;
870 }
871
872 return unary_operation;
873 }
874
875 //***************************************************************************
876 // transform
877 //***************************************************************************
878 template <typename TIteratorIn, typename TIteratorOut, typename TUnaryOperation>
879 ETL_CONSTEXPR14
881 {
882 while (first1 != last1)
883 {
885
886 ++d_first;
887 ++first1;
888 }
889
890 return d_first;
891 }
892
893 template <typename TIteratorIn1, typename TIteratorIn2, typename TIteratorOut, typename TBinaryOperation>
894 ETL_CONSTEXPR14
896 {
897 while (first1 != last1)
898 {
900
901 ++d_first;
902 ++first1;
903 ++first2;
904 }
905
906 return d_first;
907 }
908
909 //***************************************************************************
910 // replace
911 //***************************************************************************
912 template <typename TIterator, typename T>
913 ETL_CONSTEXPR14 void replace(TIterator first, TIterator last, const T& old_value, const T& new_value)
914 {
915 while (first != last)
916 {
917 if (*first == old_value)
918 {
919 *first = new_value;
920 }
921
922 ++first;
923 }
924 }
925
926 //***************************************************************************
927 // replace_if
928 //***************************************************************************
929 template <typename TIterator, typename TPredicate, typename T>
930 ETL_CONSTEXPR14 void replace_if(TIterator first, TIterator last, TPredicate predicate, const T& new_value)
931 {
932 while (first != last)
933 {
934 if (predicate(*first))
935 {
936 *first = new_value;
937 }
938
939 ++first;
940 }
941 }
942
943 //***************************************************************************
944 // Heap
945 //***************************************************************************
946 namespace private_heap
947 {
948 // Push Heap Helper
949 template <typename TIterator, typename TDistance, typename TValue, typename TCompare>
950 void push_heap(TIterator first, TDistance value_index, TDistance top_index, TValue value, TCompare compare)
951 {
952 TDistance parent = (value_index - 1) / 2;
953
954 while ((value_index > top_index) && compare(first[parent], value))
955 {
956 first[value_index] = ETL_MOVE(first[parent]);
957 value_index = parent;
958 parent = (value_index - 1) / 2;
959 }
960
961 first[value_index] = ETL_MOVE(value);
962 }
963
964 // Adjust Heap Helper
965 template <typename TIterator, typename TDistance, typename TValue, typename TCompare>
966 void adjust_heap(TIterator first, TDistance value_index, TDistance length, TValue value, TCompare compare)
967 {
968 TDistance top_index = value_index;
969 TDistance child2nd = (2 * value_index) + 2;
970
971 while (child2nd < length)
972 {
973 if (compare(first[child2nd], first[child2nd - 1]))
974 {
975 --child2nd;
976 }
977
978 first[value_index] = ETL_MOVE(first[child2nd]);
980 child2nd = 2 * (child2nd + 1);
981 }
982
983 if (child2nd == length)
984 {
985 first[value_index] = ETL_MOVE(first[child2nd - 1]);
986 value_index = child2nd - 1;
987 }
988
989 push_heap(first, value_index, top_index, ETL_MOVE(value), compare);
990 }
991
992 // Is Heap Helper
993 template <typename TIterator, typename TDistance, typename TCompare>
994 bool is_heap(const TIterator first, const TDistance n, TCompare compare)
995 {
996 TDistance parent = 0;
997
998 for (TDistance child = 1; child < n; ++child)
999 {
1000 if (compare(first[parent], first[child]))
1001 {
1002 return false;
1003 }
1004
1005 if ((child & 1) == 0)
1006 {
1007 ++parent;
1008 }
1009 }
1010
1011 return true;
1012 }
1013 }
1014
1015 // Pop Heap
1016 template <typename TIterator, typename TCompare>
1017 void pop_heap(TIterator first, TIterator last, TCompare compare)
1018 {
1019 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1020 typedef typename etl::iterator_traits<TIterator>::difference_type distance_t;
1021
1022 value_t value = ETL_MOVE(last[-1]);
1023 last[-1] = ETL_MOVE(first[0]);
1024
1025 private_heap::adjust_heap(first, distance_t(0), distance_t(last - first - 1), ETL_MOVE(value), compare);
1026 }
1027
1028 // Pop Heap
1029 template <typename TIterator>
1030 void pop_heap(TIterator first, TIterator last)
1031 {
1033
1034 etl::pop_heap(first, last, compare());
1035 }
1036
1037 // Push Heap
1038 template <typename TIterator, typename TCompare>
1039 void push_heap(TIterator first, TIterator last, TCompare compare)
1040 {
1041 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
1042 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1043
1044 private_heap::push_heap(first, difference_t(last - first - 1), difference_t(0), value_t(ETL_MOVE(*(last - 1))), compare);
1045 }
1046
1047 // Push Heap
1048 template <typename TIterator>
1049 void push_heap(TIterator first, TIterator last)
1050 {
1052
1053 etl::push_heap(first, last, compare());
1054 }
1055
1056 // Make Heap
1057 template <typename TIterator, typename TCompare>
1058 void make_heap(TIterator first, TIterator last, TCompare compare)
1059 {
1060 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
1061
1062 if ((last - first) < 2)
1063 {
1064 return;
1065 }
1066
1067 difference_t length = last - first;
1068 difference_t parent = (length - 2) / 2;
1069
1070 while (true)
1071 {
1072 private_heap::adjust_heap(first, parent, length, ETL_MOVE(*(first + parent)), compare);
1073
1074 if (parent == 0)
1075 {
1076 return;
1077 }
1078
1079 --parent;
1080 }
1081 }
1082
1083 // Make Heap
1084 template <typename TIterator>
1085 void make_heap(TIterator first, TIterator last)
1086 {
1088
1089 etl::make_heap(first, last, compare());
1090 }
1091
1092 // Is Heap
1093 template <typename TIterator>
1094 ETL_NODISCARD
1095 bool is_heap(TIterator first, TIterator last)
1096 {
1098
1099 return private_heap::is_heap(first, last - first, compare());
1100 }
1101
1102 // Is Heap
1103 template <typename TIterator, typename TCompare>
1104 ETL_NODISCARD
1105 bool is_heap(TIterator first, TIterator last, TCompare compare)
1106 {
1107 return private_heap::is_heap(first, last - first, compare);
1108 }
1109
1110 // Sort Heap
1111 template <typename TIterator>
1112 void sort_heap(TIterator first, TIterator last)
1113 {
1114 while (first != last)
1115 {
1116 etl::pop_heap(first, last);
1117 --last;
1118 }
1119 }
1120
1121 // Sort Heap
1122 template <typename TIterator, typename TCompare>
1123 void sort_heap(TIterator first, TIterator last, TCompare compare)
1124 {
1125 while (first != last)
1126 {
1127 etl::pop_heap(first, last, compare);
1128 --last;
1129 }
1130 }
1131
1132 //***************************************************************************
1133 // Search
1134 //***************************************************************************
1135 template<typename TIterator1, typename TIterator2, typename TCompare>
1136 ETL_NODISCARD
1137 ETL_CONSTEXPR14
1139 {
1140 while (true)
1141 {
1142 TIterator1 itr = first;
1144
1145 while (true)
1146 {
1147 if (search_itr == search_last)
1148 {
1149 return first;
1150 }
1151
1152 if (itr == last)
1153 {
1154 return last;
1155 }
1156
1157 if (!compare(*itr, *search_itr))
1158 {
1159 break;
1160 }
1161
1162 ++itr;
1163 ++search_itr;
1164 }
1165
1166 ++first;
1167 }
1168 }
1169
1170 // Search
1171 template<typename TIterator1, typename TIterator2>
1172 ETL_NODISCARD
1173 ETL_CONSTEXPR14
1175 {
1177
1178 return etl::search(first, last, search_first, search_last, compare());
1179 }
1180
1181 //***************************************************************************
1182 // Rotate
1183 //***************************************************************************
1184 namespace private_algorithm
1185 {
1186#if ETL_USING_CPP11
1187 //*********************************
1188 // For random access iterators
1189 template <typename TIterator>
1190 ETL_CONSTEXPR14
1192 rotate_general(TIterator first, TIterator middle, TIterator last)
1193 {
1194 if (first == middle || middle == last)
1195 {
1196 return first;
1197 }
1198
1199 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
1200
1201 int n = last - first;
1202 int m = middle - first;
1203 int gcd_nm = (n == 0 || m == 0) ? n + m : etl::gcd(n, m);
1204
1205 TIterator result = first + (last - middle);
1206
1207 for (int i = 0; i < gcd_nm; i++)
1208 {
1209 value_type temp = ETL_MOVE(*(first + i));
1210 int j = i;
1211
1212 while (true)
1213 {
1214 int k = j + m;
1215
1216 if (k >= n)
1217 {
1218 k = k - n;
1219 }
1220
1221 if (k == i)
1222 {
1223 break;
1224 }
1225
1226 *(first + j) = ETL_MOVE(*(first + k));
1227 j = k;
1228 }
1229
1230 *(first + j) = ETL_MOVE(temp);
1231 }
1232
1233 return result;
1234 }
1235#else
1236 //*********************************
1237 // For random access iterators
1238 template <typename TIterator>
1239 ETL_CONSTEXPR14
1241 rotate_general(TIterator first, TIterator middle, TIterator last)
1242 {
1243 if (first == middle || middle == last)
1244 {
1245 return first;
1246 }
1247
1248 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
1249
1250 int n = last - first;
1251 int m = middle - first;
1252 int gcd_nm = (n == 0 || m == 0) ? n + m : etl::gcd(n, m);
1253
1254 TIterator result = first + (last - middle);
1255
1256 for (int i = 0; i < gcd_nm; i++)
1257 {
1258 value_type temp = *(first + i);
1259 int j = i;
1260
1261 while (true)
1262 {
1263 int k = j + m;
1264
1265 if (k >= n)
1266 {
1267 k = k - n;
1268 }
1269
1270 if (k == i)
1271 {
1272 break;
1273 }
1274
1275 *(first + j) = *(first + k);
1276 j = k;
1277 }
1278
1279 *(first + j) = temp;
1280 }
1281
1282 return result;
1283 }
1284#endif
1285
1286 //*********************************
1287 // For bidirectional iterators
1288 template <typename TIterator>
1289 ETL_CONSTEXPR14
1291 rotate_general(TIterator first, TIterator middle, TIterator last)
1292 {
1293 if (first == middle || middle == last)
1294 {
1295 return first;
1296 }
1297
1298 TIterator result = first;
1299 etl::advance(result, etl::distance(middle, last));
1300
1301 reverse(first, middle);
1302 reverse(middle, last);
1303 reverse(first, last);
1304
1305 return result;
1306 }
1307
1308 //*********************************
1309 // For forward iterators
1310 template <typename TIterator>
1311 ETL_CONSTEXPR14
1313 rotate_general(TIterator first, TIterator middle, TIterator last)
1314 {
1315 if (first == middle || middle == last)
1316 {
1317 return first;
1318 }
1319
1320 TIterator next = middle;
1321 TIterator result = first;
1322 etl::advance(result, etl::distance(middle, last));
1323
1324 while (first != next)
1325 {
1326 using ETL_OR_STD::swap;
1327 swap(*first++, *next++);
1328
1329 if (next == last)
1330 {
1331 next = middle;
1332 }
1333 else if (first == middle)
1334 {
1335 middle = next;
1336 }
1337 }
1338
1339 return result;
1340 }
1341
1342 //*********************************
1343 // Simplified algorithm for rotate left by one
1344 template <typename TIterator>
1345 ETL_CONSTEXPR14
1346 TIterator rotate_left_by_one(TIterator first, TIterator last)
1347 {
1348 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
1349
1350 // Save the first item.
1351 value_type temp(ETL_MOVE(*first));
1352
1353 // Move the rest.
1354 TIterator result = etl::move(etl::next(first), last, first);
1355
1356 // Restore the first item in its rotated position.
1357 *result = ETL_MOVE(temp);
1358
1359 // The new position of the first item.
1360 return result;
1361 }
1362
1363 //*********************************
1364 // Simplified for algorithm rotate right by one
1365 template <typename TIterator>
1366 ETL_CONSTEXPR14
1367 TIterator rotate_right_by_one(TIterator first, TIterator last)
1368 {
1369 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
1370
1371 // Save the last item.
1372 TIterator previous = etl::prev(last);
1373 value_type temp(ETL_MOVE(*previous));
1374
1375 // Move the rest.
1376 TIterator result = etl::move_backward(first, previous, last);
1377
1378 // Restore the last item in its rotated position.
1379 *first = ETL_MOVE(temp);
1380
1381 // The new position of the first item.
1382 return result;
1383 }
1384 }
1385
1386 //*********************************
1387 template<typename TIterator>
1388 ETL_CONSTEXPR14
1389 TIterator rotate(TIterator first, TIterator middle, TIterator last)
1390 {
1391 if (etl::next(first) == middle)
1392 {
1393 return private_algorithm::rotate_left_by_one(first, last);
1394 }
1395
1396 if (etl::next(middle) == last)
1397 {
1398#if ETL_USING_CPP20
1400 {
1401 return private_algorithm::rotate_general(first, middle, last);
1402 }
1403 else
1404 {
1405 return private_algorithm::rotate_right_by_one(first, last);
1406 }
1407#else
1408 return private_algorithm::rotate_general(first, middle, last);
1409#endif
1410 }
1411
1412 return private_algorithm::rotate_general(first, middle, last);
1413 }
1414
1415 //***************************************************************************
1416 // find_end
1417 //***************************************************************************
1418 // Predicate
1419 template <typename TIterator1, typename TIterator2, typename TPredicate>
1420 ETL_NODISCARD
1421 ETL_CONSTEXPR14
1422 TIterator1 find_end(TIterator1 b, TIterator1 e,
1425 {
1426 if (sb == se)
1427 {
1428 return e;
1429 }
1430
1431 TIterator1 result = e;
1432
1433 while (true)
1434 {
1435 TIterator1 new_result = etl::search(b, e, sb, se, predicate);
1436
1437 if (new_result == e)
1438 {
1439 break;
1440 }
1441 else
1442 {
1443 result = new_result;
1444 b = result;
1445 ++b;
1446 }
1447 }
1448 return result;
1449 }
1450
1451 // Default
1452 template <typename TIterator1, typename TIterator2>
1453 ETL_NODISCARD
1454 ETL_CONSTEXPR14
1455 TIterator1 find_end(TIterator1 b, TIterator1 e,
1457 {
1459
1460 return find_end(b, e, sb, se, predicate());
1461 }
1462
1463 //***************************************************************************
1467 //***************************************************************************
1468 template <typename TIterator, typename TCompare>
1469 ETL_NODISCARD
1470 ETL_CONSTEXPR14
1472 TIterator end,
1474 {
1476
1477 if (begin != end)
1478 {
1479 ++begin;
1480
1481 while (begin != end)
1482 {
1483 if (compare(*begin, *minimum))
1484 {
1485 minimum = begin;
1486 }
1487
1488 ++begin;
1489 }
1490 }
1491
1492 return minimum;
1493 }
1494
1495 //***************************************************************************
1499 //***************************************************************************
1500 template <typename TIterator>
1501 ETL_NODISCARD
1502 ETL_CONSTEXPR14
1504 TIterator end)
1505 {
1506 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1507
1509 }
1510
1511 //***************************************************************************
1515 //***************************************************************************
1516 template <typename TIterator, typename TCompare>
1517 ETL_NODISCARD
1518 ETL_CONSTEXPR14
1520 TIterator end,
1522 {
1523 TIterator maximum = begin;
1524
1525 if (begin != end)
1526 {
1527 ++begin;
1528
1529 while (begin != end)
1530 {
1531 if (!compare(*begin, *maximum))
1532 {
1533 maximum = begin;
1534 }
1535
1536 ++begin;
1537 }
1538 }
1539
1540 return maximum;
1541 }
1542
1543 //***************************************************************************
1547 //***************************************************************************
1548 template <typename TIterator>
1549 ETL_NODISCARD
1550 ETL_CONSTEXPR14
1552 TIterator end)
1553 {
1554 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1555
1557 }
1558
1559 //***************************************************************************
1563 //***************************************************************************
1564 template <typename TIterator, typename TCompare>
1565 ETL_NODISCARD
1566 ETL_CONSTEXPR14
1567 ETL_OR_STD::pair<TIterator, TIterator> minmax_element(TIterator begin,
1568 TIterator end,
1570 {
1572 TIterator maximum = begin;
1573
1574 if (begin != end)
1575 {
1576 ++begin;
1577
1578 while (begin != end)
1579 {
1580 if (compare(*begin, *minimum))
1581 {
1582 minimum = begin;
1583 }
1584
1585 if (compare(*maximum, *begin))
1586 {
1587 maximum = begin;
1588 }
1589
1590 ++begin;
1591 }
1592 }
1593
1594 return ETL_OR_STD::pair<TIterator, TIterator>(minimum, maximum);
1595 }
1596
1597 //***************************************************************************
1601 //***************************************************************************
1602 template <typename TIterator>
1603 ETL_NODISCARD
1604 ETL_CONSTEXPR14
1605 ETL_OR_STD::pair<TIterator, TIterator> minmax_element(TIterator begin,
1606 TIterator end)
1607 {
1608 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1609
1611 }
1612
1613 //***************************************************************************
1617 //***************************************************************************
1618 template <typename T>
1619 ETL_NODISCARD
1620 ETL_CONSTEXPR14
1621 ETL_OR_STD::pair<const T&, const T&> minmax(const T& a,
1622 const T& b)
1623 {
1624 return (b < a) ? ETL_OR_STD::pair<const T&, const T&>(b, a) : ETL_OR_STD::pair<const T&, const T&>(a, b);
1625 }
1626
1627 //***************************************************************************
1631 //***************************************************************************
1632 template <typename T, typename TCompare>
1633 ETL_NODISCARD
1634 ETL_CONSTEXPR14
1635 ETL_OR_STD::pair<const T&, const T&> minmax(const T& a,
1636 const T& b,
1638 {
1639 return compare(b, a) ? ETL_OR_STD::pair<const T&, const T&>(b, a) : ETL_OR_STD::pair<const T&, const T&>(a, b);
1640 }
1641
1642 //***************************************************************************
1646 //***************************************************************************
1647 template <typename TIterator>
1648 ETL_NODISCARD
1649 ETL_CONSTEXPR14
1651 TIterator end)
1652 {
1653 if (begin != end)
1654 {
1655 TIterator next = begin;
1656
1657 while (++next != end)
1658 {
1659 if (*next < *begin)
1660 {
1661 return next;
1662 }
1663
1664 ++begin;
1665 }
1666 }
1667
1668 return end;
1669 }
1670
1671 //***************************************************************************
1675 //***************************************************************************
1676 template <typename TIterator, typename TCompare>
1677 ETL_NODISCARD
1678 ETL_CONSTEXPR14
1680 TIterator end,
1682 {
1683 if (begin != end)
1684 {
1685 TIterator next = begin;
1686
1687 while (++next != end)
1688 {
1689 if (compare(*next, *begin))
1690 {
1691 return next;
1692 }
1693
1694 ++begin;
1695 }
1696 }
1697
1698 return end;
1699 }
1700
1701 //***************************************************************************
1705 //***************************************************************************
1706 template<typename TIterator>
1707 ETL_NODISCARD
1708 ETL_CONSTEXPR14
1710 TIterator end)
1711 {
1712 return etl::is_sorted_until(begin, end) == end;
1713 }
1714
1715 //***************************************************************************
1719 //***************************************************************************
1720 template<typename TIterator, typename TCompare>
1721 ETL_NODISCARD
1722 ETL_CONSTEXPR14
1724 TIterator end,
1726 {
1728 }
1729
1730 //***************************************************************************
1733 //***************************************************************************
1734 template <typename TIterator, typename TCompare>
1735 ETL_NODISCARD
1736 ETL_CONSTEXPR14
1738 TIterator end,
1740 {
1741 if (begin != end)
1742 {
1743 TIterator next = begin;
1744
1745 while (++next != end)
1746 {
1747 if (!compare(*begin, *next))
1748 {
1749 return next;
1750 }
1751
1752 ++begin;
1753 }
1754 }
1755
1756 return end;
1757 }
1758
1759 //***************************************************************************
1762 //***************************************************************************
1763 template <typename TIterator>
1764 ETL_NODISCARD
1765 ETL_CONSTEXPR14
1767 TIterator end)
1768 {
1769 if (begin != end)
1770 {
1771 TIterator next = begin;
1772
1773 while (++next != end)
1774 {
1775 if (!(*begin < *next))
1776 {
1777 return next;
1778 }
1779
1780 ++begin;
1781 }
1782 }
1783
1784 return end;
1785 }
1786
1787 //***************************************************************************
1790 //***************************************************************************
1791 template<typename TIterator>
1792 ETL_NODISCARD
1793 ETL_CONSTEXPR14
1799
1800 //***************************************************************************
1803 //***************************************************************************
1804 template<typename TIterator, typename TCompare>
1805 ETL_NODISCARD
1806 ETL_CONSTEXPR14
1813
1814 //***************************************************************************
1818 //***************************************************************************
1819 template <typename TIterator, typename TUnaryPredicate>
1820 ETL_NODISCARD
1821 ETL_CONSTEXPR14
1823 TIterator end,
1825 {
1826 while (begin != end)
1827 {
1828 if (!predicate(*begin))
1829 {
1830 return begin;
1831 }
1832
1833 ++begin;
1834 }
1835
1836 return end;
1837 }
1838
1839 //***************************************************************************
1843 //***************************************************************************
1844 template <typename TIterator1, typename TIterator2>
1845 ETL_NODISCARD
1846 ETL_CONSTEXPR14
1850 {
1851 if (begin1 != end1)
1852 {
1854
1855 etl::advance(end2, etl::distance(begin1, end1));
1856
1857 for (TIterator1 i = begin1; i != end1; ++i)
1858 {
1859 if (i == etl::find(begin1, i, *i))
1860 {
1861 size_t n = etl::count(begin2, end2, *i);
1862
1863 if (n == 0 || size_t(etl::count(i, end1, *i)) != n)
1864 {
1865 return false;
1866 }
1867 }
1868 }
1869 }
1870
1871 return true;
1872 }
1873
1874 //***************************************************************************
1878 //***************************************************************************
1879 template <typename TIterator1, typename TIterator2, typename TBinaryPredicate>
1880 ETL_NODISCARD
1881 ETL_CONSTEXPR14
1886 {
1887 if (begin1 != end1)
1888 {
1890
1891 etl::advance(end2, etl::distance(begin1, end1));
1892
1893 for (TIterator1 i = begin1; i != end1; ++i)
1894 {
1895 if (i == etl::find_if(begin1, i, etl::bind1st(predicate, *i)))
1896 {
1897 size_t n = etl::count(begin2, end2, *i);
1898
1899 if (n == 0 || size_t(etl::count(i, end1, *i)) != n)
1900 {
1901 return false;
1902 }
1903 }
1904 }
1905 }
1906
1907 return true;
1908 }
1909
1910 //***************************************************************************
1914 //***************************************************************************
1915 template <typename TIterator1, typename TIterator2>
1916 ETL_NODISCARD
1917 ETL_CONSTEXPR14
1922 {
1923 if (begin1 != end1)
1924 {
1925 for (TIterator1 i = begin1; i != end1; ++i)
1926 {
1927 if (i == etl::find(begin1, i, *i))
1928 {
1929 size_t n = etl::count(begin2, end2, *i);
1930
1931 if (n == 0 || size_t(etl::count(i, end1, *i)) != n)
1932 {
1933 return false;
1934 }
1935 }
1936 }
1937 }
1938
1939 return true;
1940 }
1941
1942 //***************************************************************************
1946 //***************************************************************************
1947 template <typename TIterator1, typename TIterator2, typename TBinaryPredicate>
1948 ETL_NODISCARD
1954 {
1955 if (begin1 != end1)
1956 {
1957 for (TIterator1 i = begin1; i != end1; ++i)
1958 {
1959 if (i == etl::find_if(begin1, i, etl::bind1st(predicate, *i)))
1960 {
1961 size_t n = etl::count(begin2, end2, *i);
1962
1963 if (n == 0 || size_t(etl::count(i, end1, *i)) != n)
1964 {
1965 return false;
1966 }
1967 }
1968 }
1969 }
1970
1971 return true;
1972 }
1973
1974 //***************************************************************************
1978 //***************************************************************************
1979 template <typename TIterator, typename TUnaryPredicate>
1980 ETL_NODISCARD
1981 ETL_CONSTEXPR14
1983 TIterator end,
1985 {
1986 while (begin != end)
1987 {
1988 if (!predicate(*begin))
1989 {
1990 break;
1991 }
1992
1993 ++begin;
1994 }
1995
1996 while (begin != end)
1997 {
1998 if (predicate(*begin))
1999 {
2000 return false;
2001 }
2002
2003 ++begin;
2004 }
2005
2006 return true;
2007 }
2008
2009 //***************************************************************************
2013 //***************************************************************************
2014 template <typename TIterator, typename TUnaryPredicate>
2015 ETL_NODISCARD
2016 ETL_CONSTEXPR14
2018 TIterator end,
2020 {
2021 while (begin != end)
2022 {
2023 if (!predicate(*begin))
2024 {
2025 return begin;
2026 }
2027
2028 ++begin;
2029 }
2030
2031 return begin;
2032 }
2033
2034 //***************************************************************************
2039 //***************************************************************************
2040 template <typename TSource, typename TDestinationTrue, typename TDestinationFalse, typename TUnaryPredicate>
2041 ETL_CONSTEXPR14
2042 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse> partition_copy(TSource begin,
2043 TSource end,
2047 {
2048 while (begin != end)
2049 {
2050 if (predicate(*begin))
2051 {
2054 }
2055 else
2056 {
2059 }
2060
2061 ++begin;
2062 }
2063
2064 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
2065 }
2066
2067 //***************************************************************************
2071 //***************************************************************************
2072 template <typename TIterator, typename TOutputIterator, typename TUnaryPredicate>
2073 ETL_CONSTEXPR14
2075 TIterator end,
2076 TOutputIterator out,
2078 {
2079 while (begin != end)
2080 {
2081 if (predicate(*begin))
2082 {
2083 *out = *begin;
2084 ++out;
2085 }
2086
2087 ++begin;
2088 }
2089
2090 return out;
2091 }
2092
2093 //***************************************************************************
2097 //***************************************************************************
2098 template <typename TIterator, typename TUnaryPredicate>
2099 ETL_NODISCARD
2100 ETL_CONSTEXPR14
2107
2108 //***************************************************************************
2112 //***************************************************************************
2113 template <typename TIterator, typename TUnaryPredicate>
2114 ETL_NODISCARD
2115 ETL_CONSTEXPR14
2117 TIterator end,
2119 {
2120 return etl::find_if(begin, end, predicate) != end;
2121 }
2122
2123 //***************************************************************************
2127 //***************************************************************************
2128 template <typename TIterator, typename TUnaryPredicate>
2129 ETL_NODISCARD
2130 ETL_CONSTEXPR14
2132 TIterator end,
2134 {
2135 return etl::find_if(begin, end, predicate) == end;
2136 }
2137
2138#if ETL_NOT_USING_STL
2139 //***************************************************************************
2143 //***************************************************************************
2144 template <typename TIterator, typename TCompare>
2145 void sort(TIterator first, TIterator last, TCompare compare)
2146 {
2147 etl::shell_sort(first, last, compare);
2148 }
2149
2150 //***************************************************************************
2153 //***************************************************************************
2154 template <typename TIterator>
2155 void sort(TIterator first, TIterator last)
2156 {
2157 etl::shell_sort(first, last, etl::less<typename etl::iterator_traits<TIterator>::value_type>());
2158 }
2159
2160 //***************************************************************************
2165 //***************************************************************************
2166 template <typename TIterator, typename TCompare>
2167 void stable_sort(TIterator first, TIterator last, TCompare compare)
2168 {
2169 etl::insertion_sort(first, last, compare);
2170 }
2171
2172 //***************************************************************************
2176 //***************************************************************************
2177 template <typename TIterator>
2178 void stable_sort(TIterator first, TIterator last)
2179 {
2180 etl::insertion_sort(first, last, etl::less<typename etl::iterator_traits<TIterator>::value_type>());
2181 }
2182#else
2183 //***************************************************************************
2187 //***************************************************************************
2188 template <typename TIterator, typename TCompare>
2190 {
2191 std::sort(first, last, compare);
2192 }
2193
2194 //***************************************************************************
2197 //***************************************************************************
2198 template <typename TIterator>
2199 void sort(TIterator first, TIterator last)
2200 {
2201 std::sort(first, last);
2202 }
2203
2204 //***************************************************************************
2209 //***************************************************************************
2210 template <typename TIterator, typename TCompare>
2212 {
2213 std::stable_sort(first, last, compare);
2214 }
2215
2216 //***************************************************************************
2220 //***************************************************************************
2221 template <typename TIterator>
2223 {
2224 std::stable_sort(first, last);
2225 }
2226#endif
2227
2228 //***************************************************************************
2231 //***************************************************************************
2232 template <typename TIterator, typename T>
2233 ETL_CONSTEXPR14
2235 {
2236 while (first != last)
2237 {
2238 sum = ETL_MOVE(sum) + *first;
2239 ++first;
2240 }
2241
2242 return sum;
2243 }
2244
2245 //***************************************************************************
2248 //***************************************************************************
2249 template <typename TIterator, typename T, typename TBinaryOperation>
2250 ETL_CONSTEXPR14
2251 T accumulate(TIterator first, TIterator last, T sum, TBinaryOperation operation)
2252 {
2253 while (first != last)
2254 {
2255 sum = operation(ETL_MOVE(sum), *first);
2256 ++first;
2257 }
2258
2259 return sum;
2260 }
2261
2262 //***************************************************************************
2265 //***************************************************************************
2266 template<typename T, typename TCompare>
2267 ETL_CONSTEXPR
2268 T clamp(const T& value, const T& low, const T& high, TCompare compare)
2269 {
2270 return compare(value, low) ? low : compare(high, value) ? high : value;
2271 }
2272
2273 template <typename T>
2274 ETL_CONSTEXPR
2275 T clamp(const T& value, const T& low, const T& high)
2276 {
2277 return clamp(value, low, high, etl::less<T>());
2278 }
2279
2280 template<typename T, T Low, T High, typename TCompare>
2281 ETL_CONSTEXPR
2282 T clamp(const T& value, TCompare compare)
2283 {
2284 return compare(value, Low) ? Low : compare(High, value) ? High : value;
2285 }
2286
2287 template <typename T, T Low, T High>
2288 ETL_CONSTEXPR
2289 T clamp(const T& value)
2290 {
2291 return clamp<T, Low, High>(value, etl::less<T>());
2292 }
2293
2294 //***************************************************************************
2297 //***************************************************************************
2298 template <typename TIterator, typename T>
2299 ETL_CONSTEXPR14
2300 TIterator remove(TIterator first, TIterator last, const T& value)
2301 {
2302 first = etl::find(first, last, value);
2303
2304 if (first != last)
2305 {
2306 TIterator itr = first;
2307
2308 while (++itr != last)
2309 {
2310 if (!(*itr == value))
2311 {
2312 *first++ = ETL_MOVE(*itr);
2313 }
2314 }
2315 }
2316
2317 return first;
2318 }
2319
2320 //***************************************************************************
2323 //***************************************************************************
2324 template <typename TIterator, typename TUnaryPredicate>
2325 ETL_CONSTEXPR14
2327 {
2328 first = etl::find_if(first, last, predicate);
2329
2330 if (first != last)
2331 {
2332 TIterator itr = first;
2333
2334 while (++itr != last)
2335 {
2336 if (!predicate(*itr))
2337 {
2338 *first++ = ETL_MOVE(*itr);
2339 }
2340 }
2341 }
2342
2343 return first;
2344 }
2345}
2346
2347//*****************************************************************************
2348// ETL extensions to the STL algorithms.
2349//*****************************************************************************
2350namespace etl
2351{
2352 //***************************************************************************
2362 //***************************************************************************
2363 template <typename TInputIterator,
2364 typename TOutputIterator>
2365 ETL_CONSTEXPR14
2372 {
2373 typedef typename iterator_traits<TInputIterator>::difference_type s_size_type;
2374 typedef typename iterator_traits<TOutputIterator>::difference_type d_size_type;
2375
2376#if ETL_USING_CPP11
2377 typedef typename etl::common_type<s_size_type, d_size_type>::type min_size_type;
2378#else
2379 typedef typename etl::largest_type<s_size_type, d_size_type>::type min_size_type;
2380#endif
2381
2382 s_size_type s_size = etl::distance(i_begin, i_end);
2383 ETL_ASSERT(s_size >= 0, ETL_ERROR(algorithm_error));
2384 d_size_type d_size = etl::distance(o_begin, o_end);
2385 ETL_ASSERT(d_size >= 0, ETL_ERROR(algorithm_error));
2387
2388 return etl::copy(i_begin, i_begin + size, o_begin);
2389 }
2390
2391 //***************************************************************************
2401 //***************************************************************************
2402 template <typename TInputIterator,
2403 typename TOutputIterator>
2404 ETL_CONSTEXPR14
2411 {
2412 while ((i_begin != i_end) && (o_begin != o_end))
2413 {
2414 *o_begin = *i_begin;
2415 ++o_begin;
2416 ++i_begin;
2417 }
2418
2419 return o_begin;
2420 }
2421
2422 //***************************************************************************
2426 //***************************************************************************
2427 template <typename TInputIterator,
2428 typename TSize,
2429 typename TOutputIterator>
2430 ETL_CONSTEXPR14
2432 TSize n,
2435 {
2436 while ((n-- > 0) && (o_begin != o_end))
2437 {
2438 *o_begin = *i_begin;
2439 ++o_begin;
2440 ++i_begin;
2441 }
2442
2443 return o_begin;
2444 }
2445
2446 //***************************************************************************
2450 //***************************************************************************
2451 template <typename TInputIterator,
2452 typename TSize1,
2453 typename TOutputIterator,
2454 typename TSize2>
2455 ETL_CONSTEXPR14
2457 TSize1 n1,
2459 TSize2 n2)
2460 {
2461 while ((n1-- > 0) && (n2-- > 0))
2462 {
2463 *o_begin = *i_begin;
2464 ++o_begin;
2465 ++i_begin;
2466 }
2467
2468 return o_begin;
2469 }
2470
2471 //***************************************************************************
2476 //***************************************************************************
2477 template <typename TInputIterator,
2478 typename TOutputIterator,
2479 typename TUnaryPredicate>
2480 ETL_CONSTEXPR14
2486 {
2487 while ((i_begin != i_end) && (o_begin != o_end))
2488 {
2489 if (predicate(*i_begin))
2490 {
2491 *o_begin = *i_begin;
2492 ++o_begin;
2493 }
2494
2495 ++i_begin;
2496 }
2497
2498 return o_begin;
2499 }
2500
2501 //***************************************************************************
2505 //***************************************************************************
2506 template <typename TInputIterator,
2507 typename TSize,
2508 typename TOutputIterator,
2509 typename TUnaryPredicate>
2510 ETL_CONSTEXPR14
2512 TSize n,
2515 {
2516 while (n-- > 0)
2517 {
2518 if (predicate(*i_begin))
2519 {
2520 *o_begin = *i_begin;
2521 ++o_begin;
2522 }
2523
2524 ++i_begin;
2525 }
2526
2527 return o_begin;
2528 }
2529
2530#if ETL_USING_CPP11
2531 //***************************************************************************
2541 //***************************************************************************
2542 template <typename TInputIterator, typename TOutputIterator>
2543 ETL_CONSTEXPR14
2550 {
2551 using s_size_type = typename iterator_traits<TInputIterator>::difference_type;
2552 using d_size_type = typename iterator_traits<TOutputIterator>::difference_type;
2553 using min_size_type = typename etl::common_type<s_size_type, d_size_type>::type;
2554
2555 s_size_type s_size = etl::distance(i_begin, i_end);
2556 ETL_ASSERT(s_size >= 0, ETL_ERROR(algorithm_error));
2557 d_size_type d_size = etl::distance(o_begin, o_end);
2558 ETL_ASSERT(d_size >= 0, ETL_ERROR(algorithm_error));
2560
2561 return etl::move(i_begin, i_begin + size, o_begin);
2562 }
2563
2564 //***************************************************************************
2574 //***************************************************************************
2575 template <typename TInputIterator, typename TOutputIterator>
2576 ETL_CONSTEXPR14
2583 {
2584 while ((i_begin != i_end) && (o_begin != o_end))
2585 {
2586 *o_begin = etl::move(*i_begin);
2587 ++i_begin;
2588 ++o_begin;
2589 }
2590
2591 return o_begin;
2592 }
2593#else
2594 //***************************************************************************
2605 //***************************************************************************
2606 template <typename TInputIterator, typename TOutputIterator>
2611 {
2612 // Move not supported. Defer to copy.
2614 }
2615#endif
2616
2617 //***************************************************************************
2621 //***************************************************************************
2622 template <typename TIterator, typename TValue>
2623 ETL_NODISCARD
2624 ETL_CONSTEXPR14
2626 TIterator end,
2627 const TValue& value)
2628 {
2629 TIterator it = etl::lower_bound(begin, end, value);
2630
2631 if ((it == end) || (*it != value))
2632 {
2633 it = end;
2634 }
2635
2636 return it;
2637 }
2638
2639 //***************************************************************************
2643 //***************************************************************************
2644 template <typename TIterator,
2645 typename TValue,
2646 typename TBinaryPredicate,
2647 typename TBinaryEquality>
2648 ETL_NODISCARD
2649 ETL_CONSTEXPR14
2651 TIterator end,
2652 const TValue& value,
2655 {
2656 TIterator it = etl::lower_bound(begin, end, value, predicate);
2657
2658 if ((it == end) || !equality(*it, value))
2659 {
2660 it = end;
2661 }
2662
2663 return it;
2664 }
2665
2666 //***************************************************************************
2669 //***************************************************************************
2670 template <typename TIterator,
2671 typename TUnaryFunction,
2672 typename TUnaryPredicate>
2673 ETL_CONSTEXPR14
2675 const TIterator end,
2678 {
2679 while (begin != end)
2680 {
2681 if (predicate(*begin))
2682 {
2683 function(*begin);
2684 }
2685
2686 ++begin;
2687 }
2688
2689 return function;
2690 }
2691
2692 //***************************************************************************
2695 //***************************************************************************
2696 template <typename TIterator,
2697 typename TSize,
2698 typename TUnaryFunction>
2699 ETL_CONSTEXPR14
2701 TSize n,
2703 {
2704 while (n-- > 0)
2705 {
2706 function(*begin);
2707 ++begin;
2708 }
2709
2710 return begin;
2711 }
2712
2713 //***************************************************************************
2716 //***************************************************************************
2717 template <typename TIterator,
2718 typename TSize,
2719 typename TUnaryFunction,
2720 typename TUnaryPredicate>
2721 ETL_CONSTEXPR14
2723 TSize n,
2726 {
2727 while (n-- > 0)
2728 {
2729 if (predicate(*begin))
2730 {
2731 function(*begin);
2732 }
2733
2734 ++begin;
2735 }
2736
2737 return begin;
2738 }
2739
2740 //***************************************************************************
2745 //***************************************************************************
2746 template <typename TInputIterator, typename TOutputIterator, typename TUnaryFunction>
2747 ETL_CONSTEXPR14
2753 {
2754 while ((i_begin != i_end) && (o_begin != o_end))
2755 {
2757 ++i_begin;
2758 ++o_begin;
2759 }
2760
2761 return o_begin;
2762 }
2763
2764 //***************************************************************************
2769 //***************************************************************************
2770 template <typename TInputIterator,
2771 typename TSize,
2772 typename TOutputIterator,
2773 typename TUnaryFunction>
2774 ETL_CONSTEXPR14
2776 TSize n,
2779 {
2781 etl::advance(i_end, n);
2782
2783 etl::transform(i_begin, i_end, o_begin, function);
2784 }
2785
2786 //***************************************************************************
2791 //***************************************************************************
2792 template <typename TInputIterator1,
2793 typename TInputIterator2,
2794 typename TSize,
2795 typename TOutputIterator,
2796 typename TBinaryFunction>
2797 ETL_CONSTEXPR14
2800 TSize n,
2803 {
2805 etl::advance(i_end1, n);
2806
2807 etl::transform(i_begin1, i_end1, i_begin2, o_begin, function);
2808 }
2809
2810 //***************************************************************************
2813 //***************************************************************************
2814 template <typename TInputIterator,
2815 typename TOutputIterator,
2816 typename TUnaryFunction,
2817 typename TUnaryPredicate>
2818 ETL_CONSTEXPR14
2820 const TInputIterator i_end,
2824 {
2825 while (i_begin != i_end)
2826 {
2827 if (predicate(*i_begin))
2828 {
2830 ++o_begin;
2831 }
2832
2833 ++i_begin;
2834 }
2835
2836 return o_begin;
2837 }
2838
2839 //***************************************************************************
2842 //***************************************************************************
2843 template <typename TInputIterator1,
2844 typename TInputIterator2,
2845 typename TOutputIterator,
2846 typename TBinaryFunction,
2847 typename TBinaryPredicate>
2848 ETL_CONSTEXPR14
2850 const TInputIterator1 i_end1,
2855 {
2856 while (i_begin1 != i_end1)
2857 {
2858 if (predicate(*i_begin1, *i_begin2))
2859 {
2861 ++o_begin;
2862 }
2863
2864 ++i_begin1;
2865 ++i_begin2;
2866 }
2867
2868 return o_begin;
2869 }
2870
2871 //***************************************************************************
2874 //***************************************************************************
2875 template <typename TInputIterator,
2876 typename TSize,
2877 typename TOutputIterator,
2878 typename TUnaryFunction,
2879 typename TUnaryPredicate>
2880 ETL_CONSTEXPR14
2882 TSize n,
2886 {
2887 while (n-- > 0)
2888 {
2889 if (predicate(*i_begin))
2890 {
2892 ++o_begin;
2893 }
2894
2895 ++i_begin;
2896 }
2897
2898 return o_begin;
2899 }
2900
2901 //***************************************************************************
2904 //***************************************************************************
2905 template <typename TInputIterator1,
2906 typename TInputIterator2,
2907 typename TSize,
2908 typename TOutputIterator,
2909 typename TBinaryFunction,
2910 typename TBinaryPredicate>
2911 ETL_CONSTEXPR14
2914 TSize n,
2918 {
2919 while (n-- > 0)
2920 {
2921 if (predicate(*i_begin1, *i_begin2))
2922 {
2924 }
2925
2926 ++i_begin1;
2927 ++i_begin2;
2928 }
2929
2930 return o_begin;
2931 }
2932
2933 //***************************************************************************
2937 //***************************************************************************
2938 template <typename TSource, typename TDestinationTrue, typename TDestinationFalse,
2939 typename TUnaryFunctionTrue, typename TUnaryFunctionFalse,
2940 typename TUnaryPredicate>
2941 ETL_CONSTEXPR14
2942 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse> partition_transform(TSource begin,
2943 TSource end,
2949 {
2950 while (begin != end)
2951 {
2952 if (predicate(*begin))
2953 {
2956 }
2957 else
2958 {
2961 }
2962
2963 ++begin;
2964 }
2965
2966 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
2967 }
2968
2969 //***************************************************************************
2973 //***************************************************************************
2974 template <typename TSource1,
2975 typename TSource2,
2976 typename TDestinationTrue,
2977 typename TDestinationFalse,
2978 typename TBinaryFunctionTrue,
2979 typename TBinaryFunctionFalse,
2980 typename TBinaryPredicate>
2981 ETL_CONSTEXPR14
2982 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse> partition_transform(TSource1 begin1,
2983 TSource1 end1,
2990 {
2991 while (begin1 != end1)
2992 {
2993 if (predicate(*begin1, *begin2))
2994 {
2997 }
2998 else
2999 {
3002 }
3003
3004 ++begin1;
3005 ++begin2;
3006 }
3007
3008 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
3009 }
3010
3011 //***************************************************************************
3015 //***************************************************************************
3016 template <typename TIterator, typename TCompare>
3017#if ETL_USING_STD_NAMESPACE
3018 ETL_CONSTEXPR20
3019#else
3020 ETL_CONSTEXPR14
3021#endif
3023 {
3024 if (first == last)
3025 {
3026 return;
3027 }
3028
3029 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
3030
3031 difference_t n = etl::distance(first, last);
3032
3033 for (difference_t i = n / 2; i > 0; i /= 2)
3034 {
3035 for (difference_t j = i; j < n; ++j)
3036 {
3037 for (difference_t k = j - i; k >= 0; k -= i)
3038 {
3039 TIterator itr1 = first;
3040 TIterator itr2 = first;
3041
3042 etl::advance(itr1, k);
3043 etl::advance(itr2, k + i);
3044
3045 if (compare(*itr2, *itr1))
3046 {
3047 etl::iter_swap(itr1, itr2);
3048 }
3049 }
3050 }
3051 }
3052 }
3053
3054 //***************************************************************************
3057 //***************************************************************************
3058 template <typename TIterator>
3059#if ETL_USING_STD_NAMESPACE
3060 ETL_CONSTEXPR20
3061#else
3062 ETL_CONSTEXPR14
3063#endif
3065 {
3066 etl::shell_sort(first, last, etl::less<typename etl::iterator_traits<TIterator>::value_type>());
3067 }
3068
3069 //***************************************************************************
3073 //***************************************************************************
3074 template <typename TIterator, typename TCompare>
3075 ETL_CONSTEXPR14
3077 {
3078 for (TIterator itr = first; itr != last; ++itr)
3079 {
3080 etl::rotate(etl::upper_bound(first, itr, *itr, compare), itr, etl::next(itr));
3081 }
3082 }
3083
3084 //***************************************************************************
3087 //***************************************************************************
3088 template <typename TIterator>
3089 ETL_CONSTEXPR14
3091 {
3092 etl::insertion_sort(first, last, etl::less<typename etl::iterator_traits<TIterator>::value_type>());
3093 }
3094
3095 //***************************************************************************
3096 namespace private_algorithm
3097 {
3098 template <typename TIterator>
3099 ETL_CONSTEXPR14
3101 get_before_last(TIterator first_, TIterator last_)
3102 {
3103 TIterator last = first_;
3105 ++lastplus1;
3106
3107 while (lastplus1 != last_)
3108 {
3109 ++last;
3110 ++lastplus1;
3111 }
3112
3113 return last;
3114 }
3115
3116 template <typename TIterator>
3117 ETL_CONSTEXPR14
3119 get_before_last(TIterator /*first_*/, TIterator last_)
3120 {
3121 TIterator last = last_;
3122 --last;
3123
3124 return last;
3125 }
3126
3127 template <typename TIterator>
3128 ETL_CONSTEXPR14
3130 get_before_last(TIterator /*first_*/, TIterator last_)
3131 {
3132 return last_ - 1;
3133 }
3134 }
3135
3136 //***************************************************************************
3140 //***************************************************************************
3141 template <typename TIterator, typename TCompare>
3142 ETL_CONSTEXPR20
3144 {
3145 TIterator min;
3146 const TIterator ilast = private_algorithm::get_before_last(first, last);
3147 const TIterator jlast = last;
3148
3149 for (TIterator i = first; i != ilast; ++i)
3150 {
3151 min = i;
3152
3153 TIterator j = i;
3154 ++j;
3155
3156 for (; j != jlast; ++j)
3157 {
3158 if (compare(*j, *min))
3159 {
3160 min = j;
3161 }
3162 }
3163
3164 using ETL_OR_STD::swap; // Allow ADL
3165 swap(*i, *min);
3166 }
3167 }
3168
3169 //***************************************************************************
3172 //***************************************************************************
3173 template <typename TIterator>
3174 ETL_CONSTEXPR20
3176 {
3177 selection_sort(first, last, etl::less<typename etl::iterator_traits<TIterator>::value_type>());
3178 }
3179
3180 //***************************************************************************
3184 //***************************************************************************
3185 template <typename TIterator, typename TCompare>
3186 ETL_CONSTEXPR14
3188 {
3189 if (!etl::is_heap(first, last, compare))
3190 {
3191 etl::make_heap(first, last, compare);
3192 }
3193
3194 etl::sort_heap(first, last, compare);
3195 }
3196
3197 //***************************************************************************
3200 //***************************************************************************
3201 template <typename TIterator>
3202 ETL_CONSTEXPR14
3204 {
3205 if (!etl::is_heap(first, last))
3206 {
3207 etl::make_heap(first, last);
3208 }
3209
3210 etl::sort_heap(first, last);
3211 }
3212
3213 //***************************************************************************
3215 //***************************************************************************
3216#if ETL_USING_CPP11
3217 template <typename T>
3218 ETL_NODISCARD
3219 constexpr const T& multimax(const T& a, const T& b)
3220 {
3221 return a < b ? b : a;
3222 }
3223
3224 template <typename T, typename... Tx>
3225 ETL_NODISCARD
3226 constexpr const T& multimax(const T& t, const Tx&... tx)
3227 {
3228 return multimax(t, multimax(tx...));
3229 }
3230#endif
3231
3232 //***************************************************************************
3235 //***************************************************************************
3236#if ETL_USING_CPP11
3237 template <typename TCompare, typename T>
3238 ETL_NODISCARD
3239 constexpr const T& multimax_compare(TCompare compare, const T& a, const T& b)
3240 {
3241 return compare(a, b) ? b : a;
3242 }
3243
3244 template <typename TCompare, typename T, typename... Tx>
3245 ETL_NODISCARD
3246 constexpr const T& multimax_compare(TCompare compare, const T& t, const Tx&... tx)
3247 {
3248 return multimax_compare(compare, t, multimax_compare(compare, tx...));
3249 }
3250#endif
3251
3252 //***************************************************************************
3254 //***************************************************************************
3255#if ETL_USING_CPP11
3256 template <typename T>
3257 ETL_NODISCARD
3258 constexpr const T& multimin(const T& a, const T& b)
3259 {
3260 return a < b ? a : b;
3261 }
3262
3263 template <typename T, typename... Tx>
3264 ETL_NODISCARD
3265 constexpr const T& multimin(const T& t, const Tx&... tx)
3266 {
3267 return multimin(t, multimin(tx...));
3268 }
3269#endif
3270
3271 //***************************************************************************
3274 //***************************************************************************
3275#if ETL_USING_CPP11
3276 template <typename TCompare, typename T>
3277 ETL_NODISCARD
3278 constexpr const T& multimin_compare(TCompare compare, const T& a, const T& b)
3279 {
3280 return compare(a, b) ? a : b;
3281 }
3282
3283 template <typename TCompare, typename T, typename... Tx>
3284 ETL_NODISCARD
3285 constexpr const T& multimin_compare(TCompare compare, const T& t, const Tx&... tx)
3286 {
3287 return multimin_compare(compare, t, multimin_compare(compare, tx...));
3288 }
3289#endif
3290
3291 //***************************************************************************
3293 //***************************************************************************
3294#if ETL_USING_CPP11
3295 template <typename TIterator>
3296 ETL_NODISCARD
3297 constexpr const TIterator& multimax_iter(const TIterator& a, const TIterator& b)
3298 {
3299 return *a < *b ? b : a;
3300 }
3301
3302 template <typename TIterator, typename... TIteratorx>
3303 ETL_NODISCARD
3304 constexpr const TIterator& multimax_iter(const TIterator& t, const TIteratorx&... tx)
3305 {
3306 return multimax_iter(t, multimax_iter(tx...));
3307 }
3308#endif
3309
3310 //***************************************************************************
3313 //***************************************************************************
3314#if ETL_USING_CPP11
3315 template <typename TCompare, typename TIterator>
3316 ETL_NODISCARD
3317 constexpr const TIterator& multimax_iter_compare(TCompare compare, const TIterator& a, const TIterator& b)
3318 {
3319 return compare(*a, *b) ? b : a;
3320 }
3321
3322 template <typename TCompare, typename TIterator, typename... TIteratorx>
3323 ETL_NODISCARD
3324 constexpr const TIterator& multimax_iter_compare(TCompare compare, const TIterator& t, const TIteratorx&... tx)
3325 {
3326 return multimax_iter_compare(compare, t, multimax_iter_compare(compare, tx...));
3327 }
3328#endif
3329
3330 //***************************************************************************
3332 //***************************************************************************
3333#if ETL_USING_CPP11
3334 template <typename TIterator>
3335 ETL_NODISCARD
3336 constexpr const TIterator& multimin_iter(const TIterator& a, const TIterator& b)
3337 {
3338 return *a < *b ? a : b;
3339 }
3340
3341 template <typename TIterator, typename... Tx>
3342 ETL_NODISCARD
3343 constexpr const TIterator& multimin_iter(const TIterator& t, const Tx&... tx)
3344 {
3345 return multimin_iter(t, multimin_iter(tx...));
3346 }
3347#endif
3348
3349 //***************************************************************************
3352 //***************************************************************************
3353#if ETL_USING_CPP11
3354 template <typename TCompare, typename TIterator>
3355 ETL_NODISCARD
3356 constexpr const TIterator& multimin_iter_compare(TCompare compare, const TIterator& a, const TIterator& b)
3357 {
3358 return compare(*a, *b) ? a : b;
3359 }
3360
3361 template <typename TCompare, typename TIterator, typename... Tx>
3362 ETL_NODISCARD
3363 constexpr const TIterator& multimin_iter_compare(TCompare compare, const TIterator& t, const Tx&... tx)
3364 {
3365 return multimin_iter_compare(compare, t, multimin_iter_compare(compare, tx...));
3366 }
3367#endif
3368
3369 //***************************************************************************
3373 //***************************************************************************
3374 template <typename TIterator, typename TPredicate>
3375 ETL_CONSTEXPR14
3378 {
3379 first = etl::find_if_not(first, last, predicate);
3380
3381 if (first == last)
3382 {
3383 return first;
3384 }
3385
3386 for (TIterator i = etl::next(first); i != last; ++i)
3387 {
3388 if (predicate(*i))
3389 {
3390 using ETL_OR_STD::swap;
3391 swap(*i, *first);
3392 ++first;
3393 }
3394 }
3395
3396 return first;
3397 }
3398
3399 //***************************************************************************
3403 //***************************************************************************
3404 template <typename TIterator, typename TPredicate>
3405 ETL_CONSTEXPR14
3408 {
3409 while (first != last)
3410 {
3411 first = etl::find_if_not(first, last, predicate);
3412
3413 if (first == last)
3414 {
3415 break;
3416 }
3417
3418 last = etl::find_if(etl::reverse_iterator<TIterator>(last),
3420 predicate).base();
3421
3422 if (first == last)
3423 {
3424 break;
3425 }
3426
3427 --last;
3428 using ETL_OR_STD::swap;
3429 swap(*first, *last);
3430 ++first;
3431 }
3432
3433 return first;
3434 }
3435
3436 //*********************************************************
3437 namespace private_algorithm
3438 {
3439 using ETL_OR_STD::swap;
3440
3441 template <typename TIterator, typename TCompare>
3442#if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST))
3443 constexpr
3444#endif
3445 TIterator nth_partition(TIterator first, TIterator last, TCompare compare)
3446 {
3447 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
3448
3449 TIterator pivot = last; // Maybe find a better pivot choice?
3450 value_type pivot_value = *pivot;
3451
3452 // Swap the pivot with the last, if necessary.
3453 if (pivot != last)
3454 {
3455 swap(*pivot, *last);
3456 }
3457
3458 TIterator i = first;
3459
3460 for (TIterator j = first; j < last; ++j)
3461 {
3462 if (!compare(pivot_value, *j)) // Hack to get '*j <= pivot_value' in terms of 'pivot_value < *j'
3463 {
3464 swap(*i, *j);
3465 ++i;
3466 }
3467 }
3468
3469 swap(*i, *last);
3470
3471 return i;
3472 }
3473 }
3474
3475 //*********************************************************
3478 //*********************************************************
3479#if ETL_USING_CPP11
3481#if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST))
3482 constexpr
3483#endif
3485 nth_element(TIterator first, TIterator nth, TIterator last, TCompare compare = TCompare())
3486 {
3487 if (first == last)
3488 {
3489 return;
3490 }
3491
3492 // 'last' must point to the actual last value.
3493 --last;
3494
3495 while (first <= last)
3496 {
3497 TIterator p = private_algorithm::nth_partition(first, last, compare);
3498
3499 if (p == nth)
3500 {
3501 return;
3502 }
3503 else if (p > nth)
3504 {
3505 last = p - 1;
3506 }
3507 else
3508 {
3509 first = p + 1;
3510 }
3511 }
3512 }
3513
3514#else
3515
3516 //*********************************************************
3517 template <typename TIterator, typename TCompare>
3520 {
3521 if (first == last)
3522 {
3523 return;
3524 }
3525
3526 // 'last' must point to the actual last value.
3527 --last;
3528
3529 while (first <= last)
3530 {
3531 TIterator p = private_algorithm::nth_partition(first, last, compare);
3532
3533 if (p == nth)
3534 {
3535 return;
3536 }
3537 else if (p > nth)
3538 {
3539 last = p - 1;
3540 }
3541 else
3542 {
3543 first = p + 1;
3544 }
3545 }
3546 }
3547
3548 //*********************************************************
3549 template <typename TIterator>
3552 {
3554
3555 nth_element(first, last, compare_t());
3556 }
3557#endif
3558}
3559
3560#include "private/minmax_pop.h"
3561
3562#endif
Definition algorithm.h:100
Definition algorithm.h:90
Definition iterator.h:228
ETL_CONSTEXPR T clamp(const T &value, const T &low, const T &high, TCompare compare)
Definition algorithm.h:2268
ETL_CONSTEXPR20 void shell_sort(TIterator first, TIterator last)
Definition algorithm.h:3064
ETL_CONSTEXPR14 TOutputIterator copy_if(TIterator begin, TIterator end, TOutputIterator out, TUnaryPredicate predicate)
Definition algorithm.h:2074
ETL_CONSTEXPR14 ETL_OR_STD::pair< TDestinationTrue, TDestinationFalse > partition_transform(TSource begin, TSource end, TDestinationTrue destination_true, TDestinationFalse destination_false, TUnaryFunctionTrue function_true, TUnaryFunctionFalse function_false, TUnaryPredicate predicate)
Definition algorithm.h:2942
ETL_NODISCARD ETL_CONSTEXPR14 bool any_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2116
ETL_NODISCARD ETL_CONSTEXPR14 TIterator min_element(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1471
ETL_CONSTEXPR14 TOutputIterator transform_n_if(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:2881
ETL_CONSTEXPR14 T accumulate(TIterator first, TIterator last, T sum)
Definition algorithm.h:2234
ETL_NODISCARD ETL_CONSTEXPR14 bool all_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2101
ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair< TIterator, TIterator > minmax_element(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1567
ETL_CONSTEXPR14 TOutputIterator transform_if(TInputIterator i_begin, const TInputIterator i_end, TOutputIterator o_begin, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:2819
ETL_CONSTEXPR14 TUnaryFunction for_each_if(TIterator begin, const TIterator end, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:2674
ETL_NODISCARD ETL_CONSTEXPR14 TIterator find_if_not(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:1822
ETL_NODISCARD ETL_CONSTEXPR14 bool is_sorted(TIterator begin, TIterator end)
Definition algorithm.h:1709
ETL_CONSTEXPR14 TOutputIterator transform_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end, TUnaryFunction function)
Definition algorithm.h:2748
ETL_CONSTEXPR14 TIterator remove(TIterator first, TIterator last, const T &value)
Definition algorithm.h:2300
ETL_CONSTEXPR14 void transform_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryFunction function)
Definition algorithm.h:2775
ETL_CONSTEXPR14 TOutputIterator copy_n_if(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryPredicate predicate)
Definition algorithm.h:2511
ETL_NODISCARD ETL_CONSTEXPR14 TIterator is_sorted_until(TIterator begin, TIterator end)
Definition algorithm.h:1650
ETL_CONSTEXPR14 void insertion_sort(TIterator first, TIterator last)
Definition algorithm.h:3090
void sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:2189
ETL_NODISCARD ETL_CONSTEXPR14 bool is_unique_sorted(TIterator begin, TIterator end)
Definition algorithm.h:1794
ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair< const T &, const T & > minmax(const T &a, const T &b)
Definition algorithm.h:1621
ETL_CONSTEXPR14 etl::enable_if< etl::is_random_iterator< TInputIterator >::value &&etl::is_random_iterator< TOutputIterator >::value, TOutputIterator >::type copy_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
Definition algorithm.h:2368
ETL_CONSTEXPR14 TIterator remove_if(TIterator first, TIterator last, TUnaryPredicate predicate)
Definition algorithm.h:2326
ETL_CONSTEXPR14 ETL_OR_STD::pair< TDestinationTrue, TDestinationFalse > partition_copy(TSource begin, TSource end, TDestinationTrue destination_true, TDestinationFalse destination_false, TUnaryPredicate predicate)
Definition algorithm.h:2042
ETL_CONSTEXPR14 TIterator for_each_n(TIterator begin, TSize n, TUnaryFunction function)
Definition algorithm.h:2700
ETL_NODISCARD ETL_CONSTEXPR14 TIterator binary_find(TIterator begin, TIterator end, const TValue &value)
Definition algorithm.h:2625
ETL_CONSTEXPR14 void heap_sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:3187
ETL_NODISCARD ETL_CONSTEXPR14 bool none_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2131
ETL_CONSTEXPR20 void selection_sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:3143
ETL_CONSTEXPR14 TOutputIterator copy_n_s(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TOutputIterator o_end)
Definition algorithm.h:2431
ETL_NODISCARD ETL_CONSTEXPR14 TIterator is_unique_sorted_until(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1737
TOutputIterator move_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
Definition algorithm.h:2607
ETL_CONSTEXPR14 TOutputIterator copy_if_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end, TUnaryPredicate predicate)
Definition algorithm.h:2481
ETL_CONSTEXPR14 TIterator for_each_n_if(TIterator begin, TSize n, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:2722
void stable_sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:2211
ETL_NODISCARD ETL_CONSTEXPR14 bool is_partitioned(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:1982
ETL_NODISCARD ETL_CONSTEXPR14 TIterator max_element(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1519
ETL_NODISCARD ETL_CONSTEXPR14 TIterator partition_point(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2017
ETL_NODISCARD ETL_CONSTEXPR14 bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2)
Definition algorithm.h:1847
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
Definition exception.h:47
Definition function.h:94
enable_if
Definition type_traits_generator.h:1230
is_reference
Definition type_traits_generator.h:1150
is_same
Definition type_traits_generator.h:1080
bitset_ext
Definition absolute.h:38
etl::enable_if< etl::is_random_access_iterator_concept< TIterator >::value, void >::type nth_element(TIterator first, TIterator nth, TIterator last, TCompare compare)
Definition algorithm.h:3519
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition array.h:1085
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1187
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:962
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:314
ETL_CONSTEXPR14 etl::enable_if< etl::is_forward_iterator< TIterator >::value, TIterator >::type partition(TIterator first, TIterator last, TPredicate predicate)
Returns the maximum value.
Definition algorithm.h:3377
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition iterator.h:992
Definition compare.h:51
Definition functional.h:274
Definition iterator.h:854
Definition iterator.h:873
Definition iterator.h:63
Definition functional.h:170
Definition algorithm.h:119