33#ifndef ETL_ALGORITHM_INCLUDED
34#define ETL_ALGORITHM_INCLUDED
70 template <
typename TIterator>
71#if ETL_USING_STD_NAMESPACE
79 template <
typename TIterator,
typename TCompare>
80#if ETL_USING_STD_NAMESPACE
88 template <
typename TIterator>
89 ETL_CONSTEXPR14
void insertion_sort(TIterator first, TIterator last);
91 template <
typename TIterator,
typename TCompare>
98 algorithm_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
99 :
exception(reason_, file_name_, line_number_)
104 class algorithm_error :
public algorithm_exception
108 algorithm_error(string_type file_name_, numeric_type line_number_)
109 : algorithm_exception(ETL_ERROR_TEXT(
"algorithm:error", ETL_ALGORITHM_FILE_ID
"A"), file_name_, line_number_)
121 namespace private_algorithm
123 template <
bool use_swap>
130 template <
typename TIterator1,
typename TIterator2>
131 static void do_swap(TIterator1 a, TIterator2 b)
133 typename etl::iterator_traits<TIterator1>::value_type tmp = *a;
143 template <
typename TIterator1,
typename TIterator2>
144 static void do_swap(TIterator1 a, TIterator2 b)
146 using ETL_OR_STD::swap;
155 template <
typename TIterator1,
typename TIterator2>
156#if ETL_USING_STD_NAMESPACE
162 iter_swap(TIterator1 a, TIterator2 b)
167 typedef typename traits1::value_type v1;
168 typedef typename traits2::value_type v2;
170 typedef typename traits1::reference r1;
171 typedef typename traits2::reference r2;
173 const bool use_swap = etl::is_same<v1, v2>::value && etl::is_reference<r1>::value && etl::is_reference<r2>::value;
181 template <
typename TIterator1,
typename TIterator2>
182#if ETL_USING_STD_NAMESPACE
188 swap_ranges(TIterator1 first1, TIterator1 last1, TIterator2 first2)
190 while (first1 != last1)
192 etl::iter_swap(first1, first2);
202 template <
typename TIterator,
typename TFunction>
203 ETL_CONSTEXPR14
void generate(TIterator db, TIterator de, TFunction funct)
213#if ETL_USING_STL && ETL_USING_CPP20
215 template <
typename TIterator1,
typename TIterator2>
216 constexpr TIterator2 copy(TIterator1 sb, TIterator1 se, TIterator2 db)
218 return std::copy(sb, se, db);
222 template <
typename TIterator1,
typename TIterator2>
223 ETL_CONSTEXPR14 TIterator2 copy(TIterator1 sb, TIterator1 se, TIterator2 db)
238#if ETL_USING_STL && ETL_USING_CPP20
239 template <
typename TIterator1,
typename TIterator2>
240 constexpr TIterator2 reverse_copy(TIterator1 sb, TIterator1 se, TIterator2 db)
242 return std::reverse_copy(sb, se, db);
245 template <
typename TIterator1,
typename TIterator2>
246 ETL_CONSTEXPR14 TIterator2 reverse_copy(TIterator1 sb, TIterator1 se, TIterator2 db)
260#if ETL_USING_STL && ETL_USING_CPP20
262 template <
typename TIterator1,
typename TSize,
typename TIterator2>
263 constexpr TIterator2 copy_n(TIterator1 sb, TSize count, TIterator2 db)
265 return std::copy_n(sb, count, db);
269 template <
typename TIterator1,
typename TSize,
typename TIterator2>
270 ETL_CONSTEXPR14 TIterator2 copy_n(TIterator1 sb, TSize count, TIterator2 db)
286#if ETL_USING_STL && ETL_USING_CPP20
287 template <
typename TIterator1,
typename TIterator2>
288 constexpr TIterator2 copy_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
290 return std::copy_backward(sb, se, de);
293 template <
typename TIterator1,
typename TIterator2>
294 ETL_CONSTEXPR14 TIterator2 copy_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
307#if ETL_USING_STL && ETL_USING_CPP20
308 template <
typename TIterator1,
typename TIterator2>
309 constexpr TIterator2 move(TIterator1 sb, TIterator1 se, TIterator2 db)
311 return std::move(sb, se, db);
315 template <
typename TIterator1,
typename TIterator2>
316 ETL_CONSTEXPR14 TIterator2 move(TIterator1 sb, TIterator1 se, TIterator2 db)
320 *db = etl::move(*sb);
329 template <
typename TIterator1,
typename TIterator2>
330 ETL_CONSTEXPR14 TIterator2 move(TIterator1 sb, TIterator1 se, TIterator2 db)
332 return copy(sb, se, db);
338#if ETL_USING_STL && ETL_USING_CPP20
339 template <
typename TIterator1,
typename TIterator2>
340 ETL_CONSTEXPR20 TIterator2 move_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
343 return std::move_backward(sb, se, de);
348 template <
typename TIterator1,
typename TIterator2>
349 ETL_CONSTEXPR14 TIterator2 move_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
353 *(--de) = etl::move(*(--se));
360 template <
typename TIterator1,
typename TIterator2>
361 ETL_CONSTEXPR14 TIterator2 move_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
363 return etl::copy_backward(sb, se, de);
371 template <
typename TIterator>
372 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_pointer<TIterator>::value,
void>::type reverse(TIterator b, TIterator e)
378 etl::iter_swap(b, e);
385 template <
typename TIterator>
386 ETL_CONSTEXPR14
typename etl::enable_if<!etl::is_pointer<TIterator>::value,
void>::type reverse(TIterator b, TIterator e)
388 while ((b != e) && (b != --e))
390 etl::iter_swap(b++, e);
397 template <
typename TIterator,
typename TValue,
typename TCompare>
398 ETL_NODISCARD ETL_CONSTEXPR14 TIterator lower_bound(TIterator first, TIterator last,
const TValue& value, TCompare
compare)
400 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
402 difference_t count = etl::distance(first, last);
406 TIterator itr = first;
407 difference_t step = count / 2;
409 etl::advance(itr, step);
425 template <
typename TIterator,
typename TValue>
426 ETL_NODISCARD ETL_CONSTEXPR14 TIterator lower_bound(TIterator first, TIterator last,
const TValue& value)
428 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
430 return etl::lower_bound(first, last, value,
compare());
436 template <
typename TIterator,
typename TValue,
typename TCompare>
437 ETL_NODISCARD ETL_CONSTEXPR14 TIterator upper_bound(TIterator first, TIterator last,
const TValue& value, TCompare
compare)
439 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
441 difference_t count = etl::distance(first, last);
445 TIterator itr = first;
446 difference_t step = count / 2;
448 etl::advance(itr, step);
464 template <
typename TIterator,
typename TValue>
465 ETL_NODISCARD ETL_CONSTEXPR14 TIterator upper_bound(TIterator first, TIterator last,
const TValue& value)
467 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
469 return etl::upper_bound(first, last, value,
compare());
475 template <
typename TIterator,
typename TValue,
typename TCompare>
476 ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair<TIterator, TIterator> equal_range(TIterator first, TIterator last,
const TValue& value, TCompare
compare)
478 return ETL_OR_STD::make_pair(etl::lower_bound(first, last, value,
compare), etl::upper_bound(first, last, value,
compare));
481 template <
typename TIterator,
typename TValue>
483 ETL_OR_STD::pair<TIterator, TIterator> equal_range(TIterator first, TIterator last,
const TValue& value)
485 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
487 return ETL_OR_STD::make_pair(etl::lower_bound(first, last, value,
compare()), etl::upper_bound(first, last, value,
compare()));
493 template <
typename TIterator,
typename T,
typename Compare>
494 ETL_NODISCARD ETL_CONSTEXPR14
bool binary_search(TIterator first, TIterator last,
const T& value, Compare
compare)
496 first = etl::lower_bound(first, last, value,
compare);
498 return (!(first == last) && !(
compare(value, *first)));
501 template <
typename TIterator,
typename T>
502 ETL_NODISCARD ETL_CONSTEXPR14
bool binary_search(TIterator first, TIterator last,
const T& value)
504 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
506 return binary_search(first, last, value,
compare());
512 template <
typename TIterator,
typename TUnaryPredicate>
513 ETL_NODISCARD ETL_CONSTEXPR14 TIterator find_if(TIterator first, TIterator last, TUnaryPredicate predicate)
515 while (first != last)
517 if (predicate(*first))
531 template <
typename TIterator,
typename T>
532 ETL_NODISCARD ETL_CONSTEXPR14 TIterator find(TIterator first, TIterator last,
const T& value)
534 while (first != last)
549#if ETL_USING_STL && ETL_USING_CPP20
550 template <
typename TIterator,
typename TValue>
551 constexpr void fill(TIterator first, TIterator last,
const TValue& value)
553 std::fill(first, last, value);
556 template <
typename TIterator,
typename TValue>
557 ETL_CONSTEXPR14
void fill(TIterator first, TIterator last,
const TValue& value)
559 while (first != last)
569#if ETL_USING_STL && ETL_USING_CPP20
570 template <
typename TIterator,
typename TSize,
typename TValue>
571 constexpr TIterator fill_n(TIterator first, TSize count,
const TValue& value)
573 return std::fill_n(first, count, value);
576 template <
typename TIterator,
typename TSize,
typename TValue>
577 ETL_CONSTEXPR14 TIterator fill_n(TIterator first, TSize count,
const TValue& value)
592 template <
typename TIterator,
typename T>
593 ETL_NODISCARD ETL_CONSTEXPR14
typename etl::iterator_traits<TIterator>::difference_type count(TIterator first, TIterator last,
const T& value)
595 typename iterator_traits<TIterator>::difference_type n = 0;
597 while (first != last)
613 template <
typename TIterator,
typename TUnaryPredicate>
614 ETL_NODISCARD ETL_CONSTEXPR14
typename etl::iterator_traits<TIterator>::difference_type count_if(TIterator first, TIterator last, TUnaryPredicate predicate)
616 typename iterator_traits<TIterator>::difference_type n = 0;
618 while (first != last)
620 if (predicate(*first))
633#if ETL_USING_STL && ETL_USING_CPP20
635 template <
typename TIterator1,
typename TIterator2>
637 constexpr bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2)
639 return std::equal(first1, last1, first2);
643 template <
typename TIterator1,
typename TIterator2,
typename TPredicate>
645 constexpr bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TPredicate predicate)
647 return std::equal(first1, last1, first2, predicate);
651 template <
typename TIterator1,
typename TIterator2>
653 constexpr bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2)
655 return std::equal(first1, last1, first2, last2);
659 template <
typename TIterator1,
typename TIterator2,
typename TPredicate>
661 constexpr bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2, TPredicate predicate)
663 return std::equal(first1, last1, first2, last2, predicate);
668 template <
typename TIterator1,
typename TIterator2>
669 ETL_NODISCARD ETL_CONSTEXPR14
bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2)
671 while (first1 != last1)
673 if (*first1 != *first2)
686 template <
typename TIterator1,
typename TIterator2,
typename TPredicate>
687 ETL_NODISCARD ETL_CONSTEXPR14
bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TPredicate predicate)
689 while (first1 != last1)
691 if (!predicate(*first1, *first2))
704 template <
typename TIterator1,
typename TIterator2>
705 ETL_NODISCARD ETL_CONSTEXPR14
bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2)
707 while ((first1 != last1) && (first2 != last2))
709 if (*first1 != *first2)
718 return (first1 == last1) && (first2 == last2);
722 template <
typename TIterator1,
typename TIterator2,
typename TPredicate>
723 ETL_NODISCARD ETL_CONSTEXPR14
bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2, TPredicate predicate)
725 while ((first1 != last1) && (first2 != last2))
727 if (!predicate(*first1, *first2))
736 return (first1 == last1) && (first2 == last2);
743 template <
typename TIterator1,
typename TIterator2,
typename TCompare>
744 ETL_NODISCARD ETL_CONSTEXPR14
bool lexicographical_compare(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2, TCompare
compare)
746 while ((first1 != last1) && (first2 != last2))
762 return (first1 == last1) && (first2 != last2);
766 template <
typename TIterator1,
typename TIterator2>
767 ETL_NODISCARD ETL_CONSTEXPR14
bool lexicographical_compare(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2)
769 typedef etl::less<typename etl::iterator_traits<TIterator1>::value_type>
compare;
771 return etl::lexicographical_compare(first1, last1, first2, last2,
compare());
777 template <
typename T,
typename TCompare>
778 ETL_NODISCARD ETL_CONSTEXPR
const T& min(
const T& a,
const T& b, TCompare
compare)
780 return (
compare(a, b)) ? a : b;
783 template <
typename T>
784 ETL_NODISCARD ETL_CONSTEXPR
const T& min(
const T& a,
const T& b)
788 return etl::min(a, b,
compare());
794 template <
typename T,
typename TCompare>
795 ETL_NODISCARD ETL_CONSTEXPR
const T& max(
const T& a,
const T& b, TCompare
compare)
797 return (
compare(a, b)) ? b : a;
800 template <
typename T>
801 ETL_NODISCARD ETL_CONSTEXPR
const T& max(
const T& a,
const T& b)
805 return etl::max(a, b,
compare());
811 template <
typename TIterator,
typename TUnaryOperation>
812 ETL_CONSTEXPR14 TUnaryOperation for_each(TIterator first, TIterator last, TUnaryOperation unary_operation)
814 while (first != last)
816 unary_operation(*first);
820 return unary_operation;
826 template <
typename TIteratorIn,
typename TIteratorOut,
typename TUnaryOperation>
827 ETL_CONSTEXPR14 TIteratorOut transform(TIteratorIn first1, TIteratorIn last1, TIteratorOut d_first, TUnaryOperation unary_operation)
829 while (first1 != last1)
831 *d_first = unary_operation(*first1);
840 template <
typename TIteratorIn1,
typename TIteratorIn2,
typename TIteratorOut,
typename TBinaryOperation>
841 ETL_CONSTEXPR14 TIteratorOut transform(TIteratorIn1 first1, TIteratorIn1 last1, TIteratorIn2 first2, TIteratorOut d_first,
842 TBinaryOperation binary_operation)
844 while (first1 != last1)
846 *d_first = binary_operation(*first1, *first2);
859 template <
typename TIterator,
typename T>
860 ETL_CONSTEXPR14
void replace(TIterator first, TIterator last,
const T& old_value,
const T& new_value)
862 while (first != last)
864 if (*first == old_value)
876 template <
typename TIterator,
typename TPredicate,
typename T>
877 ETL_CONSTEXPR14
void replace_if(TIterator first, TIterator last, TPredicate predicate,
const T& new_value)
879 while (first != last)
881 if (predicate(*first))
893 namespace private_heap
896 template <
typename TIterator,
typename TDistance,
typename TValue,
typename TCompare>
897 ETL_CONSTEXPR14
void push_heap(TIterator first, TDistance value_index, TDistance top_index, TValue value, TCompare compare)
899 TDistance parent = (value_index - 1) / 2;
901 while ((value_index > top_index) && compare(first[parent], value))
903 first[value_index] = ETL_MOVE(first[parent]);
904 value_index = parent;
905 parent = (value_index - 1) / 2;
908 first[value_index] = ETL_MOVE(value);
912 template <
typename TIterator,
typename TDistance,
typename TValue,
typename TCompare>
913 ETL_CONSTEXPR14
void adjust_heap(TIterator first, TDistance value_index, TDistance length, TValue value, TCompare compare)
915 TDistance top_index = value_index;
916 TDistance child2nd = (2 * value_index) + 2;
918 while (child2nd < length)
920 if (compare(first[child2nd], first[child2nd - 1]))
925 first[value_index] = ETL_MOVE(first[child2nd]);
926 value_index = child2nd;
927 child2nd = 2 * (child2nd + 1);
930 if (child2nd == length)
932 first[value_index] = ETL_MOVE(first[child2nd - 1]);
933 value_index = child2nd - 1;
936 push_heap(first, value_index, top_index, ETL_MOVE(value), compare);
940 template <
typename TIterator,
typename TDistance,
typename TCompare>
941 ETL_CONSTEXPR14
bool is_heap(
const TIterator first,
const TDistance n, TCompare compare)
943 TDistance parent = 0;
945 for (TDistance child = 1; child < n; ++child)
947 if (compare(first[parent], first[child]))
952 if ((child & 1) == 0)
963 template <
typename TIterator,
typename TCompare>
964 ETL_CONSTEXPR14
void pop_heap(TIterator first, TIterator last, TCompare
compare)
966 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
967 typedef typename etl::iterator_traits<TIterator>::difference_type distance_t;
969 value_t value = ETL_MOVE(last[-1]);
970 last[-1] = ETL_MOVE(first[0]);
972 private_heap::adjust_heap(first, distance_t(0), distance_t(last - first - 1), ETL_MOVE(value),
compare);
976 template <
typename TIterator>
977 ETL_CONSTEXPR14
void pop_heap(TIterator first, TIterator last)
979 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
981 etl::pop_heap(first, last,
compare());
985 template <
typename TIterator,
typename TCompare>
986 ETL_CONSTEXPR14
void push_heap(TIterator first, TIterator last, TCompare
compare)
988 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
989 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
991 private_heap::push_heap(first, difference_t(last - first - 1), difference_t(0), value_t(ETL_MOVE(*(last - 1))),
compare);
995 template <
typename TIterator>
996 ETL_CONSTEXPR14
void push_heap(TIterator first, TIterator last)
998 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
1000 etl::push_heap(first, last,
compare());
1004 template <
typename TIterator,
typename TCompare>
1005 ETL_CONSTEXPR14
void make_heap(TIterator first, TIterator last, TCompare
compare)
1007 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
1009 if ((last - first) < 2)
1014 difference_t length = last - first;
1015 difference_t parent = (length - 2) / 2;
1019 private_heap::adjust_heap(first, parent, length, ETL_MOVE(*(first + parent)),
compare);
1031 template <
typename TIterator>
1032 ETL_CONSTEXPR14
void make_heap(TIterator first, TIterator last)
1034 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
1036 etl::make_heap(first, last,
compare());
1040 template <
typename TIterator>
1041 ETL_NODISCARD ETL_CONSTEXPR14
bool is_heap(TIterator first, TIterator last)
1043 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
1045 return private_heap::is_heap(first, last - first,
compare());
1049 template <
typename TIterator,
typename TCompare>
1050 ETL_NODISCARD ETL_CONSTEXPR14
bool is_heap(TIterator first, TIterator last, TCompare
compare)
1052 return private_heap::is_heap(first, last - first,
compare);
1056 template <
typename TIterator>
1057 ETL_CONSTEXPR14
void sort_heap(TIterator first, TIterator last)
1059 while (first != last)
1061 etl::pop_heap(first, last);
1067 template <
typename TIterator,
typename TCompare>
1068 ETL_CONSTEXPR14
void sort_heap(TIterator first, TIterator last, TCompare
compare)
1070 while (first != last)
1072 etl::pop_heap(first, last,
compare);
1082 template <
typename TIterator,
typename TCompare>
1085 if (first == middle)
1090 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1091 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
1093 etl::make_heap(first, middle,
compare);
1095 for (TIterator i = middle; i != last; ++i)
1099 value_t value = ETL_MOVE(*i);
1100 *i = ETL_MOVE(*first);
1102 private_heap::adjust_heap(first, difference_t(0), difference_t(middle - first), ETL_MOVE(value),
compare);
1106 etl::sort_heap(first, middle,
compare);
1114 template <
typename TIterator>
1115 ETL_CONSTEXPR14
void partial_sort(TIterator first, TIterator middle, TIterator last)
1128 template <
typename TInputIterator,
typename TRandomAccessIterator,
typename TCompare>
1129 ETL_CONSTEXPR14 TRandomAccessIterator
partial_sort_copy(TInputIterator first, TInputIterator last, TRandomAccessIterator d_first,
1130 TRandomAccessIterator d_last, TCompare
compare)
1132 typedef typename etl::iterator_traits<TRandomAccessIterator>::value_type value_t;
1133 typedef typename etl::iterator_traits<TRandomAccessIterator>::difference_type difference_t;
1135 TRandomAccessIterator result = d_first;
1138 while ((first != last) && (result != d_last))
1145 if (result == d_first)
1151 etl::make_heap(d_first, result,
compare);
1154 for (TInputIterator i = first; i != last; ++i)
1159 private_heap::adjust_heap(d_first, difference_t(0), difference_t(result - d_first), ETL_MOVE(value),
compare);
1163 etl::sort_heap(d_first, result,
compare);
1174 template <
typename TInputIterator,
typename TRandomAccessIterator>
1175 ETL_CONSTEXPR14 TRandomAccessIterator
partial_sort_copy(TInputIterator first, TInputIterator last, TRandomAccessIterator d_first,
1176 TRandomAccessIterator d_last)
1186 template <
typename TIterator1,
typename TIterator2,
typename TCompare>
1187 ETL_NODISCARD ETL_CONSTEXPR14 TIterator1 search(TIterator1 first, TIterator1 last, TIterator2 search_first, TIterator2 search_last, TCompare compare)
1191 TIterator1 itr = first;
1192 TIterator2 search_itr = search_first;
1196 if (search_itr == search_last)
1206 if (!
compare(*itr, *search_itr))
1220 template <
typename TIterator1,
typename TIterator2>
1221 ETL_NODISCARD ETL_CONSTEXPR14 TIterator1 search(TIterator1 first, TIterator1 last, TIterator2 search_first, TIterator2 search_last)
1223 typedef etl::equal_to<typename etl::iterator_traits<TIterator1>::value_type>
compare;
1225 return etl::search(first, last, search_first, search_last,
compare());
1231 namespace private_algorithm
1235 template <
typename TIterator>
1236 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_random_access_iterator<TIterator>::value, TIterator>::type
1237 rotate_general(TIterator first, TIterator middle, TIterator last)
1239 if (first == middle)
1249 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
1250 typedef typename etl::iterator_traits<TIterator>::difference_type difference_type;
1252 difference_type n = last - first;
1253 difference_type m = middle - first;
1254 difference_type gcd_nm = (n == 0 || m == 0) ? n + m : etl::gcd(n, m);
1255 TIterator result = first + (last - middle);
1257 for (difference_type i = 0; i < gcd_nm; i++)
1259 value_type temp = ETL_MOVE(*(first + i));
1260 difference_type j = i;
1264 difference_type k = j + m;
1276 *(first + j) = ETL_MOVE(*(first + k));
1280 *(first + j) = ETL_MOVE(temp);
1288 template <
typename TIterator>
1289 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_bidirectional_iterator<TIterator>::value, TIterator>::type
1290 rotate_general(TIterator first, TIterator middle, TIterator last)
1292 if (first == middle)
1302 TIterator result = first;
1303 etl::advance(result, etl::distance(middle, last));
1305 reverse(first, middle);
1306 reverse(middle, last);
1307 reverse(first, last);
1314 template <
typename TIterator>
1315 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_forward_iterator<TIterator>::value, TIterator>::type rotate_general(TIterator first, TIterator middle,
1318 if (first == middle)
1328 TIterator next = middle;
1329 TIterator result = first;
1330 etl::advance(result, etl::distance(middle, last));
1332 while (first != next)
1334 using ETL_OR_STD::swap;
1335 swap(*first++, *next++);
1341 else if (first == middle)
1352 template <
typename TIterator>
1353 ETL_CONSTEXPR14 TIterator rotate_left_by_one(TIterator first, TIterator last)
1355 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
1358 value_type temp(ETL_MOVE(*first));
1361 TIterator result = etl::move(etl::next(first), last, first);
1364 *result = ETL_MOVE(temp);
1372 template <
typename TIterator>
1373 ETL_CONSTEXPR14 TIterator rotate_right_by_one(TIterator first, TIterator last)
1375 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
1378 TIterator previous = etl::prev(last);
1379 value_type temp(ETL_MOVE(*previous));
1382 TIterator result = etl::move_backward(first, previous, last);
1385 *first = ETL_MOVE(temp);
1393 template <
typename TIterator>
1394 ETL_CONSTEXPR14 TIterator rotate(TIterator first, TIterator middle, TIterator last)
1396 if (first == middle)
1405 if (etl::next(first) == middle)
1407 return private_algorithm::rotate_left_by_one(first, last);
1411 if (etl::next(middle) == last)
1413 if ETL_IF_CONSTEXPR (etl::is_bidirectional_iterator_concept< TIterator>::value)
1415 return private_algorithm::rotate_right_by_one(first, last);
1420 return private_algorithm::rotate_general(first, middle, last);
1427 template <
typename TIterator1,
typename TIterator2,
typename TPredicate>
1428 ETL_NODISCARD ETL_CONSTEXPR14 TIterator1 find_end(TIterator1 b, TIterator1 e, TIterator2 sb, TIterator2 se, TPredicate predicate)
1435 TIterator1 result = e;
1439 TIterator1 new_result = etl::search(b, e, sb, se, predicate);
1441 if (new_result == e)
1447 result = new_result;
1456 template <
typename TIterator1,
typename TIterator2>
1457 ETL_NODISCARD ETL_CONSTEXPR14 TIterator1 find_end(TIterator1 b, TIterator1 e, TIterator2 sb, TIterator2 se)
1459 typedef etl::equal_to<typename etl::iterator_traits<TIterator1>::value_type> predicate;
1461 return find_end(b, e, sb, se, predicate());
1469 template <
typename TIterator,
typename TCompare>
1472 TIterator minimum =
begin;
1497 template <
typename TIterator>
1500 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1510 template <
typename TIterator,
typename TCompare>
1513 TIterator maximum =
begin;
1538 template <
typename TIterator>
1541 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1551 template <
typename TIterator,
typename TCompare>
1554 TIterator minimum =
begin;
1555 TIterator maximum =
begin;
1577 return ETL_OR_STD::pair<TIterator, TIterator>(minimum, maximum);
1585 template <
typename TIterator>
1588 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1598 template <
typename T>
1599 ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair<const T&, const T&>
minmax(
const T& a,
const T& b)
1601 return (b < a) ? ETL_OR_STD::pair<const T&, const T&>(b, a) : ETL_OR_STD::pair<const T&, const T&>(a, b);
1609 template <
typename T,
typename TCompare>
1610 ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair<const T&, const T&>
minmax(
const T& a,
const T& b, TCompare
compare)
1612 return compare(b, a) ? ETL_OR_STD::pair<const T&, const T&>(b, a) : ETL_OR_STD::pair<const T&, const T&>(a, b);
1620 template <
typename TIterator,
typename TCompare>
1625 TIterator next =
begin;
1627 while (++next !=
end)
1646 template <
typename TIterator>
1659 template <
typename TIterator>
1670 template <
typename TIterator,
typename TCompare>
1680 template <
typename TIterator,
typename TCompare>
1685 TIterator next =
begin;
1687 while (++next !=
end)
1705 template <
typename TIterator>
1717 template <
typename TIterator>
1727 template <
typename TIterator,
typename TCompare>
1738 template <
typename TIterator,
typename TUnaryPredicate>
1739 ETL_NODISCARD ETL_CONSTEXPR14 TIterator
find_if_not(TIterator
begin, TIterator
end, TUnaryPredicate predicate)
1743 if (!predicate(*
begin))
1759 template <
typename TIterator,
typename TBinaryPredicate>
1760 ETL_NODISCARD ETL_CONSTEXPR14 TIterator
adjacent_find(TIterator first, TIterator last, TBinaryPredicate predicate)
1764 TIterator next = first;
1767 while (next != last)
1769 if (predicate(*first, *next))
1787 template <
typename TIterator>
1788 ETL_NODISCARD ETL_CONSTEXPR14 TIterator
adjacent_find(TIterator first, TIterator last)
1800 template <
typename TIterator1,
typename TIterator2>
1801 ETL_NODISCARD ETL_CONSTEXPR14
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2)
1805 TIterator2 end2 = begin2;
1807 etl::advance(end2, etl::distance(begin1, end1));
1809 for (TIterator1 i = begin1; i != end1; ++i)
1811 if (i == etl::find(begin1, i, *i))
1813 size_t n =
static_cast<size_t>(etl::count(begin2, end2, *i));
1815 if (n == 0 ||
size_t(etl::count(i, end1, *i)) != n)
1831 template <
typename TIterator1,
typename TIterator2,
typename TBinaryPredicate>
1832 ETL_NODISCARD ETL_CONSTEXPR14
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TBinaryPredicate predicate)
1836 TIterator2 end2 = begin2;
1838 etl::advance(end2, etl::distance(begin1, end1));
1840 for (TIterator1 i = begin1; i != end1; ++i)
1843 if (i == etl::find_if(begin1, i, predicate_is_i))
1845 size_t n =
static_cast<size_t>(etl::count_if(begin2, end2, predicate_is_i));
1847 if (n == 0 ||
size_t(etl::count_if(i, end1, predicate_is_i)) != n)
1863 template <
typename TIterator1,
typename TIterator2>
1864 ETL_NODISCARD ETL_CONSTEXPR14
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2)
1866 if (etl::distance(begin1, end1) != etl::distance(begin2, end2))
1873 for (TIterator1 i = begin1; i != end1; ++i)
1875 if (i == etl::find(begin1, i, *i))
1877 size_t n =
static_cast<size_t>(etl::count(begin2, end2, *i));
1879 if (n == 0 ||
size_t(etl::count(i, end1, *i)) != n)
1895 template <
typename TIterator1,
typename TIterator2,
typename TBinaryPredicate>
1896 ETL_NODISCARD ETL_CONSTEXPR14
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2, TBinaryPredicate predicate)
1898 if (etl::distance(begin1, end1) != etl::distance(begin2, end2))
1905 for (TIterator1 i = begin1; i != end1; ++i)
1908 if (i == etl::find_if(begin1, i, predicate_is_i))
1910 size_t n =
static_cast<size_t>(etl::count_if(begin2, end2, predicate_is_i));
1912 if (n == 0 ||
size_t(etl::count_if(i, end1, predicate_is_i)) != n)
1928 template <
typename TIterator,
typename TCompare>
1959 etl::iter_swap(i, j);
1960 etl::reverse(i1, last);
1966 etl::reverse(first, last);
1977 template <
typename TIterator>
1989 template <
typename TIterator,
typename TCompare>
2020 etl::iter_swap(i, j);
2021 etl::reverse(i1, last);
2027 etl::reverse(first, last);
2038 template <
typename TIterator>
2050 template <
typename TIterator,
typename TUnaryPredicate>
2055 if (!predicate(*
begin))
2065 if (predicate(*
begin))
2081 template <
typename TIterator,
typename TUnaryPredicate>
2084 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
2087 for (difference_t length = etl::distance(
begin,
end); 0 < length;)
2089 difference_t half = length / 2;
2090 TIterator middle = etl::next(
begin, half);
2091 if (predicate(*middle))
2093 begin = etl::next(middle);
2094 length -= (half + 1);
2111 template <
typename TSource,
typename TDestinationTrue,
typename TDestinationFalse,
typename TUnaryPredicate>
2112 ETL_CONSTEXPR14 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>
partition_copy(TSource
begin, TSource
end, TDestinationTrue destination_true,
2113 TDestinationFalse destination_false, TUnaryPredicate predicate)
2117 if (predicate(*
begin))
2119 *destination_true = *
begin;
2124 *destination_false = *
begin;
2125 ++destination_false;
2131 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
2139 template <
typename TIterator,
typename TOutputIterator,
typename TUnaryPredicate>
2140 ETL_CONSTEXPR14 TOutputIterator
copy_if(TIterator
begin, TIterator
end, TOutputIterator out, TUnaryPredicate predicate)
2144 if (predicate(*
begin))
2161 template <
typename TIterator,
typename TUnaryPredicate>
2162 ETL_NODISCARD ETL_CONSTEXPR14
bool all_of(TIterator
begin, TIterator
end, TUnaryPredicate predicate)
2172 template <
typename TIterator,
typename TUnaryPredicate>
2173 ETL_NODISCARD ETL_CONSTEXPR14
bool any_of(TIterator
begin, TIterator
end, TUnaryPredicate predicate)
2175 return etl::find_if(
begin,
end, predicate) !=
end;
2183 template <
typename TIterator,
typename TUnaryPredicate>
2184 ETL_NODISCARD ETL_CONSTEXPR14
bool none_of(TIterator
begin, TIterator
end, TUnaryPredicate predicate)
2186 return etl::find_if(
begin,
end, predicate) ==
end;
2189#if ETL_NOT_USING_STL
2195 template <
typename TIterator,
typename TCompare>
2196 void sort(TIterator first, TIterator last, TCompare compare)
2205 template <
typename TIterator>
2206 void sort(TIterator first, TIterator last)
2208 etl::shell_sort(first, last, etl::less<
typename etl::iterator_traits<TIterator>::value_type>());
2217 template <
typename TIterator,
typename TCompare>
2228 template <
typename TIterator>
2231 etl::insertion_sort(first, last, etl::less<
typename etl::iterator_traits<TIterator>::value_type>());
2239 template <
typename TIterator,
typename TCompare>
2242 std::sort(first, last,
compare);
2249 template <
typename TIterator>
2250 void sort(TIterator first, TIterator last)
2252 std::sort(first, last);
2261 template <
typename TIterator,
typename TCompare>
2264 std::stable_sort(first, last,
compare);
2272 template <
typename TIterator>
2275 std::stable_sort(first, last);
2283 template <
typename TIterator,
typename T>
2284 ETL_CONSTEXPR14 T
accumulate(TIterator first, TIterator last, T sum)
2286 while (first != last)
2288 sum =
static_cast<T
>(ETL_MOVE(sum) +
static_cast<T
>(*first));
2299 template <
typename TIterator,
typename T,
typename TBinaryOperation>
2300 ETL_CONSTEXPR14 T
accumulate(TIterator first, TIterator last, T sum, TBinaryOperation operation)
2302 while (first != last)
2304 sum = operation(ETL_MOVE(sum), *first);
2315 template <
typename T,
typename TCompare>
2316 ETL_CONSTEXPR T
clamp(
const T& value,
const T& low,
const T& high, TCompare
compare)
2318 return compare(value, low) ? low :
compare(high, value) ? high : value;
2321 template <
typename T>
2322 ETL_CONSTEXPR T
clamp(
const T& value,
const T& low,
const T& high)
2327 template <
typename T, T Low, T High,
typename TCompare>
2328 ETL_CONSTEXPR T
clamp(
const T& value, TCompare
compare)
2330 return compare(value, Low) ? Low :
compare(High, value) ? High : value;
2333 template <
typename T, T Low, T High>
2334 ETL_CONSTEXPR T
clamp(
const T& value)
2343 template <
typename TIterator,
typename T>
2344 ETL_CONSTEXPR14 TIterator
remove(TIterator first, TIterator last,
const T& value)
2346 first = etl::find(first, last, value);
2350 TIterator itr = first;
2352 while (++itr != last)
2354 if (!(*itr == value))
2356 *first++ = ETL_MOVE(*itr);
2368 template <
typename TIterator,
typename TUnaryPredicate>
2369 ETL_CONSTEXPR14 TIterator
remove_if(TIterator first, TIterator last, TUnaryPredicate predicate)
2371 first = etl::find_if(first, last, predicate);
2375 TIterator itr = first;
2377 while (++itr != last)
2379 if (!predicate(*itr))
2381 *first++ = ETL_MOVE(*itr);
2394 template <
typename TIterator>
2395 ETL_CONSTEXPR14 TIterator
unique(TIterator first, TIterator last)
2402 TIterator result = first;
2404 while (++first != last)
2406 if (!(*result == *first) && (++result != first))
2408 *result = ETL_MOVE(*first);
2421 template <
typename TIterator,
typename TBinaryPredicate>
2422 ETL_CONSTEXPR14 TIterator
unique(TIterator first, TIterator last, TBinaryPredicate predicate)
2429 TIterator result = first;
2431 while (++first != last)
2433 if (!predicate(*result, *first) && (++result != first))
2435 *result = ETL_MOVE(*first);
2447 template <
typename TInputIterator,
typename TOutputIterator>
2448 ETL_CONSTEXPR14 TOutputIterator
unique_copy(TInputIterator first, TInputIterator last, TOutputIterator d_first)
2455 typename etl::iterator_traits<TInputIterator>::value_type prev = *first;
2458 while (++first != last)
2460 if (!(prev == *first))
2463 *(++d_first) = prev;
2476 template <
typename TInputIterator,
typename TOutputIterator,
typename TBinaryPredicate>
2477 ETL_CONSTEXPR14 TOutputIterator
unique_copy(TInputIterator first, TInputIterator last, TOutputIterator d_first, TBinaryPredicate predicate)
2484 typename etl::iterator_traits<TInputIterator>::value_type prev = *first;
2487 while (++first != last)
2489 if (!predicate(prev, *first))
2492 *(++d_first) = prev;
2505 template <
typename TInputIterator1,
typename TInputIterator2,
typename TOutputIterator,
typename TCompare>
2506 ETL_CONSTEXPR14 TOutputIterator
merge(TInputIterator1 first1, TInputIterator1 last1, TInputIterator2 first2, TInputIterator2 last2,
2507 TOutputIterator d_first, TCompare
compare)
2509 while ((first1 != last1) && (first2 != last2))
2511 if (
compare(*first2, *first1))
2524 d_first = etl::copy(first1, last1, d_first);
2525 d_first = etl::copy(first2, last2, d_first);
2537 template <
typename TInputIterator1,
typename TInputIterator2,
typename TOutputIterator>
2538 ETL_CONSTEXPR14 TOutputIterator
merge(TInputIterator1 first1, TInputIterator1 last1, TInputIterator2 first2, TInputIterator2 last2,
2539 TOutputIterator d_first)
2557 template <
typename TB
idirectionalIterator,
typename TCompare>
2558 void inplace_merge(TBidirectionalIterator first, TBidirectionalIterator middle, TBidirectionalIterator last, TCompare
compare)
2560 typedef typename etl::iterator_traits<TBidirectionalIterator>::difference_type
difference_type;
2565 while ((len1 != 0) && (len2 != 0))
2570 TBidirectionalIterator cut1 = etl::upper_bound(first, middle, *middle,
compare);
2586 TBidirectionalIterator cut2 = etl::lower_bound(middle, last, *first,
compare);
2594 etl::rotate(first, middle, cut2);
2597 etl::advance(first, run);
2610 template <
typename TB
idirectionalIterator>
2611 void inplace_merge(TBidirectionalIterator first, TBidirectionalIterator middle, TBidirectionalIterator last)
2635 template <
typename TInputIterator,
typename TOutputIterator>
2637 typename etl::enable_if< etl::is_random_iterator<TInputIterator>::value && etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>::type
2638 copy_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
2640 typedef typename iterator_traits<TInputIterator>::difference_type s_size_type;
2641 typedef typename iterator_traits<TOutputIterator>::difference_type d_size_type;
2644 typedef typename etl::common_type<s_size_type, d_size_type>::type min_size_type;
2646 typedef typename etl::largest_type<s_size_type, d_size_type>::type min_size_type;
2649 s_size_type s_size = etl::distance(i_begin, i_end);
2650 d_size_type d_size = etl::distance(o_begin, o_end);
2651 min_size_type min_size = etl::min<min_size_type>(s_size, d_size);
2653 return etl::copy(i_begin, i_begin + min_size, o_begin);
2667 template <
typename TInputIterator,
typename TOutputIterator>
2668 ETL_CONSTEXPR14
typename etl::enable_if< !etl::is_random_iterator<TInputIterator>::value || !etl::is_random_iterator<TOutputIterator>::value,
2670 copy_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
2672 while ((i_begin != i_end) && (o_begin != o_end))
2674 *o_begin = *i_begin;
2687 template <
typename TInputIterator,
typename TSize,
typename TOutputIterator>
2688 ETL_CONSTEXPR14 TOutputIterator
copy_n_s(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TOutputIterator o_end)
2690 while ((n-- > 0) && (o_begin != o_end))
2692 *o_begin = *i_begin;
2705 template <
typename TInputIterator,
typename TSize1,
typename TOutputIterator,
typename TSize2>
2706 ETL_CONSTEXPR14 TOutputIterator
copy_n_s(TInputIterator i_begin, TSize1 n1, TOutputIterator o_begin, TSize2 n2)
2708 while ((n1-- > 0) && (n2-- > 0))
2710 *o_begin = *i_begin;
2724 template <
typename TInputIterator,
typename TOutputIterator,
typename TUnaryPredicate>
2725 ETL_CONSTEXPR14 TOutputIterator
copy_if_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end,
2726 TUnaryPredicate predicate)
2728 while ((i_begin != i_end) && (o_begin != o_end))
2730 if (predicate(*i_begin))
2732 *o_begin = *i_begin;
2747 template <
typename TInputIterator,
typename TSize,
typename TOutputIterator,
typename TUnaryPredicate>
2748 ETL_CONSTEXPR14 TOutputIterator
copy_n_if(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryPredicate predicate)
2752 if (predicate(*i_begin))
2754 *o_begin = *i_begin;
2776 template <
typename TInputIterator,
typename TOutputIterator>
2778 typename etl::enable_if< etl::is_random_iterator<TInputIterator>::value && etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>
::type
2779 move_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
2781 using s_size_type =
typename iterator_traits<TInputIterator>::difference_type;
2782 using d_size_type =
typename iterator_traits<TOutputIterator>::difference_type;
2783 using min_size_type =
typename etl::common_type<s_size_type, d_size_type>::type;
2785 s_size_type s_size = etl::distance(i_begin, i_end);
2786 d_size_type d_size = etl::distance(o_begin, o_end);
2787 min_size_type min_size = etl::min<min_size_type>(s_size, d_size);
2789 return etl::move(i_begin, i_begin + min_size, o_begin);
2803 template <
typename TInputIterator,
typename TOutputIterator>
2804 ETL_CONSTEXPR14
typename etl::enable_if< !etl::is_random_iterator<TInputIterator>::value || !etl::is_random_iterator<TOutputIterator>::value,
2805 TOutputIterator>::type
2806 move_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
2808 while ((i_begin != i_end) && (o_begin != o_end))
2810 *o_begin = etl::move(*i_begin);
2830 template <
typename TInputIterator,
typename TOutputIterator>
2831 TOutputIterator
move_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
2834 return etl::copy_s(i_begin, i_end, o_begin, o_end);
2844 template <
typename TIterator,
typename TValue>
2847 TIterator it = etl::lower_bound(
begin,
end, value);
2849 if ((it ==
end) || (*it != value))
2863 template <
typename TIterator,
typename TValue,
typename TBinaryPredicate,
typename TBinaryEquality>
2864 ETL_NODISCARD ETL_CONSTEXPR14 TIterator
binary_find(TIterator
begin, TIterator
end,
const TValue& value, TBinaryPredicate predicate, TBinaryEquality equality)
2866 TIterator it = etl::lower_bound(
begin,
end, value, predicate);
2868 if ((it ==
end) || !equality(*it, value))
2880 template <
typename TIterator,
typename TUnaryFunction,
typename TUnaryPredicate>
2885 if (predicate(*
begin))
2900 template <
typename TIterator,
typename TSize,
typename TUnaryFunction>
2917 template <
typename TIterator,
typename TSize,
typename TUnaryFunction,
typename TUnaryPredicate>
2922 if (predicate(*
begin))
2939 template <
typename TInputIterator,
typename TOutputIterator,
typename TUnaryFunction>
2940 ETL_CONSTEXPR14 TOutputIterator
transform_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end,
2943 while ((i_begin != i_end) && (o_begin != o_end))
2959 template <
typename TInputIterator,
typename TSize,
typename TOutputIterator,
typename TUnaryFunction>
2960 ETL_CONSTEXPR14
void transform_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryFunction
function)
2962 TInputIterator i_end(i_begin);
2963 etl::advance(i_end, n);
2965 etl::transform(i_begin, i_end, o_begin,
function);
2974 template <
typename TInputIterator1,
typename TInputIterator2,
typename TSize,
typename TOutputIterator,
typename TBinaryFunction>
2975 ETL_CONSTEXPR14
void transform_n(TInputIterator1 i_begin1, TInputIterator2 i_begin2, TSize n, TOutputIterator o_begin, TBinaryFunction
function)
2977 TInputIterator1 i_end1(i_begin1);
2978 etl::advance(i_end1, n);
2980 etl::transform(i_begin1, i_end1, i_begin2, o_begin,
function);
2987 template <
typename TInputIterator,
typename TOutputIterator,
typename TUnaryFunction,
typename TUnaryPredicate>
2988 ETL_CONSTEXPR14 TOutputIterator
transform_if(TInputIterator i_begin,
const TInputIterator i_end, TOutputIterator o_begin, TUnaryFunction
function,
2989 TUnaryPredicate predicate)
2991 while (i_begin != i_end)
2993 if (predicate(*i_begin))
3009 template <
typename TInputIterator1,
typename TInputIterator2,
typename TOutputIterator,
typename TBinaryFunction,
typename TBinaryPredicate>
3010 ETL_CONSTEXPR14 TOutputIterator
transform_if(TInputIterator1 i_begin1,
const TInputIterator1 i_end1, TInputIterator2 i_begin2, TOutputIterator o_begin,
3011 TBinaryFunction
function, TBinaryPredicate predicate)
3013 while (i_begin1 != i_end1)
3015 if (predicate(*i_begin1, *i_begin2))
3017 *o_begin =
function(*i_begin1, *i_begin2);
3032 template <
typename TInputIterator,
typename TSize,
typename TOutputIterator,
typename TUnaryFunction,
typename TUnaryPredicate>
3033 ETL_CONSTEXPR14 TOutputIterator
transform_n_if(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryFunction
function,
3034 TUnaryPredicate predicate)
3038 if (predicate(*i_begin))
3054 template <
typename TInputIterator1,
typename TInputIterator2,
typename TSize,
typename TOutputIterator,
typename TBinaryFunction,
3055 typename TBinaryPredicate>
3056 ETL_CONSTEXPR14 TOutputIterator
transform_n_if(TInputIterator1 i_begin1, TInputIterator2 i_begin2, TSize n, TOutputIterator o_begin,
3057 TBinaryFunction
function, TBinaryPredicate predicate)
3061 if (predicate(*i_begin1, *i_begin2))
3063 *o_begin++ =
function(*i_begin1, *i_begin2);
3078 template <
typename TSource,
typename TDestinationTrue,
typename TDestinationFalse,
typename TUnaryFunctionTrue,
typename TUnaryFunctionFalse,
3079 typename TUnaryPredicate>
3080 ETL_CONSTEXPR14 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>
3082 TUnaryFunctionTrue function_true, TUnaryFunctionFalse function_false, TUnaryPredicate predicate)
3086 if (predicate(*
begin))
3088 *destination_true = function_true(*
begin);
3093 *destination_false = function_false(*
begin);
3094 ++destination_false;
3100 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
3108 template <
typename TSource1,
typename TSource2,
typename TDestinationTrue,
typename TDestinationFalse,
typename TBinaryFunctionTrue,
3109 typename TBinaryFunctionFalse,
typename TBinaryPredicate>
3110 ETL_CONSTEXPR14 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>
3111 partition_transform(TSource1 begin1, TSource1 end1, TSource2 begin2, TDestinationTrue destination_true, TDestinationFalse destination_false,
3112 TBinaryFunctionTrue function_true, TBinaryFunctionFalse function_false, TBinaryPredicate predicate)
3114 while (begin1 != end1)
3116 if (predicate(*begin1, *begin2))
3118 *destination_true = function_true(*begin1, *begin2);
3123 *destination_false = function_false(*begin1, *begin2);
3124 ++destination_false;
3131 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
3139 template <
typename TIterator,
typename TCompare>
3140#if ETL_USING_STD_NAMESPACE
3153 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
3155 difference_t n = etl::distance(first, last);
3157 for (difference_t i = n / 2; i > 0; i /= 2)
3159 for (difference_t j = i; j < n; ++j)
3161 for (difference_t k = j - i; k >= 0; k -= i)
3163 TIterator itr1 = first;
3164 TIterator itr2 = first;
3166 etl::advance(itr1, k);
3167 etl::advance(itr2, k + i);
3171 etl::iter_swap(itr1, itr2);
3182 template <
typename TIterator>
3183#if ETL_USING_STD_NAMESPACE
3199 template <
typename TIterator,
typename TCompare>
3202 for (TIterator itr = first; itr != last; ++itr)
3204 etl::rotate(etl::upper_bound(first, itr, *itr,
compare), itr, etl::next(itr));
3212 template <
typename TIterator>
3219 namespace private_algorithm
3221 template <
typename TIterator>
3222 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_forward_iterator<TIterator>::value, TIterator>
::type get_before_last(TIterator first_, TIterator last_)
3224 TIterator last = first_;
3225 TIterator lastplus1 = first_;
3228 while (lastplus1 != last_)
3237 template <
typename TIterator>
3238 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_bidirectional_iterator<TIterator>::value, TIterator>::type get_before_last(TIterator ,
3241 TIterator last = last_;
3247 template <
typename TIterator>
3248 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_random_access_iterator<TIterator>::value, TIterator>::type get_before_last(TIterator ,
3260 template <
typename TIterator,
typename TCompare>
3269 const TIterator ilast = private_algorithm::get_before_last(first, last);
3270 const TIterator jlast = last;
3272 for (TIterator i = first; i != ilast; ++i)
3279 for (; j != jlast; ++j)
3287 using ETL_OR_STD::swap;
3299 template <
typename TIterator>
3310 template <
typename TIterator,
typename TCompare>
3313 etl::make_heap(first, last,
compare);
3314 etl::sort_heap(first, last,
compare);
3321 template <
typename TIterator>
3322 ETL_CONSTEXPR14
void heap_sort(TIterator first, TIterator last)
3324 etl::make_heap(first, last);
3325 etl::sort_heap(first, last);
3332 template <
typename T>
3334 constexpr const T& multimax(
const T& a,
const T& b)
3336 return a < b ? b : a;
3339 template <
typename T,
typename... Tx>
3341 constexpr const T& multimax(
const T& t,
const Tx&... tx)
3343 return multimax(t, multimax(tx...));
3352 template <
typename TCompare,
typename T>
3354 constexpr const T& multimax_compare(TCompare
compare,
const T& a,
const T& b)
3359 template <
typename TCompare,
typename T,
typename... Tx>
3361 constexpr const T& multimax_compare(TCompare
compare,
const T& t,
const Tx&... tx)
3363 return multimax_compare(
compare, t, multimax_compare(
compare, tx...));
3371 template <
typename T>
3373 constexpr const T& multimin(
const T& a,
const T& b)
3375 return a < b ? a : b;
3378 template <
typename T,
typename... Tx>
3380 constexpr const T& multimin(
const T& t,
const Tx&... tx)
3382 return multimin(t, multimin(tx...));
3391 template <
typename TCompare,
typename T>
3393 constexpr const T& multimin_compare(TCompare
compare,
const T& a,
const T& b)
3398 template <
typename TCompare,
typename T,
typename... Tx>
3400 constexpr const T& multimin_compare(TCompare
compare,
const T& t,
const Tx&... tx)
3402 return multimin_compare(
compare, t, multimin_compare(
compare, tx...));
3410 template <
typename TIterator>
3412 constexpr const TIterator& multimax_iter(
const TIterator& a,
const TIterator& b)
3414 return *a < *b ? b : a;
3417 template <
typename TIterator,
typename... TIteratorx>
3419 constexpr const TIterator& multimax_iter(
const TIterator& t,
const TIteratorx&... tx)
3421 return multimax_iter(t, multimax_iter(tx...));
3430 template <
typename TCompare,
typename TIterator>
3432 constexpr const TIterator& multimax_iter_compare(TCompare
compare,
const TIterator& a,
const TIterator& b)
3434 return compare(*a, *b) ? b : a;
3437 template <
typename TCompare,
typename TIterator,
typename... TIteratorx>
3439 constexpr const TIterator& multimax_iter_compare(TCompare
compare,
const TIterator& t,
const TIteratorx&... tx)
3441 return multimax_iter_compare(
compare, t, multimax_iter_compare(
compare, tx...));
3449 template <
typename TIterator>
3451 constexpr const TIterator& multimin_iter(
const TIterator& a,
const TIterator& b)
3453 return *a < *b ? a : b;
3456 template <
typename TIterator,
typename... Tx>
3458 constexpr const TIterator& multimin_iter(
const TIterator& t,
const Tx&... tx)
3460 return multimin_iter(t, multimin_iter(tx...));
3469 template <
typename TCompare,
typename TIterator>
3471 constexpr const TIterator& multimin_iter_compare(TCompare
compare,
const TIterator& a,
const TIterator& b)
3473 return compare(*a, *b) ? a : b;
3476 template <
typename TCompare,
typename TIterator,
typename... Tx>
3478 constexpr const TIterator& multimin_iter_compare(TCompare
compare,
const TIterator& t,
const Tx&... tx)
3480 return multimin_iter_compare(
compare, t, multimin_iter_compare(
compare, tx...));
3489 template <
typename TIterator,
typename TPredicate>
3490 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_forward_iterator<TIterator>::value, TIterator>
::type partition(TIterator first, TIterator last,
3491 TPredicate predicate)
3500 for (TIterator i = etl::next(first); i != last; ++i)
3504 using ETL_OR_STD::swap;
3518 template <
typename TIterator,
typename TPredicate>
3519 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_bidirectional_iterator_concept<TIterator>::value, TIterator>
::type
3520 partition(TIterator first, TIterator last, TPredicate predicate)
3522 while (first != last)
3539 using ETL_OR_STD::swap;
3540 swap(*first, *last);
3548 namespace private_algorithm
3550 using ETL_OR_STD::swap;
3552 template <
typename TIterator,
typename TCompare>
3553#if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST))
3557 nth_partition(TIterator first, TIterator last, TCompare compare)
3559 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
3561 value_type pivot_value = ETL_MOVE(*last);
3563 TIterator i = first;
3565 for (TIterator j = first; j < last; ++j)
3567 if (!compare(pivot_value, *j))
3586 template <typename TIterator, typename TCompare = etl::less<typename etl::iterator_traits<TIterator>::value_type>>
3587 #if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST))
3590 typename etl::enable_if< etl::is_random_access_iterator_concept<TIterator>::value,
void>::type
3591 nth_element(TIterator first, TIterator nth, TIterator last, TCompare
compare = TCompare())
3601 while (first <= last)
3603 TIterator p = private_algorithm::nth_partition(first, last,
compare);
3623 template <
typename TIterator,
typename TCompare>
3624 typename etl::enable_if< etl::is_random_access_iterator_concept<TIterator>::value,
void>
::type nth_element(TIterator first, TIterator nth,
3625 TIterator last, TCompare
compare)
3635 while (first <= last)
3637 TIterator p = private_algorithm::nth_partition(first, last,
compare);
3655 template <
typename TIterator>
3656 typename etl::enable_if< etl::is_random_access_iterator_concept<TIterator>::value,
void>
::type nth_element(TIterator first, TIterator nth,
3669 template <
class I,
class F>
3670 struct in_fun_result
3672 ETL_NO_UNIQUE_ADDRESS I in;
3673 ETL_NO_UNIQUE_ADDRESS F fun;
3675 template <
class I2,
class F2>
3676 constexpr operator in_fun_result<I2, F2>() const&
3681 template <
class I2,
class F2>
3682 constexpr operator in_fun_result<I2, F2>() &&
3684 return {etl::move(in), etl::move(fun)};
3688 template <
class I1,
class I2>
3691 ETL_NO_UNIQUE_ADDRESS I1 in1;
3692 ETL_NO_UNIQUE_ADDRESS I2 in2;
3694 template <
class II1,
class II2>
3695 constexpr operator in_in_result<II1, II2>() const&
3700 template <
class II1,
class II2>
3701 constexpr operator in_in_result<II1, II2>() &&
3703 return {etl::move(in1), etl::move(in2)};
3707 template <
class I,
class O>
3708 struct in_out_result
3710 ETL_NO_UNIQUE_ADDRESS I in;
3711 ETL_NO_UNIQUE_ADDRESS O out;
3713 template <
class I2,
class O2>
3714 constexpr operator in_out_result<I2, O2>() const&
3719 template <
class I2,
class O2>
3720 constexpr operator in_out_result<I2, O2>() &&
3722 return {etl::move(in), etl::move(out)};
3726 template <
class I1,
class I2,
class O>
3727 struct in_in_out_result
3729 ETL_NO_UNIQUE_ADDRESS I1 in1;
3730 ETL_NO_UNIQUE_ADDRESS I2 in2;
3731 ETL_NO_UNIQUE_ADDRESS O out;
3733 template <
class II1,
class II2,
class OO>
3734 constexpr operator in_in_out_result<II1, II2, OO>() const&
3736 return {in1, in2, out};
3739 template <
class II1,
class II2,
class OO>
3740 constexpr operator in_in_out_result<II1, II2, OO>() &&
3742 return {etl::move(in1), etl::move(in2), etl::move(out)};
3746 template <
class I,
class O1,
class O2>
3747 struct in_out_out_result
3749 ETL_NO_UNIQUE_ADDRESS I in;
3750 ETL_NO_UNIQUE_ADDRESS O1 out1;
3751 ETL_NO_UNIQUE_ADDRESS O2 out2;
3753 template <
class II,
class OO1,
class OO2>
3754 constexpr operator in_out_out_result<II, OO1, OO2>() const&
3756 return {in, out1, out2};
3759 template <
class II,
class OO1,
class OO2>
3760 constexpr operator in_out_out_result<II, OO1, OO2>() &&
3762 return {etl::move(in), etl::move(out1), etl::move(out2)};
3767 struct in_found_result
3769 ETL_NO_UNIQUE_ADDRESS I in;
3773 constexpr operator in_found_result<I2>() const&
3779 constexpr operator in_found_result<I2>() &&
3781 return {etl::move(in), found};
3785 template <
class O,
class T>
3786 struct out_value_result
3788 ETL_NO_UNIQUE_ADDRESS O out;
3789 ETL_NO_UNIQUE_ADDRESS T value;
3791 template <
class O2,
class T2>
3792 constexpr operator out_value_result<O2, T2>() const&
3794 return {out, value};
3797 template <
class O2,
class T2>
3798 constexpr operator out_value_result<O2, T2>() &&
3800 return {etl::move(out), etl::move(value)};
3804 template <
class O,
class T>
3805 using iota_result = out_value_result<O, T>;
3807 template <
class I,
class O>
3808 using copy_result = in_out_result<I, O>;
3810 template <
class I,
class O>
3811 using copy_n_result = in_out_result<I, O>;
3813 template <
class I,
class O>
3814 using copy_if_result = in_out_result<I, O>;
3816 template <
class I,
class O>
3817 using copy_backward_result = in_out_result<I, O>;
3819 template <
class I,
class O>
3820 using uninitialized_copy_result = in_out_result<I, O>;
3822 template <
class I,
class O>
3823 using uninitialized_copy_n_result = in_out_result<I, O>;
3825 template <
class I,
class O>
3826 using uninitialized_move_result = in_out_result<I, O>;
3828 template <
class I,
class O>
3829 using uninitialized_move_n_result = in_out_result<I, O>;
3831 template <
class I,
class O>
3832 using move_result = in_out_result<I, O>;
3834 template <
class I,
class O>
3835 using move_backward_result = in_out_result<I, O>;
3837 template <
class I1,
class I2>
3838 using mismatch_result = in_in_result<I1, I2>;
3840 template <
class I1,
class I2>
3841 using swap_ranges_result = in_in_result<I1, I2>;
3843 template <
class I,
class O>
3844 using unary_transform_result = in_out_result<I, O>;
3846 template <
class I1,
class I2,
class O>
3847 using binary_transform_result = in_in_out_result<I1, I2, O>;
3849 template <
class I,
class O>
3850 using replace_copy_result = in_out_result<I, O>;
3852 template <
class I,
class O>
3853 using replace_copy_if_result = in_out_result<I, O>;
3855 template <
class I,
class O>
3856 using remove_copy_result = in_out_result<I, O>;
3858 template <
class I,
class O>
3859 using unique_copy_result = in_out_result<I, O>;
3861 template <
class I,
class O>
3862 using rotate_copy_result = in_out_result<I, O>;
3864 template <
class I,
class O>
3865 using partial_sort_copy_result = in_out_result<I, O>;
3867 template <
class I,
class O1,
class O2>
3868 using partition_copy_result = in_out_out_result<I, O1, O2>;
3870 template <
class I1,
class I2,
class O>
3871 using set_union_result = in_in_out_result<I1, I2, O>;
3873 template <
class I1,
class I2,
class O>
3874 using set_intersection_result = in_in_out_result<I1, I2, O>;
3876 template <
class I,
class O>
3877 using set_difference_result = in_out_result<I, O>;
3879 template <
class I1,
class I2,
class O>
3880 using set_symmetric_difference_result = in_in_out_result<I1, I2, O>;
3882 template <
class I1,
class I2,
class O>
3883 using merge_result = in_in_out_result<I1, I2, O>;
3886 using next_permutation_result = in_found_result<I>;
3889 using prev_permutation_result = in_found_result<I>;
3892 struct min_max_result
3898 constexpr operator min_max_result<T2>() const&
3904 constexpr operator min_max_result<T2>() &&
3906 return {etl::move(min), etl::move(max)};
3911 using minmax_result = min_max_result<T>;
3914 using minmax_element_result = min_max_result<I>;
3916 template <
class I,
class F>
3917 using for_each_result = in_fun_result<I, F>;
3921 template <
class I,
class S,
class Fun,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
3922 constexpr ranges::for_each_result<I, Fun> operator()(I first, S last, Fun f, Proj proj = {})
const
3924 for (; first != last; ++first)
3926 etl::invoke(f, etl::invoke(proj, *first));
3928 return {etl::move(first), etl::move(f)};
3931 template <
class R,
class Fun,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
3932 constexpr ranges::for_each_result<ranges::borrowed_iterator_t<R>, Fun> operator()(R&& r, Fun f, Proj proj = {})
const
3934 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(f), etl::ref(proj));
3938 inline constexpr for_each_fn for_each;
3940 template <
class I,
class F>
3941 using for_each_n_result = in_fun_result<I, F>;
3943 struct for_each_n_fn
3945 template <
class I,
class Fun,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
3946 constexpr for_each_n_result<I, Fun> operator()(I first, etl::iter_difference_t<I> n, Fun fun, Proj proj = Proj{})
const
3948 for (; n-- > 0; ++first)
3950 etl::invoke(fun, etl::invoke(proj, *first));
3952 return {etl::move(first), etl::move(fun)};
3960 template <
class I,
class S,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
3961 constexpr I operator()(I first, S last,
const T& value, Proj proj = {})
const
3963 for (; first != last; ++first)
3965 if (etl::invoke(proj, *first) == value)
3973 template <
class R,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
3974 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r,
const T& value, Proj proj = {})
const
3976 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::ref(proj));
3980 inline constexpr find_fn find;
3984 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
3985 constexpr I operator()(I first, S last, Pred pred, Proj proj = {})
const
3987 for (; first != last; ++first)
3989 if (etl::invoke(pred, etl::invoke(proj, *first)))
3997 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
3998 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
4000 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4004 inline constexpr find_if_fn find_if;
4006 struct find_if_not_fn
4008 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4009 constexpr I operator()(I first, S last, Pred pred, Proj proj = {})
const
4011 for (; first != last; ++first)
4013 if (!etl::invoke(pred, etl::invoke(proj, *first)))
4021 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4022 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
4024 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4032 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4033 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4034 constexpr ranges::subrange<I1> operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4039 for (I2 it2 = first2;; ++it1, ++it2)
4043 return {first1, it1};
4049 if (!etl::invoke(pred, etl::invoke(proj1, *it1), etl::invoke(proj2, *it2)))
4057 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4058 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4059 constexpr ranges::borrowed_subrange_t<R1> operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4061 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4065 inline constexpr search_fn search{};
4069 template <
class I,
class S,
class T = etl::iter_value_t<I>,
class Pred = ranges::equal_to,
class Proj = etl::
identity,
4070 typename = etl::enable_if_t<!etl::is_range_v<I>>>
4071 constexpr ranges::subrange<I> operator()(I first, S last, etl::iter_difference_t<I> count,
const T& value, Pred pred = {}, Proj proj = {})
const
4075 return {first, first};
4078 for (; first != last; ++first)
4080 if (etl::invoke(pred, etl::invoke(proj, *first), value))
4083 etl::iter_difference_t<I> n = 1;
4089 return {start, ++first};
4094 return {first, first};
4096 if (!etl::invoke(pred, etl::invoke(proj, *first), value))
4104 return {first, first};
4107 template <
class R,
class T = etl::ranges::range_value_t<R>,
class Pred = ranges::equal_to,
class Proj = etl::
identity,
4108 typename = etl::enable_if_t<etl::is_range_v<R>>>
4109 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, ranges::range_difference_t<R> count,
const T& value, Pred pred = {},
4110 Proj proj = {})
const
4112 return (*
this)(ranges::begin(r), ranges::end(r), count, value, etl::move(pred), etl::move(proj));
4116 inline constexpr search_n_fn search_n{};
4120 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4121 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4122 constexpr ranges::subrange<I1> operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4124 if (first2 == last2)
4126 auto last_it = ranges::next(first1, last1);
4127 return {last_it, last_it};
4129 auto result = ranges::search(etl::move(first1), last1, first2, last2, pred, proj1, proj2);
4138 auto new_result = ranges::search(etl::next(result.begin()), last1, first2, last2, pred, proj1, proj2);
4139 if (new_result.empty())
4145 result = etl::move(new_result);
4150 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4151 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4152 constexpr ranges::borrowed_subrange_t<R1> operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4154 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4158 inline constexpr find_end_fn find_end{};
4160 struct find_first_of_fn
4162 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4163 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4164 constexpr I1 operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4166 for (; first1 != last1; ++first1)
4168 for (
auto i = first2; i != last2; ++i)
4170 if (etl::invoke(pred, etl::invoke(proj1, *first1), etl::invoke(proj2, *i)))
4179 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4180 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4181 constexpr ranges::borrowed_iterator_t<R1> operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4183 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4189 struct adjacent_find_fn
4191 template <
class I,
class S,
class Proj = etl::
identity,
class Pred = ranges::equal_to,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4192 constexpr I operator()(I first, S last, Pred pred = {}, Proj proj = {})
const
4198 auto next_it = ranges::next(first);
4199 for (; next_it != last; ++next_it, ++first)
4201 if (etl::invoke(pred, etl::invoke(proj, *first), etl::invoke(proj, *next_it)))
4209 template <
class R,
class Proj = etl::
identity,
class Pred = ranges::equal_to,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4210 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Pred pred = {}, Proj proj = {})
const
4212 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4220 template <
class I,
class S,
class Proj = etl::
identity,
class T = etl::projected_value_t<I, Proj>,
4221 typename = etl::enable_if_t<!etl::is_range_v<I>>>
4222 constexpr etl::iter_difference_t<I> operator()(I first, S last,
const T& value, Proj proj = {})
const
4224 etl::iter_difference_t<I> counter = 0;
4225 for (; first != last; ++first)
4227 if (etl::invoke(proj, *first) == value)
4235 template <
class R,
class Proj = etl::
identity,
class T = etl::projected_value_t<ranges::iterator_t<R>, Proj>,
4236 typename = etl::enable_if_t<etl::is_range_v<R>>>
4237 constexpr ranges::range_difference_t<R> operator()(R&& r,
const T& value, Proj proj = {})
const
4239 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::ref(proj));
4243 inline constexpr count_fn count;
4247 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4248 constexpr etl::iter_difference_t<I> operator()(I first, S last, Pred pred, Proj proj = {})
const
4250 etl::iter_difference_t<I> counter = 0;
4251 for (; first != last; ++first)
4253 if (etl::invoke(pred, etl::invoke(proj, *first)))
4261 template <
class R,
class Proj = etl::
identity,
class Pred,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4262 constexpr ranges::range_difference_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
4264 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4268 inline constexpr count_if_fn count_if;
4272 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4273 constexpr bool operator()(I first, S last, Pred pred, Proj proj = {})
const
4275 return ranges::find_if_not(first, last, etl::ref(pred), etl::ref(proj)) == last;
4278 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4279 constexpr bool operator()(R&& r, Pred pred, Proj proj = {})
const
4281 return operator()(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4285 inline constexpr all_of_fn
all_of;
4289 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4290 constexpr bool operator()(I first, S last, Pred pred, Proj proj = {})
const
4292 return ranges::find_if(first, last, etl::ref(pred), etl::ref(proj)) != last;
4295 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4296 constexpr bool operator()(R&& r, Pred pred, Proj proj = {})
const
4298 return operator()(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4302 inline constexpr any_of_fn
any_of;
4306 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4307 constexpr bool operator()(I first, S last, Pred pred, Proj proj = {})
const
4309 return ranges::find_if(first, last, etl::ref(pred), etl::ref(proj)) == last;
4312 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4313 constexpr bool operator()(R&& r, Pred pred, Proj proj = {})
const
4315 return operator()(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4319 inline constexpr none_of_fn
none_of;
4323 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4324 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4325 constexpr ranges::mismatch_result<I1, I2> operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {},
4326 Proj2 proj2 = {})
const
4328 for (; first1 != last1 && first2 != last2; ++first1, ++first2)
4330 if (!etl::invoke(pred, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
4335 return {etl::move(first1), etl::move(first2)};
4338 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4339 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4340 constexpr ranges::mismatch_result<ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>>
4341 operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4343 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4347 inline constexpr mismatch_fn mismatch{};
4351 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4352 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4353 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4355 for (; first1 != last1 && first2 != last2; ++first1, ++first2)
4357 if (!etl::invoke(pred, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
4362 return first1 == last1 && first2 == last2;
4365 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4366 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4367 constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4369 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4373 inline constexpr equal_fn equal{};
4375 struct is_permutation_fn
4377 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4378 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4379 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4382 for (; first1 != last1 && first2 != last2; ++first1, ++first2)
4384 if (!etl::invoke(pred, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
4390 if (first1 == last1)
4392 return first2 == last2;
4395 if (first2 == last2)
4401 for (I1 i = first1; i != last1; ++i)
4404 bool already_seen =
false;
4405 for (I1 j = first1; j != i; ++j)
4407 if (etl::invoke(pred, etl::invoke(proj1, *i), etl::invoke(proj1, *j)))
4409 already_seen =
true;
4420 auto count2 = etl::iter_difference_t<I2>(0);
4421 for (I2 k = first2; k != last2; ++k)
4423 if (etl::invoke(pred, etl::invoke(proj1, *i), etl::invoke(proj2, *k)))
4435 auto count1 = etl::iter_difference_t<I1>(0);
4436 for (I1 k = i; k != last1; ++k)
4438 if (etl::invoke(pred, etl::invoke(proj1, *i), etl::invoke(proj1, *k)))
4444 if (count1 != count2)
4453 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4454 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4455 constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4457 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4463 struct starts_with_fn
4465 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4466 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4467 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4469 for (; first2 != last2; ++first1, ++first2)
4471 if (first1 == last1 || !etl::invoke(pred, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
4479 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4480 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4481 constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4483 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4487 inline constexpr starts_with_fn starts_with{};
4491 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4492 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4493 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4495 auto n1 = etl::distance(first1, last1);
4496 auto n2 = etl::distance(first2, last2);
4503 ranges::advance(first1, n1 - n2);
4505 return starts_with(first1, last1, first2, last2, etl::move(pred), etl::move(proj1), etl::move(proj2));
4508 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4509 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4510 constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4512 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4516 inline constexpr ends_with_fn ends_with{};
4518 struct lexicographical_compare_fn
4520 template <
class I1,
class S1,
class I2,
class S2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4521 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4522 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4524 for (; first1 != last1 && first2 != last2; ++first1, ++first2)
4526 if (etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
4531 if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
4536 return first1 == last1 && first2 != last2;
4539 template <
class R1,
class R2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4540 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4541 constexpr bool operator()(R1&& r1, R2&& r2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4543 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(comp), etl::move(proj1), etl::move(proj2));
4547 inline constexpr lexicographical_compare_fn lexicographical_compare{};
4549 template <
class I,
class T>
4550 struct in_value_result
4552 ETL_NO_UNIQUE_ADDRESS I in;
4553 ETL_NO_UNIQUE_ADDRESS T value;
4555 template <
class I2,
class T2>
4556 constexpr operator in_value_result<I2, T2>() const&
4561 template <
class I2,
class T2>
4562 constexpr operator in_value_result<I2, T2>() &&
4564 return {etl::move(in), etl::move(value)};
4568 template <
class I,
class T>
4569 using fold_left_with_iter_result = in_value_result<I, T>;
4573 template <
class I,
class S,
class T,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4574 constexpr auto operator()(I first, S last, T init, F f)
const -> etl::decay_t<etl::invoke_result_t<F&, T, etl::iter_reference_t<I>>>
4576 using U = etl::decay_t<etl::invoke_result_t<F&, T, etl::iter_reference_t<I>>>;
4577 U accum = etl::move(init);
4578 for (; first != last; ++first)
4580 accum = etl::invoke(f, etl::move(accum), *first);
4585 template <
class R,
class T,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4586 constexpr auto operator()(R&& r, T init, F f)
const -> etl::decay_t< etl::invoke_result_t<F&, T, etl::ranges::range_reference_t<R>>>
4588 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(init), etl::move(f));
4592 inline constexpr fold_left_fn fold_left{};
4594 struct fold_left_with_iter_fn
4596 template <
class I,
class S,
class T,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4597 constexpr auto operator()(I first, S last, T init,
4598 F f)
const -> fold_left_with_iter_result< I, etl::decay_t<etl::invoke_result_t<F&, T, etl::iter_reference_t<I>>>>
4600 using U = etl::decay_t<etl::invoke_result_t<F&, T, etl::iter_reference_t<I>>>;
4601 U accum = etl::move(init);
4602 for (; first != last; ++first)
4604 accum = etl::invoke(f, etl::move(accum), *first);
4606 return {etl::move(first), etl::move(accum)};
4609 template <
class R,
class T,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4610 constexpr auto operator()(R&& r, T init, F f)
const
4611 -> fold_left_with_iter_result< ranges::borrowed_iterator_t<R>, etl::decay_t< etl::invoke_result_t<F&, T, etl::ranges::range_reference_t<R>>>>
4613 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(init), etl::move(f));
4617 inline constexpr fold_left_with_iter_fn fold_left_with_iter{};
4619 struct fold_left_first_fn
4621 template <
class I,
class S,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4622 constexpr auto operator()(I first, S last, F f)
const -> etl::decay_t<etl::invoke_result_t<F&, etl::iter_value_t<I>, etl::iter_reference_t<I>>>
4624 using U = etl::decay_t<etl::invoke_result_t<F&, etl::iter_value_t<I>, etl::iter_reference_t<I>>>;
4631 for (; first != last; ++first)
4633 accum = etl::invoke(f, etl::move(accum), *first);
4638 template <
class R,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4639 constexpr auto operator()(R&& r,
4640 F f)
const -> etl::decay_t<etl::invoke_result_t<F&, etl::ranges::range_value_t<R>, etl::ranges::range_reference_t<R>>>
4642 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(f));
4646 inline constexpr fold_left_first_fn fold_left_first{};
4648 struct fold_left_first_with_iter_fn
4650 template <
class I,
class S,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4651 constexpr auto operator()(I first, S last, F f)
const
4652 -> fold_left_with_iter_result< I, etl::decay_t<etl::invoke_result_t<F&, etl::iter_value_t<I>, etl::iter_reference_t<I>>>>
4654 using U = etl::decay_t<etl::invoke_result_t<F&, etl::iter_value_t<I>, etl::iter_reference_t<I>>>;
4657 return {etl::move(first), U{}};
4661 for (; first != last; ++first)
4663 accum = etl::invoke(f, etl::move(accum), *first);
4665 return {etl::move(first), etl::move(accum)};
4668 template <
class R,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4669 constexpr auto operator()(R&& r, F f)
const
4670 -> fold_left_with_iter_result< ranges::borrowed_iterator_t<R>,
4671 etl::decay_t<etl::invoke_result_t<F&, etl::ranges::range_value_t<R>, etl::ranges::range_reference_t<R>>>>
4673 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(f));
4677 inline constexpr fold_left_first_with_iter_fn fold_left_first_with_iter{};
4679 struct fold_right_fn
4681 template <
class I,
class S,
class T,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4682 constexpr auto operator()(I first, S last, T init, F f)
const -> etl::decay_t<etl::invoke_result_t<F&, etl::iter_reference_t<I>, T>>
4684 using U = etl::decay_t<etl::invoke_result_t<F&, etl::iter_reference_t<I>, T>>;
4685 U accum = etl::move(init);
4686 I tail = ranges::next(first, last);
4687 while (tail != first)
4689 tail = ranges::prev(tail);
4690 accum = etl::invoke(f, *tail, etl::move(accum));
4695 template <
class R,
class T,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4696 constexpr auto operator()(R&& r, T init, F f)
const -> etl::decay_t< etl::invoke_result_t<F&, etl::ranges::range_reference_t<R>, T>>
4698 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(init), etl::move(f));
4702 inline constexpr fold_right_fn fold_right{};
4704 struct fold_right_last_fn
4706 template <
class I,
class S,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4707 constexpr auto operator()(I first, S last, F f)
const -> etl::decay_t<etl::invoke_result_t<F&, etl::iter_reference_t<I>, etl::iter_value_t<I>>>
4709 using U = etl::decay_t<etl::invoke_result_t<F&, etl::iter_reference_t<I>, etl::iter_value_t<I>>>;
4710 I tail = ranges::next(first, last);
4715 tail = ranges::prev(tail);
4717 while (tail != first)
4719 tail = ranges::prev(tail);
4720 accum = etl::invoke(f, *tail, etl::move(accum));
4725 template <
class R,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4727 operator()(R&& r, F f)
const -> etl::decay_t<etl::invoke_result_t< F&, etl::ranges::range_reference_t<R>, etl::ranges::range_value_t<R>>>
4729 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(f));
4733 inline constexpr fold_right_last_fn fold_right_last{};
4737 template <
class I,
class S,
class O,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4738 constexpr ranges::copy_result<I, O> operator()(I first, S last, O result)
const
4740 for (; first != last; ++first, ++result)
4744 return {etl::move(first), etl::move(result)};
4747 template <
class R,
class O,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4748 constexpr ranges::copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result)
const
4750 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result));
4754 inline constexpr copy_fn copy{};
4758 template <
class I,
class O>
4759 constexpr ranges::copy_n_result<I, O> operator()(I first, etl::iter_difference_t<I> n, O result)
const
4761 for (etl::iter_difference_t<I> i = 0; i < n; ++i, ++first, ++result)
4765 return {etl::move(first), etl::move(result)};
4769 inline constexpr copy_n_fn copy_n{};
4773 template <
class I,
class S,
class O,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4774 constexpr ranges::copy_if_result<I, O> operator()(I first, S last, O result, Pred pred, Proj proj = {})
const
4776 for (; first != last; ++first)
4778 if (etl::invoke(pred, etl::invoke(proj, *first)))
4784 return {etl::move(first), etl::move(result)};
4787 template <
class R,
class O,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4788 constexpr ranges::copy_if_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result, Pred pred, Proj proj = {})
const
4790 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), etl::ref(pred), etl::ref(proj));
4794 inline constexpr copy_if_fn
copy_if{};
4796 struct copy_backward_fn
4798 template <
class I1,
class S1,
class I2,
typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4799 constexpr ranges::copy_backward_result<I1, I2> operator()(I1 first, S1 last, I2 result)
const
4801 I1 last_it = ranges::next(first, last);
4803 while (first != tail)
4805 *(--result) = *(--tail);
4807 return {etl::move(last_it), etl::move(result)};
4810 template <
class R,
class I,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4811 constexpr ranges::copy_backward_result<ranges::borrowed_iterator_t<R>, I> operator()(R&& r, I result)
const
4813 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result));
4817 inline constexpr copy_backward_fn copy_backward{};
4821 template <
class I,
class S,
class O,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4822 constexpr ranges::move_result<I, O> operator()(I first, S last, O result)
const
4824 for (; first != last; ++first, ++result)
4826 *result = etl::move(*first);
4828 return {etl::move(first), etl::move(result)};
4831 template <
class R,
class O,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4832 constexpr ranges::move_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result)
const
4834 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result));
4838 inline constexpr move_fn move{};
4840 struct move_backward_fn
4842 template <
class I1,
class S1,
class I2,
typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4843 constexpr ranges::move_backward_result<I1, I2> operator()(I1 first, S1 last, I2 result)
const
4845 I1 last_it = ranges::next(first, last);
4847 while (first != tail)
4849 *(--result) = etl::move(*(--tail));
4851 return {etl::move(last_it), etl::move(result)};
4854 template <
class R,
class I,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4855 constexpr ranges::move_backward_result<ranges::borrowed_iterator_t<R>, I> operator()(R&& r, I result)
const
4857 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result));
4861 inline constexpr move_backward_fn move_backward{};
4863 struct swap_ranges_fn
4865 template <
class I1,
class S1,
class I2,
class S2,
typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4866 constexpr ranges::swap_ranges_result<I1, I2> operator()(I1 first1, S1 last1, I2 first2, S2 last2)
const
4868 for (; first1 != last1 && first2 != last2; ++first1, ++first2)
4870 etl::iter_swap(first1, first2);
4872 return {etl::move(first1), etl::move(first2)};
4875 template <
class R1,
class R2,
typename = etl::enable_if_t<etl::is_range_v<R1>>>
4876 constexpr ranges::swap_ranges_result<ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>> operator()(R1&& r1, R2&& r2)
const
4878 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2));
4882 inline constexpr swap_ranges_fn swap_ranges{};
4886 template <
class I,
class S,
class T1,
class T2,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4887 constexpr I operator()(I first, S last,
const T1& old_value,
const T2& new_value, Proj proj = {})
const
4889 for (; first != last; ++first)
4891 if (etl::invoke(proj, *first) == old_value)
4899 template <
class R,
class T1,
class T2,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4900 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r,
const T1& old_value,
const T2& new_value, Proj proj = {})
const
4902 return (*
this)(ranges::begin(r), ranges::end(r), old_value, new_value, etl::ref(proj));
4906 inline constexpr replace_fn replace{};
4908 struct replace_if_fn
4910 template <
class I,
class S,
class Pred,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4911 constexpr I operator()(I first, S last, Pred pred,
const T& new_value, Proj proj = {})
const
4913 for (; first != last; ++first)
4915 if (etl::invoke(pred, etl::invoke(proj, *first)))
4923 template <
class R,
class Pred,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4924 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Pred pred,
const T& new_value, Proj proj = {})
const
4926 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), new_value, etl::ref(proj));
4930 inline constexpr replace_if_fn replace_if{};
4932 struct replace_copy_fn
4934 template <
class I,
class S,
class O,
class T1,
class T2,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4935 constexpr ranges::replace_copy_result<I, O> operator()(I first, S last, O result,
const T1& old_value,
const T2& new_value,
4936 Proj proj = {})
const
4938 for (; first != last; ++first, ++result)
4940 if (etl::invoke(proj, *first) == old_value)
4942 *result = new_value;
4949 return {etl::move(first), etl::move(result)};
4952 template <
class R,
class O,
class T1,
class T2,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4953 constexpr ranges::replace_copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result,
const T1& old_value,
const T2& new_value,
4954 Proj proj = {})
const
4956 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), old_value, new_value, etl::ref(proj));
4960 inline constexpr replace_copy_fn replace_copy{};
4962 struct replace_copy_if_fn
4964 template <
class I,
class S,
class O,
class Pred,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4965 constexpr ranges::replace_copy_if_result<I, O> operator()(I first, S last, O result, Pred pred,
const T& new_value, Proj proj = {})
const
4967 for (; first != last; ++first, ++result)
4969 if (etl::invoke(pred, etl::invoke(proj, *first)))
4971 *result = new_value;
4978 return {etl::move(first), etl::move(result)};
4981 template <
class R,
class O,
class Pred,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4982 constexpr ranges::replace_copy_if_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result, Pred pred,
const T& new_value,
4983 Proj proj = {})
const
4985 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), etl::ref(pred), new_value, etl::ref(proj));
4989 inline constexpr replace_copy_if_fn replace_copy_if{};
4993 template <
class I,
class S,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4994 constexpr ranges::subrange<I> operator()(I first, S last,
const T& value, Proj proj = {})
const
4996 first = ranges::find(first, last, value, etl::ref(proj));
5002 for (I it = result; ++it != last;)
5004 if (!(etl::invoke(proj, *it) == value))
5006 *result = etl::move(*it);
5011 return {result, last};
5014 return {first, last};
5017 template <
class R,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5018 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r,
const T& value, Proj proj = {})
const
5020 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::ref(proj));
5024 inline constexpr remove_fn
remove{};
5028 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5029 constexpr ranges::subrange<I> operator()(I first, S last, Pred pred, Proj proj = {})
const
5031 first = ranges::find_if(first, last, etl::ref(pred), etl::ref(proj));
5037 for (I it = result; ++it != last;)
5039 if (!etl::invoke(pred, etl::invoke(proj, *it)))
5041 *result = etl::move(*it);
5046 return {result, last};
5049 return {first, last};
5052 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5053 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
5055 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
5059 inline constexpr remove_if_fn
remove_if{};
5061 struct remove_copy_fn
5063 template <
class I,
class S,
class O,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5064 constexpr ranges::remove_copy_result<I, O> operator()(I first, S last, O result,
const T& value, Proj proj = {})
const
5066 for (; first != last; ++first)
5068 if (!(etl::invoke(proj, *first) == value))
5074 return {etl::move(first), etl::move(result)};
5077 template <
class R,
class O,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5078 constexpr ranges::remove_copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result,
const T& value, Proj proj = {})
const
5080 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), value, etl::ref(proj));
5084 inline constexpr remove_copy_fn remove_copy{};
5088 template <
class I,
class S,
class T,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5089 constexpr I operator()(I first, S last,
const T& value)
const
5091 for (; first != last; ++first)
5098 template <
class R,
class T,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5099 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r,
const T& value)
const
5101 return (*
this)(ranges::begin(r), ranges::end(r), value);
5105 inline constexpr fill_fn fill{};
5109 template <
class I,
class T>
5110 constexpr I operator()(I first, etl::iter_difference_t<I> n,
const T& value)
const
5112 for (; n-- > 0; ++first)
5120 inline constexpr fill_n_fn fill_n{};
5124 template <
class I,
class S,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5125 constexpr I operator()(I first, S last, F gen)
const
5127 for (; first != last; ++first)
5134 template <
class R,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5135 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, F gen)
const
5137 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(gen));
5141 inline constexpr generate_fn generate{};
5143 struct generate_n_fn
5145 template <
class I,
class F>
5146 constexpr I operator()(I first, etl::iter_difference_t<I> n, F gen)
const
5148 for (; n-- > 0; ++first)
5156 inline constexpr generate_n_fn generate_n{};
5160 template <
class O,
class S,
class T,
typename = etl::enable_if_t<!etl::is_range_v<O>>>
5161 constexpr ranges::iota_result<O, T> operator()(O first, S last, T value)
const
5163 while (first != last)
5169 return {etl::move(first), etl::move(value)};
5172 template <
class R,
class T,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5173 constexpr ranges::iota_result<ranges::borrowed_iterator_t<R>, T> operator()(R&& r, T value)
const
5175 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(value));
5179 inline constexpr iota_fn
iota{};
5183 template <
class I,
class S,
class Pred = ranges::equal_to,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5184 constexpr ranges::subrange<I> operator()(I first, S last, Pred pred = {}, Proj proj = {})
const
5186 first = ranges::adjacent_find(first, last, etl::ref(pred), etl::ref(proj));
5193 while (++first != last)
5195 if (!etl::invoke(pred, etl::invoke(proj, *result), etl::invoke(proj, *first)))
5197 *++result = etl::move(*first);
5201 return {++result, last};
5204 return {first, last};
5207 template <
class R,
class Pred = ranges::equal_to,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5208 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred = {}, Proj proj = {})
const
5210 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
5214 inline constexpr unique_fn
unique{};
5216 struct unique_copy_fn
5218 template <
class I,
class S,
class O,
class Pred = ranges::equal_to,
class Proj = etl::identity,
5219 typename = etl::enable_if_t<!etl::is_range_v<I>>>
5220 constexpr ranges::unique_copy_result<I, O> operator()(I first, S last, O result, Pred pred = {}, Proj proj = {})
const
5227 auto previous = first;
5230 for (; first != last; ++first)
5232 if (!etl::invoke(pred, etl::invoke(proj, *previous), etl::invoke(proj, *first)))
5241 return {etl::move(first), etl::move(result)};
5244 template <
class R,
class O,
class Pred = ranges::equal_to,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5245 constexpr ranges::unique_copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result, Pred pred = {}, Proj proj = {})
const
5247 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), etl::ref(pred), etl::ref(proj));
5256 template <
class I,
class S,
class O,
class F,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5257 constexpr ranges::unary_transform_result<I, O> operator()(I first, S last, O result, F op, Proj proj = {})
const
5259 for (; first != last; ++first, ++result)
5261 *result = etl::invoke(op, etl::invoke(proj, *first));
5263 return {etl::move(first), etl::move(result)};
5267 template <
class R,
class O,
class F,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R> && !etl::is_range_v<O>>>
5268 constexpr ranges::unary_transform_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result, F op, Proj proj = {})
const
5270 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), etl::ref(op), etl::ref(proj));
5274 template <
class I1,
class S1,
class I2,
class S2,
class O,
class F,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
5275 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
5276 constexpr ranges::binary_transform_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, F op, Proj1 proj1 = {},
5277 Proj2 proj2 = {})
const
5279 for (; first1 != last1 && first2 != last2; ++first1, ++first2, ++result)
5281 *result = etl::invoke(op, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2));
5283 return {etl::move(first1), etl::move(first2), etl::move(result)};
5287 template <
class R1,
class R2,
class O,
class F,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
5288 typename = etl::enable_if_t<etl::is_range_v<R1> && etl::is_range_v<R2>>>
5289 constexpr ranges::binary_transform_result< ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O>
5290 operator()(R1&& r1, R2&& r2, O result, F op, Proj1 proj1 = {}, Proj2 proj2 = {})
const
5292 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::ref(op), etl::ref(proj1),
5297 inline constexpr transform_fn transform{};
5301 template <
class I,
class S,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5302 constexpr I operator()(I first, S last)
const
5304 I tail = ranges::next(first, last);
5307 for (; first != tail && first != --tail; ++first)
5309 etl::iter_swap(first, tail);
5315 template <
class R,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5316 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r)
const
5318 return (*
this)(ranges::begin(r), ranges::end(r));
5322 inline constexpr reverse_fn reverse{};
5324 template <
class I,
class O>
5325 using reverse_copy_result = in_out_result<I, O>;
5327 struct reverse_copy_fn
5329 template <
class I,
class S,
class O,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5330 constexpr ranges::reverse_copy_result<I, O> operator()(I first, S last, O result)
const
5332 I tail = ranges::next(first, last);
5335 while (tail != first)
5341 return {etl::move(end_it), etl::move(result)};
5344 template <
class R,
class O,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5345 constexpr ranges::reverse_copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result)
const
5347 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result));
5351 inline constexpr reverse_copy_fn reverse_copy{};
5354 using rotate_result = ranges::subrange<I>;
5358 template <
class I,
class S,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5359 constexpr ranges::rotate_result<I> operator()(I first, I middle, S last)
const
5361 if (first == middle)
5363 I last_it = ranges::next(first, last);
5364 return {last_it, last_it};
5367 I last_it = ranges::next(first, last);
5369 if (middle == last_it)
5371 return {first, last_it};
5374 I new_first = etl::rotate(first, middle, last_it);
5375 return {etl::move(new_first), etl::move(last_it)};
5378 template <
class R,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5379 constexpr ranges::rotate_result<ranges::borrowed_iterator_t<R>> operator()(R&& r, ranges::iterator_t<R> middle)
const
5381 return (*
this)(ranges::begin(r), etl::move(middle), ranges::end(r));
5385 inline constexpr rotate_fn rotate{};
5387 struct rotate_copy_fn
5389 template <
class I,
class S,
class O,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5390 constexpr ranges::rotate_copy_result<I, O> operator()(I first, I middle, S last, O result)
const
5392 I last_it = ranges::next(first, last);
5393 O end_out = etl::copy(middle, last_it, result);
5394 end_out = etl::copy(first, middle, end_out);
5395 return {etl::move(last_it), etl::move(end_out)};
5398 template <
class R,
class O,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5399 constexpr ranges::rotate_copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, ranges::iterator_t<R> middle, O result)
const
5401 return (*
this)(ranges::begin(r), etl::move(middle), ranges::end(r), etl::move(result));
5405 inline constexpr rotate_copy_fn rotate_copy{};
5407 struct shift_left_fn
5409 template <
class I,
class S,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5410 constexpr ranges::subrange<I> operator()(I first, S last, etl::iter_difference_t<I> n)
const
5412 I last_it = ranges::next(first, last);
5416 return {first, last_it};
5420 if (ranges::advance(mid, n, last_it) != 0)
5422 return {first, first};
5425 I result = ranges::move(mid, last_it, first).out;
5426 return {first, etl::move(result)};
5429 template <
class R,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5430 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, etl::ranges::range_difference_t<R> n)
const
5432 return (*
this)(ranges::begin(r), ranges::end(r), n);
5436 inline constexpr shift_left_fn shift_left{};
5438 struct shift_right_fn
5440 template <
class I,
class S,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5441 constexpr ranges::subrange<I> operator()(I first, S last, etl::iter_difference_t<I> n)
const
5443 I last_it = ranges::next(first, last);
5447 return {first, last_it};
5451 if (ranges::advance(trail, -n, first) != 0)
5453 return {last_it, last_it};
5456 I new_first = ranges::move_backward(first, trail, last_it).out;
5457 return {etl::move(new_first), etl::move(last_it)};
5460 template <
class R,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5461 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, etl::ranges::range_difference_t<R> n)
const
5463 return (*
this)(ranges::begin(r), ranges::end(r), n);
5467 inline constexpr shift_right_fn shift_right{};
5471 template <
class I,
class S,
class Gen,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5472 I operator()(I first, S last, Gen&& gen)
const
5474 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"shuffle requires random access iterators");
5476 using diff_t = etl::iter_difference_t<I>;
5477 using udiff_t = etl::make_unsigned_t<diff_t>;
5478 using gen_t = etl::remove_reference_t<Gen>;
5479 using uresult_t =
decltype(gen());
5481 I last_it = ranges::next(first, last);
5482 diff_t n = last_it - first;
5489 for (diff_t i = n - 1; i > 0; --i)
5493 udiff_t range =
static_cast<udiff_t
>(i);
5494 constexpr uresult_t gmin = gen_t::min();
5495 constexpr uresult_t gmax = gen_t::max();
5496 constexpr uresult_t grange = gmax - gmin;
5500 if ETL_IF_CONSTEXPR (grange ==
static_cast<uresult_t
>(-1))
5504 uresult_t limit = (
static_cast<uresult_t
>(-1) / (
static_cast<uresult_t
>(range) + 1)) * (
static_cast<uresult_t
>(range) + 1);
5506 j =
static_cast<uresult_t
>(gen() - gmin);
5507 }
while (j >= limit);
5508 j %= (
static_cast<uresult_t
>(range) + 1);
5512 uresult_t limit = (grange / (
static_cast<uresult_t
>(range) + 1)) * (
static_cast<uresult_t
>(range) + 1);
5514 j =
static_cast<uresult_t
>(gen() - gmin);
5515 }
while (j >= limit);
5516 j %= (
static_cast<uresult_t
>(range) + 1);
5519 etl::iter_swap(first + i, first +
static_cast<diff_t
>(j));
5525 template <
class R,
class Gen,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5526 ranges::borrowed_iterator_t<R> operator()(R&& r, Gen&& gen)
const
5528 ETL_STATIC_ASSERT(etl::is_random_access_iterator<ranges::iterator_t<R>>::value,
"shuffle requires a range with random access iterators");
5530 return (*
this)(ranges::begin(r), ranges::end(r),
static_cast<Gen&&
>(gen));
5534 inline constexpr shuffle_fn shuffle{};
5538 template <
class I,
class S,
class O,
class Gen,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5539 O operator()(I first, S last, O out, etl::iter_difference_t<I> n, Gen&& gen)
const
5541 using diff_t = etl::iter_difference_t<I>;
5542 using udiff_t = etl::make_unsigned_t<diff_t>;
5543 using gen_t = etl::remove_reference_t<Gen>;
5544 using uresult_t =
decltype(gen());
5552 I first_copy = first;
5553 diff_t pop_size = 0;
5554 for (I it = first_copy; it != last; ++it)
5562 for (; first != last; ++first, ++out)
5571 diff_t remaining = pop_size;
5574 for (; first != last && needed > 0; ++first, --remaining)
5577 udiff_t range =
static_cast<udiff_t
>(remaining - 1);
5578 constexpr uresult_t gmin = gen_t::min();
5579 constexpr uresult_t gmax = gen_t::max();
5580 constexpr uresult_t grange = gmax - gmin;
5584 if ETL_IF_CONSTEXPR (grange ==
static_cast<uresult_t
>(-1))
5592 uresult_t limit = (
static_cast<uresult_t
>(-1) / (
static_cast<uresult_t
>(range) + 1)) * (
static_cast<uresult_t
>(range) + 1);
5594 j =
static_cast<uresult_t
>(gen() - gmin);
5595 }
while (j >= limit);
5596 j %= (
static_cast<uresult_t
>(range) + 1);
5607 uresult_t limit = (grange / (
static_cast<uresult_t
>(range) + 1)) * (
static_cast<uresult_t
>(range) + 1);
5609 j =
static_cast<uresult_t
>(gen() - gmin);
5610 }
while (j >= limit);
5611 j %= (
static_cast<uresult_t
>(range) + 1);
5615 if (
static_cast<diff_t
>(j) < needed)
5626 template <
class R,
class O,
class Gen,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5627 O operator()(R&& r, O out, etl::ranges::range_difference_t<R> n, Gen&& gen)
const
5629 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(out), n,
static_cast<Gen&&
>(gen));
5633 inline constexpr sample_fn sample{};
5637 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5638 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
5640 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"sort requires random access iterators");
5642 I last_it = ranges::next(first, last);
5644 if (first == last_it)
5650 auto n = etl::distance(first, last_it);
5652 for (
auto gap = n / 2; gap > 0; gap /= 2)
5654 for (
auto i = gap; i < n; ++i)
5656 auto temp = etl::move(*(first + i));
5659 while (j >= gap && etl::invoke(comp, etl::invoke(proj, temp), etl::invoke(proj, *(first + (j - gap)))))
5661 *(first + j) = etl::move(*(first + (j - gap)));
5665 *(first + j) = etl::move(temp);
5672 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5673 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
5675 ETL_STATIC_ASSERT(etl::is_random_access_iterator<ranges::iterator_t<R>>::value,
"sort requires a range with random access iterators");
5677 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
5681 inline constexpr sort_fn
sort{};
5683 struct stable_sort_fn
5685 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5686 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
5688 I last_it = ranges::next(first, last);
5690 if (first == last_it)
5696 for (I i = ranges::next(first); i != last_it; ++i)
5698 auto temp = etl::move(*i);
5703 I prev_j = ranges::prev(j);
5704 if (etl::invoke(comp, etl::invoke(proj, temp), etl::invoke(proj, *prev_j)))
5706 *j = etl::move(*prev_j);
5715 *j = etl::move(temp);
5721 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5722 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
5724 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
5730 struct partial_sort_fn
5732 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5733 constexpr I operator()(I first, I middle, S last, Comp comp = {}, Proj proj = {})
const
5735 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"partial_sort requires random access iterators");
5737 I last_it = ranges::next(first, last);
5739 if (first == middle || first == last_it)
5745 auto heap_size = etl::distance(first, middle);
5748 for (
auto start = (heap_size - 1) / 2; start >= 0; --start)
5750 sift_down(first, start, heap_size, comp, proj);
5755 for (I it = middle; it != last_it; ++it)
5757 if (etl::invoke(comp, etl::invoke(proj, *it), etl::invoke(proj, *first)))
5759 etl::iter_swap(it, first);
5760 sift_down(first,
decltype(heap_size){0}, heap_size, comp, proj);
5766 for (
auto heap_end = heap_size - 1; heap_end > 0; --heap_end)
5768 etl::iter_swap(first, first + heap_end);
5769 sift_down(first,
decltype(heap_size){0}, heap_end, comp, proj);
5775 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5776 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, ranges::iterator_t<R> middle, Comp comp = {}, Proj proj = {})
const
5778 ETL_STATIC_ASSERT(etl::is_random_access_iterator<ranges::iterator_t<R>>::value,
"partial_sort requires a range with random access iterators");
5780 return (*
this)(ranges::begin(r), etl::move(middle), ranges::end(r), etl::move(comp), etl::move(proj));
5785 template <
class I,
class DiffType,
class Comp,
class Proj>
5786 static constexpr void sift_down(I first, DiffType index, DiffType heap_size, Comp& comp, Proj& proj)
5790 auto largest = index;
5791 auto left = 2 * index + 1;
5792 auto right = 2 * index + 2;
5794 if (left < heap_size && etl::invoke(comp, etl::invoke(proj, *(first + largest)), etl::invoke(proj, *(first + left))))
5799 if (right < heap_size && etl::invoke(comp, etl::invoke(proj, *(first + largest)), etl::invoke(proj, *(first + right))))
5804 if (largest == index)
5809 etl::iter_swap(first + index, first + largest);
5817 struct partial_sort_copy_fn
5819 template <
class I1,
class S1,
class I2,
class S2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
5820 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
5821 constexpr ranges::partial_sort_copy_result<I1, I2> operator()(I1 first, S1 last, I2 result_first, S2 result_last, Comp comp = {},
5822 Proj1 proj1 = {}, Proj2 proj2 = {})
const
5824 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I2>::value,
"partial_sort_copy requires the output to be random access iterators");
5826 I1 in_last = ranges::next(first, last);
5827 I2 out_last = ranges::next(result_first, result_last);
5829 I2 r = result_first;
5832 for (I1 it = first; it != in_last && r != out_last; ++it, ++r)
5837 auto heap_size = etl::distance(result_first, r);
5841 return {etl::move(in_last), etl::move(r)};
5845 for (
auto start = (heap_size - 1) / 2; start >= 0; --start)
5847 sift_down(result_first, start, heap_size, comp, proj2);
5853 etl::advance(it, heap_size);
5854 for (; it != in_last; ++it)
5856 if (etl::invoke(comp, etl::invoke(proj1, *it), etl::invoke(proj2, *result_first)))
5858 *result_first = *it;
5859 sift_down(result_first,
decltype(heap_size){0}, heap_size, comp, proj2);
5864 for (
auto heap_end = heap_size - 1; heap_end > 0; --heap_end)
5866 etl::iter_swap(result_first, result_first + heap_end);
5867 sift_down(result_first,
decltype(heap_size){0}, heap_end, comp, proj2);
5870 return {etl::move(in_last), etl::move(r)};
5873 template <
class R1,
class R2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
5874 typename = etl::enable_if_t<etl::is_range_v<R1>>>
5875 constexpr ranges::partial_sort_copy_result< ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>>
5876 operator()(R1&& r, R2&& result_r, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
5878 ETL_STATIC_ASSERT(etl::is_random_access_iterator<ranges::iterator_t<R2>>::value,
5879 "partial_sort_copy requires the output range to have random access iterators");
5881 return (*
this)(ranges::begin(r), ranges::end(r), ranges::begin(result_r), ranges::end(result_r), etl::move(comp), etl::move(proj1),
5887 template <
class I,
class DiffType,
class Comp,
class Proj>
5888 static constexpr void sift_down(I first, DiffType index, DiffType heap_size, Comp& comp, Proj& proj)
5892 auto largest = index;
5893 auto left = 2 * index + 1;
5894 auto right = 2 * index + 2;
5896 if (left < heap_size && etl::invoke(comp, etl::invoke(proj, *(first + largest)), etl::invoke(proj, *(first + left))))
5901 if (right < heap_size && etl::invoke(comp, etl::invoke(proj, *(first + largest)), etl::invoke(proj, *(first + right))))
5906 if (largest == index)
5911 etl::iter_swap(first + index, first + largest);
5919 struct nth_element_fn
5921 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5922 constexpr I operator()(I first, I nth, S last, Comp comp = {}, Proj proj = {})
const
5924 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"nth_element requires random access iterators");
5926 I last_it = ranges::next(first, last);
5928 if (first == last_it || ranges::next(first) == last_it)
5934 I hi = ranges::prev(last_it);
5938 I p = nth_partition(lo, hi, comp, proj);
5946 hi = ranges::prev(p);
5950 lo = ranges::next(p);
5957 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5958 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, ranges::iterator_t<R> nth, Comp comp = {}, Proj proj = {})
const
5960 ETL_STATIC_ASSERT(etl::is_random_access_iterator<ranges::iterator_t<R>>::value,
"nth_element requires a range with random access iterators");
5962 return (*
this)(ranges::begin(r), etl::move(nth), ranges::end(r), etl::move(comp), etl::move(proj));
5967 template <
class I,
class Comp,
class Proj>
5968 static constexpr I nth_partition(I first, I last, Comp& comp, Proj& proj)
5975 if (last - first == 1)
5977 if (etl::invoke(comp, etl::invoke(proj, *last), etl::invoke(proj, *first)))
5979 etl::iter_swap(first, last);
5985 I mid = first + (last - first) / 2;
5987 if (etl::invoke(comp, etl::invoke(proj, *mid), etl::invoke(proj, *first)))
5989 etl::iter_swap(first, mid);
5992 if (etl::invoke(comp, etl::invoke(proj, *last), etl::invoke(proj, *first)))
5994 etl::iter_swap(first, last);
5997 if (etl::invoke(comp, etl::invoke(proj, *mid), etl::invoke(proj, *last)))
5999 etl::iter_swap(mid, last);
6008 while (etl::invoke(comp, etl::invoke(proj, *i), etl::invoke(proj, *last)))
6015 while (i < j && etl::invoke(comp, etl::invoke(proj, *last), etl::invoke(proj, *j)))
6025 etl::iter_swap(i, j);
6029 etl::iter_swap(i, last);
6038 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6039 constexpr ranges::subrange<I> operator()(I first, S last, Pred pred, Proj proj = {})
const
6041 first = ranges::find_if_not(first, last, etl::ref(pred), etl::ref(proj));
6045 return {first, first};
6048 for (I i = ranges::next(first); i != last; ++i)
6050 if (etl::invoke(pred, etl::invoke(proj, *i)))
6052 etl::iter_swap(i, first);
6057 return {first, ranges::next(first, last)};
6060 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6061 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
6063 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
6067 inline constexpr partition_fn
partition{};
6069 struct is_partitioned_fn
6071 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6072 constexpr bool operator()(I first, S last, Pred pred, Proj proj = {})
const
6074 for (; first != last; ++first)
6076 if (!etl::invoke(pred, etl::invoke(proj, *first)))
6082 for (; first != last; ++first)
6084 if (etl::invoke(pred, etl::invoke(proj, *first)))
6093 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6094 constexpr bool operator()(R&& r, Pred pred, Proj proj = {})
const
6096 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
6102 struct partition_copy_fn
6104 template <
class I,
class S,
class O1,
class O2,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6105 constexpr ranges::partition_copy_result<I, O1, O2> operator()(I first, S last, O1 out_true, O2 out_false, Pred pred, Proj proj = {})
const
6107 for (; first != last; ++first)
6109 if (etl::invoke(pred, etl::invoke(proj, *first)))
6116 *out_false = *first;
6121 return {etl::move(first), etl::move(out_true), etl::move(out_false)};
6124 template <
class R,
class O1,
class O2,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6125 constexpr ranges::partition_copy_result<ranges::borrowed_iterator_t<R>, O1, O2> operator()(R&& r, O1 out_true, O2 out_false, Pred pred,
6126 Proj proj = {})
const
6128 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(out_true), etl::move(out_false), etl::ref(pred), etl::ref(proj));
6134 struct partition_point_fn
6136 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6137 constexpr I operator()(I first, S last, Pred pred, Proj proj = {})
const
6139 for (; first != last; ++first)
6141 if (!etl::invoke(pred, etl::invoke(proj, *first)))
6150 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6151 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
6153 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
6159 struct stable_partition_fn
6161 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6162 constexpr ranges::subrange<I> operator()(I first, S last, Pred pred, Proj proj = {})
const
6165 first = ranges::find_if_not(first, last, etl::ref(pred), etl::ref(proj));
6169 return {first, first};
6172 I last_it = ranges::next(first, last);
6174 I pp = stable_partition_impl(first, last_it, etl::ref(pred), etl::ref(proj), etl::distance(first, last_it));
6176 return {pp, last_it};
6179 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6180 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
6182 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
6187 template <
class I,
class Pred,
class Proj>
6188 static constexpr I stable_partition_impl(I first, I last, Pred pred, Proj proj,
typename etl::iterator_traits<I>::difference_type len)
6197 return etl::invoke(pred, etl::invoke(proj, *first)) ? ranges::next(first) : first;
6200 I middle = ranges::next(first, len / 2);
6202 I left_partition = stable_partition_impl(first, middle, etl::ref(pred), etl::ref(proj), len / 2);
6203 I right_partition = stable_partition_impl(middle, last, etl::ref(pred), etl::ref(proj), len - len / 2);
6205 return etl::rotate(left_partition, middle, right_partition);
6209 inline constexpr stable_partition_fn stable_partition{};
6211 struct is_sorted_until_fn
6213 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6214 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6218 I next_it = ranges::next(first);
6220 while (next_it != last)
6222 if (etl::invoke(comp, etl::invoke(proj, *next_it), etl::invoke(proj, *first)))
6232 return ranges::next(first, last);
6235 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6236 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
6238 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
6246 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6247 constexpr bool operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6249 return ranges::is_sorted_until(first, last, etl::ref(comp), etl::ref(proj)) == last;
6252 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6253 constexpr bool operator()(R&& r, Comp comp = {}, Proj proj = {})
const
6255 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
6259 inline constexpr is_sorted_fn
is_sorted{};
6261 struct lower_bound_fn
6263 template <
class I,
class S,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6264 constexpr I operator()(I first, S last,
const T& value, Comp comp = {}, Proj proj = {})
const
6266 auto len = etl::distance(first, last);
6270 auto half = len / 2;
6271 I middle = ranges::next(first, half);
6273 if (etl::invoke(comp, etl::invoke(proj, *middle), value))
6275 first = ranges::next(middle);
6287 template <
class R,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6288 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r,
const T& value, Comp comp = {}, Proj proj = {})
const
6290 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::move(comp), etl::move(proj));
6294 inline constexpr lower_bound_fn lower_bound{};
6296 struct upper_bound_fn
6298 template <
class I,
class S,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6299 constexpr I operator()(I first, S last,
const T& value, Comp comp = {}, Proj proj = {})
const
6301 auto len = etl::distance(first, last);
6305 auto half = len / 2;
6306 I middle = ranges::next(first, half);
6308 if (!etl::invoke(comp, value, etl::invoke(proj, *middle)))
6310 first = ranges::next(middle);
6322 template <
class R,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6323 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r,
const T& value, Comp comp = {}, Proj proj = {})
const
6325 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::move(comp), etl::move(proj));
6329 inline constexpr upper_bound_fn upper_bound{};
6331 struct equal_range_fn
6333 template <
class I,
class S,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6334 constexpr ranges::subrange<I> operator()(I first, S last,
const T& value, Comp comp = {}, Proj proj = {})
const
6336 return {ranges::lower_bound(first, last, value, etl::ref(comp), etl::ref(proj)),
6337 ranges::upper_bound(first, last, value, etl::ref(comp), etl::ref(proj))};
6340 template <
class R,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6341 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r,
const T& value, Comp comp = {}, Proj proj = {})
const
6343 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::move(comp), etl::move(proj));
6347 inline constexpr equal_range_fn equal_range{};
6349 struct binary_search_fn
6351 template <
class I,
class S,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6353 constexpr bool operator()(I first, S last,
const T& value, Comp comp = {}, Proj proj = {})
const
6355 first = ranges::lower_bound(first, last, value, etl::ref(comp), etl::ref(proj));
6357 return (!(first == last) && !(etl::invoke(comp, value, etl::invoke(proj, *first))));
6360 template <
class R,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6362 constexpr bool operator()(R&& r,
const T& value, Comp comp = {}, Proj proj = {})
const
6364 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::move(comp), etl::move(proj));
6368 inline constexpr binary_search_fn binary_search{};
6372 template <
class I1,
class S1,
class I2,
class S2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6373 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6375 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6377 for (; first2 != last2; ++first1)
6379 if (first1 == last1)
6384 if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6389 if (!etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
6398 template <
class R1,
class R2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6399 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6401 constexpr bool operator()(R1&& r1, R2&& r2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6403 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(comp), etl::move(proj1), etl::move(proj2));
6407 inline constexpr includes_fn includes{};
6411 template <
class I1,
class S1,
class I2,
class S2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6412 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6413 constexpr ranges::merge_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {},
6414 Proj2 proj2 = {})
const
6416 while (first1 != last1 && first2 != last2)
6418 if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6431 while (first1 != last1)
6438 while (first2 != last2)
6445 return {etl::move(first1), etl::move(first2), etl::move(result)};
6448 template <
class R1,
class R2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6449 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6450 constexpr ranges::merge_result<ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O>
6451 operator()(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6453 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::move(comp), etl::move(proj1),
6458 inline constexpr merge_fn
merge{};
6460 struct inplace_merge_fn
6462 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6463 constexpr I operator()(I first, I middle, S last, Comp comp = {}, Proj proj = {})
const
6465 I last_it = ranges::next(first, last);
6467 if (first == middle || middle == last_it)
6472 inplace_merge_impl(first, middle, last_it, comp, proj, etl::distance(first, middle), etl::distance(middle, last_it));
6477 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6478 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, ranges::iterator_t<R> middle, Comp comp = {}, Proj proj = {})
const
6480 return (*
this)(ranges::begin(r), etl::move(middle), ranges::end(r), etl::move(comp), etl::move(proj));
6485 template <
class I,
class Comp,
class Proj>
6486 static constexpr void inplace_merge_impl(I first, I middle, I last, Comp& comp, Proj& proj,
6487 typename etl::iterator_traits<I>::difference_type len1,
6488 typename etl::iterator_traits<I>::difference_type len2)
6490 if (len1 == 0 || len2 == 0)
6495 if (len1 + len2 == 2)
6497 if (etl::invoke(comp, etl::invoke(proj, *middle), etl::invoke(proj, *first)))
6499 etl::iter_swap(first, middle);
6506 typename etl::iterator_traits<I>::difference_type new_len1;
6507 typename etl::iterator_traits<I>::difference_type new_len2;
6511 new_len1 = len1 / 2;
6512 first_cut = ranges::next(first, new_len1);
6513 second_cut = ranges::lower_bound(middle, last, etl::invoke(proj, *first_cut), etl::ref(comp), etl::ref(proj));
6514 new_len2 = etl::distance(middle, second_cut);
6518 new_len2 = len2 / 2;
6519 second_cut = ranges::next(middle, new_len2);
6520 first_cut = ranges::upper_bound(first, middle, etl::invoke(proj, *second_cut), etl::ref(comp), etl::ref(proj));
6521 new_len1 = etl::distance(first, first_cut);
6531 if (first_cut == middle)
6533 new_middle = second_cut;
6535 else if (second_cut == middle)
6537 new_middle = first_cut;
6541 new_middle = etl::rotate(first_cut, middle, second_cut);
6544 inplace_merge_impl(first, first_cut, new_middle, comp, proj, new_len1, new_len2);
6545 inplace_merge_impl(new_middle, second_cut, last, comp, proj, len1 - new_len1, len2 - new_len2);
6553 template <
class I1,
class S1,
class I2,
class S2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6554 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6555 constexpr ranges::set_union_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {},
6556 Proj2 proj2 = {})
const
6558 while (first1 != last1 && first2 != last2)
6560 if (etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
6565 else if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6579 while (first1 != last1)
6586 while (first2 != last2)
6593 return {etl::move(first1), etl::move(first2), etl::move(result)};
6596 template <
class R1,
class R2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6597 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6598 constexpr ranges::set_union_result<ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O>
6599 operator()(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6601 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::move(comp), etl::move(proj1),
6606 inline constexpr set_union_fn set_union{};
6608 struct set_intersection_fn
6610 template <
class I1,
class S1,
class I2,
class S2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6611 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6612 constexpr ranges::set_intersection_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {},
6613 Proj1 proj1 = {}, Proj2 proj2 = {})
const
6615 while (first1 != last1 && first2 != last2)
6617 if (etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
6621 else if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6634 return {etl::move(first1), etl::move(first2), etl::move(result)};
6637 template <
class R1,
class R2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6638 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6639 constexpr ranges::set_intersection_result< ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O>
6640 operator()(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6642 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::move(comp), etl::move(proj1),
6647 inline constexpr set_intersection_fn set_intersection{};
6649 struct set_difference_fn
6651 template <
class I1,
class S1,
class I2,
class S2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6652 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6653 constexpr ranges::set_difference_result<I1, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {},
6654 Proj2 proj2 = {})
const
6656 while (first1 != last1 && first2 != last2)
6658 if (etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
6664 else if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6675 while (first1 != last1)
6682 return {etl::move(first1), etl::move(result)};
6685 template <
class R1,
class R2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6686 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6687 constexpr ranges::set_difference_result<ranges::borrowed_iterator_t<R1>, O> operator()(R1&& r1, R2&& r2, O result, Comp comp = {},
6688 Proj1 proj1 = {}, Proj2 proj2 = {})
const
6690 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::move(comp), etl::move(proj1),
6695 inline constexpr set_difference_fn set_difference{};
6697 struct set_symmetric_difference_fn
6699 template <
class I1,
class S1,
class I2,
class S2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6700 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6701 constexpr ranges::set_symmetric_difference_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {},
6702 Proj1 proj1 = {}, Proj2 proj2 = {})
const
6704 while (first1 != last1 && first2 != last2)
6706 if (etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
6712 else if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6725 while (first1 != last1)
6732 while (first2 != last2)
6739 return {etl::move(first1), etl::move(first2), etl::move(result)};
6742 template <
class R1,
class R2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6743 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6744 constexpr ranges::set_symmetric_difference_result< ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O>
6745 operator()(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6747 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::move(comp), etl::move(proj1),
6752 inline constexpr set_symmetric_difference_fn set_symmetric_difference{};
6758 template <
class I,
class Comp,
class Proj>
6759 static constexpr void sift_down(I first,
typename etl::iterator_traits<I>::difference_type index,
6760 typename etl::iterator_traits<I>::difference_type length, Comp& comp, Proj& proj)
6764 auto child = 2 * index + 1;
6766 if (child >= length)
6771 if ((child + 1 < length) && etl::invoke(comp, etl::invoke(proj, *(first + child)), etl::invoke(proj, *(first + (child + 1)))))
6776 if (!etl::invoke(comp, etl::invoke(proj, *(first + index)), etl::invoke(proj, *(first + child))))
6781 etl::iter_swap(first + index, first + child);
6788 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6789 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6791 I last_it = ranges::next(first, last);
6793 auto length = etl::distance(first, last_it);
6800 auto parent = (length - 2) / 2;
6804 sift_down(first, parent, length, comp, proj);
6817 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6818 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
6820 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
6824 inline constexpr make_heap_fn make_heap{};
6828 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6829 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6831 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"push_heap requires random access iterators");
6833 I last_it = ranges::next(first, last);
6835 auto length = etl::distance(first, last_it);
6842 auto value_index = length - 1;
6843 auto parent = (value_index - 1) / 2;
6844 auto value = etl::move(*(first + value_index));
6846 while ((value_index > 0) && etl::invoke(comp, etl::invoke(proj, *(first + parent)), etl::invoke(proj, value)))
6848 *(first + value_index) = etl::move(*(first + parent));
6849 value_index = parent;
6850 parent = (value_index - 1) / 2;
6853 *(first + value_index) = etl::move(value);
6858 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6859 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
6861 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
6865 inline constexpr push_heap_fn push_heap{};
6871 template <
class I,
class Comp,
class Proj>
6872 static constexpr void sift_down(I first,
typename etl::iterator_traits<I>::difference_type index,
6873 typename etl::iterator_traits<I>::difference_type length, Comp& comp, Proj& proj)
6877 auto child = 2 * index + 1;
6879 if (child >= length)
6884 if ((child + 1 < length) && etl::invoke(comp, etl::invoke(proj, *(first + child)), etl::invoke(proj, *(first + (child + 1)))))
6889 if (!etl::invoke(comp, etl::invoke(proj, *(first + index)), etl::invoke(proj, *(first + child))))
6894 etl::iter_swap(first + index, first + child);
6901 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6902 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6904 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"pop_heap requires random access iterators");
6906 I last_it = ranges::next(first, last);
6908 auto length = etl::distance(first, last_it);
6917 etl::iter_swap(first, last_it);
6919 sift_down(first,
decltype(length)(0), etl::distance(first, last_it), comp, proj);
6921 return ranges::next(first, last);
6924 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6925 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
6927 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
6931 inline constexpr pop_heap_fn pop_heap{};
6933 struct is_heap_until_fn
6935 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6936 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6938 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"is_heap_until requires random access iterators");
6940 I last_it = ranges::next(first, last);
6942 auto length = etl::distance(first, last_it);
6944 decltype(length) parent = 0;
6946 for (
decltype(length) child = 1; child < length; ++child)
6948 if (etl::invoke(comp, etl::invoke(proj, *(first + parent)), etl::invoke(proj, *(first + child))))
6950 return first + child;
6953 if ((child & 1) == 0)
6962 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6963 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
6965 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
6969 inline constexpr is_heap_until_fn is_heap_until{};
6973 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6974 constexpr bool operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6976 return ranges::is_heap_until(first, last, etl::ref(comp), etl::ref(proj)) == last;
6979 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6980 constexpr bool operator()(R&& r, Comp comp = {}, Proj proj = {})
const
6982 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
6986 inline constexpr is_heap_fn is_heap{};
6990 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6991 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6993 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"sort_heap requires random access iterators");
6995 I last_it = ranges::next(first, last);
6996 I current_last = last_it;
6998 while (first != current_last)
7000 ranges::pop_heap(first, current_last, comp, proj);
7007 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7008 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7010 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7014 inline constexpr sort_heap_fn sort_heap{};
7018 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7019 constexpr const T& operator()(
const T& a,
const T& b, Comp comp = {}, Proj proj = {})
const
7021 return etl::invoke(comp, etl::invoke(proj, b), etl::invoke(proj, a)) ? b : a;
7024 #if ETL_HAS_INITIALIZER_LIST
7025 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7026 constexpr T operator()(std::initializer_list<T> r, Comp comp = {}, Proj proj = {})
const
7028 auto first = r.begin();
7029 auto last = r.end();
7031 auto smallest = first;
7032 while (++first != last)
7034 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7043 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7044 constexpr ranges::range_value_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7046 auto first = ranges::begin(r);
7047 auto last = ranges::end(r);
7049 auto smallest = first;
7050 while (++first != last)
7052 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7061 inline constexpr min_fn min{};
7063 struct min_element_fn
7065 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7066 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7076 for (; first != last; ++first)
7078 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7087 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7088 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7090 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7098 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7099 constexpr const T& operator()(
const T& a,
const T& b, Comp comp = {}, Proj proj = {})
const
7101 return etl::invoke(comp, etl::invoke(proj, a), etl::invoke(proj, b)) ? b : a;
7104 #if ETL_HAS_INITIALIZER_LIST
7105 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7106 constexpr T operator()(std::initializer_list<T> r, Comp comp = {}, Proj proj = {})
const
7108 auto first = r.begin();
7109 auto last = r.end();
7111 auto largest = first;
7112 while (++first != last)
7114 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7123 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7124 constexpr ranges::range_value_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7126 auto first = ranges::begin(r);
7127 auto last = ranges::end(r);
7129 auto largest = first;
7130 while (++first != last)
7132 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7141 inline constexpr max_fn max{};
7143 struct max_element_fn
7145 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7146 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7156 for (; first != last; ++first)
7158 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7167 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7168 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7170 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7178 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7179 constexpr ranges::minmax_result<const T&> operator()(
const T& a,
const T& b, Comp comp = {}, Proj proj = {})
const
7181 if (etl::invoke(comp, etl::invoke(proj, b), etl::invoke(proj, a)))
7188 #if ETL_HAS_INITIALIZER_LIST
7189 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7190 constexpr ranges::minmax_result<T> operator()(std::initializer_list<T> r, Comp comp = {}, Proj proj = {})
const
7192 auto first = r.begin();
7193 auto last = r.end();
7195 auto smallest = first;
7196 auto largest = first;
7198 while (++first != last)
7200 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7204 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7209 return {*smallest, *largest};
7213 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7214 constexpr ranges::minmax_result<ranges::range_value_t<R>> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7216 auto first = ranges::begin(r);
7217 auto last = ranges::end(r);
7219 auto smallest = first;
7220 auto largest = first;
7222 while (++first != last)
7224 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7228 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7233 return {*smallest, *largest};
7237 inline constexpr minmax_fn
minmax{};
7239 struct minmax_element_fn
7241 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7242 constexpr ranges::minmax_element_result<I> operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7246 return {first, first};
7253 for (; first != last; ++first)
7255 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7259 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7265 return {smallest, largest};
7268 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7269 constexpr ranges::minmax_element_result<ranges::borrowed_iterator_t<R>> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7271 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7279 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7280 constexpr const T& operator()(
const T& value,
const T& low,
const T& high, Comp comp = {}, Proj proj = {})
const
7282 auto&& projected_value = etl::invoke(proj, value);
7284 return etl::invoke(comp, projected_value, etl::invoke(proj, low)) ? low
7285 : etl::invoke(comp, etl::invoke(proj, high), projected_value) ? high
7290 inline constexpr clamp_fn
clamp{};
7292 struct next_permutation_fn
7294 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7295 constexpr ranges::next_permutation_result<I> operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7297 I last_it = ranges::next(first, last);
7300 if (first == last_it)
7302 return {etl::move(last_it),
false};
7310 return {etl::move(last_it),
false};
7319 if (etl::invoke(comp, etl::invoke(proj, *i), etl::invoke(proj, *i1)))
7323 while (!etl::invoke(comp, etl::invoke(proj, *i), etl::invoke(proj, *--j)))
7327 etl::iter_swap(i, j);
7332 while (left != right && left != --right)
7334 etl::iter_swap(left, right);
7338 return {etl::move(last_it),
true};
7347 while (left != right && left != --right)
7349 etl::iter_swap(left, right);
7353 return {etl::move(last_it),
false};
7358 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7359 constexpr ranges::next_permutation_result<ranges::borrowed_iterator_t<R>> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7361 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7367 struct prev_permutation_fn
7369 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7370 constexpr ranges::prev_permutation_result<I> operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7372 I last_it = ranges::next(first, last);
7375 if (first == last_it)
7377 return {etl::move(last_it),
false};
7385 return {etl::move(last_it),
false};
7394 if (etl::invoke(comp, etl::invoke(proj, *i1), etl::invoke(proj, *i)))
7398 while (!etl::invoke(comp, etl::invoke(proj, *--j), etl::invoke(proj, *i)))
7402 etl::iter_swap(i, j);
7407 while (left != right && left != --right)
7409 etl::iter_swap(left, right);
7413 return {etl::move(last_it),
true};
7422 while (left != right && left != --right)
7424 etl::iter_swap(left, right);
7428 return {etl::move(last_it),
false};
7433 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7434 constexpr ranges::prev_permutation_result<ranges::borrowed_iterator_t<R>> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7436 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
Definition functional.h:358
Definition iterator.h:252
ETL_CONSTEXPR T clamp(const T &value, const T &low, const T &high, TCompare compare)
Definition algorithm.h:2316
ETL_CONSTEXPR20 void shell_sort(TIterator first, TIterator last)
Definition algorithm.h:3189
ETL_CONSTEXPR14 TOutputIterator copy_if(TIterator begin, TIterator end, TOutputIterator out, TUnaryPredicate predicate)
Definition algorithm.h:2140
void inplace_merge(TBidirectionalIterator first, TBidirectionalIterator middle, TBidirectionalIterator last, TCompare compare)
Definition algorithm.h:2558
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:3081
ETL_NODISCARD ETL_CONSTEXPR14 bool any_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2173
ETL_NODISCARD ETL_CONSTEXPR14 TIterator min_element(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1470
ETL_CONSTEXPR14 TOutputIterator transform_n_if(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:3033
ETL_CONSTEXPR14 T accumulate(TIterator first, TIterator last, T sum)
Definition algorithm.h:2284
ETL_CONSTEXPR14 bool next_permutation(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:1929
ETL_NODISCARD ETL_CONSTEXPR14 bool all_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2162
ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair< TIterator, TIterator > minmax_element(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1552
ETL_CONSTEXPR14 TOutputIterator transform_if(TInputIterator i_begin, const TInputIterator i_end, TOutputIterator o_begin, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:2988
ETL_CONSTEXPR14 TUnaryFunction for_each_if(TIterator begin, const TIterator end, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:2881
ETL_NODISCARD ETL_CONSTEXPR14 TIterator find_if_not(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:1739
ETL_NODISCARD ETL_CONSTEXPR14 bool is_sorted(TIterator begin, TIterator end)
Definition algorithm.h:1660
ETL_CONSTEXPR14 TOutputIterator transform_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end, TUnaryFunction function)
Definition algorithm.h:2940
ETL_CONSTEXPR14 TIterator remove(TIterator first, TIterator last, const T &value)
Definition algorithm.h:2344
ETL_CONSTEXPR14 TRandomAccessIterator partial_sort_copy(TInputIterator first, TInputIterator last, TRandomAccessIterator d_first, TRandomAccessIterator d_last, TCompare compare)
Definition algorithm.h:1129
ETL_CONSTEXPR14 TOutputIterator merge(TInputIterator1 first1, TInputIterator1 last1, TInputIterator2 first2, TInputIterator2 last2, TOutputIterator d_first, TCompare compare)
Definition algorithm.h:2506
ETL_CONSTEXPR14 void transform_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryFunction function)
Definition algorithm.h:2960
ETL_CONSTEXPR14 TOutputIterator unique_copy(TInputIterator first, TInputIterator last, TOutputIterator d_first)
Definition algorithm.h:2448
ETL_CONSTEXPR14 TOutputIterator copy_n_if(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryPredicate predicate)
Definition algorithm.h:2748
ETL_CONSTEXPR14 void insertion_sort(TIterator first, TIterator last)
Definition algorithm.h:3213
void sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:2240
ETL_NODISCARD ETL_CONSTEXPR14 bool is_unique_sorted(TIterator begin, TIterator end)
Definition algorithm.h:1718
ETL_CONSTEXPR14 TIterator unique(TIterator first, TIterator last)
Definition algorithm.h:2395
ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair< const T &, const T & > minmax(const T &a, const T &b)
Definition algorithm.h:1599
ETL_NODISCARD ETL_CONSTEXPR14 TIterator is_sorted_until(TIterator begin, TIterator end, TCompare compare)
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:2638
ETL_CONSTEXPR14 TIterator remove_if(TIterator first, TIterator last, TUnaryPredicate predicate)
Definition algorithm.h:2369
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:2112
ETL_CONSTEXPR14 TIterator for_each_n(TIterator begin, TSize n, TUnaryFunction function)
Definition algorithm.h:2901
ETL_NODISCARD ETL_CONSTEXPR14 TIterator binary_find(TIterator begin, TIterator end, const TValue &value)
Definition algorithm.h:2845
ETL_CONSTEXPR14 void heap_sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:3311
ETL_NODISCARD ETL_CONSTEXPR14 bool none_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2184
ETL_CONSTEXPR20 void selection_sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:3261
ETL_CONSTEXPR14 TOutputIterator copy_n_s(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TOutputIterator o_end)
Definition algorithm.h:2688
ETL_NODISCARD ETL_CONSTEXPR14 TIterator is_unique_sorted_until(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1681
TOutputIterator move_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
Definition algorithm.h:2831
ETL_CONSTEXPR14 TOutputIterator copy_if_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end, TUnaryPredicate predicate)
Definition algorithm.h:2725
ETL_CONSTEXPR14 TIterator for_each_n_if(TIterator begin, TSize n, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:2918
void stable_sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:2262
ETL_NODISCARD ETL_CONSTEXPR14 bool is_partitioned(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2051
ETL_NODISCARD ETL_CONSTEXPR14 TIterator adjacent_find(TIterator first, TIterator last, TBinaryPredicate predicate)
Definition algorithm.h:1760
ETL_NODISCARD ETL_CONSTEXPR14 TIterator max_element(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1511
ETL_NODISCARD ETL_CONSTEXPR14 TIterator partition_point(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2082
ETL_NODISCARD ETL_CONSTEXPR14 bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2)
Definition algorithm.h:1801
ETL_CONSTEXPR14 bool prev_permutation(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:1990
ETL_CONSTEXPR14 void partial_sort(TIterator first, TIterator middle, TIterator last, TCompare compare)
Definition algorithm.h:1083
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
Definition exception.h:59
ETL_CONSTEXPR14 void iota(TIterator first, TIterator last, T value)
Definition numeric.h:58
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR14 void swap(etl::typed_storage_ext< T > &lhs, etl::typed_storage_ext< T > &rhs) ETL_NOEXCEPT
Swap two etl::typed_storage_ext.
Definition alignment.h:856
TIterator find_first_of(TIterator first, TIterator last, TPointer delimiters)
Find first of any of delimiters within the string.
Definition string_utilities.h:500
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:3624
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:967
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:3490
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition iterator.h:997
Definition functional.h:305
Definition functional.h:201
Definition algorithm.h:124