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
89 class algorithm_exception : public etl::exception
90 {
91 public:
92
93 algorithm_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
94 : exception(reason_, file_name_, line_number_)
95 {
96 }
97 };
98
99 class algorithm_error : public algorithm_exception
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 {
158 typedef etl::iterator_traits<TIterator1> traits1;
159 typedef etl::iterator_traits<TIterator2> traits2;
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
167 const bool use_swap = etl::is_same<v1, v2>::value &&
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,
184 TIterator1 last1,
185 TIterator2 first2)
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>
214 constexpr TIterator2 copy(TIterator1 sb, TIterator1 se, TIterator2 db)
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
245 TIterator2 reverse_copy(TIterator1 sb, TIterator1 se, TIterator2 db)
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>
308 constexpr TIterator2 move(TIterator1 sb, TIterator1 se, TIterator2 db)
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
370 typename etl::enable_if<etl::is_pointer<TIterator>::value, void>::type
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
386 typename etl::enable_if<!etl::is_pointer<TIterator>::value, void>::type
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 {
433 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
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 {
476 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
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 {
497 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
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 {
519 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
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
530 TIterator find_if(TIterator first, TIterator last, TUnaryPredicate predicate)
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
662 bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2)
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
671 bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TPredicate predicate)
672 {
673 return std::equal(first1, last1, first2, predicate);
674 }
675
676 // Four parameter
677 template <typename TIterator1, typename TIterator2>
678 [[nodiscard]]
679 constexpr
680 bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2)
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
689 bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2, TPredicate predicate)
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
699 bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2)
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
719 bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TPredicate predicate)
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
739 bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2)
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
759 bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2, TPredicate predicate)
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,
783 TIterator2 first2, TIterator2 last2,
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,
810 TIterator2 first2, TIterator2 last2)
811 {
812 typedef etl::less<typename etl::iterator_traits<TIterator1>::value_type> compare;
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
864 TUnaryOperation for_each(TIterator first, TIterator last, TUnaryOperation unary_operation)
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
880 TIteratorOut transform(TIteratorIn first1, TIteratorIn last1, TIteratorOut d_first, TUnaryOperation unary_operation)
881 {
882 while (first1 != last1)
883 {
884 *d_first = unary_operation(*first1);
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
895 TIteratorOut transform(TIteratorIn1 first1, TIteratorIn1 last1, TIteratorIn2 first2, TIteratorOut d_first, TBinaryOperation binary_operation)
896 {
897 while (first1 != last1)
898 {
899 *d_first = binary_operation(*first1, *first2);
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]);
979 value_index = 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 {
1032 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
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 {
1051 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
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 {
1087 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
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 {
1097 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
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
1138 TIterator1 search(TIterator1 first, TIterator1 last, TIterator2 search_first, TIterator2 search_last, TCompare compare)
1139 {
1140 while (true)
1141 {
1142 TIterator1 itr = first;
1143 TIterator2 search_itr = search_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
1174 TIterator1 search(TIterator1 first, TIterator1 last, TIterator2 search_first, TIterator2 search_last)
1175 {
1176 typedef etl::equal_to<typename etl::iterator_traits<TIterator1>::value_type> compare;
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
1191 typename etl::enable_if<etl::is_random_access_iterator<TIterator>::value, TIterator>::type
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
1240 typename etl::enable_if<etl::is_random_access_iterator<TIterator>::value, TIterator>::type
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
1290 typename etl::enable_if<etl::is_bidirectional_iterator<TIterator>::value, TIterator>::type
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
1312 typename etl::enable_if<etl::is_forward_iterator<TIterator>::value, TIterator>::type
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
1399 if ETL_IF_CONSTEXPR(etl::is_forward_iterator<TIterator>::value)
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,
1423 TIterator2 sb, TIterator2 se,
1424 TPredicate predicate)
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,
1456 TIterator2 sb, TIterator2 se)
1457 {
1458 typedef etl::equal_to<typename etl::iterator_traits<TIterator1>::value_type> predicate;
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
1471 TIterator min_element(TIterator begin,
1472 TIterator end,
1473 TCompare compare)
1474 {
1475 TIterator minimum = begin;
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
1503 TIterator min_element(TIterator begin,
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
1519 TIterator max_element(TIterator begin,
1520 TIterator end,
1521 TCompare compare)
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
1551 TIterator max_element(TIterator begin,
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,
1569 TCompare compare)
1570 {
1571 TIterator minimum = begin;
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,
1637 TCompare compare)
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
1650 TIterator is_sorted_until(TIterator begin,
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
1679 TIterator is_sorted_until(TIterator begin,
1680 TIterator end,
1681 TCompare compare)
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
1709 bool is_sorted(TIterator begin,
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
1723 bool is_sorted(TIterator begin,
1724 TIterator end,
1725 TCompare compare)
1726 {
1728 }
1729
1730 //***************************************************************************
1733 //***************************************************************************
1734 template <typename TIterator, typename TCompare>
1735 ETL_NODISCARD
1736 ETL_CONSTEXPR14
1737 TIterator is_unique_sorted_until(TIterator begin,
1738 TIterator end,
1739 TCompare compare)
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
1766 TIterator is_unique_sorted_until(TIterator begin,
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
1794 bool is_unique_sorted(TIterator begin,
1795 TIterator end)
1796 {
1798 }
1799
1800 //***************************************************************************
1803 //***************************************************************************
1804 template<typename TIterator, typename TCompare>
1805 ETL_NODISCARD
1806 ETL_CONSTEXPR14
1807 bool is_unique_sorted(TIterator begin,
1808 TIterator end,
1809 TCompare compare)
1810 {
1812 }
1813
1814 //***************************************************************************
1818 //***************************************************************************
1819 template <typename TIterator, typename TUnaryPredicate>
1820 ETL_NODISCARD
1821 ETL_CONSTEXPR14
1822 TIterator find_if_not(TIterator begin,
1823 TIterator end,
1824 TUnaryPredicate predicate)
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
1847 bool is_permutation(TIterator1 begin1,
1848 TIterator1 end1,
1849 TIterator2 begin2)
1850 {
1851 if (begin1 != end1)
1852 {
1853 TIterator2 end2 = begin2;
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
1882 bool is_permutation(TIterator1 begin1,
1883 TIterator1 end1,
1884 TIterator2 begin2,
1885 TBinaryPredicate predicate)
1886 {
1887 if (begin1 != end1)
1888 {
1889 TIterator2 end2 = begin2;
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
1918 bool is_permutation(TIterator1 begin1,
1919 TIterator1 end1,
1920 TIterator2 begin2,
1921 TIterator2 end2)
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
1949 bool is_permutation(TIterator1 begin1,
1950 TIterator1 end1,
1951 TIterator2 begin2,
1952 TIterator2 end2,
1953 TBinaryPredicate predicate)
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
1982 bool is_partitioned(TIterator begin,
1983 TIterator end,
1984 TUnaryPredicate predicate)
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
2017 TIterator partition_point(TIterator begin,
2018 TIterator end,
2019 TUnaryPredicate predicate)
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,
2044 TDestinationTrue destination_true,
2045 TDestinationFalse destination_false,
2046 TUnaryPredicate predicate)
2047 {
2048 while (begin != end)
2049 {
2050 if (predicate(*begin))
2051 {
2052 *destination_true = *begin;
2053 ++destination_true;
2054 }
2055 else
2056 {
2057 *destination_false = *begin;
2058 ++destination_false;
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
2074 TOutputIterator copy_if(TIterator begin,
2075 TIterator end,
2076 TOutputIterator out,
2077 TUnaryPredicate predicate)
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
2101 bool all_of(TIterator begin,
2102 TIterator end,
2103 TUnaryPredicate predicate)
2104 {
2105 return etl::find_if_not(begin, end, predicate) == end;
2106 }
2107
2108 //***************************************************************************
2112 //***************************************************************************
2113 template <typename TIterator, typename TUnaryPredicate>
2114 ETL_NODISCARD
2115 ETL_CONSTEXPR14
2116 bool any_of(TIterator begin,
2117 TIterator end,
2118 TUnaryPredicate predicate)
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
2131 bool none_of(TIterator begin,
2132 TIterator end,
2133 TUnaryPredicate predicate)
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>
2189 void sort(TIterator first, TIterator last, TCompare compare)
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>
2211 void stable_sort(TIterator first, TIterator last, TCompare compare)
2212 {
2213 std::stable_sort(first, last, compare);
2214 }
2215
2216 //***************************************************************************
2220 //***************************************************************************
2221 template <typename TIterator>
2222 void stable_sort(TIterator first, TIterator last)
2223 {
2224 std::stable_sort(first, last);
2225 }
2226#endif
2227
2228 //***************************************************************************
2231 //***************************************************************************
2232 template <typename TIterator, typename T>
2233 ETL_CONSTEXPR14
2234 T accumulate(TIterator first, TIterator last, T sum)
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
2326 TIterator remove_if(TIterator first, TIterator last, TUnaryPredicate predicate)
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
2366 typename etl::enable_if<etl::is_random_iterator<TInputIterator>::value &&
2367 etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>::type
2368 copy_s(TInputIterator i_begin,
2369 TInputIterator i_end,
2370 TOutputIterator o_begin,
2371 TOutputIterator o_end)
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 d_size_type d_size = etl::distance(o_begin, o_end);
2384 min_size_type min_size = etl::min<min_size_type>(s_size, d_size);
2385
2386 return etl::copy(i_begin, i_begin + min_size, o_begin);
2387 }
2388
2389 //***************************************************************************
2399 //***************************************************************************
2400 template <typename TInputIterator,
2401 typename TOutputIterator>
2402 ETL_CONSTEXPR14
2404 !etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>::type
2405 copy_s(TInputIterator i_begin,
2406 TInputIterator i_end,
2407 TOutputIterator o_begin,
2408 TOutputIterator o_end)
2409 {
2410 while ((i_begin != i_end) && (o_begin != o_end))
2411 {
2412 *o_begin = *i_begin;
2413 ++o_begin;
2414 ++i_begin;
2415 }
2416
2417 return o_begin;
2418 }
2419
2420 //***************************************************************************
2424 //***************************************************************************
2425 template <typename TInputIterator,
2426 typename TSize,
2427 typename TOutputIterator>
2428 ETL_CONSTEXPR14
2429 TOutputIterator copy_n_s(TInputIterator i_begin,
2430 TSize n,
2431 TOutputIterator o_begin,
2432 TOutputIterator o_end)
2433 {
2434 while ((n-- > 0) && (o_begin != o_end))
2435 {
2436 *o_begin = *i_begin;
2437 ++o_begin;
2438 ++i_begin;
2439 }
2440
2441 return o_begin;
2442 }
2443
2444 //***************************************************************************
2448 //***************************************************************************
2449 template <typename TInputIterator,
2450 typename TSize1,
2451 typename TOutputIterator,
2452 typename TSize2>
2453 ETL_CONSTEXPR14
2454 TOutputIterator copy_n_s(TInputIterator i_begin,
2455 TSize1 n1,
2456 TOutputIterator o_begin,
2457 TSize2 n2)
2458 {
2459 while ((n1-- > 0) && (n2-- > 0))
2460 {
2461 *o_begin = *i_begin;
2462 ++o_begin;
2463 ++i_begin;
2464 }
2465
2466 return o_begin;
2467 }
2468
2469 //***************************************************************************
2474 //***************************************************************************
2475 template <typename TInputIterator,
2476 typename TOutputIterator,
2477 typename TUnaryPredicate>
2478 ETL_CONSTEXPR14
2479 TOutputIterator copy_if_s(TInputIterator i_begin,
2480 TInputIterator i_end,
2481 TOutputIterator o_begin,
2482 TOutputIterator o_end,
2483 TUnaryPredicate predicate)
2484 {
2485 while ((i_begin != i_end) && (o_begin != o_end))
2486 {
2487 if (predicate(*i_begin))
2488 {
2489 *o_begin = *i_begin;
2490 ++o_begin;
2491 }
2492
2493 ++i_begin;
2494 }
2495
2496 return o_begin;
2497 }
2498
2499 //***************************************************************************
2503 //***************************************************************************
2504 template <typename TInputIterator,
2505 typename TSize,
2506 typename TOutputIterator,
2507 typename TUnaryPredicate>
2508 ETL_CONSTEXPR14
2509 TOutputIterator copy_n_if(TInputIterator i_begin,
2510 TSize n,
2511 TOutputIterator o_begin,
2512 TUnaryPredicate predicate)
2513 {
2514 while (n-- > 0)
2515 {
2516 if (predicate(*i_begin))
2517 {
2518 *o_begin = *i_begin;
2519 ++o_begin;
2520 }
2521
2522 ++i_begin;
2523 }
2524
2525 return o_begin;
2526 }
2527
2528#if ETL_USING_CPP11
2529 //***************************************************************************
2539 //***************************************************************************
2540 template <typename TInputIterator, typename TOutputIterator>
2541 ETL_CONSTEXPR14
2543 etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>::type
2544 move_s(TInputIterator i_begin,
2545 TInputIterator i_end,
2546 TOutputIterator o_begin,
2547 TOutputIterator o_end)
2548 {
2549 using s_size_type = typename iterator_traits<TInputIterator>::difference_type;
2550 using d_size_type = typename iterator_traits<TOutputIterator>::difference_type;
2551 using min_size_type = typename etl::common_type<s_size_type, d_size_type>::type;
2552
2553 s_size_type s_size = etl::distance(i_begin, i_end);
2554 d_size_type d_size = etl::distance(o_begin, o_end);
2555 min_size_type min_size = etl::min<min_size_type>(s_size, d_size);
2556
2557 return etl::move(i_begin, i_begin + min_size, o_begin);
2558 }
2559
2560 //***************************************************************************
2570 //***************************************************************************
2571 template <typename TInputIterator, typename TOutputIterator>
2572 ETL_CONSTEXPR14
2573 typename etl::enable_if<!etl::is_random_iterator<TInputIterator>::value ||
2574 !etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>::type
2575 move_s(TInputIterator i_begin,
2576 TInputIterator i_end,
2577 TOutputIterator o_begin,
2578 TOutputIterator o_end)
2579 {
2580 while ((i_begin != i_end) && (o_begin != o_end))
2581 {
2582 *o_begin = etl::move(*i_begin);
2583 ++i_begin;
2584 ++o_begin;
2585 }
2586
2587 return o_begin;
2588 }
2589#else
2590 //***************************************************************************
2601 //***************************************************************************
2602 template <typename TInputIterator, typename TOutputIterator>
2603 TOutputIterator move_s(TInputIterator i_begin,
2604 TInputIterator i_end,
2605 TOutputIterator o_begin,
2606 TOutputIterator o_end)
2607 {
2608 // Move not supported. Defer to copy.
2609 return etl::copy_s(i_begin, i_end, o_begin, o_end);
2610 }
2611#endif
2612
2613 //***************************************************************************
2617 //***************************************************************************
2618 template <typename TIterator, typename TValue>
2619 ETL_NODISCARD
2620 ETL_CONSTEXPR14
2621 TIterator binary_find(TIterator begin,
2622 TIterator end,
2623 const TValue& value)
2624 {
2625 TIterator it = etl::lower_bound(begin, end, value);
2626
2627 if ((it == end) || (*it != value))
2628 {
2629 it = end;
2630 }
2631
2632 return it;
2633 }
2634
2635 //***************************************************************************
2639 //***************************************************************************
2640 template <typename TIterator,
2641 typename TValue,
2642 typename TBinaryPredicate,
2643 typename TBinaryEquality>
2644 ETL_NODISCARD
2645 ETL_CONSTEXPR14
2646 TIterator binary_find(TIterator begin,
2647 TIterator end,
2648 const TValue& value,
2649 TBinaryPredicate predicate,
2650 TBinaryEquality equality)
2651 {
2652 TIterator it = etl::lower_bound(begin, end, value, predicate);
2653
2654 if ((it == end) || !equality(*it, value))
2655 {
2656 it = end;
2657 }
2658
2659 return it;
2660 }
2661
2662 //***************************************************************************
2665 //***************************************************************************
2666 template <typename TIterator,
2667 typename TUnaryFunction,
2668 typename TUnaryPredicate>
2669 ETL_CONSTEXPR14
2670 TUnaryFunction for_each_if(TIterator begin,
2671 const TIterator end,
2672 TUnaryFunction function,
2673 TUnaryPredicate predicate)
2674 {
2675 while (begin != end)
2676 {
2677 if (predicate(*begin))
2678 {
2679 function(*begin);
2680 }
2681
2682 ++begin;
2683 }
2684
2685 return function;
2686 }
2687
2688 //***************************************************************************
2691 //***************************************************************************
2692 template <typename TIterator,
2693 typename TSize,
2694 typename TUnaryFunction>
2695 ETL_CONSTEXPR14
2696 TIterator for_each_n(TIterator begin,
2697 TSize n,
2698 TUnaryFunction function)
2699 {
2700 while (n-- > 0)
2701 {
2702 function(*begin);
2703 ++begin;
2704 }
2705
2706 return begin;
2707 }
2708
2709 //***************************************************************************
2712 //***************************************************************************
2713 template <typename TIterator,
2714 typename TSize,
2715 typename TUnaryFunction,
2716 typename TUnaryPredicate>
2717 ETL_CONSTEXPR14
2718 TIterator for_each_n_if(TIterator begin,
2719 TSize n,
2720 TUnaryFunction function,
2721 TUnaryPredicate predicate)
2722 {
2723 while (n-- > 0)
2724 {
2725 if (predicate(*begin))
2726 {
2727 function(*begin);
2728 }
2729
2730 ++begin;
2731 }
2732
2733 return begin;
2734 }
2735
2736 //***************************************************************************
2741 //***************************************************************************
2742 template <typename TInputIterator, typename TOutputIterator, typename TUnaryFunction>
2743 ETL_CONSTEXPR14
2744 TOutputIterator transform_s(TInputIterator i_begin,
2745 TInputIterator i_end,
2746 TOutputIterator o_begin,
2747 TOutputIterator o_end,
2748 TUnaryFunction function)
2749 {
2750 while ((i_begin != i_end) && (o_begin != o_end))
2751 {
2752 *o_begin = function(*i_begin);
2753 ++i_begin;
2754 ++o_begin;
2755 }
2756
2757 return o_begin;
2758 }
2759
2760 //***************************************************************************
2765 //***************************************************************************
2766 template <typename TInputIterator,
2767 typename TSize,
2768 typename TOutputIterator,
2769 typename TUnaryFunction>
2770 ETL_CONSTEXPR14
2771 void transform_n(TInputIterator i_begin,
2772 TSize n,
2773 TOutputIterator o_begin,
2774 TUnaryFunction function)
2775 {
2776 TInputIterator i_end(i_begin);
2777 etl::advance(i_end, n);
2778
2779 etl::transform(i_begin, i_end, o_begin, function);
2780 }
2781
2782 //***************************************************************************
2787 //***************************************************************************
2788 template <typename TInputIterator1,
2789 typename TInputIterator2,
2790 typename TSize,
2791 typename TOutputIterator,
2792 typename TBinaryFunction>
2793 ETL_CONSTEXPR14
2794 void transform_n(TInputIterator1 i_begin1,
2795 TInputIterator2 i_begin2,
2796 TSize n,
2797 TOutputIterator o_begin,
2798 TBinaryFunction function)
2799 {
2800 TInputIterator1 i_end1(i_begin1);
2801 etl::advance(i_end1, n);
2802
2803 etl::transform(i_begin1, i_end1, i_begin2, o_begin, function);
2804 }
2805
2806 //***************************************************************************
2809 //***************************************************************************
2810 template <typename TInputIterator,
2811 typename TOutputIterator,
2812 typename TUnaryFunction,
2813 typename TUnaryPredicate>
2814 ETL_CONSTEXPR14
2815 TOutputIterator transform_if(TInputIterator i_begin,
2816 const TInputIterator i_end,
2817 TOutputIterator o_begin,
2818 TUnaryFunction function,
2819 TUnaryPredicate predicate)
2820 {
2821 while (i_begin != i_end)
2822 {
2823 if (predicate(*i_begin))
2824 {
2825 *o_begin = function(*i_begin);
2826 ++o_begin;
2827 }
2828
2829 ++i_begin;
2830 }
2831
2832 return o_begin;
2833 }
2834
2835 //***************************************************************************
2838 //***************************************************************************
2839 template <typename TInputIterator1,
2840 typename TInputIterator2,
2841 typename TOutputIterator,
2842 typename TBinaryFunction,
2843 typename TBinaryPredicate>
2844 ETL_CONSTEXPR14
2845 TOutputIterator transform_if(TInputIterator1 i_begin1,
2846 const TInputIterator1 i_end1,
2847 TInputIterator2 i_begin2,
2848 TOutputIterator o_begin,
2849 TBinaryFunction function,
2850 TBinaryPredicate predicate)
2851 {
2852 while (i_begin1 != i_end1)
2853 {
2854 if (predicate(*i_begin1, *i_begin2))
2855 {
2856 *o_begin = function(*i_begin1, *i_begin2);
2857 ++o_begin;
2858 }
2859
2860 ++i_begin1;
2861 ++i_begin2;
2862 }
2863
2864 return o_begin;
2865 }
2866
2867 //***************************************************************************
2870 //***************************************************************************
2871 template <typename TInputIterator,
2872 typename TSize,
2873 typename TOutputIterator,
2874 typename TUnaryFunction,
2875 typename TUnaryPredicate>
2876 ETL_CONSTEXPR14
2877 TOutputIterator transform_n_if(TInputIterator i_begin,
2878 TSize n,
2879 TOutputIterator o_begin,
2880 TUnaryFunction function,
2881 TUnaryPredicate predicate)
2882 {
2883 while (n-- > 0)
2884 {
2885 if (predicate(*i_begin))
2886 {
2887 *o_begin = function(*i_begin);
2888 ++o_begin;
2889 }
2890
2891 ++i_begin;
2892 }
2893
2894 return o_begin;
2895 }
2896
2897 //***************************************************************************
2900 //***************************************************************************
2901 template <typename TInputIterator1,
2902 typename TInputIterator2,
2903 typename TSize,
2904 typename TOutputIterator,
2905 typename TBinaryFunction,
2906 typename TBinaryPredicate>
2907 ETL_CONSTEXPR14
2908 TOutputIterator transform_n_if(TInputIterator1 i_begin1,
2909 TInputIterator2 i_begin2,
2910 TSize n,
2911 TOutputIterator o_begin,
2912 TBinaryFunction function,
2913 TBinaryPredicate predicate)
2914 {
2915 while (n-- > 0)
2916 {
2917 if (predicate(*i_begin1, *i_begin2))
2918 {
2919 *o_begin++ = function(*i_begin1, *i_begin2);
2920 }
2921
2922 ++i_begin1;
2923 ++i_begin2;
2924 }
2925
2926 return o_begin;
2927 }
2928
2929 //***************************************************************************
2933 //***************************************************************************
2934 template <typename TSource, typename TDestinationTrue, typename TDestinationFalse,
2935 typename TUnaryFunctionTrue, typename TUnaryFunctionFalse,
2936 typename TUnaryPredicate>
2937 ETL_CONSTEXPR14
2938 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse> partition_transform(TSource begin,
2939 TSource end,
2940 TDestinationTrue destination_true,
2941 TDestinationFalse destination_false,
2942 TUnaryFunctionTrue function_true,
2943 TUnaryFunctionFalse function_false,
2944 TUnaryPredicate predicate)
2945 {
2946 while (begin != end)
2947 {
2948 if (predicate(*begin))
2949 {
2950 *destination_true = function_true(*begin);
2951 ++destination_true;
2952 }
2953 else
2954 {
2955 *destination_false = function_false(*begin);
2956 ++destination_false;
2957 }
2958
2959 ++begin;
2960 }
2961
2962 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
2963 }
2964
2965 //***************************************************************************
2969 //***************************************************************************
2970 template <typename TSource1,
2971 typename TSource2,
2972 typename TDestinationTrue,
2973 typename TDestinationFalse,
2974 typename TBinaryFunctionTrue,
2975 typename TBinaryFunctionFalse,
2976 typename TBinaryPredicate>
2977 ETL_CONSTEXPR14
2978 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse> partition_transform(TSource1 begin1,
2979 TSource1 end1,
2980 TSource2 begin2,
2981 TDestinationTrue destination_true,
2982 TDestinationFalse destination_false,
2983 TBinaryFunctionTrue function_true,
2984 TBinaryFunctionFalse function_false,
2985 TBinaryPredicate predicate)
2986 {
2987 while (begin1 != end1)
2988 {
2989 if (predicate(*begin1, *begin2))
2990 {
2991 *destination_true = function_true(*begin1, *begin2);
2992 ++destination_true;
2993 }
2994 else
2995 {
2996 *destination_false = function_false(*begin1, *begin2);
2997 ++destination_false;
2998 }
2999
3000 ++begin1;
3001 ++begin2;
3002 }
3003
3004 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
3005 }
3006
3007 //***************************************************************************
3011 //***************************************************************************
3012 template <typename TIterator, typename TCompare>
3013#if ETL_USING_STD_NAMESPACE
3014 ETL_CONSTEXPR20
3015#else
3016 ETL_CONSTEXPR14
3017#endif
3018 void shell_sort(TIterator first, TIterator last, TCompare compare)
3019 {
3020 if (first == last)
3021 {
3022 return;
3023 }
3024
3025 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
3026
3027 difference_t n = etl::distance(first, last);
3028
3029 for (difference_t i = n / 2; i > 0; i /= 2)
3030 {
3031 for (difference_t j = i; j < n; ++j)
3032 {
3033 for (difference_t k = j - i; k >= 0; k -= i)
3034 {
3035 TIterator itr1 = first;
3036 TIterator itr2 = first;
3037
3038 etl::advance(itr1, k);
3039 etl::advance(itr2, k + i);
3040
3041 if (compare(*itr2, *itr1))
3042 {
3043 etl::iter_swap(itr1, itr2);
3044 }
3045 }
3046 }
3047 }
3048 }
3049
3050 //***************************************************************************
3053 //***************************************************************************
3054 template <typename TIterator>
3055#if ETL_USING_STD_NAMESPACE
3056 ETL_CONSTEXPR20
3057#else
3058 ETL_CONSTEXPR14
3059#endif
3060 void shell_sort(TIterator first, TIterator last)
3061 {
3062 etl::shell_sort(first, last, etl::less<typename etl::iterator_traits<TIterator>::value_type>());
3063 }
3064
3065 //***************************************************************************
3069 //***************************************************************************
3070 template <typename TIterator, typename TCompare>
3071 ETL_CONSTEXPR14
3072 void insertion_sort(TIterator first, TIterator last, TCompare compare)
3073 {
3074 for (TIterator itr = first; itr != last; ++itr)
3075 {
3076 etl::rotate(etl::upper_bound(first, itr, *itr, compare), itr, etl::next(itr));
3077 }
3078 }
3079
3080 //***************************************************************************
3083 //***************************************************************************
3084 template <typename TIterator>
3085 ETL_CONSTEXPR14
3086 void insertion_sort(TIterator first, TIterator last)
3087 {
3088 etl::insertion_sort(first, last, etl::less<typename etl::iterator_traits<TIterator>::value_type>());
3089 }
3090
3091 //***************************************************************************
3092 namespace private_algorithm
3093 {
3094 template <typename TIterator>
3095 ETL_CONSTEXPR14
3097 get_before_last(TIterator first_, TIterator last_)
3098 {
3099 TIterator last = first_;
3100 TIterator lastplus1 = first_;
3101 ++lastplus1;
3102
3103 while (lastplus1 != last_)
3104 {
3105 ++last;
3106 ++lastplus1;
3107 }
3108
3109 return last;
3110 }
3111
3112 template <typename TIterator>
3113 ETL_CONSTEXPR14
3114 typename etl::enable_if<etl::is_bidirectional_iterator<TIterator>::value, TIterator>::type
3115 get_before_last(TIterator /*first_*/, TIterator last_)
3116 {
3117 TIterator last = last_;
3118 --last;
3119
3120 return last;
3121 }
3122
3123 template <typename TIterator>
3124 ETL_CONSTEXPR14
3125 typename etl::enable_if<etl::is_random_access_iterator<TIterator>::value, TIterator>::type
3126 get_before_last(TIterator /*first_*/, TIterator last_)
3127 {
3128 return last_ - 1;
3129 }
3130 }
3131
3132 //***************************************************************************
3136 //***************************************************************************
3137 template <typename TIterator, typename TCompare>
3138 ETL_CONSTEXPR20
3139 void selection_sort(TIterator first, TIterator last, TCompare compare)
3140 {
3141 TIterator min;
3142 const TIterator ilast = private_algorithm::get_before_last(first, last);
3143 const TIterator jlast = last;
3144
3145 for (TIterator i = first; i != ilast; ++i)
3146 {
3147 min = i;
3148
3149 TIterator j = i;
3150 ++j;
3151
3152 for (; j != jlast; ++j)
3153 {
3154 if (compare(*j, *min))
3155 {
3156 min = j;
3157 }
3158 }
3159
3160 using ETL_OR_STD::swap; // Allow ADL
3161 swap(*i, *min);
3162 }
3163 }
3164
3165 //***************************************************************************
3168 //***************************************************************************
3169 template <typename TIterator>
3170 ETL_CONSTEXPR20
3171 void selection_sort(TIterator first, TIterator last)
3172 {
3173 selection_sort(first, last, etl::less<typename etl::iterator_traits<TIterator>::value_type>());
3174 }
3175
3176 //***************************************************************************
3180 //***************************************************************************
3181 template <typename TIterator, typename TCompare>
3182 ETL_CONSTEXPR14
3183 void heap_sort(TIterator first, TIterator last, TCompare compare)
3184 {
3185 if (!etl::is_heap(first, last, compare))
3186 {
3187 etl::make_heap(first, last, compare);
3188 }
3189
3190 etl::sort_heap(first, last, compare);
3191 }
3192
3193 //***************************************************************************
3196 //***************************************************************************
3197 template <typename TIterator>
3198 ETL_CONSTEXPR14
3199 void heap_sort(TIterator first, TIterator last)
3200 {
3201 if (!etl::is_heap(first, last))
3202 {
3203 etl::make_heap(first, last);
3204 }
3205
3206 etl::sort_heap(first, last);
3207 }
3208
3209 //***************************************************************************
3211 //***************************************************************************
3212#if ETL_USING_CPP11
3213 template <typename T>
3214 ETL_NODISCARD
3215 constexpr const T& multimax(const T& a, const T& b)
3216 {
3217 return a < b ? b : a;
3218 }
3219
3220 template <typename T, typename... Tx>
3221 ETL_NODISCARD
3222 constexpr const T& multimax(const T& t, const Tx&... tx)
3223 {
3224 return multimax(t, multimax(tx...));
3225 }
3226#endif
3227
3228 //***************************************************************************
3231 //***************************************************************************
3232#if ETL_USING_CPP11
3233 template <typename TCompare, typename T>
3234 ETL_NODISCARD
3235 constexpr const T& multimax_compare(TCompare compare, const T& a, const T& b)
3236 {
3237 return compare(a, b) ? b : a;
3238 }
3239
3240 template <typename TCompare, typename T, typename... Tx>
3241 ETL_NODISCARD
3242 constexpr const T& multimax_compare(TCompare compare, const T& t, const Tx&... tx)
3243 {
3244 return multimax_compare(compare, t, multimax_compare(compare, tx...));
3245 }
3246#endif
3247
3248 //***************************************************************************
3250 //***************************************************************************
3251#if ETL_USING_CPP11
3252 template <typename T>
3253 ETL_NODISCARD
3254 constexpr const T& multimin(const T& a, const T& b)
3255 {
3256 return a < b ? a : b;
3257 }
3258
3259 template <typename T, typename... Tx>
3260 ETL_NODISCARD
3261 constexpr const T& multimin(const T& t, const Tx&... tx)
3262 {
3263 return multimin(t, multimin(tx...));
3264 }
3265#endif
3266
3267 //***************************************************************************
3270 //***************************************************************************
3271#if ETL_USING_CPP11
3272 template <typename TCompare, typename T>
3273 ETL_NODISCARD
3274 constexpr const T& multimin_compare(TCompare compare, const T& a, const T& b)
3275 {
3276 return compare(a, b) ? a : b;
3277 }
3278
3279 template <typename TCompare, typename T, typename... Tx>
3280 ETL_NODISCARD
3281 constexpr const T& multimin_compare(TCompare compare, const T& t, const Tx&... tx)
3282 {
3283 return multimin_compare(compare, t, multimin_compare(compare, tx...));
3284 }
3285#endif
3286
3287 //***************************************************************************
3289 //***************************************************************************
3290#if ETL_USING_CPP11
3291 template <typename TIterator>
3292 ETL_NODISCARD
3293 constexpr const TIterator& multimax_iter(const TIterator& a, const TIterator& b)
3294 {
3295 return *a < *b ? b : a;
3296 }
3297
3298 template <typename TIterator, typename... TIteratorx>
3299 ETL_NODISCARD
3300 constexpr const TIterator& multimax_iter(const TIterator& t, const TIteratorx&... tx)
3301 {
3302 return multimax_iter(t, multimax_iter(tx...));
3303 }
3304#endif
3305
3306 //***************************************************************************
3309 //***************************************************************************
3310#if ETL_USING_CPP11
3311 template <typename TCompare, typename TIterator>
3312 ETL_NODISCARD
3313 constexpr const TIterator& multimax_iter_compare(TCompare compare, const TIterator& a, const TIterator& b)
3314 {
3315 return compare(*a, *b) ? b : a;
3316 }
3317
3318 template <typename TCompare, typename TIterator, typename... TIteratorx>
3319 ETL_NODISCARD
3320 constexpr const TIterator& multimax_iter_compare(TCompare compare, const TIterator& t, const TIteratorx&... tx)
3321 {
3322 return multimax_iter_compare(compare, t, multimax_iter_compare(compare, tx...));
3323 }
3324#endif
3325
3326 //***************************************************************************
3328 //***************************************************************************
3329#if ETL_USING_CPP11
3330 template <typename TIterator>
3331 ETL_NODISCARD
3332 constexpr const TIterator& multimin_iter(const TIterator& a, const TIterator& b)
3333 {
3334 return *a < *b ? a : b;
3335 }
3336
3337 template <typename TIterator, typename... Tx>
3338 ETL_NODISCARD
3339 constexpr const TIterator& multimin_iter(const TIterator& t, const Tx&... tx)
3340 {
3341 return multimin_iter(t, multimin_iter(tx...));
3342 }
3343#endif
3344
3345 //***************************************************************************
3348 //***************************************************************************
3349#if ETL_USING_CPP11
3350 template <typename TCompare, typename TIterator>
3351 ETL_NODISCARD
3352 constexpr const TIterator& multimin_iter_compare(TCompare compare, const TIterator& a, const TIterator& b)
3353 {
3354 return compare(*a, *b) ? a : b;
3355 }
3356
3357 template <typename TCompare, typename TIterator, typename... Tx>
3358 ETL_NODISCARD
3359 constexpr const TIterator& multimin_iter_compare(TCompare compare, const TIterator& t, const Tx&... tx)
3360 {
3361 return multimin_iter_compare(compare, t, multimin_iter_compare(compare, tx...));
3362 }
3363#endif
3364
3365 //***************************************************************************
3369 //***************************************************************************
3370 template <typename TIterator, typename TPredicate>
3371 ETL_CONSTEXPR14
3372 typename etl::enable_if<etl::is_forward_iterator<TIterator>::value, TIterator>::type
3373 partition(TIterator first, TIterator last, TPredicate predicate)
3374 {
3375 first = etl::find_if_not(first, last, predicate);
3376
3377 if (first == last)
3378 {
3379 return first;
3380 }
3381
3382 for (TIterator i = etl::next(first); i != last; ++i)
3383 {
3384 if (predicate(*i))
3385 {
3386 using ETL_OR_STD::swap;
3387 swap(*i, *first);
3388 ++first;
3389 }
3390 }
3391
3392 return first;
3393 }
3394
3395 //***************************************************************************
3399 //***************************************************************************
3400 template <typename TIterator, typename TPredicate>
3401 ETL_CONSTEXPR14
3403 partition(TIterator first, TIterator last, TPredicate predicate)
3404 {
3405 while (first != last)
3406 {
3407 first = etl::find_if_not(first, last, predicate);
3408
3409 if (first == last)
3410 {
3411 break;
3412 }
3413
3414 last = etl::find_if(etl::reverse_iterator<TIterator>(last),
3416 predicate).base();
3417
3418 if (first == last)
3419 {
3420 break;
3421 }
3422
3423 --last;
3424 using ETL_OR_STD::swap;
3425 swap(*first, *last);
3426 ++first;
3427 }
3428
3429 return first;
3430 }
3431
3432 //*********************************************************
3433 namespace private_algorithm
3434 {
3435 using ETL_OR_STD::swap;
3436
3437 template <typename TIterator, typename TCompare>
3438#if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST))
3439 constexpr
3440#endif
3441 TIterator nth_partition(TIterator first, TIterator last, TCompare compare)
3442 {
3443 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
3444
3445 TIterator pivot = last; // Maybe find a better pivot choice?
3446 value_type pivot_value = *pivot;
3447
3448 // Swap the pivot with the last, if necessary.
3449 if (pivot != last)
3450 {
3451 swap(*pivot, *last);
3452 }
3453
3454 TIterator i = first;
3455
3456 for (TIterator j = first; j < last; ++j)
3457 {
3458 if (!compare(pivot_value, *j)) // Hack to get '*j <= pivot_value' in terms of 'pivot_value < *j'
3459 {
3460 swap(*i, *j);
3461 ++i;
3462 }
3463 }
3464
3465 swap(*i, *last);
3466
3467 return i;
3468 }
3469 }
3470
3471 //*********************************************************
3474 //*********************************************************
3475#if ETL_USING_CPP11
3476 template <typename TIterator, typename TCompare = etl::less<typename etl::iterator_traits<TIterator>::value_type>>
3477#if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST))
3478 constexpr
3479#endif
3480 typename etl::enable_if<etl::is_random_access_iterator_concept<TIterator>::value, void>::type
3481 nth_element(TIterator first, TIterator nth, TIterator last, TCompare compare = TCompare())
3482 {
3483 if (first == last)
3484 {
3485 return;
3486 }
3487
3488 // 'last' must point to the actual last value.
3489 --last;
3490
3491 while (first <= last)
3492 {
3493 TIterator p = private_algorithm::nth_partition(first, last, compare);
3494
3495 if (p == nth)
3496 {
3497 return;
3498 }
3499 else if (p > nth)
3500 {
3501 last = p - 1;
3502 }
3503 else
3504 {
3505 first = p + 1;
3506 }
3507 }
3508 }
3509
3510#else
3511
3512 //*********************************************************
3513 template <typename TIterator, typename TCompare>
3514 typename etl::enable_if<etl::is_random_access_iterator_concept<TIterator>::value, void>::type
3515 nth_element(TIterator first, TIterator nth, TIterator last, TCompare compare)
3516 {
3517 if (first == last)
3518 {
3519 return;
3520 }
3521
3522 // 'last' must point to the actual last value.
3523 --last;
3524
3525 while (first <= last)
3526 {
3527 TIterator p = private_algorithm::nth_partition(first, last, compare);
3528
3529 if (p == nth)
3530 {
3531 return;
3532 }
3533 else if (p > nth)
3534 {
3535 last = p - 1;
3536 }
3537 else
3538 {
3539 first = p + 1;
3540 }
3541 }
3542 }
3543
3544 //*********************************************************
3545 template <typename TIterator>
3547 nth_element(TIterator first, TIterator nth, TIterator last)
3548 {
3550
3551 nth_element(first, last, compare_t());
3552 }
3553#endif
3554}
3555
3556#include "private/minmax_pop.h"
3557
3558#endif
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:3060
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:2938
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:2877
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:2815
ETL_CONSTEXPR14 TUnaryFunction for_each_if(TIterator begin, const TIterator end, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:2670
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:2744
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:2771
ETL_CONSTEXPR14 TOutputIterator copy_n_if(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryPredicate predicate)
Definition algorithm.h:2509
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:3086
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:2696
ETL_NODISCARD ETL_CONSTEXPR14 TIterator binary_find(TIterator begin, TIterator end, const TValue &value)
Definition algorithm.h:2621
ETL_CONSTEXPR14 void heap_sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:3183
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:3139
ETL_CONSTEXPR14 TOutputIterator copy_n_s(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TOutputIterator o_end)
Definition algorithm.h:2429
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:2603
ETL_CONSTEXPR14 TOutputIterator copy_if_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end, TUnaryPredicate predicate)
Definition algorithm.h:2479
ETL_CONSTEXPR14 TIterator for_each_n_if(TIterator begin, TSize n, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:2718
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
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition exception.h:69
Definition exception.h:47
Definition function.h:94
enable_if
Definition type_traits_generator.h:1254
is_reference
Definition type_traits_generator.h:1174
is_same
Definition type_traits_generator.h:1104
bitset_ext
Definition absolute.h:39
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:838
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:3515
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:962
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:3373
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition iterator.h:992
Definition compare.h:51
Definition iterator.h:63
Definition functional.h:170
Definition algorithm.h:119