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>
103 stable_partition_exception(string_type reason_, string_type file_, numeric_type line_)
109 struct stable_partition_buffer_too_small : stable_partition_exception
111 stable_partition_buffer_too_small(string_type file_, numeric_type line_)
112 : stable_partition_exception(ETL_ERROR_TEXT(
"stable_partition:buffer too small", ETL_ALGORITHM_FILE_ID
"A"), file_, line_)
117 namespace private_algorithm
119 template <
bool use_swap>
126 template <
typename TIterator1,
typename TIterator2>
127 static void do_swap(TIterator1 a, TIterator2 b)
129 typename etl::iterator_traits<TIterator1>::value_type tmp = *a;
139 template <
typename TIterator1,
typename TIterator2>
140 static void do_swap(TIterator1 a, TIterator2 b)
142 using ETL_OR_STD::swap;
151 template <
typename TIterator1,
typename TIterator2>
152#if ETL_USING_STD_NAMESPACE
158 iter_swap(TIterator1 a, TIterator2 b)
163 typedef typename traits1::value_type v1;
164 typedef typename traits2::value_type v2;
166 typedef typename traits1::reference r1;
167 typedef typename traits2::reference r2;
169 const bool use_swap = etl::is_same<v1, v2>::value && etl::is_reference<r1>::value && etl::is_reference<r2>::value;
177 template <
typename TIterator1,
typename TIterator2>
178#if ETL_USING_STD_NAMESPACE
184 swap_ranges(TIterator1 first1, TIterator1 last1, TIterator2 first2)
186 while (first1 != last1)
188 etl::iter_swap(first1, first2);
198 template <
typename TIterator,
typename TFunction>
199 ETL_CONSTEXPR14
void generate(TIterator db, TIterator de, TFunction funct)
209#if ETL_USING_STL && ETL_USING_CPP20
211 template <
typename TIterator1,
typename TIterator2>
212 constexpr TIterator2 copy(TIterator1 sb, TIterator1 se, TIterator2 db)
214 return std::copy(sb, se, db);
218 template <
typename TIterator1,
typename TIterator2>
219 ETL_CONSTEXPR14 TIterator2 copy(TIterator1 sb, TIterator1 se, TIterator2 db)
234#if ETL_USING_STL && ETL_USING_CPP20
235 template <
typename TIterator1,
typename TIterator2>
236 constexpr TIterator2 reverse_copy(TIterator1 sb, TIterator1 se, TIterator2 db)
238 return std::reverse_copy(sb, se, db);
241 template <
typename TIterator1,
typename TIterator2>
242 ETL_CONSTEXPR14 TIterator2 reverse_copy(TIterator1 sb, TIterator1 se, TIterator2 db)
256#if ETL_USING_STL && ETL_USING_CPP20
258 template <
typename TIterator1,
typename TSize,
typename TIterator2>
259 constexpr TIterator2 copy_n(TIterator1 sb, TSize count, TIterator2 db)
261 return std::copy_n(sb, count, db);
265 template <
typename TIterator1,
typename TSize,
typename TIterator2>
266 ETL_CONSTEXPR14 TIterator2 copy_n(TIterator1 sb, TSize count, TIterator2 db)
282#if ETL_USING_STL && ETL_USING_CPP20
283 template <
typename TIterator1,
typename TIterator2>
284 constexpr TIterator2 copy_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
286 return std::copy_backward(sb, se, de);
289 template <
typename TIterator1,
typename TIterator2>
290 ETL_CONSTEXPR14 TIterator2 copy_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
303#if ETL_USING_STL && ETL_USING_CPP20
304 template <
typename TIterator1,
typename TIterator2>
305 constexpr TIterator2 move(TIterator1 sb, TIterator1 se, TIterator2 db)
307 return std::move(sb, se, db);
311 template <
typename TIterator1,
typename TIterator2>
312 ETL_CONSTEXPR14 TIterator2 move(TIterator1 sb, TIterator1 se, TIterator2 db)
316 *db = etl::move(*sb);
325 template <
typename TIterator1,
typename TIterator2>
326 ETL_CONSTEXPR14 TIterator2 move(TIterator1 sb, TIterator1 se, TIterator2 db)
328 return copy(sb, se, db);
334#if ETL_USING_STL && ETL_USING_CPP20
335 template <
typename TIterator1,
typename TIterator2>
336 ETL_CONSTEXPR20 TIterator2 move_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
339 return std::move_backward(sb, se, de);
344 template <
typename TIterator1,
typename TIterator2>
345 ETL_CONSTEXPR14 TIterator2 move_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
349 *(--de) = etl::move(*(--se));
356 template <
typename TIterator1,
typename TIterator2>
357 ETL_CONSTEXPR14 TIterator2 move_backward(TIterator1 sb, TIterator1 se, TIterator2 de)
359 return etl::copy_backward(sb, se, de);
367 template <
typename TIterator>
368 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_pointer<TIterator>::value,
void>::type reverse(TIterator b, TIterator e)
374 etl::iter_swap(b, e);
381 template <
typename TIterator>
382 ETL_CONSTEXPR14
typename etl::enable_if<!etl::is_pointer<TIterator>::value,
void>::type reverse(TIterator b, TIterator e)
384 while ((b != e) && (b != --e))
386 etl::iter_swap(b++, e);
393 template <
typename TIterator,
typename TValue,
typename TCompare>
394 ETL_NODISCARD ETL_CONSTEXPR14 TIterator lower_bound(TIterator first, TIterator last,
const TValue& value, TCompare
compare)
396 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
398 difference_t count = etl::distance(first, last);
402 TIterator itr = first;
403 difference_t step = count / 2;
405 etl::advance(itr, step);
421 template <
typename TIterator,
typename TValue>
422 ETL_NODISCARD ETL_CONSTEXPR14 TIterator lower_bound(TIterator first, TIterator last,
const TValue& value)
424 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
426 return etl::lower_bound(first, last, value,
compare());
432 template <
typename TIterator,
typename TValue,
typename TCompare>
433 ETL_NODISCARD ETL_CONSTEXPR14 TIterator upper_bound(TIterator first, TIterator last,
const TValue& value, TCompare
compare)
435 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
437 difference_t count = etl::distance(first, last);
441 TIterator itr = first;
442 difference_t step = count / 2;
444 etl::advance(itr, step);
460 template <
typename TIterator,
typename TValue>
461 ETL_NODISCARD ETL_CONSTEXPR14 TIterator upper_bound(TIterator first, TIterator last,
const TValue& value)
463 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
465 return etl::upper_bound(first, last, value,
compare());
471 template <
typename TIterator,
typename TValue,
typename TCompare>
472 ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair<TIterator, TIterator> equal_range(TIterator first, TIterator last,
const TValue& value, TCompare
compare)
474 return ETL_OR_STD::make_pair(etl::lower_bound(first, last, value,
compare), etl::upper_bound(first, last, value,
compare));
477 template <
typename TIterator,
typename TValue>
479 ETL_OR_STD::pair<TIterator, TIterator> equal_range(TIterator first, TIterator last,
const TValue& value)
481 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
483 return ETL_OR_STD::make_pair(etl::lower_bound(first, last, value,
compare()), etl::upper_bound(first, last, value,
compare()));
489 template <
typename TIterator,
typename T,
typename Compare>
490 ETL_NODISCARD ETL_CONSTEXPR14
bool binary_search(TIterator first, TIterator last,
const T& value, Compare
compare)
492 first = etl::lower_bound(first, last, value,
compare);
494 return (!(first == last) && !(
compare(value, *first)));
497 template <
typename TIterator,
typename T>
498 ETL_NODISCARD ETL_CONSTEXPR14
bool binary_search(TIterator first, TIterator last,
const T& value)
500 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
502 return binary_search(first, last, value,
compare());
508 template <
typename TIterator,
typename TUnaryPredicate>
509 ETL_NODISCARD ETL_CONSTEXPR14 TIterator find_if(TIterator first, TIterator last, TUnaryPredicate predicate)
511 while (first != last)
513 if (predicate(*first))
527 template <
typename TIterator,
typename T>
528 ETL_NODISCARD ETL_CONSTEXPR14 TIterator find(TIterator first, TIterator last,
const T& value)
530 while (first != last)
545#if ETL_USING_STL && ETL_USING_CPP20
546 template <
typename TIterator,
typename TValue>
547 constexpr void fill(TIterator first, TIterator last,
const TValue& value)
549 std::fill(first, last, value);
552 template <
typename TIterator,
typename TValue>
553 ETL_CONSTEXPR14
void fill(TIterator first, TIterator last,
const TValue& value)
555 while (first != last)
558 *first =
static_cast<typename etl::iterator_traits<TIterator>::value_type
>(value);
566#if ETL_USING_STL && ETL_USING_CPP20
567 template <
typename TIterator,
typename TSize,
typename TValue>
568 constexpr TIterator fill_n(TIterator first, TSize count,
const TValue& value)
570 return std::fill_n(first, count, value);
573 template <
typename TIterator,
typename TSize,
typename TValue>
574 ETL_CONSTEXPR14 TIterator fill_n(TIterator first, TSize count,
const TValue& value)
589 template <
typename TIterator,
typename T>
590 ETL_NODISCARD ETL_CONSTEXPR14
typename etl::iterator_traits<TIterator>::difference_type count(TIterator first, TIterator last,
const T& value)
592 typename iterator_traits<TIterator>::difference_type n = 0;
594 while (first != last)
610 template <
typename TIterator,
typename TUnaryPredicate>
611 ETL_NODISCARD ETL_CONSTEXPR14
typename etl::iterator_traits<TIterator>::difference_type count_if(TIterator first, TIterator last, TUnaryPredicate predicate)
613 typename iterator_traits<TIterator>::difference_type n = 0;
615 while (first != last)
617 if (predicate(*first))
630#if ETL_USING_STL && ETL_USING_CPP20
632 template <
typename TIterator1,
typename TIterator2>
634 constexpr bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2)
636 return std::equal(first1, last1, first2);
640 template <
typename TIterator1,
typename TIterator2,
typename TPredicate>
642 constexpr bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TPredicate predicate)
644 return std::equal(first1, last1, first2, predicate);
648 template <
typename TIterator1,
typename TIterator2>
650 constexpr bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2)
652 return std::equal(first1, last1, first2, last2);
656 template <
typename TIterator1,
typename TIterator2,
typename TPredicate>
658 constexpr bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2, TPredicate predicate)
660 return std::equal(first1, last1, first2, last2, predicate);
665 template <
typename TIterator1,
typename TIterator2>
666 ETL_NODISCARD ETL_CONSTEXPR14
bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2)
668 while (first1 != last1)
670 if (*first1 != *first2)
683 template <
typename TIterator1,
typename TIterator2,
typename TPredicate>
684 ETL_NODISCARD ETL_CONSTEXPR14
bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TPredicate predicate)
686 while (first1 != last1)
688 if (!predicate(*first1, *first2))
701 template <
typename TIterator1,
typename TIterator2>
702 ETL_NODISCARD ETL_CONSTEXPR14
bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2)
704 while ((first1 != last1) && (first2 != last2))
706 if (*first1 != *first2)
715 return (first1 == last1) && (first2 == last2);
719 template <
typename TIterator1,
typename TIterator2,
typename TPredicate>
720 ETL_NODISCARD ETL_CONSTEXPR14
bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2, TPredicate predicate)
722 while ((first1 != last1) && (first2 != last2))
724 if (!predicate(*first1, *first2))
733 return (first1 == last1) && (first2 == last2);
740 template <
typename TIterator1,
typename TIterator2,
typename TCompare>
741 ETL_NODISCARD ETL_CONSTEXPR14
bool lexicographical_compare(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2, TCompare
compare)
743 while ((first1 != last1) && (first2 != last2))
759 return (first1 == last1) && (first2 != last2);
763 template <
typename TIterator1,
typename TIterator2>
764 ETL_NODISCARD ETL_CONSTEXPR14
bool lexicographical_compare(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2)
766 typedef etl::less<typename etl::iterator_traits<TIterator1>::value_type>
compare;
768 return etl::lexicographical_compare(first1, last1, first2, last2,
compare());
774 template <
typename T,
typename TCompare>
775 ETL_NODISCARD ETL_CONSTEXPR
const T& min(
const T& a,
const T& b, TCompare
compare)
777 return (
compare(a, b)) ? a : b;
780 template <
typename T>
781 ETL_NODISCARD ETL_CONSTEXPR
const T& min(
const T& a,
const T& b)
785 return etl::min(a, b,
compare());
791 template <
typename T,
typename TCompare>
792 ETL_NODISCARD ETL_CONSTEXPR
const T& max(
const T& a,
const T& b, TCompare
compare)
794 return (
compare(a, b)) ? b : a;
797 template <
typename T>
798 ETL_NODISCARD ETL_CONSTEXPR
const T& max(
const T& a,
const T& b)
802 return etl::max(a, b,
compare());
808 template <
typename TIterator,
typename TUnaryOperation>
809 ETL_CONSTEXPR14 TUnaryOperation for_each(TIterator first, TIterator last, TUnaryOperation unary_operation)
811 while (first != last)
813 unary_operation(*first);
817 return unary_operation;
823 template <
typename TIteratorIn,
typename TIteratorOut,
typename TUnaryOperation>
824 ETL_CONSTEXPR14 TIteratorOut transform(TIteratorIn first1, TIteratorIn last1, TIteratorOut d_first, TUnaryOperation unary_operation)
826 while (first1 != last1)
828 *d_first = unary_operation(*first1);
837 template <
typename TIteratorIn1,
typename TIteratorIn2,
typename TIteratorOut,
typename TBinaryOperation>
838 ETL_CONSTEXPR14 TIteratorOut transform(TIteratorIn1 first1, TIteratorIn1 last1, TIteratorIn2 first2, TIteratorOut d_first,
839 TBinaryOperation binary_operation)
841 while (first1 != last1)
843 *d_first = binary_operation(*first1, *first2);
856 template <
typename TIterator,
typename T>
857 ETL_CONSTEXPR14
void replace(TIterator first, TIterator last,
const T& old_value,
const T& new_value)
859 while (first != last)
861 if (*first == old_value)
873 template <
typename TIterator,
typename TPredicate,
typename T>
874 ETL_CONSTEXPR14
void replace_if(TIterator first, TIterator last, TPredicate predicate,
const T& new_value)
876 while (first != last)
878 if (predicate(*first))
890 namespace private_heap
893 template <
typename TIterator,
typename TDistance,
typename TValue,
typename TCompare>
894 ETL_CONSTEXPR14
void push_heap(TIterator first, TDistance value_index, TDistance top_index, TValue value, TCompare compare)
896 TDistance parent = (value_index - 1) / 2;
899 while ((value_index > top_index) && compare(*(first + parent), value))
901 *(first + value_index) = ETL_MOVE(*(first + parent));
902 value_index = parent;
903 parent = (value_index - 1) / 2;
906 *(first + value_index) = ETL_MOVE(value);
911 template <
typename TIterator,
typename TDistance,
typename TValue,
typename TCompare>
912 ETL_CONSTEXPR14
void adjust_heap(TIterator first, TDistance value_index, TDistance length, TValue value, TCompare compare)
914 TDistance top_index = value_index;
915 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;
937 push_heap(first, value_index, top_index, ETL_MOVE(value), compare);
941 template <
typename TIterator,
typename TDistance,
typename TCompare>
942 ETL_CONSTEXPR14
bool is_heap(
const TIterator first,
const TDistance n, TCompare compare)
944 TDistance parent = 0;
946 for (TDistance child = 1; child < n; ++child)
948 if (compare(*(first + parent), *(first + child)))
953 if ((child & 1) == 0)
964 template <
typename TIterator,
typename TCompare>
965 ETL_CONSTEXPR14
void pop_heap(TIterator first, TIterator last, TCompare
compare)
967 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
968 typedef typename etl::iterator_traits<TIterator>::difference_type distance_t;
970 const distance_t n = last - first;
976 value_t value = ETL_MOVE(*(last - 1));
977 *(last - 1) = ETL_MOVE(*first);
979 private_heap::adjust_heap(first, distance_t(0), distance_t(last - first - 1), ETL_MOVE(value),
compare);
983 template <
typename TIterator>
984 ETL_CONSTEXPR14
void pop_heap(TIterator first, TIterator last)
986 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
988 etl::pop_heap(first, last,
compare());
992 template <
typename TIterator,
typename TCompare>
993 ETL_CONSTEXPR14
void push_heap(TIterator first, TIterator last, TCompare
compare)
995 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
996 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
998 private_heap::push_heap(first, difference_t(last - first - 1), difference_t(0), value_t(ETL_MOVE(*(last - 1))),
compare);
1002 template <
typename TIterator>
1003 ETL_CONSTEXPR14
void push_heap(TIterator first, TIterator last)
1005 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
1007 etl::push_heap(first, last,
compare());
1011 template <
typename TIterator,
typename TCompare>
1012 ETL_CONSTEXPR14
void make_heap(TIterator first, TIterator last, TCompare
compare)
1014 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
1016 if ((last - first) < 2)
1021 difference_t length = last - first;
1022 difference_t parent = (length - 2) / 2;
1026 private_heap::adjust_heap(first, parent, length, ETL_MOVE(*(first + parent)),
compare);
1038 template <
typename TIterator>
1039 ETL_CONSTEXPR14
void make_heap(TIterator first, TIterator last)
1041 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
1043 etl::make_heap(first, last,
compare());
1047 template <
typename TIterator>
1048 ETL_NODISCARD ETL_CONSTEXPR14
bool is_heap(TIterator first, TIterator last)
1050 typedef etl::less<typename etl::iterator_traits<TIterator>::value_type>
compare;
1052 return private_heap::is_heap(first, last - first,
compare());
1056 template <
typename TIterator,
typename TCompare>
1057 ETL_NODISCARD ETL_CONSTEXPR14
bool is_heap(TIterator first, TIterator last, TCompare
compare)
1059 return private_heap::is_heap(first, last - first,
compare);
1063 template <
typename TIterator>
1064 ETL_CONSTEXPR14
void sort_heap(TIterator first, TIterator last)
1066 while (first != last)
1068 etl::pop_heap(first, last);
1074 template <
typename TIterator,
typename TCompare>
1075 ETL_CONSTEXPR14
void sort_heap(TIterator first, TIterator last, TCompare
compare)
1077 while (first != last)
1079 etl::pop_heap(first, last,
compare);
1089 template <
typename TIterator,
typename TCompare>
1092 if (first == middle)
1097 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1098 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
1100 etl::make_heap(first, middle,
compare);
1102 for (TIterator i = middle; i != last; ++i)
1106 value_t value = ETL_MOVE(*i);
1107 *i = ETL_MOVE(*first);
1109 private_heap::adjust_heap(first, difference_t(0), difference_t(middle - first), ETL_MOVE(value),
compare);
1113 etl::sort_heap(first, middle,
compare);
1121 template <
typename TIterator>
1122 ETL_CONSTEXPR14
void partial_sort(TIterator first, TIterator middle, TIterator last)
1135 template <
typename TInputIterator,
typename TRandomAccessIterator,
typename TCompare>
1136 ETL_CONSTEXPR14 TRandomAccessIterator
partial_sort_copy(TInputIterator first, TInputIterator last, TRandomAccessIterator d_first,
1137 TRandomAccessIterator d_last, TCompare
compare)
1139 typedef typename etl::iterator_traits<TRandomAccessIterator>::value_type value_t;
1140 typedef typename etl::iterator_traits<TRandomAccessIterator>::difference_type difference_t;
1142 TRandomAccessIterator result = d_first;
1145 while ((first != last) && (result != d_last))
1152 if (result == d_first)
1158 etl::make_heap(d_first, result,
compare);
1161 for (TInputIterator i = first; i != last; ++i)
1166 private_heap::adjust_heap(d_first, difference_t(0), difference_t(result - d_first), ETL_MOVE(value),
compare);
1170 etl::sort_heap(d_first, result,
compare);
1181 template <
typename TInputIterator,
typename TRandomAccessIterator>
1182 ETL_CONSTEXPR14 TRandomAccessIterator
partial_sort_copy(TInputIterator first, TInputIterator last, TRandomAccessIterator d_first,
1183 TRandomAccessIterator d_last)
1193 template <
typename TIterator1,
typename TIterator2,
typename TCompare>
1194 ETL_NODISCARD ETL_CONSTEXPR14 TIterator1 search(TIterator1 first, TIterator1 last, TIterator2 search_first, TIterator2 search_last, TCompare compare)
1198 TIterator1 itr = first;
1199 TIterator2 search_itr = search_first;
1203 if (search_itr == search_last)
1213 if (!
compare(*itr, *search_itr))
1227 template <
typename TIterator1,
typename TIterator2>
1228 ETL_NODISCARD ETL_CONSTEXPR14 TIterator1 search(TIterator1 first, TIterator1 last, TIterator2 search_first, TIterator2 search_last)
1230 typedef etl::equal_to<typename etl::iterator_traits<TIterator1>::value_type>
compare;
1232 return etl::search(first, last, search_first, search_last,
compare());
1238 namespace private_algorithm
1242 template <
typename TIterator>
1243 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_random_access_iterator<TIterator>::value, TIterator>::type
1244 rotate_general(TIterator first, TIterator middle, TIterator last)
1246 if (first == middle)
1256 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
1257 typedef typename etl::iterator_traits<TIterator>::difference_type difference_type;
1259 difference_type n = last - first;
1260 difference_type m = middle - first;
1261 difference_type gcd_nm = (n == 0 || m == 0) ? n + m : etl::gcd(n, m);
1262 TIterator result = first + (last - middle);
1264 for (difference_type i = 0; i < gcd_nm; i++)
1266 value_type temp = ETL_MOVE(*(first + i));
1267 difference_type j = i;
1271 difference_type k = j + m;
1283 *(first + j) = ETL_MOVE(*(first + k));
1287 *(first + j) = ETL_MOVE(temp);
1295 template <
typename TIterator>
1296 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_bidirectional_iterator<TIterator>::value, TIterator>::type
1297 rotate_general(TIterator first, TIterator middle, TIterator last)
1299 if (first == middle)
1309 TIterator result = first;
1310 etl::advance(result, etl::distance(middle, last));
1312 reverse(first, middle);
1313 reverse(middle, last);
1314 reverse(first, last);
1321 template <
typename TIterator>
1322 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_forward_iterator<TIterator>::value, TIterator>::type rotate_general(TIterator first, TIterator middle,
1325 if (first == middle)
1335 TIterator next = middle;
1336 TIterator result = first;
1337 etl::advance(result, etl::distance(middle, last));
1339 while (first != next)
1341 using ETL_OR_STD::swap;
1342 swap(*first++, *next++);
1348 else if (first == middle)
1359 template <
typename TIterator>
1360 ETL_CONSTEXPR14 TIterator rotate_left_by_one(TIterator first, TIterator last)
1362 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
1365 value_type temp(ETL_MOVE(*first));
1369 TIterator result = etl::move(etl::next(first), last, first);
1373 *result = ETL_MOVE(temp);
1381 template <
typename TIterator>
1382 ETL_CONSTEXPR14 TIterator rotate_right_by_one(TIterator first, TIterator last)
1384 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
1387 TIterator previous = etl::prev(last);
1388 value_type temp(ETL_MOVE(*previous));
1391 TIterator result = etl::move_backward(first, previous, last);
1394 *first = ETL_MOVE(temp);
1402 template <
typename TIterator>
1403 ETL_CONSTEXPR14 TIterator rotate(TIterator first, TIterator middle, TIterator last)
1405 if (first == middle)
1414 if (etl::next(first) == middle)
1416 return private_algorithm::rotate_left_by_one(first, last);
1420 if (etl::next(middle) == last)
1422 if ETL_IF_CONSTEXPR (etl::is_bidirectional_iterator_concept< TIterator>::value)
1424 return private_algorithm::rotate_right_by_one(first, last);
1429 return private_algorithm::rotate_general(first, middle, last);
1436 template <
typename TIterator1,
typename TIterator2,
typename TPredicate>
1437 ETL_NODISCARD ETL_CONSTEXPR14 TIterator1 find_end(TIterator1 b, TIterator1 e, TIterator2 sb, TIterator2 se, TPredicate predicate)
1444 TIterator1 result = e;
1448 TIterator1 new_result = etl::search(b, e, sb, se, predicate);
1450 if (new_result == e)
1456 result = new_result;
1465 template <
typename TIterator1,
typename TIterator2>
1466 ETL_NODISCARD ETL_CONSTEXPR14 TIterator1 find_end(TIterator1 b, TIterator1 e, TIterator2 sb, TIterator2 se)
1468 typedef etl::equal_to<typename etl::iterator_traits<TIterator1>::value_type> predicate;
1470 return find_end(b, e, sb, se, predicate());
1478 template <
typename TIterator,
typename TCompare>
1481 TIterator minimum =
begin;
1506 template <
typename TIterator>
1509 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1519 template <
typename TIterator,
typename TCompare>
1522 TIterator maximum =
begin;
1547 template <
typename TIterator>
1550 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1560 template <
typename TIterator,
typename TCompare>
1563 TIterator minimum =
begin;
1564 TIterator maximum =
begin;
1586 return ETL_OR_STD::pair<TIterator, TIterator>(minimum, maximum);
1594 template <
typename TIterator>
1597 typedef typename etl::iterator_traits<TIterator>::value_type value_t;
1607 template <
typename T>
1608 ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair<const T&, const T&>
minmax(
const T& a,
const T& b)
1610 return (b < a) ? ETL_OR_STD::pair<const T&, const T&>(b, a) : ETL_OR_STD::pair<const T&, const T&>(a, b);
1618 template <
typename T,
typename TCompare>
1619 ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair<const T&, const T&>
minmax(
const T& a,
const T& b, TCompare
compare)
1621 return compare(b, a) ? ETL_OR_STD::pair<const T&, const T&>(b, a) : ETL_OR_STD::pair<const T&, const T&>(a, b);
1629 template <
typename TIterator,
typename TCompare>
1634 TIterator next =
begin;
1636 while (++next !=
end)
1655 template <
typename TIterator>
1668 template <
typename TIterator>
1679 template <
typename TIterator,
typename TCompare>
1689 template <
typename TIterator,
typename TCompare>
1694 TIterator next =
begin;
1696 while (++next !=
end)
1714 template <
typename TIterator>
1726 template <
typename TIterator>
1736 template <
typename TIterator,
typename TCompare>
1747 template <
typename TIterator,
typename TUnaryPredicate>
1748 ETL_NODISCARD ETL_CONSTEXPR14 TIterator
find_if_not(TIterator
begin, TIterator
end, TUnaryPredicate predicate)
1752 if (!predicate(*
begin))
1768 template <
typename TIterator,
typename TBinaryPredicate>
1769 ETL_NODISCARD ETL_CONSTEXPR14 TIterator
adjacent_find(TIterator first, TIterator last, TBinaryPredicate predicate)
1773 TIterator next = first;
1776 while (next != last)
1778 if (predicate(*first, *next))
1796 template <
typename TIterator>
1797 ETL_NODISCARD ETL_CONSTEXPR14 TIterator
adjacent_find(TIterator first, TIterator last)
1809 template <
typename TIterator1,
typename TIterator2>
1810 ETL_NODISCARD ETL_CONSTEXPR14
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2)
1814 TIterator2 end2 = begin2;
1816 etl::advance(end2, etl::distance(begin1, end1));
1818 for (TIterator1 i = begin1; i != end1; ++i)
1820 if (i == etl::find(begin1, i, *i))
1822 size_t n =
static_cast<size_t>(etl::count(begin2, end2, *i));
1824 if (n == 0 ||
size_t(etl::count(i, end1, *i)) != n)
1840 template <
typename TIterator1,
typename TIterator2,
typename TBinaryPredicate>
1841 ETL_NODISCARD ETL_CONSTEXPR14
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TBinaryPredicate predicate)
1845 TIterator2 end2 = begin2;
1847 etl::advance(end2, etl::distance(begin1, end1));
1849 for (TIterator1 i = begin1; i != end1; ++i)
1852 if (i == etl::find_if(begin1, i, predicate_is_i))
1854 size_t n =
static_cast<size_t>(etl::count_if(begin2, end2, predicate_is_i));
1856 if (n == 0 ||
size_t(etl::count_if(i, end1, predicate_is_i)) != n)
1872 template <
typename TIterator1,
typename TIterator2>
1873 ETL_NODISCARD ETL_CONSTEXPR14
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2)
1875 if (etl::distance(begin1, end1) != etl::distance(begin2, end2))
1882 for (TIterator1 i = begin1; i != end1; ++i)
1884 if (i == etl::find(begin1, i, *i))
1886 size_t n =
static_cast<size_t>(etl::count(begin2, end2, *i));
1888 if (n == 0 ||
size_t(etl::count(i, end1, *i)) != n)
1904 template <
typename TIterator1,
typename TIterator2,
typename TBinaryPredicate>
1905 ETL_NODISCARD ETL_CONSTEXPR14
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2, TBinaryPredicate predicate)
1907 if (etl::distance(begin1, end1) != etl::distance(begin2, end2))
1914 for (TIterator1 i = begin1; i != end1; ++i)
1917 if (i == etl::find_if(begin1, i, predicate_is_i))
1919 size_t n =
static_cast<size_t>(etl::count_if(begin2, end2, predicate_is_i));
1921 if (n == 0 ||
size_t(etl::count_if(i, end1, predicate_is_i)) != n)
1937 template <
typename TIterator,
typename TCompare>
1968 etl::iter_swap(i, j);
1969 etl::reverse(i1, last);
1975 etl::reverse(first, last);
1986 template <
typename TIterator>
1998 template <
typename TIterator,
typename TCompare>
2029 etl::iter_swap(i, j);
2030 etl::reverse(i1, last);
2036 etl::reverse(first, last);
2047 template <
typename TIterator>
2059 template <
typename TIterator,
typename TUnaryPredicate>
2064 if (!predicate(*
begin))
2074 if (predicate(*
begin))
2090 template <
typename TIterator,
typename TUnaryPredicate>
2093 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
2096 for (difference_t length = etl::distance(
begin,
end); 0 < length;)
2098 difference_t half = length / 2;
2099 TIterator middle = etl::next(
begin, half);
2100 if (predicate(*middle))
2102 begin = etl::next(middle);
2103 length -= (half + 1);
2120 template <
typename TSource,
typename TDestinationTrue,
typename TDestinationFalse,
typename TUnaryPredicate>
2121 ETL_CONSTEXPR14 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>
partition_copy(TSource
begin, TSource
end, TDestinationTrue destination_true,
2122 TDestinationFalse destination_false, TUnaryPredicate predicate)
2126 if (predicate(*
begin))
2128 *destination_true = *
begin;
2133 *destination_false = *
begin;
2134 ++destination_false;
2140 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
2148 template <
typename TSource,
typename TDestinationTrue,
typename TDestinationFalse,
typename TUnaryPredicate>
2149 ETL_CONSTEXPR14 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>
partition_move(TSource
begin, TSource
end, TDestinationTrue destination_true,
2150 TDestinationFalse destination_false, TUnaryPredicate predicate)
2154 if (predicate(*
begin))
2156 *destination_true = etl::move(*
begin);
2161 *destination_false = etl::move(*
begin);
2162 ++destination_false;
2168 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
2176 template <
typename TIterator,
typename TOutputIterator,
typename TUnaryPredicate>
2177 ETL_CONSTEXPR14 TOutputIterator
copy_if(TIterator
begin, TIterator
end, TOutputIterator out, TUnaryPredicate predicate)
2181 if (predicate(*
begin))
2198 template <
typename TIterator,
typename TUnaryPredicate>
2199 ETL_NODISCARD ETL_CONSTEXPR14
bool all_of(TIterator
begin, TIterator
end, TUnaryPredicate predicate)
2209 template <
typename TIterator,
typename TUnaryPredicate>
2210 ETL_NODISCARD ETL_CONSTEXPR14
bool any_of(TIterator
begin, TIterator
end, TUnaryPredicate predicate)
2212 return etl::find_if(
begin,
end, predicate) !=
end;
2220 template <
typename TIterator,
typename TUnaryPredicate>
2221 ETL_NODISCARD ETL_CONSTEXPR14
bool none_of(TIterator
begin, TIterator
end, TUnaryPredicate predicate)
2223 return etl::find_if(
begin,
end, predicate) ==
end;
2226#if ETL_NOT_USING_STL
2232 template <
typename TIterator,
typename TCompare>
2233 void sort(TIterator first, TIterator last, TCompare compare)
2242 template <
typename TIterator>
2243 void sort(TIterator first, TIterator last)
2245 etl::shell_sort(first, last, etl::less<
typename etl::iterator_traits<TIterator>::value_type>());
2254 template <
typename TIterator,
typename TCompare>
2265 template <
typename TIterator>
2268 etl::insertion_sort(first, last, etl::less<
typename etl::iterator_traits<TIterator>::value_type>());
2276 template <
typename TIterator,
typename TCompare>
2279 std::sort(first, last,
compare);
2286 template <
typename TIterator>
2287 void sort(TIterator first, TIterator last)
2289 std::sort(first, last);
2298 template <
typename TIterator,
typename TCompare>
2301 std::stable_sort(first, last,
compare);
2309 template <
typename TIterator>
2312 std::stable_sort(first, last);
2320 template <
typename TIterator,
typename T>
2321 ETL_CONSTEXPR14 T
accumulate(TIterator first, TIterator last, T sum)
2323 while (first != last)
2325 sum =
static_cast<T
>(ETL_MOVE(sum) +
static_cast<T
>(*first));
2336 template <
typename TIterator,
typename T,
typename TBinaryOperation>
2337 ETL_CONSTEXPR14 T
accumulate(TIterator first, TIterator last, T sum, TBinaryOperation operation)
2339 while (first != last)
2341 sum = operation(ETL_MOVE(sum), *first);
2352 template <
typename T,
typename TCompare>
2353 ETL_CONSTEXPR T
clamp(
const T& value,
const T& low,
const T& high, TCompare
compare)
2355 return compare(value, low) ? low :
compare(high, value) ? high : value;
2358 template <
typename T>
2359 ETL_CONSTEXPR T
clamp(
const T& value,
const T& low,
const T& high)
2364 template <
typename T, T Low, T High,
typename TCompare>
2365 ETL_CONSTEXPR T
clamp(
const T& value, TCompare
compare)
2367 return compare(value, Low) ? Low :
compare(High, value) ? High : value;
2370 template <
typename T, T Low, T High>
2371 ETL_CONSTEXPR T
clamp(
const T& value)
2380 template <
typename TIterator,
typename T>
2381 ETL_CONSTEXPR14 TIterator
remove(TIterator first, TIterator last,
const T& value)
2383 first = etl::find(first, last, value);
2387 TIterator itr = first;
2389 while (++itr != last)
2391 if (!(*itr == value))
2393 *first++ = ETL_MOVE(*itr);
2405 template <
typename TIterator,
typename TUnaryPredicate>
2406 ETL_CONSTEXPR14 TIterator
remove_if(TIterator first, TIterator last, TUnaryPredicate predicate)
2408 first = etl::find_if(first, last, predicate);
2412 TIterator itr = first;
2414 while (++itr != last)
2416 if (!predicate(*itr))
2418 *first++ = ETL_MOVE(*itr);
2431 template <
typename TIterator>
2432 ETL_CONSTEXPR14 TIterator
unique(TIterator first, TIterator last)
2439 TIterator result = first;
2441 while (++first != last)
2443 if (!(*result == *first) && (++result != first))
2445 *result = ETL_MOVE(*first);
2458 template <
typename TIterator,
typename TBinaryPredicate>
2459 ETL_CONSTEXPR14 TIterator
unique(TIterator first, TIterator last, TBinaryPredicate predicate)
2466 TIterator result = first;
2468 while (++first != last)
2470 if (!predicate(*result, *first) && (++result != first))
2472 *result = ETL_MOVE(*first);
2484 template <
typename TInputIterator,
typename TOutputIterator>
2485 ETL_CONSTEXPR14 TOutputIterator
unique_copy(TInputIterator first, TInputIterator last, TOutputIterator d_first)
2492 typename etl::iterator_traits<TInputIterator>::value_type prev = *first;
2495 while (++first != last)
2497 if (!(prev == *first))
2500 *(++d_first) = prev;
2513 template <
typename TInputIterator,
typename TOutputIterator,
typename TBinaryPredicate>
2514 ETL_CONSTEXPR14 TOutputIterator
unique_copy(TInputIterator first, TInputIterator last, TOutputIterator d_first, TBinaryPredicate predicate)
2521 typename etl::iterator_traits<TInputIterator>::value_type prev = *first;
2524 while (++first != last)
2526 if (!predicate(prev, *first))
2529 *(++d_first) = prev;
2542 template <
typename TInputIterator1,
typename TInputIterator2,
typename TOutputIterator,
typename TCompare>
2543 ETL_CONSTEXPR14 TOutputIterator
merge(TInputIterator1 first1, TInputIterator1 last1, TInputIterator2 first2, TInputIterator2 last2,
2544 TOutputIterator d_first, TCompare
compare)
2546 while ((first1 != last1) && (first2 != last2))
2548 if (
compare(*first2, *first1))
2561 d_first = etl::copy(first1, last1, d_first);
2562 d_first = etl::copy(first2, last2, d_first);
2574 template <
typename TInputIterator1,
typename TInputIterator2,
typename TOutputIterator>
2575 ETL_CONSTEXPR14 TOutputIterator
merge(TInputIterator1 first1, TInputIterator1 last1, TInputIterator2 first2, TInputIterator2 last2,
2576 TOutputIterator d_first)
2594 template <
typename TB
idirectionalIterator,
typename TCompare>
2595 void inplace_merge(TBidirectionalIterator first, TBidirectionalIterator middle, TBidirectionalIterator last, TCompare
compare)
2597 typedef typename etl::iterator_traits<TBidirectionalIterator>::difference_type
difference_type;
2602 while ((len1 != 0) && (len2 != 0))
2607 TBidirectionalIterator cut1 = etl::upper_bound(first, middle, *middle,
compare);
2623 TBidirectionalIterator cut2 = etl::lower_bound(middle, last, *first,
compare);
2631 etl::rotate(first, middle, cut2);
2634 etl::advance(first, run);
2647 template <
typename TB
idirectionalIterator>
2648 void inplace_merge(TBidirectionalIterator first, TBidirectionalIterator middle, TBidirectionalIterator last)
2672 template <
typename TInputIterator,
typename TOutputIterator>
2674 typename etl::enable_if< etl::is_random_iterator<TInputIterator>::value && etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>::type
2675 copy_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
2677 typedef typename iterator_traits<TInputIterator>::difference_type s_size_type;
2678 typedef typename iterator_traits<TOutputIterator>::difference_type d_size_type;
2681 typedef typename etl::common_type<s_size_type, d_size_type>::type min_size_type;
2683 typedef typename etl::largest_type<s_size_type, d_size_type>::type min_size_type;
2686 s_size_type s_size = etl::distance(i_begin, i_end);
2687 d_size_type d_size = etl::distance(o_begin, o_end);
2688 min_size_type min_size = etl::min<min_size_type>(s_size, d_size);
2690 return etl::copy(i_begin, i_begin + min_size, o_begin);
2704 template <
typename TInputIterator,
typename TOutputIterator>
2705 ETL_CONSTEXPR14
typename etl::enable_if< !etl::is_random_iterator<TInputIterator>::value || !etl::is_random_iterator<TOutputIterator>::value,
2707 copy_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
2709 while ((i_begin != i_end) && (o_begin != o_end))
2711 *o_begin = *i_begin;
2724 template <
typename TInputIterator,
typename TSize,
typename TOutputIterator>
2725 ETL_CONSTEXPR14 TOutputIterator
copy_n_s(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TOutputIterator o_end)
2727 while ((n-- > 0) && (o_begin != o_end))
2729 *o_begin = *i_begin;
2742 template <
typename TInputIterator,
typename TSize1,
typename TOutputIterator,
typename TSize2>
2743 ETL_CONSTEXPR14 TOutputIterator
copy_n_s(TInputIterator i_begin, TSize1 n1, TOutputIterator o_begin, TSize2 n2)
2745 while ((n1-- > 0) && (n2-- > 0))
2747 *o_begin = *i_begin;
2761 template <
typename TInputIterator,
typename TOutputIterator,
typename TUnaryPredicate>
2762 ETL_CONSTEXPR14 TOutputIterator
copy_if_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end,
2763 TUnaryPredicate predicate)
2765 while ((i_begin != i_end) && (o_begin != o_end))
2767 if (predicate(*i_begin))
2769 *o_begin = *i_begin;
2784 template <
typename TInputIterator,
typename TSize,
typename TOutputIterator,
typename TUnaryPredicate>
2785 ETL_CONSTEXPR14 TOutputIterator
copy_n_if(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryPredicate predicate)
2789 if (predicate(*i_begin))
2791 *o_begin = *i_begin;
2813 template <
typename TInputIterator,
typename TOutputIterator>
2815 typename etl::enable_if< etl::is_random_iterator<TInputIterator>::value && etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>
::type
2816 move_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
2818 using s_size_type =
typename iterator_traits<TInputIterator>::difference_type;
2819 using d_size_type =
typename iterator_traits<TOutputIterator>::difference_type;
2820 using min_size_type =
typename etl::common_type<s_size_type, d_size_type>::type;
2822 s_size_type s_size = etl::distance(i_begin, i_end);
2823 d_size_type d_size = etl::distance(o_begin, o_end);
2824 min_size_type min_size = etl::min<min_size_type>(s_size, d_size);
2827 return etl::move(i_begin, i_begin + min_size, o_begin);
2842 template <
typename TInputIterator,
typename TOutputIterator>
2843 ETL_CONSTEXPR14
typename etl::enable_if< !etl::is_random_iterator<TInputIterator>::value || !etl::is_random_iterator<TOutputIterator>::value,
2844 TOutputIterator>::type
2845 move_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
2847 while ((i_begin != i_end) && (o_begin != o_end))
2849 *o_begin = etl::move(*i_begin);
2869 template <
typename TInputIterator,
typename TOutputIterator>
2870 TOutputIterator
move_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
2873 return etl::copy_s(i_begin, i_end, o_begin, o_end);
2883 template <
typename TIterator,
typename TValue>
2886 TIterator it = etl::lower_bound(
begin,
end, value);
2888 if ((it ==
end) || (*it != value))
2902 template <
typename TIterator,
typename TValue,
typename TBinaryPredicate,
typename TBinaryEquality>
2903 ETL_NODISCARD ETL_CONSTEXPR14 TIterator
binary_find(TIterator
begin, TIterator
end,
const TValue& value, TBinaryPredicate predicate, TBinaryEquality equality)
2905 TIterator it = etl::lower_bound(
begin,
end, value, predicate);
2907 if ((it ==
end) || !equality(*it, value))
2919 template <
typename TIterator,
typename TUnaryFunction,
typename TUnaryPredicate>
2924 if (predicate(*
begin))
2939 template <
typename TIterator,
typename TSize,
typename TUnaryFunction>
2956 template <
typename TIterator,
typename TSize,
typename TUnaryFunction,
typename TUnaryPredicate>
2961 if (predicate(*
begin))
2978 template <
typename TInputIterator,
typename TOutputIterator,
typename TUnaryFunction>
2979 ETL_CONSTEXPR14 TOutputIterator
transform_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end,
2982 while ((i_begin != i_end) && (o_begin != o_end))
2998 template <
typename TInputIterator,
typename TSize,
typename TOutputIterator,
typename TUnaryFunction>
2999 ETL_CONSTEXPR14
void transform_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryFunction
function)
3001 TInputIterator i_end(i_begin);
3002 etl::advance(i_end, n);
3004 etl::transform(i_begin, i_end, o_begin,
function);
3013 template <
typename TInputIterator1,
typename TInputIterator2,
typename TSize,
typename TOutputIterator,
typename TBinaryFunction>
3014 ETL_CONSTEXPR14
void transform_n(TInputIterator1 i_begin1, TInputIterator2 i_begin2, TSize n, TOutputIterator o_begin, TBinaryFunction
function)
3016 TInputIterator1 i_end1(i_begin1);
3017 etl::advance(i_end1, n);
3019 etl::transform(i_begin1, i_end1, i_begin2, o_begin,
function);
3026 template <
typename TInputIterator,
typename TOutputIterator,
typename TUnaryFunction,
typename TUnaryPredicate>
3027 ETL_CONSTEXPR14 TOutputIterator
transform_if(TInputIterator i_begin,
const TInputIterator i_end, TOutputIterator o_begin, TUnaryFunction
function,
3028 TUnaryPredicate predicate)
3030 while (i_begin != i_end)
3032 if (predicate(*i_begin))
3048 template <
typename TInputIterator1,
typename TInputIterator2,
typename TOutputIterator,
typename TBinaryFunction,
typename TBinaryPredicate>
3049 ETL_CONSTEXPR14 TOutputIterator
transform_if(TInputIterator1 i_begin1,
const TInputIterator1 i_end1, TInputIterator2 i_begin2, TOutputIterator o_begin,
3050 TBinaryFunction
function, TBinaryPredicate predicate)
3052 while (i_begin1 != i_end1)
3054 if (predicate(*i_begin1, *i_begin2))
3056 *o_begin =
function(*i_begin1, *i_begin2);
3071 template <
typename TInputIterator,
typename TSize,
typename TOutputIterator,
typename TUnaryFunction,
typename TUnaryPredicate>
3072 ETL_CONSTEXPR14 TOutputIterator
transform_n_if(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryFunction
function,
3073 TUnaryPredicate predicate)
3077 if (predicate(*i_begin))
3093 template <
typename TInputIterator1,
typename TInputIterator2,
typename TSize,
typename TOutputIterator,
typename TBinaryFunction,
3094 typename TBinaryPredicate>
3095 ETL_CONSTEXPR14 TOutputIterator
transform_n_if(TInputIterator1 i_begin1, TInputIterator2 i_begin2, TSize n, TOutputIterator o_begin,
3096 TBinaryFunction
function, TBinaryPredicate predicate)
3100 if (predicate(*i_begin1, *i_begin2))
3102 *o_begin++ =
function(*i_begin1, *i_begin2);
3117 template <
typename TSource,
typename TDestinationTrue,
typename TDestinationFalse,
typename TUnaryFunctionTrue,
typename TUnaryFunctionFalse,
3118 typename TUnaryPredicate>
3119 ETL_CONSTEXPR14 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>
3121 TUnaryFunctionTrue function_true, TUnaryFunctionFalse function_false, TUnaryPredicate predicate)
3125 if (predicate(*
begin))
3127 *destination_true = function_true(*
begin);
3132 *destination_false = function_false(*
begin);
3133 ++destination_false;
3139 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
3147 template <
typename TSource1,
typename TSource2,
typename TDestinationTrue,
typename TDestinationFalse,
typename TBinaryFunctionTrue,
3148 typename TBinaryFunctionFalse,
typename TBinaryPredicate>
3149 ETL_CONSTEXPR14 ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>
3150 partition_transform(TSource1 begin1, TSource1 end1, TSource2 begin2, TDestinationTrue destination_true, TDestinationFalse destination_false,
3151 TBinaryFunctionTrue function_true, TBinaryFunctionFalse function_false, TBinaryPredicate predicate)
3153 while (begin1 != end1)
3155 if (predicate(*begin1, *begin2))
3157 *destination_true = function_true(*begin1, *begin2);
3162 *destination_false = function_false(*begin1, *begin2);
3163 ++destination_false;
3170 return ETL_OR_STD::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
3178 template <
typename TIterator,
typename TCompare>
3179#if ETL_USING_STD_NAMESPACE
3192 typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
3194 difference_t n = etl::distance(first, last);
3196 for (difference_t i = n / 2; i > 0; i /= 2)
3198 for (difference_t j = i; j < n; ++j)
3200 for (difference_t k = j - i; k >= 0; k -= i)
3202 TIterator itr1 = first;
3203 TIterator itr2 = first;
3205 etl::advance(itr1, k);
3206 etl::advance(itr2, k + i);
3210 etl::iter_swap(itr1, itr2);
3221 template <
typename TIterator>
3222#if ETL_USING_STD_NAMESPACE
3238 template <
typename TIterator,
typename TCompare>
3241 for (TIterator itr = first; itr != last; ++itr)
3243 etl::rotate(etl::upper_bound(first, itr, *itr,
compare), itr, etl::next(itr));
3251 template <
typename TIterator>
3258 namespace private_algorithm
3260 template <
typename TIterator>
3261 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_forward_iterator<TIterator>::value, TIterator>
::type get_before_last(TIterator first_, TIterator last_)
3263 TIterator last = first_;
3264 TIterator lastplus1 = first_;
3267 while (lastplus1 != last_)
3276 template <
typename TIterator>
3277 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_bidirectional_iterator<TIterator>::value, TIterator>::type get_before_last(TIterator ,
3280 TIterator last = last_;
3286 template <
typename TIterator>
3287 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_random_access_iterator<TIterator>::value, TIterator>::type get_before_last(TIterator ,
3299 template <
typename TIterator,
typename TCompare>
3308 const TIterator ilast = private_algorithm::get_before_last(first, last);
3309 const TIterator jlast = last;
3311 for (TIterator i = first; i != ilast; ++i)
3318 for (; j != jlast; ++j)
3326 using ETL_OR_STD::swap;
3338 template <
typename TIterator>
3349 template <
typename TIterator,
typename TCompare>
3352 etl::make_heap(first, last,
compare);
3353 etl::sort_heap(first, last,
compare);
3360 template <
typename TIterator>
3361 ETL_CONSTEXPR14
void heap_sort(TIterator first, TIterator last)
3363 etl::make_heap(first, last);
3364 etl::sort_heap(first, last);
3371 template <
typename T>
3373 constexpr const T& multimax(
const T& a,
const T& b)
3375 return a < b ? b : a;
3378 template <
typename T,
typename... Tx>
3380 constexpr const T& multimax(
const T& t,
const Tx&... tx)
3382 return multimax(t, multimax(tx...));
3391 template <
typename TCompare,
typename T>
3393 constexpr const T& multimax_compare(TCompare
compare,
const T& a,
const T& b)
3398 template <
typename TCompare,
typename T,
typename... Tx>
3400 constexpr const T& multimax_compare(TCompare
compare,
const T& t,
const Tx&... tx)
3402 return multimax_compare(
compare, t, multimax_compare(
compare, tx...));
3410 template <
typename T>
3412 constexpr const T& multimin(
const T& a,
const T& b)
3414 return a < b ? a : b;
3417 template <
typename T,
typename... Tx>
3419 constexpr const T& multimin(
const T& t,
const Tx&... tx)
3421 return multimin(t, multimin(tx...));
3430 template <
typename TCompare,
typename T>
3432 constexpr const T& multimin_compare(TCompare
compare,
const T& a,
const T& b)
3437 template <
typename TCompare,
typename T,
typename... Tx>
3439 constexpr const T& multimin_compare(TCompare
compare,
const T& t,
const Tx&... tx)
3441 return multimin_compare(
compare, t, multimin_compare(
compare, tx...));
3449 template <
typename TIterator>
3451 constexpr const TIterator& multimax_iter(
const TIterator& a,
const TIterator& b)
3453 return *a < *b ? b : a;
3456 template <
typename TIterator,
typename... TIteratorx>
3458 constexpr const TIterator& multimax_iter(
const TIterator& t,
const TIteratorx&... tx)
3460 return multimax_iter(t, multimax_iter(tx...));
3469 template <
typename TCompare,
typename TIterator>
3471 constexpr const TIterator& multimax_iter_compare(TCompare
compare,
const TIterator& a,
const TIterator& b)
3473 return compare(*a, *b) ? b : a;
3476 template <
typename TCompare,
typename TIterator,
typename... TIteratorx>
3478 constexpr const TIterator& multimax_iter_compare(TCompare
compare,
const TIterator& t,
const TIteratorx&... tx)
3480 return multimax_iter_compare(
compare, t, multimax_iter_compare(
compare, tx...));
3488 template <
typename TIterator>
3490 constexpr const TIterator& multimin_iter(
const TIterator& a,
const TIterator& b)
3492 return *a < *b ? a : b;
3495 template <
typename TIterator,
typename... Tx>
3497 constexpr const TIterator& multimin_iter(
const TIterator& t,
const Tx&... tx)
3499 return multimin_iter(t, multimin_iter(tx...));
3508 template <
typename TCompare,
typename TIterator>
3510 constexpr const TIterator& multimin_iter_compare(TCompare
compare,
const TIterator& a,
const TIterator& b)
3512 return compare(*a, *b) ? a : b;
3515 template <
typename TCompare,
typename TIterator,
typename... Tx>
3517 constexpr const TIterator& multimin_iter_compare(TCompare
compare,
const TIterator& t,
const Tx&... tx)
3519 return multimin_iter_compare(
compare, t, multimin_iter_compare(
compare, tx...));
3528 template <
typename TIterator,
typename TPredicate>
3529 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_forward_iterator<TIterator>::value, TIterator>
::type partition(TIterator first, TIterator last,
3530 TPredicate predicate)
3539 for (TIterator i = etl::next(first); i != last; ++i)
3543 using ETL_OR_STD::swap;
3557 template <
typename TIterator,
typename TPredicate>
3558 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_bidirectional_iterator_concept<TIterator>::value, TIterator>
::type
3559 partition(TIterator first, TIterator last, TPredicate predicate)
3561 while (first != last)
3578 using ETL_OR_STD::swap;
3579 swap(*first, *last);
3591 template <
typename TIterator,
typename TPredicate>
3592 ETL_CONSTEXPR14 TIterator
stable_partition(TIterator first, TIterator last, TPredicate predicate)
3594 typename etl::iterator_traits<TIterator>::difference_type n = etl::distance(first, last);
3602 TIterator mid = first;
3603 etl::advance(mid, n / 2);
3609 TIterator right_partition_start = etl::find_if(left_partition_start, last, predicate);
3610 TIterator right_partition_end =
etl::find_if_not(right_partition_start, last, predicate);
3612 return etl::rotate(left_partition_start, right_partition_start, right_partition_end);
3620 template <
typename TIterator,
typename TPredicate>
3621 ETL_CONSTEXPR14 TIterator
stable_partition(TIterator first, TIterator last, TIterator buffer_first, TIterator buffer_last, TPredicate predicate)
3623 typename etl::iterator_traits<TIterator>::difference_type n = etl::distance(first, last);
3633 TIterator input_first = first;
3634 TIterator buffer_true = buffer_first;
3637 typename etl::iterator_traits<TIterator>::difference_type true_count = etl::count_if(first, last, predicate);
3638 TIterator buffer_false = buffer_first + true_count;
3641 while (first != last)
3643 if (predicate(*first))
3645 *buffer_true++ = etl::move(*first);
3649 *buffer_false++ = etl::move(*first);
3656 TIterator buffer_end = buffer_first;
3657 etl::advance(buffer_end, n);
3658 etl::move(buffer_first, buffer_end, input_first);
3660 etl::advance(input_first, true_count);
3666 namespace private_algorithm
3668 using ETL_OR_STD::swap;
3670 template <
typename TIterator,
typename TCompare>
3671#if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST))
3675 nth_partition(TIterator first, TIterator last, TCompare compare)
3677 typedef typename etl::iterator_traits<TIterator>::value_type value_type;
3679 value_type pivot_value = ETL_MOVE(*last);
3681 TIterator i = first;
3683 for (TIterator j = first; j < last; ++j)
3685 if (!compare(pivot_value, *j))
3704 template <typename TIterator, typename TCompare = etl::less<typename etl::iterator_traits<TIterator>::value_type>>
3705 #if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST))
3708 typename etl::enable_if< etl::is_random_access_iterator_concept<TIterator>::value,
void>::type
3709 nth_element(TIterator first, TIterator nth, TIterator last, TCompare
compare = TCompare())
3719 while (first <= last)
3721 TIterator p = private_algorithm::nth_partition(first, last,
compare);
3741 template <
typename TIterator,
typename TCompare>
3742 typename etl::enable_if< etl::is_random_access_iterator_concept<TIterator>::value,
void>
::type nth_element(TIterator first, TIterator nth,
3743 TIterator last, TCompare
compare)
3753 while (first <= last)
3755 TIterator p = private_algorithm::nth_partition(first, last,
compare);
3773 template <
typename TIterator>
3774 typename etl::enable_if< etl::is_random_access_iterator_concept<TIterator>::value,
void>
::type nth_element(TIterator first, TIterator nth,
3787 template <
class I,
class F>
3788 struct in_fun_result
3790 ETL_NO_UNIQUE_ADDRESS I in;
3791 ETL_NO_UNIQUE_ADDRESS F fun;
3793 template <
class I2,
class F2>
3794 constexpr operator in_fun_result<I2, F2>() const&
3799 template <
class I2,
class F2>
3800 constexpr operator in_fun_result<I2, F2>() &&
3802 return {etl::move(in), etl::move(fun)};
3806 template <
class I1,
class I2>
3809 ETL_NO_UNIQUE_ADDRESS I1 in1;
3810 ETL_NO_UNIQUE_ADDRESS I2 in2;
3812 template <
class II1,
class II2>
3813 constexpr operator in_in_result<II1, II2>() const&
3818 template <
class II1,
class II2>
3819 constexpr operator in_in_result<II1, II2>() &&
3821 return {etl::move(in1), etl::move(in2)};
3825 template <
class I,
class O>
3826 struct in_out_result
3828 ETL_NO_UNIQUE_ADDRESS I in;
3829 ETL_NO_UNIQUE_ADDRESS O out;
3831 template <
class I2,
class O2>
3832 constexpr operator in_out_result<I2, O2>() const&
3837 template <
class I2,
class O2>
3838 constexpr operator in_out_result<I2, O2>() &&
3840 return {etl::move(in), etl::move(out)};
3844 template <
class I1,
class I2,
class O>
3845 struct in_in_out_result
3847 ETL_NO_UNIQUE_ADDRESS I1 in1;
3848 ETL_NO_UNIQUE_ADDRESS I2 in2;
3849 ETL_NO_UNIQUE_ADDRESS O out;
3851 template <
class II1,
class II2,
class OO>
3852 constexpr operator in_in_out_result<II1, II2, OO>() const&
3854 return {in1, in2, out};
3857 template <
class II1,
class II2,
class OO>
3858 constexpr operator in_in_out_result<II1, II2, OO>() &&
3860 return {etl::move(in1), etl::move(in2), etl::move(out)};
3864 template <
class I,
class O1,
class O2>
3865 struct in_out_out_result
3867 ETL_NO_UNIQUE_ADDRESS I in;
3868 ETL_NO_UNIQUE_ADDRESS O1 out1;
3869 ETL_NO_UNIQUE_ADDRESS O2 out2;
3871 template <
class II,
class OO1,
class OO2>
3872 constexpr operator in_out_out_result<II, OO1, OO2>() const&
3874 return {in, out1, out2};
3877 template <
class II,
class OO1,
class OO2>
3878 constexpr operator in_out_out_result<II, OO1, OO2>() &&
3880 return {etl::move(in), etl::move(out1), etl::move(out2)};
3885 struct in_found_result
3887 ETL_NO_UNIQUE_ADDRESS I in;
3891 constexpr operator in_found_result<I2>() const&
3897 constexpr operator in_found_result<I2>() &&
3899 return {etl::move(in), found};
3903 template <
class O,
class T>
3904 struct out_value_result
3906 ETL_NO_UNIQUE_ADDRESS O out;
3907 ETL_NO_UNIQUE_ADDRESS T value;
3909 template <
class O2,
class T2>
3910 constexpr operator out_value_result<O2, T2>() const&
3912 return {out, value};
3915 template <
class O2,
class T2>
3916 constexpr operator out_value_result<O2, T2>() &&
3918 return {etl::move(out), etl::move(value)};
3922 template <
class O,
class T>
3923 using iota_result = out_value_result<O, T>;
3925 template <
class I,
class O>
3926 using copy_result = in_out_result<I, O>;
3928 template <
class I,
class O>
3929 using copy_n_result = in_out_result<I, O>;
3931 template <
class I,
class O>
3932 using copy_if_result = in_out_result<I, O>;
3934 template <
class I,
class O>
3935 using copy_backward_result = in_out_result<I, O>;
3937 template <
class I,
class O>
3938 using uninitialized_copy_result = in_out_result<I, O>;
3940 template <
class I,
class O>
3941 using uninitialized_copy_n_result = in_out_result<I, O>;
3943 template <
class I,
class O>
3944 using uninitialized_move_result = in_out_result<I, O>;
3946 template <
class I,
class O>
3947 using uninitialized_move_n_result = in_out_result<I, O>;
3949 template <
class I,
class O>
3950 using move_result = in_out_result<I, O>;
3952 template <
class I,
class O>
3953 using move_backward_result = in_out_result<I, O>;
3955 template <
class I1,
class I2>
3956 using mismatch_result = in_in_result<I1, I2>;
3958 template <
class I1,
class I2>
3959 using swap_ranges_result = in_in_result<I1, I2>;
3961 template <
class I,
class O>
3962 using unary_transform_result = in_out_result<I, O>;
3964 template <
class I1,
class I2,
class O>
3965 using binary_transform_result = in_in_out_result<I1, I2, O>;
3967 template <
class I,
class O>
3968 using replace_copy_result = in_out_result<I, O>;
3970 template <
class I,
class O>
3971 using replace_copy_if_result = in_out_result<I, O>;
3973 template <
class I,
class O>
3974 using remove_copy_result = in_out_result<I, O>;
3976 template <
class I,
class O>
3977 using unique_copy_result = in_out_result<I, O>;
3979 template <
class I,
class O>
3980 using rotate_copy_result = in_out_result<I, O>;
3982 template <
class I,
class O>
3983 using partial_sort_copy_result = in_out_result<I, O>;
3985 template <
class I,
class O1,
class O2>
3986 using partition_copy_result = in_out_out_result<I, O1, O2>;
3988 template <
class I1,
class I2,
class O>
3989 using set_union_result = in_in_out_result<I1, I2, O>;
3991 template <
class I1,
class I2,
class O>
3992 using set_intersection_result = in_in_out_result<I1, I2, O>;
3994 template <
class I,
class O>
3995 using set_difference_result = in_out_result<I, O>;
3997 template <
class I1,
class I2,
class O>
3998 using set_symmetric_difference_result = in_in_out_result<I1, I2, O>;
4000 template <
class I1,
class I2,
class O>
4001 using merge_result = in_in_out_result<I1, I2, O>;
4004 using next_permutation_result = in_found_result<I>;
4007 using prev_permutation_result = in_found_result<I>;
4010 struct min_max_result
4016 constexpr operator min_max_result<T2>() const&
4022 constexpr operator min_max_result<T2>() &&
4024 return {etl::move(min), etl::move(max)};
4029 using minmax_result = min_max_result<T>;
4032 using minmax_element_result = min_max_result<I>;
4034 template <
class I,
class F>
4035 using for_each_result = in_fun_result<I, F>;
4039 template <
class I,
class S,
class Fun,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4040 constexpr ranges::for_each_result<I, Fun> operator()(I first, S last, Fun f, Proj proj = {})
const
4042 for (; first != last; ++first)
4044 etl::invoke(f, etl::invoke(proj, *first));
4046 return {etl::move(first), etl::move(f)};
4049 template <
class R,
class Fun,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4050 constexpr ranges::for_each_result<ranges::borrowed_iterator_t<R>, Fun> operator()(R&& r, Fun f, Proj proj = {})
const
4052 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(f), etl::ref(proj));
4056 inline constexpr for_each_fn for_each;
4058 template <
class I,
class F>
4059 using for_each_n_result = in_fun_result<I, F>;
4061 struct for_each_n_fn
4063 template <
class I,
class Fun,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4064 constexpr for_each_n_result<I, Fun> operator()(I first, etl::iter_difference_t<I> n, Fun fun, Proj proj = Proj{})
const
4066 for (; n-- > 0; ++first)
4068 etl::invoke(fun, etl::invoke(proj, *first));
4070 return {etl::move(first), etl::move(fun)};
4078 template <
class I,
class S,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4079 constexpr I operator()(I first, S last,
const T& value, Proj proj = {})
const
4081 for (; first != last; ++first)
4083 if (etl::invoke(proj, *first) == value)
4091 template <
class R,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4092 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r,
const T& value, Proj proj = {})
const
4094 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::ref(proj));
4098 inline constexpr find_fn find;
4102 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4103 constexpr I operator()(I first, S last, Pred pred, Proj proj = {})
const
4105 for (; first != last; ++first)
4107 if (etl::invoke(pred, etl::invoke(proj, *first)))
4115 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4116 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
4118 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4122 inline constexpr find_if_fn find_if;
4124 struct find_if_not_fn
4126 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4127 constexpr I operator()(I first, S last, Pred pred, Proj proj = {})
const
4129 for (; first != last; ++first)
4131 if (!etl::invoke(pred, etl::invoke(proj, *first)))
4139 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4140 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
4142 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4150 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4151 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4152 constexpr ranges::subrange<I1> operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4157 for (I2 it2 = first2;; ++it1, ++it2)
4161 return {first1, it1};
4167 if (!etl::invoke(pred, etl::invoke(proj1, *it1), etl::invoke(proj2, *it2)))
4175 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4176 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4177 constexpr ranges::borrowed_subrange_t<R1> operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4179 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4183 inline constexpr search_fn search{};
4187 template <
class I,
class S,
class T = etl::iter_value_t<I>,
class Pred = ranges::equal_to,
class Proj = etl::
identity,
4188 typename = etl::enable_if_t<!etl::is_range_v<I>>>
4189 constexpr ranges::subrange<I> operator()(I first, S last, etl::iter_difference_t<I> count,
const T& value, Pred pred = {}, Proj proj = {})
const
4193 return {first, first};
4196 for (; first != last; ++first)
4198 if (etl::invoke(pred, etl::invoke(proj, *first), value))
4201 etl::iter_difference_t<I> n = 1;
4207 return {start, ++first};
4212 return {first, first};
4214 if (!etl::invoke(pred, etl::invoke(proj, *first), value))
4222 return {first, first};
4225 template <
class R,
class T = etl::ranges::range_value_t<R>,
class Pred = ranges::equal_to,
class Proj = etl::
identity,
4226 typename = etl::enable_if_t<etl::is_range_v<R>>>
4227 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, ranges::range_difference_t<R> count,
const T& value, Pred pred = {},
4228 Proj proj = {})
const
4230 return (*
this)(ranges::begin(r), ranges::end(r), count, value, etl::move(pred), etl::move(proj));
4234 inline constexpr search_n_fn search_n{};
4238 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4239 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4240 constexpr ranges::subrange<I1> operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4242 if (first2 == last2)
4244 auto last_it = ranges::next(first1, last1);
4245 return {last_it, last_it};
4247 auto result = ranges::search(etl::move(first1), last1, first2, last2, pred, proj1, proj2);
4256 auto new_result = ranges::search(etl::next(result.begin()), last1, first2, last2, pred, proj1, proj2);
4257 if (new_result.empty())
4263 result = etl::move(new_result);
4268 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4269 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4270 constexpr ranges::borrowed_subrange_t<R1> operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4272 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4276 inline constexpr find_end_fn find_end{};
4278 struct find_first_of_fn
4280 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4281 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4282 constexpr I1 operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4284 for (; first1 != last1; ++first1)
4286 for (
auto i = first2; i != last2; ++i)
4288 if (etl::invoke(pred, etl::invoke(proj1, *first1), etl::invoke(proj2, *i)))
4297 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4298 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4299 constexpr ranges::borrowed_iterator_t<R1> operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4301 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4307 struct adjacent_find_fn
4309 template <
class I,
class S,
class Proj = etl::
identity,
class Pred = ranges::equal_to,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4310 constexpr I operator()(I first, S last, Pred pred = {}, Proj proj = {})
const
4316 auto next_it = ranges::next(first);
4317 for (; next_it != last; ++next_it, ++first)
4319 if (etl::invoke(pred, etl::invoke(proj, *first), etl::invoke(proj, *next_it)))
4327 template <
class R,
class Proj = etl::
identity,
class Pred = ranges::equal_to,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4328 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Pred pred = {}, Proj proj = {})
const
4330 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4338 template <
class I,
class S,
class Proj = etl::
identity,
class T = etl::projected_value_t<I, Proj>,
4339 typename = etl::enable_if_t<!etl::is_range_v<I>>>
4340 constexpr etl::iter_difference_t<I> operator()(I first, S last,
const T& value, Proj proj = {})
const
4342 etl::iter_difference_t<I> counter = 0;
4343 for (; first != last; ++first)
4345 if (etl::invoke(proj, *first) == value)
4353 template <
class R,
class Proj = etl::
identity,
class T = etl::projected_value_t<ranges::iterator_t<R>, Proj>,
4354 typename = etl::enable_if_t<etl::is_range_v<R>>>
4355 constexpr ranges::range_difference_t<R> operator()(R&& r,
const T& value, Proj proj = {})
const
4357 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::ref(proj));
4361 inline constexpr count_fn count;
4365 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4366 constexpr etl::iter_difference_t<I> operator()(I first, S last, Pred pred, Proj proj = {})
const
4368 etl::iter_difference_t<I> counter = 0;
4369 for (; first != last; ++first)
4371 if (etl::invoke(pred, etl::invoke(proj, *first)))
4379 template <
class R,
class Proj = etl::
identity,
class Pred,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4380 constexpr ranges::range_difference_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
4382 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4386 inline constexpr count_if_fn count_if;
4390 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4391 constexpr bool operator()(I first, S last, Pred pred, Proj proj = {})
const
4393 return ranges::find_if_not(first, last, etl::ref(pred), etl::ref(proj)) == last;
4396 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4397 constexpr bool operator()(R&& r, Pred pred, Proj proj = {})
const
4399 return operator()(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4403 inline constexpr all_of_fn
all_of;
4407 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4408 constexpr bool operator()(I first, S last, Pred pred, Proj proj = {})
const
4410 return ranges::find_if(first, last, etl::ref(pred), etl::ref(proj)) != last;
4413 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4414 constexpr bool operator()(R&& r, Pred pred, Proj proj = {})
const
4416 return operator()(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4420 inline constexpr any_of_fn
any_of;
4424 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4425 constexpr bool operator()(I first, S last, Pred pred, Proj proj = {})
const
4427 return ranges::find_if(first, last, etl::ref(pred), etl::ref(proj)) == last;
4430 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4431 constexpr bool operator()(R&& r, Pred pred, Proj proj = {})
const
4433 return operator()(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
4437 inline constexpr none_of_fn
none_of;
4441 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4442 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4443 constexpr ranges::mismatch_result<I1, I2> operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {},
4444 Proj2 proj2 = {})
const
4446 for (; first1 != last1 && first2 != last2; ++first1, ++first2)
4448 if (!etl::invoke(pred, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
4453 return {etl::move(first1), etl::move(first2)};
4456 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4457 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4458 constexpr ranges::mismatch_result<ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>>
4459 operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4461 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4465 inline constexpr mismatch_fn mismatch{};
4469 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4470 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4471 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4473 for (; first1 != last1 && first2 != last2; ++first1, ++first2)
4475 if (!etl::invoke(pred, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
4480 return first1 == last1 && first2 == last2;
4483 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4484 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4485 constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4487 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4491 inline constexpr equal_fn equal{};
4493 struct is_permutation_fn
4495 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4496 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4497 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4500 for (; first1 != last1 && first2 != last2; ++first1, ++first2)
4502 if (!etl::invoke(pred, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
4508 if (first1 == last1)
4510 return first2 == last2;
4513 if (first2 == last2)
4519 for (I1 i = first1; i != last1; ++i)
4522 bool already_seen =
false;
4523 for (I1 j = first1; j != i; ++j)
4525 if (etl::invoke(pred, etl::invoke(proj1, *i), etl::invoke(proj1, *j)))
4527 already_seen =
true;
4538 auto count2 = etl::iter_difference_t<I2>(0);
4539 for (I2 k = first2; k != last2; ++k)
4541 if (etl::invoke(pred, etl::invoke(proj1, *i), etl::invoke(proj2, *k)))
4553 auto count1 = etl::iter_difference_t<I1>(0);
4554 for (I1 k = i; k != last1; ++k)
4556 if (etl::invoke(pred, etl::invoke(proj1, *i), etl::invoke(proj1, *k)))
4562 if (count1 != count2)
4571 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4572 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4573 constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4575 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4581 struct starts_with_fn
4583 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4584 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4585 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4587 for (; first2 != last2; ++first1, ++first2)
4589 if (first1 == last1 || !etl::invoke(pred, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
4597 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4598 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4599 constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4601 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4605 inline constexpr starts_with_fn starts_with{};
4609 template <
class I1,
class S1,
class I2,
class S2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4610 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4611 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4613 auto n1 = etl::distance(first1, last1);
4614 auto n2 = etl::distance(first2, last2);
4621 ranges::advance(first1, n1 - n2);
4623 return starts_with(first1, last1, first2, last2, etl::move(pred), etl::move(proj1), etl::move(proj2));
4626 template <
class R1,
class R2,
class Pred = ranges::equal_to,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4627 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4628 constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4630 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(pred), etl::move(proj1), etl::move(proj2));
4634 inline constexpr ends_with_fn ends_with{};
4636 struct lexicographical_compare_fn
4638 template <
class I1,
class S1,
class I2,
class S2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4639 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4640 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4642 for (; first1 != last1 && first2 != last2; ++first1, ++first2)
4644 if (etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
4649 if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
4654 return first1 == last1 && first2 != last2;
4657 template <
class R1,
class R2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
4658 typename = etl::enable_if_t<etl::is_range_v<R1>>>
4659 constexpr bool operator()(R1&& r1, R2&& r2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
4661 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(comp), etl::move(proj1), etl::move(proj2));
4665 inline constexpr lexicographical_compare_fn lexicographical_compare{};
4667 template <
class I,
class T>
4668 struct in_value_result
4670 ETL_NO_UNIQUE_ADDRESS I in;
4671 ETL_NO_UNIQUE_ADDRESS T value;
4673 template <
class I2,
class T2>
4674 constexpr operator in_value_result<I2, T2>() const&
4679 template <
class I2,
class T2>
4680 constexpr operator in_value_result<I2, T2>() &&
4682 return {etl::move(in), etl::move(value)};
4686 template <
class I,
class T>
4687 using fold_left_with_iter_result = in_value_result<I, T>;
4691 template <
class I,
class S,
class T,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4692 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>>>
4694 using U = etl::decay_t<etl::invoke_result_t<F&, T, etl::iter_reference_t<I>>>;
4695 U accum = etl::move(init);
4696 for (; first != last; ++first)
4698 accum = etl::invoke(f, etl::move(accum), *first);
4703 template <
class R,
class T,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4704 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>>>
4706 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(init), etl::move(f));
4710 inline constexpr fold_left_fn fold_left{};
4712 struct fold_left_with_iter_fn
4714 template <
class I,
class S,
class T,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4715 constexpr auto operator()(I first, S last, T init,
4716 F f)
const -> fold_left_with_iter_result< I, etl::decay_t<etl::invoke_result_t<F&, T, etl::iter_reference_t<I>>>>
4718 using U = etl::decay_t<etl::invoke_result_t<F&, T, etl::iter_reference_t<I>>>;
4719 U accum = etl::move(init);
4720 for (; first != last; ++first)
4722 accum = etl::invoke(f, etl::move(accum), *first);
4724 return {etl::move(first), etl::move(accum)};
4727 template <
class R,
class T,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4728 constexpr auto operator()(R&& r, T init, F f)
const
4729 -> 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>>>>
4731 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(init), etl::move(f));
4735 inline constexpr fold_left_with_iter_fn fold_left_with_iter{};
4737 struct fold_left_first_fn
4739 template <
class I,
class S,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4740 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>>>
4742 using U = etl::decay_t<etl::invoke_result_t<F&, etl::iter_value_t<I>, etl::iter_reference_t<I>>>;
4749 for (; first != last; ++first)
4751 accum = etl::invoke(f, etl::move(accum), *first);
4756 template <
class R,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4757 constexpr auto operator()(R&& r,
4758 F f)
const -> etl::decay_t<etl::invoke_result_t<F&, etl::ranges::range_value_t<R>, etl::ranges::range_reference_t<R>>>
4760 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(f));
4764 inline constexpr fold_left_first_fn fold_left_first{};
4766 struct fold_left_first_with_iter_fn
4768 template <
class I,
class S,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4769 constexpr auto operator()(I first, S last, F f)
const
4770 -> fold_left_with_iter_result< I, etl::decay_t<etl::invoke_result_t<F&, etl::iter_value_t<I>, etl::iter_reference_t<I>>>>
4772 using U = etl::decay_t<etl::invoke_result_t<F&, etl::iter_value_t<I>, etl::iter_reference_t<I>>>;
4775 return {etl::move(first), U{}};
4779 for (; first != last; ++first)
4781 accum = etl::invoke(f, etl::move(accum), *first);
4783 return {etl::move(first), etl::move(accum)};
4786 template <
class R,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4787 constexpr auto operator()(R&& r, F f)
const
4788 -> fold_left_with_iter_result< ranges::borrowed_iterator_t<R>,
4789 etl::decay_t<etl::invoke_result_t<F&, etl::ranges::range_value_t<R>, etl::ranges::range_reference_t<R>>>>
4791 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(f));
4795 inline constexpr fold_left_first_with_iter_fn fold_left_first_with_iter{};
4797 struct fold_right_fn
4799 template <
class I,
class S,
class T,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4800 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>>
4802 using U = etl::decay_t<etl::invoke_result_t<F&, etl::iter_reference_t<I>, T>>;
4803 U accum = etl::move(init);
4804 I tail = ranges::next(first, last);
4805 while (tail != first)
4807 tail = ranges::prev(tail);
4808 accum = etl::invoke(f, *tail, etl::move(accum));
4813 template <
class R,
class T,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4814 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>>
4816 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(init), etl::move(f));
4820 inline constexpr fold_right_fn fold_right{};
4822 struct fold_right_last_fn
4824 template <
class I,
class S,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4825 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>>>
4827 using U = etl::decay_t<etl::invoke_result_t<F&, etl::iter_reference_t<I>, etl::iter_value_t<I>>>;
4828 I tail = ranges::next(first, last);
4833 tail = ranges::prev(tail);
4835 while (tail != first)
4837 tail = ranges::prev(tail);
4838 accum = etl::invoke(f, *tail, etl::move(accum));
4843 template <
class R,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4845 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>>>
4847 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(f));
4851 inline constexpr fold_right_last_fn fold_right_last{};
4855 template <
class I,
class S,
class O,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4856 constexpr ranges::copy_result<I, O> operator()(I first, S last, O result)
const
4858 for (; first != last; ++first, ++result)
4862 return {etl::move(first), etl::move(result)};
4865 template <
class R,
class O,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4866 constexpr ranges::copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result)
const
4868 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result));
4872 inline constexpr copy_fn copy{};
4876 template <
class I,
class O>
4877 constexpr ranges::copy_n_result<I, O> operator()(I first, etl::iter_difference_t<I> n, O result)
const
4879 for (etl::iter_difference_t<I> i = 0; i < n; ++i, ++first, ++result)
4883 return {etl::move(first), etl::move(result)};
4887 inline constexpr copy_n_fn copy_n{};
4891 template <
class I,
class S,
class O,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4892 constexpr ranges::copy_if_result<I, O> operator()(I first, S last, O result, Pred pred, Proj proj = {})
const
4894 for (; first != last; ++first)
4896 if (etl::invoke(pred, etl::invoke(proj, *first)))
4902 return {etl::move(first), etl::move(result)};
4905 template <
class R,
class O,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4906 constexpr ranges::copy_if_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result, Pred pred, Proj proj = {})
const
4908 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), etl::ref(pred), etl::ref(proj));
4912 inline constexpr copy_if_fn
copy_if{};
4914 struct copy_backward_fn
4916 template <
class I1,
class S1,
class I2,
typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4917 constexpr ranges::copy_backward_result<I1, I2> operator()(I1 first, S1 last, I2 result)
const
4919 I1 last_it = ranges::next(first, last);
4921 while (first != tail)
4923 *(--result) = *(--tail);
4925 return {etl::move(last_it), etl::move(result)};
4928 template <
class R,
class I,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4929 constexpr ranges::copy_backward_result<ranges::borrowed_iterator_t<R>, I> operator()(R&& r, I result)
const
4931 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result));
4935 inline constexpr copy_backward_fn copy_backward{};
4939 template <
class I,
class S,
class O,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
4940 constexpr ranges::move_result<I, O> operator()(I first, S last, O result)
const
4942 for (; first != last; ++first, ++result)
4944 *result = etl::move(*first);
4946 return {etl::move(first), etl::move(result)};
4949 template <
class R,
class O,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4950 constexpr ranges::move_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result)
const
4952 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result));
4956 inline constexpr move_fn move{};
4958 struct move_backward_fn
4960 template <
class I1,
class S1,
class I2,
typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4961 constexpr ranges::move_backward_result<I1, I2> operator()(I1 first, S1 last, I2 result)
const
4963 I1 last_it = ranges::next(first, last);
4965 while (first != tail)
4967 *(--result) = etl::move(*(--tail));
4969 return {etl::move(last_it), etl::move(result)};
4972 template <
class R,
class I,
typename = etl::enable_if_t<etl::is_range_v<R>>>
4973 constexpr ranges::move_backward_result<ranges::borrowed_iterator_t<R>, I> operator()(R&& r, I result)
const
4975 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result));
4979 inline constexpr move_backward_fn move_backward{};
4981 struct swap_ranges_fn
4983 template <
class I1,
class S1,
class I2,
class S2,
typename = etl::enable_if_t<!etl::is_range_v<I1>>>
4984 constexpr ranges::swap_ranges_result<I1, I2> operator()(I1 first1, S1 last1, I2 first2, S2 last2)
const
4986 for (; first1 != last1 && first2 != last2; ++first1, ++first2)
4988 etl::iter_swap(first1, first2);
4990 return {etl::move(first1), etl::move(first2)};
4993 template <
class R1,
class R2,
typename = etl::enable_if_t<etl::is_range_v<R1>>>
4994 constexpr ranges::swap_ranges_result<ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>> operator()(R1&& r1, R2&& r2)
const
4996 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2));
5000 inline constexpr swap_ranges_fn swap_ranges{};
5004 template <
class I,
class S,
class T1,
class T2,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5005 constexpr I operator()(I first, S last,
const T1& old_value,
const T2& new_value, Proj proj = {})
const
5007 for (; first != last; ++first)
5009 if (etl::invoke(proj, *first) == old_value)
5017 template <
class R,
class T1,
class T2,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5018 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r,
const T1& old_value,
const T2& new_value, Proj proj = {})
const
5020 return (*
this)(ranges::begin(r), ranges::end(r), old_value, new_value, etl::ref(proj));
5024 inline constexpr replace_fn replace{};
5026 struct replace_if_fn
5028 template <
class I,
class S,
class Pred,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5029 constexpr I operator()(I first, S last, Pred pred,
const T& new_value, Proj proj = {})
const
5031 for (; first != last; ++first)
5033 if (etl::invoke(pred, etl::invoke(proj, *first)))
5041 template <
class R,
class Pred,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5042 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Pred pred,
const T& new_value, Proj proj = {})
const
5044 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), new_value, etl::ref(proj));
5048 inline constexpr replace_if_fn replace_if{};
5050 struct replace_copy_fn
5052 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>>>
5053 constexpr ranges::replace_copy_result<I, O> operator()(I first, S last, O result,
const T1& old_value,
const T2& new_value,
5054 Proj proj = {})
const
5056 for (; first != last; ++first, ++result)
5058 if (etl::invoke(proj, *first) == old_value)
5060 *result = new_value;
5067 return {etl::move(first), etl::move(result)};
5070 template <
class R,
class O,
class T1,
class T2,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5071 constexpr ranges::replace_copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result,
const T1& old_value,
const T2& new_value,
5072 Proj proj = {})
const
5074 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), old_value, new_value, etl::ref(proj));
5078 inline constexpr replace_copy_fn replace_copy{};
5080 struct replace_copy_if_fn
5082 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>>>
5083 constexpr ranges::replace_copy_if_result<I, O> operator()(I first, S last, O result, Pred pred,
const T& new_value, Proj proj = {})
const
5085 for (; first != last; ++first, ++result)
5087 if (etl::invoke(pred, etl::invoke(proj, *first)))
5089 *result = new_value;
5096 return {etl::move(first), etl::move(result)};
5099 template <
class R,
class O,
class Pred,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5100 constexpr ranges::replace_copy_if_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result, Pred pred,
const T& new_value,
5101 Proj proj = {})
const
5103 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), etl::ref(pred), new_value, etl::ref(proj));
5107 inline constexpr replace_copy_if_fn replace_copy_if{};
5111 template <
class I,
class S,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5112 constexpr ranges::subrange<I> operator()(I first, S last,
const T& value, Proj proj = {})
const
5114 first = ranges::find(first, last, value, etl::ref(proj));
5120 for (I it = result; ++it != last;)
5122 if (!(etl::invoke(proj, *it) == value))
5124 *result = etl::move(*it);
5129 return {result, last};
5132 return {first, last};
5135 template <
class R,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5136 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r,
const T& value, Proj proj = {})
const
5138 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::ref(proj));
5142 inline constexpr remove_fn
remove{};
5146 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5147 constexpr ranges::subrange<I> operator()(I first, S last, Pred pred, Proj proj = {})
const
5149 first = ranges::find_if(first, last, etl::ref(pred), etl::ref(proj));
5155 for (I it = result; ++it != last;)
5157 if (!etl::invoke(pred, etl::invoke(proj, *it)))
5159 *result = etl::move(*it);
5164 return {result, last};
5167 return {first, last};
5170 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5171 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
5173 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
5177 inline constexpr remove_if_fn
remove_if{};
5179 struct remove_copy_fn
5181 template <
class I,
class S,
class O,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5182 constexpr ranges::remove_copy_result<I, O> operator()(I first, S last, O result,
const T& value, Proj proj = {})
const
5184 for (; first != last; ++first)
5186 if (!(etl::invoke(proj, *first) == value))
5192 return {etl::move(first), etl::move(result)};
5195 template <
class R,
class O,
class T,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5196 constexpr ranges::remove_copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result,
const T& value, Proj proj = {})
const
5198 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), value, etl::ref(proj));
5202 inline constexpr remove_copy_fn remove_copy{};
5206 template <
class I,
class S,
class T,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5207 constexpr I operator()(I first, S last,
const T& value)
const
5209 for (; first != last; ++first)
5216 template <
class R,
class T,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5217 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r,
const T& value)
const
5219 return (*
this)(ranges::begin(r), ranges::end(r), value);
5223 inline constexpr fill_fn fill{};
5227 template <
class I,
class T>
5228 constexpr I operator()(I first, etl::iter_difference_t<I> n,
const T& value)
const
5230 for (; n-- > 0; ++first)
5238 inline constexpr fill_n_fn fill_n{};
5242 template <
class I,
class S,
class F,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5243 constexpr I operator()(I first, S last, F gen)
const
5245 for (; first != last; ++first)
5252 template <
class R,
class F,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5253 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, F gen)
const
5255 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(gen));
5259 inline constexpr generate_fn generate{};
5261 struct generate_n_fn
5263 template <
class I,
class F>
5264 constexpr I operator()(I first, etl::iter_difference_t<I> n, F gen)
const
5266 for (; n-- > 0; ++first)
5274 inline constexpr generate_n_fn generate_n{};
5278 template <
class O,
class S,
class T,
typename = etl::enable_if_t<!etl::is_range_v<O>>>
5279 constexpr ranges::iota_result<O, T> operator()(O first, S last, T value)
const
5281 while (first != last)
5287 return {etl::move(first), etl::move(value)};
5290 template <
class R,
class T,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5291 constexpr ranges::iota_result<ranges::borrowed_iterator_t<R>, T> operator()(R&& r, T value)
const
5293 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(value));
5297 inline constexpr iota_fn
iota{};
5301 template <
class I,
class S,
class Pred = ranges::equal_to,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5302 constexpr ranges::subrange<I> operator()(I first, S last, Pred pred = {}, Proj proj = {})
const
5304 first = ranges::adjacent_find(first, last, etl::ref(pred), etl::ref(proj));
5311 while (++first != last)
5313 if (!etl::invoke(pred, etl::invoke(proj, *result), etl::invoke(proj, *first)))
5315 *++result = etl::move(*first);
5319 return {++result, last};
5322 return {first, last};
5325 template <
class R,
class Pred = ranges::equal_to,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5326 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred = {}, Proj proj = {})
const
5328 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
5332 inline constexpr unique_fn
unique{};
5334 struct unique_copy_fn
5336 template <
class I,
class S,
class O,
class Pred = ranges::equal_to,
class Proj = etl::identity,
5337 typename = etl::enable_if_t<!etl::is_range_v<I>>>
5338 constexpr ranges::unique_copy_result<I, O> operator()(I first, S last, O result, Pred pred = {}, Proj proj = {})
const
5345 auto previous = first;
5348 for (; first != last; ++first)
5350 if (!etl::invoke(pred, etl::invoke(proj, *previous), etl::invoke(proj, *first)))
5359 return {etl::move(first), etl::move(result)};
5362 template <
class R,
class O,
class Pred = ranges::equal_to,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5363 constexpr ranges::unique_copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result, Pred pred = {}, Proj proj = {})
const
5365 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), etl::ref(pred), etl::ref(proj));
5374 template <
class I,
class S,
class O,
class F,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5375 constexpr ranges::unary_transform_result<I, O> operator()(I first, S last, O result, F op, Proj proj = {})
const
5377 for (; first != last; ++first, ++result)
5379 *result = etl::invoke(op, etl::invoke(proj, *first));
5381 return {etl::move(first), etl::move(result)};
5385 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>>>
5386 constexpr ranges::unary_transform_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result, F op, Proj proj = {})
const
5388 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result), etl::ref(op), etl::ref(proj));
5392 template <
class I1,
class S1,
class I2,
class S2,
class O,
class F,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
5393 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
5394 constexpr ranges::binary_transform_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, F op, Proj1 proj1 = {},
5395 Proj2 proj2 = {})
const
5397 for (; first1 != last1 && first2 != last2; ++first1, ++first2, ++result)
5399 *result = etl::invoke(op, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2));
5401 return {etl::move(first1), etl::move(first2), etl::move(result)};
5405 template <
class R1,
class R2,
class O,
class F,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
5406 typename = etl::enable_if_t<etl::is_range_v<R1> && etl::is_range_v<R2>>>
5407 constexpr ranges::binary_transform_result< ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O>
5408 operator()(R1&& r1, R2&& r2, O result, F op, Proj1 proj1 = {}, Proj2 proj2 = {})
const
5410 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::ref(op), etl::ref(proj1),
5415 inline constexpr transform_fn transform{};
5419 template <
class I,
class S,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5420 constexpr I operator()(I first, S last)
const
5422 I tail = ranges::next(first, last);
5425 for (; first != tail && first != --tail; ++first)
5427 etl::iter_swap(first, tail);
5433 template <
class R,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5434 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r)
const
5436 return (*
this)(ranges::begin(r), ranges::end(r));
5440 inline constexpr reverse_fn reverse{};
5442 template <
class I,
class O>
5443 using reverse_copy_result = in_out_result<I, O>;
5445 struct reverse_copy_fn
5447 template <
class I,
class S,
class O,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5448 constexpr ranges::reverse_copy_result<I, O> operator()(I first, S last, O result)
const
5450 I tail = ranges::next(first, last);
5453 while (tail != first)
5459 return {etl::move(end_it), etl::move(result)};
5462 template <
class R,
class O,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5463 constexpr ranges::reverse_copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result)
const
5465 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(result));
5469 inline constexpr reverse_copy_fn reverse_copy{};
5472 using rotate_result = ranges::subrange<I>;
5476 template <
class I,
class S,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5477 constexpr ranges::rotate_result<I> operator()(I first, I middle, S last)
const
5479 if (first == middle)
5481 I last_it = ranges::next(first, last);
5482 return {last_it, last_it};
5485 I last_it = ranges::next(first, last);
5487 if (middle == last_it)
5489 return {first, last_it};
5492 I new_first = etl::rotate(first, middle, last_it);
5493 return {etl::move(new_first), etl::move(last_it)};
5496 template <
class R,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5497 constexpr ranges::rotate_result<ranges::borrowed_iterator_t<R>> operator()(R&& r, ranges::iterator_t<R> middle)
const
5499 return (*
this)(ranges::begin(r), etl::move(middle), ranges::end(r));
5503 inline constexpr rotate_fn rotate{};
5505 struct rotate_copy_fn
5507 template <
class I,
class S,
class O,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5508 constexpr ranges::rotate_copy_result<I, O> operator()(I first, I middle, S last, O result)
const
5510 I last_it = ranges::next(first, last);
5511 O end_out = etl::copy(middle, last_it, result);
5512 end_out = etl::copy(first, middle, end_out);
5513 return {etl::move(last_it), etl::move(end_out)};
5516 template <
class R,
class O,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5517 constexpr ranges::rotate_copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, ranges::iterator_t<R> middle, O result)
const
5519 return (*
this)(ranges::begin(r), etl::move(middle), ranges::end(r), etl::move(result));
5523 inline constexpr rotate_copy_fn rotate_copy{};
5525 struct shift_left_fn
5527 template <
class I,
class S,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5528 constexpr ranges::subrange<I> operator()(I first, S last, etl::iter_difference_t<I> n)
const
5530 I last_it = ranges::next(first, last);
5534 return {first, last_it};
5538 if (ranges::advance(mid, n, last_it) != 0)
5540 return {first, first};
5543 I result = ranges::move(mid, last_it, first).out;
5544 return {first, etl::move(result)};
5547 template <
class R,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5548 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, etl::ranges::range_difference_t<R> n)
const
5550 return (*
this)(ranges::begin(r), ranges::end(r), n);
5554 inline constexpr shift_left_fn shift_left{};
5556 struct shift_right_fn
5558 template <
class I,
class S,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5559 constexpr ranges::subrange<I> operator()(I first, S last, etl::iter_difference_t<I> n)
const
5561 I last_it = ranges::next(first, last);
5565 return {first, last_it};
5569 if (ranges::advance(trail, -n, first) != 0)
5571 return {last_it, last_it};
5574 I new_first = ranges::move_backward(first, trail, last_it).out;
5575 return {etl::move(new_first), etl::move(last_it)};
5578 template <
class R,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5579 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, etl::ranges::range_difference_t<R> n)
const
5581 return (*
this)(ranges::begin(r), ranges::end(r), n);
5585 inline constexpr shift_right_fn shift_right{};
5589 template <
class I,
class S,
class Gen,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5590 I operator()(I first, S last, Gen&& gen)
const
5592 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"shuffle requires random access iterators");
5594 using diff_t = etl::iter_difference_t<I>;
5595 using udiff_t = etl::make_unsigned_t<diff_t>;
5596 using gen_t = etl::remove_reference_t<Gen>;
5597 using uresult_t =
decltype(gen());
5599 I last_it = ranges::next(first, last);
5600 diff_t n = last_it - first;
5607 for (diff_t i = n - 1; i > 0; --i)
5611 udiff_t range =
static_cast<udiff_t
>(i);
5612 constexpr uresult_t gmin = gen_t::min();
5613 constexpr uresult_t gmax = gen_t::max();
5614 constexpr uresult_t grange = gmax - gmin;
5618 if ETL_IF_CONSTEXPR (grange ==
static_cast<uresult_t
>(-1))
5622 uresult_t limit = (
static_cast<uresult_t
>(-1) / (
static_cast<uresult_t
>(range) + 1)) * (
static_cast<uresult_t
>(range) + 1);
5624 j =
static_cast<uresult_t
>(gen() - gmin);
5625 }
while (j >= limit);
5626 j %= (
static_cast<uresult_t
>(range) + 1);
5630 uresult_t limit = (grange / (
static_cast<uresult_t
>(range) + 1)) * (
static_cast<uresult_t
>(range) + 1);
5632 j =
static_cast<uresult_t
>(gen() - gmin);
5633 }
while (j >= limit);
5634 j %= (
static_cast<uresult_t
>(range) + 1);
5637 etl::iter_swap(first + i, first +
static_cast<diff_t
>(j));
5643 template <
class R,
class Gen,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5644 ranges::borrowed_iterator_t<R> operator()(R&& r, Gen&& gen)
const
5646 ETL_STATIC_ASSERT(etl::is_random_access_iterator<ranges::iterator_t<R>>::value,
"shuffle requires a range with random access iterators");
5648 return (*
this)(ranges::begin(r), ranges::end(r),
static_cast<Gen&&
>(gen));
5652 inline constexpr shuffle_fn shuffle{};
5656 template <
class I,
class S,
class O,
class Gen,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5657 O operator()(I first, S last, O out, etl::iter_difference_t<I> n, Gen&& gen)
const
5659 using diff_t = etl::iter_difference_t<I>;
5660 using udiff_t = etl::make_unsigned_t<diff_t>;
5661 using gen_t = etl::remove_reference_t<Gen>;
5662 using uresult_t =
decltype(gen());
5670 I first_copy = first;
5671 diff_t pop_size = 0;
5672 for (I it = first_copy; it != last; ++it)
5680 for (; first != last; ++first, ++out)
5689 diff_t remaining = pop_size;
5692 for (; first != last && needed > 0; ++first, --remaining)
5695 udiff_t range =
static_cast<udiff_t
>(remaining - 1);
5696 constexpr uresult_t gmin = gen_t::min();
5697 constexpr uresult_t gmax = gen_t::max();
5698 constexpr uresult_t grange = gmax - gmin;
5702 if ETL_IF_CONSTEXPR (grange ==
static_cast<uresult_t
>(-1))
5710 uresult_t limit = (
static_cast<uresult_t
>(-1) / (
static_cast<uresult_t
>(range) + 1)) * (
static_cast<uresult_t
>(range) + 1);
5712 j =
static_cast<uresult_t
>(gen() - gmin);
5713 }
while (j >= limit);
5714 j %= (
static_cast<uresult_t
>(range) + 1);
5725 uresult_t limit = (grange / (
static_cast<uresult_t
>(range) + 1)) * (
static_cast<uresult_t
>(range) + 1);
5727 j =
static_cast<uresult_t
>(gen() - gmin);
5728 }
while (j >= limit);
5729 j %= (
static_cast<uresult_t
>(range) + 1);
5733 if (
static_cast<diff_t
>(j) < needed)
5744 template <
class R,
class O,
class Gen,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5745 O operator()(R&& r, O out, etl::ranges::range_difference_t<R> n, Gen&& gen)
const
5747 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(out), n,
static_cast<Gen&&
>(gen));
5751 inline constexpr sample_fn sample{};
5755 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5756 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
5758 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"sort requires random access iterators");
5760 I last_it = ranges::next(first, last);
5762 if (first == last_it)
5768 auto n = etl::distance(first, last_it);
5770 for (
auto gap = n / 2; gap > 0; gap /= 2)
5772 for (
auto i = gap; i < n; ++i)
5774 auto temp = etl::move(*(first + i));
5777 while (j >= gap && etl::invoke(comp, etl::invoke(proj, temp), etl::invoke(proj, *(first + (j - gap)))))
5779 *(first + j) = etl::move(*(first + (j - gap)));
5783 *(first + j) = etl::move(temp);
5790 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5791 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
5793 ETL_STATIC_ASSERT(etl::is_random_access_iterator<ranges::iterator_t<R>>::value,
"sort requires a range with random access iterators");
5795 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
5799 inline constexpr sort_fn
sort{};
5801 struct stable_sort_fn
5803 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5804 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
5806 I last_it = ranges::next(first, last);
5808 if (first == last_it)
5814 for (I i = ranges::next(first); i != last_it; ++i)
5816 auto temp = etl::move(*i);
5821 I prev_j = ranges::prev(j);
5822 if (etl::invoke(comp, etl::invoke(proj, temp), etl::invoke(proj, *prev_j)))
5824 *j = etl::move(*prev_j);
5833 *j = etl::move(temp);
5839 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5840 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
5842 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
5848 struct partial_sort_fn
5850 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
5851 constexpr I operator()(I first, I middle, S last, Comp comp = {}, Proj proj = {})
const
5853 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"partial_sort requires random access iterators");
5857 I last_it = ranges::next(first, last);
5859 if (first == middle || first == last_it)
5865 auto heap_size = etl::distance(first, middle);
5868 for (
auto start = (heap_size - 1) / 2; start >= 0; --start)
5870 sift_down(first, start, heap_size, comp, proj);
5875 for (I it = middle; it != last_it; ++it)
5877 if (etl::invoke(comp, etl::invoke(proj, *it), etl::invoke(proj, *first)))
5879 etl::iter_swap(it, first);
5880 sift_down(first,
decltype(heap_size){0}, heap_size, comp, proj);
5886 for (
auto heap_end = heap_size - 1; heap_end > 0; --heap_end)
5888 etl::iter_swap(first, first + heap_end);
5889 sift_down(first,
decltype(heap_size){0}, heap_end, comp, proj);
5897 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
5898 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, ranges::iterator_t<R> middle, Comp comp = {}, Proj proj = {})
const
5900 ETL_STATIC_ASSERT(etl::is_random_access_iterator<ranges::iterator_t<R>>::value,
"partial_sort requires a range with random access iterators");
5902 return (*
this)(ranges::begin(r), etl::move(middle), ranges::end(r), etl::move(comp), etl::move(proj));
5907 template <
class I,
class DiffType,
class Comp,
class Proj>
5908 static constexpr void sift_down(I first, DiffType index, DiffType heap_size, Comp& comp, Proj& proj)
5912 auto largest = index;
5913 auto left = 2 * index + 1;
5914 auto right = 2 * index + 2;
5916 if (left < heap_size && etl::invoke(comp, etl::invoke(proj, *(first + largest)), etl::invoke(proj, *(first + left))))
5921 if (right < heap_size && etl::invoke(comp, etl::invoke(proj, *(first + largest)), etl::invoke(proj, *(first + right))))
5926 if (largest == index)
5931 etl::iter_swap(first + index, first + largest);
5939 struct partial_sort_copy_fn
5941 template <
class I1,
class S1,
class I2,
class S2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
5942 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
5943 constexpr ranges::partial_sort_copy_result<I1, I2> operator()(I1 first, S1 last, I2 result_first, S2 result_last, Comp comp = {},
5944 Proj1 proj1 = {}, Proj2 proj2 = {})
const
5946 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I2>::value,
"partial_sort_copy requires the output to be random access iterators");
5950 I1 in_last = ranges::next(first, last);
5951 I2 out_last = ranges::next(result_first, result_last);
5953 I2 r = result_first;
5956 for (I1 it = first; it != in_last && r != out_last; ++it, ++r)
5961 auto heap_size = etl::distance(result_first, r);
5965 return {etl::move(in_last), etl::move(r)};
5969 for (
auto start = (heap_size - 1) / 2; start >= 0; --start)
5971 sift_down(result_first, start, heap_size, comp, proj2);
5977 etl::advance(it, heap_size);
5978 for (; it != in_last; ++it)
5980 if (etl::invoke(comp, etl::invoke(proj1, *it), etl::invoke(proj2, *result_first)))
5982 *result_first = *it;
5983 sift_down(result_first,
decltype(heap_size){0}, heap_size, comp, proj2);
5988 for (
auto heap_end = heap_size - 1; heap_end > 0; --heap_end)
5990 etl::iter_swap(result_first, result_first + heap_end);
5991 sift_down(result_first,
decltype(heap_size){0}, heap_end, comp, proj2);
5995 return {etl::move(in_last), etl::move(r)};
5998 template <
class R1,
class R2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
5999 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6000 constexpr ranges::partial_sort_copy_result< ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>>
6001 operator()(R1&& r, R2&& result_r, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6003 ETL_STATIC_ASSERT(etl::is_random_access_iterator<ranges::iterator_t<R2>>::value,
6004 "partial_sort_copy requires the output range to have random access iterators");
6006 return (*
this)(ranges::begin(r), ranges::end(r), ranges::begin(result_r), ranges::end(result_r), etl::move(comp), etl::move(proj1),
6012 template <
class I,
class DiffType,
class Comp,
class Proj>
6013 static constexpr void sift_down(I first, DiffType index, DiffType heap_size, Comp& comp, Proj& proj)
6017 auto largest = index;
6018 auto left = 2 * index + 1;
6019 auto right = 2 * index + 2;
6021 if (left < heap_size && etl::invoke(comp, etl::invoke(proj, *(first + largest)), etl::invoke(proj, *(first + left))))
6026 if (right < heap_size && etl::invoke(comp, etl::invoke(proj, *(first + largest)), etl::invoke(proj, *(first + right))))
6031 if (largest == index)
6036 etl::iter_swap(first + index, first + largest);
6044 struct nth_element_fn
6046 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6047 constexpr I operator()(I first, I nth, S last, Comp comp = {}, Proj proj = {})
const
6049 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"nth_element requires random access iterators");
6051 I last_it = ranges::next(first, last);
6053 if (first == last_it || ranges::next(first) == last_it)
6059 I hi = ranges::prev(last_it);
6063 I p = nth_partition(lo, hi, comp, proj);
6071 hi = ranges::prev(p);
6075 lo = ranges::next(p);
6082 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6083 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, ranges::iterator_t<R> nth, Comp comp = {}, Proj proj = {})
const
6085 ETL_STATIC_ASSERT(etl::is_random_access_iterator<ranges::iterator_t<R>>::value,
"nth_element requires a range with random access iterators");
6087 return (*
this)(ranges::begin(r), etl::move(nth), ranges::end(r), etl::move(comp), etl::move(proj));
6092 template <
class I,
class Comp,
class Proj>
6093 static constexpr I nth_partition(I first, I last, Comp& comp, Proj& proj)
6100 if (last - first == 1)
6102 if (etl::invoke(comp, etl::invoke(proj, *last), etl::invoke(proj, *first)))
6104 etl::iter_swap(first, last);
6110 I mid = first + (last - first) / 2;
6112 if (etl::invoke(comp, etl::invoke(proj, *mid), etl::invoke(proj, *first)))
6114 etl::iter_swap(first, mid);
6117 if (etl::invoke(comp, etl::invoke(proj, *last), etl::invoke(proj, *first)))
6119 etl::iter_swap(first, last);
6122 if (etl::invoke(comp, etl::invoke(proj, *mid), etl::invoke(proj, *last)))
6124 etl::iter_swap(mid, last);
6133 while (etl::invoke(comp, etl::invoke(proj, *i), etl::invoke(proj, *last)))
6140 while (i < j && etl::invoke(comp, etl::invoke(proj, *last), etl::invoke(proj, *j)))
6150 etl::iter_swap(i, j);
6154 etl::iter_swap(i, last);
6163 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6164 constexpr ranges::subrange<I> operator()(I first, S last, Pred pred, Proj proj = {})
const
6166 first = ranges::find_if_not(first, last, etl::ref(pred), etl::ref(proj));
6170 return {first, first};
6173 for (I i = ranges::next(first); i != last; ++i)
6175 if (etl::invoke(pred, etl::invoke(proj, *i)))
6177 etl::iter_swap(i, first);
6182 return {first, ranges::next(first, last)};
6185 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6186 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
6188 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
6192 inline constexpr partition_fn
partition{};
6194 struct is_partitioned_fn
6196 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6197 constexpr bool operator()(I first, S last, Pred pred, Proj proj = {})
const
6199 for (; first != last; ++first)
6201 if (!etl::invoke(pred, etl::invoke(proj, *first)))
6207 for (; first != last; ++first)
6209 if (etl::invoke(pred, etl::invoke(proj, *first)))
6218 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6219 constexpr bool operator()(R&& r, Pred pred, Proj proj = {})
const
6221 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
6227 struct partition_copy_fn
6229 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>>>
6230 constexpr ranges::partition_copy_result<I, O1, O2> operator()(I first, S last, O1 out_true, O2 out_false, Pred pred, Proj proj = {})
const
6232 for (; first != last; ++first)
6234 if (etl::invoke(pred, etl::invoke(proj, *first)))
6241 *out_false = *first;
6246 return {etl::move(first), etl::move(out_true), etl::move(out_false)};
6249 template <
class R,
class O1,
class O2,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6250 constexpr ranges::partition_copy_result<ranges::borrowed_iterator_t<R>, O1, O2> operator()(R&& r, O1 out_true, O2 out_false, Pred pred,
6251 Proj proj = {})
const
6253 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(out_true), etl::move(out_false), etl::ref(pred), etl::ref(proj));
6259 struct partition_point_fn
6261 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6262 constexpr I operator()(I first, S last, Pred pred, Proj proj = {})
const
6264 for (; first != last; ++first)
6266 if (!etl::invoke(pred, etl::invoke(proj, *first)))
6275 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6276 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
6278 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
6284 struct stable_partition_fn
6286 template <
class I,
class S,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6287 constexpr ranges::subrange<I> operator()(I first, S last, Pred pred, Proj proj = {})
const
6290 first = ranges::find_if_not(first, last, etl::ref(pred), etl::ref(proj));
6294 return {first, first};
6297 I last_it = ranges::next(first, last);
6299 I pp = stable_partition_impl(first, last_it, etl::ref(pred), etl::ref(proj), etl::distance(first, last_it));
6301 return {pp, last_it};
6304 template <
class R,
class Pred,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6305 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred, Proj proj = {})
const
6307 return (*
this)(ranges::begin(r), ranges::end(r), etl::ref(pred), etl::ref(proj));
6312 template <
class I,
class Pred,
class Proj>
6313 static constexpr I stable_partition_impl(I first, I last, Pred pred, Proj proj,
typename etl::iterator_traits<I>::difference_type len)
6322 return etl::invoke(pred, etl::invoke(proj, *first)) ? ranges::next(first) : first;
6325 I middle = ranges::next(first, len / 2);
6327 I left_partition = stable_partition_impl(first, middle, etl::ref(pred), etl::ref(proj), len / 2);
6328 I right_partition = stable_partition_impl(middle, last, etl::ref(pred), etl::ref(proj), len - len / 2);
6330 if (left_partition == middle)
6332 return right_partition;
6335 if (middle == right_partition)
6337 return left_partition;
6340 return etl::rotate(left_partition, middle, right_partition);
6346 struct is_sorted_until_fn
6348 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6349 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6353 I next_it = ranges::next(first);
6355 while (next_it != last)
6357 if (etl::invoke(comp, etl::invoke(proj, *next_it), etl::invoke(proj, *first)))
6367 return ranges::next(first, last);
6370 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6371 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
6373 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
6381 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6382 constexpr bool operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6384 return ranges::is_sorted_until(first, last, etl::ref(comp), etl::ref(proj)) == last;
6387 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6388 constexpr bool operator()(R&& r, Comp comp = {}, Proj proj = {})
const
6390 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
6394 inline constexpr is_sorted_fn
is_sorted{};
6396 struct lower_bound_fn
6398 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>>>
6399 constexpr I operator()(I first, S last,
const T& value, Comp comp = {}, Proj proj = {})
const
6401 auto len = etl::distance(first, last);
6405 auto half = len / 2;
6406 I middle = ranges::next(first, half);
6408 if (etl::invoke(comp, etl::invoke(proj, *middle), value))
6410 first = ranges::next(middle);
6422 template <
class R,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6423 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r,
const T& value, Comp comp = {}, Proj proj = {})
const
6425 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::move(comp), etl::move(proj));
6429 inline constexpr lower_bound_fn lower_bound{};
6431 struct upper_bound_fn
6433 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>>>
6434 constexpr I operator()(I first, S last,
const T& value, Comp comp = {}, Proj proj = {})
const
6436 auto len = etl::distance(first, last);
6440 auto half = len / 2;
6441 I middle = ranges::next(first, half);
6443 if (!etl::invoke(comp, value, etl::invoke(proj, *middle)))
6445 first = ranges::next(middle);
6457 template <
class R,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6458 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r,
const T& value, Comp comp = {}, Proj proj = {})
const
6460 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::move(comp), etl::move(proj));
6464 inline constexpr upper_bound_fn upper_bound{};
6466 struct equal_range_fn
6468 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>>>
6469 constexpr ranges::subrange<I> operator()(I first, S last,
const T& value, Comp comp = {}, Proj proj = {})
const
6471 return {ranges::lower_bound(first, last, value, etl::ref(comp), etl::ref(proj)),
6472 ranges::upper_bound(first, last, value, etl::ref(comp), etl::ref(proj))};
6475 template <
class R,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6476 constexpr ranges::borrowed_subrange_t<R> operator()(R&& r,
const T& value, Comp comp = {}, Proj proj = {})
const
6478 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::move(comp), etl::move(proj));
6482 inline constexpr equal_range_fn equal_range{};
6484 struct binary_search_fn
6486 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>>>
6488 constexpr bool operator()(I first, S last,
const T& value, Comp comp = {}, Proj proj = {})
const
6490 first = ranges::lower_bound(first, last, value, etl::ref(comp), etl::ref(proj));
6492 return (!(first == last) && !(etl::invoke(comp, value, etl::invoke(proj, *first))));
6495 template <
class R,
class T,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6497 constexpr bool operator()(R&& r,
const T& value, Comp comp = {}, Proj proj = {})
const
6499 return (*
this)(ranges::begin(r), ranges::end(r), value, etl::move(comp), etl::move(proj));
6503 inline constexpr binary_search_fn binary_search{};
6507 template <
class I1,
class S1,
class I2,
class S2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6508 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6510 constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6512 for (; first2 != last2; ++first1)
6514 if (first1 == last1)
6519 if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6524 if (!etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
6533 template <
class R1,
class R2,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6534 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6536 constexpr bool operator()(R1&& r1, R2&& r2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6538 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(comp), etl::move(proj1), etl::move(proj2));
6542 inline constexpr includes_fn includes{};
6546 template <
class I1,
class S1,
class I2,
class S2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6547 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6548 constexpr ranges::merge_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {},
6549 Proj2 proj2 = {})
const
6551 while (first1 != last1 && first2 != last2)
6553 if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6566 while (first1 != last1)
6573 while (first2 != last2)
6580 return {etl::move(first1), etl::move(first2), etl::move(result)};
6583 template <
class R1,
class R2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6584 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6585 constexpr ranges::merge_result<ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O>
6586 operator()(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6588 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::move(comp), etl::move(proj1),
6593 inline constexpr merge_fn
merge{};
6595 struct inplace_merge_fn
6597 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6598 constexpr I operator()(I first, I middle, S last, Comp comp = {}, Proj proj = {})
const
6600 I last_it = ranges::next(first, last);
6602 if (first == middle || middle == last_it)
6607 inplace_merge_impl(first, middle, last_it, comp, proj, etl::distance(first, middle), etl::distance(middle, last_it));
6612 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6613 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, ranges::iterator_t<R> middle, Comp comp = {}, Proj proj = {})
const
6615 return (*
this)(ranges::begin(r), etl::move(middle), ranges::end(r), etl::move(comp), etl::move(proj));
6620 template <
class I,
class Comp,
class Proj>
6621 static constexpr void inplace_merge_impl(I first, I middle, I last, Comp& comp, Proj& proj,
6622 typename etl::iterator_traits<I>::difference_type len1,
6623 typename etl::iterator_traits<I>::difference_type len2)
6625 if (len1 == 0 || len2 == 0)
6630 if (len1 + len2 == 2)
6632 if (etl::invoke(comp, etl::invoke(proj, *middle), etl::invoke(proj, *first)))
6634 etl::iter_swap(first, middle);
6641 typename etl::iterator_traits<I>::difference_type new_len1;
6642 typename etl::iterator_traits<I>::difference_type new_len2;
6646 new_len1 = len1 / 2;
6647 first_cut = ranges::next(first, new_len1);
6648 second_cut = ranges::lower_bound(middle, last, etl::invoke(proj, *first_cut), etl::ref(comp), etl::ref(proj));
6649 new_len2 = etl::distance(middle, second_cut);
6653 new_len2 = len2 / 2;
6654 second_cut = ranges::next(middle, new_len2);
6655 first_cut = ranges::upper_bound(first, middle, etl::invoke(proj, *second_cut), etl::ref(comp), etl::ref(proj));
6656 new_len1 = etl::distance(first, first_cut);
6666 if (first_cut == middle)
6668 new_middle = second_cut;
6670 else if (second_cut == middle)
6672 new_middle = first_cut;
6676 new_middle = etl::rotate(first_cut, middle, second_cut);
6679 inplace_merge_impl(first, first_cut, new_middle, comp, proj, new_len1, new_len2);
6680 inplace_merge_impl(new_middle, second_cut, last, comp, proj, len1 - new_len1, len2 - new_len2);
6688 template <
class I1,
class S1,
class I2,
class S2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6689 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6690 constexpr ranges::set_union_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {},
6691 Proj2 proj2 = {})
const
6693 while (first1 != last1 && first2 != last2)
6695 if (etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
6700 else if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6714 while (first1 != last1)
6721 while (first2 != last2)
6728 return {etl::move(first1), etl::move(first2), etl::move(result)};
6731 template <
class R1,
class R2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6732 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6733 constexpr ranges::set_union_result<ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O>
6734 operator()(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6736 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::move(comp), etl::move(proj1),
6741 inline constexpr set_union_fn set_union{};
6743 struct set_intersection_fn
6745 template <
class I1,
class S1,
class I2,
class S2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6746 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6747 constexpr ranges::set_intersection_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {},
6748 Proj1 proj1 = {}, Proj2 proj2 = {})
const
6750 while (first1 != last1 && first2 != last2)
6752 if (etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
6756 else if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6769 return {etl::move(first1), etl::move(first2), etl::move(result)};
6772 template <
class R1,
class R2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6773 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6774 constexpr ranges::set_intersection_result< ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O>
6775 operator()(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6777 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::move(comp), etl::move(proj1),
6782 inline constexpr set_intersection_fn set_intersection{};
6784 struct set_difference_fn
6786 template <
class I1,
class S1,
class I2,
class S2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6787 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6788 constexpr ranges::set_difference_result<I1, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {},
6789 Proj2 proj2 = {})
const
6791 while (first1 != last1 && first2 != last2)
6793 if (etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
6799 else if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6810 while (first1 != last1)
6817 return {etl::move(first1), etl::move(result)};
6820 template <
class R1,
class R2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6821 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6822 constexpr ranges::set_difference_result<ranges::borrowed_iterator_t<R1>, O> operator()(R1&& r1, R2&& r2, O result, Comp comp = {},
6823 Proj1 proj1 = {}, Proj2 proj2 = {})
const
6825 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::move(comp), etl::move(proj1),
6830 inline constexpr set_difference_fn set_difference{};
6832 struct set_symmetric_difference_fn
6834 template <
class I1,
class S1,
class I2,
class S2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6835 typename = etl::enable_if_t<!etl::is_range_v<I1>>>
6836 constexpr ranges::set_symmetric_difference_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {},
6837 Proj1 proj1 = {}, Proj2 proj2 = {})
const
6839 while (first1 != last1 && first2 != last2)
6841 if (etl::invoke(comp, etl::invoke(proj1, *first1), etl::invoke(proj2, *first2)))
6847 else if (etl::invoke(comp, etl::invoke(proj2, *first2), etl::invoke(proj1, *first1)))
6860 while (first1 != last1)
6867 while (first2 != last2)
6874 return {etl::move(first1), etl::move(first2), etl::move(result)};
6877 template <
class R1,
class R2,
class O,
class Comp = ranges::less,
class Proj1 = etl::identity,
class Proj2 = etl::identity,
6878 typename = etl::enable_if_t<etl::is_range_v<R1>>>
6879 constexpr ranges::set_symmetric_difference_result< ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O>
6880 operator()(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {})
const
6882 return (*
this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), etl::move(result), etl::move(comp), etl::move(proj1),
6887 inline constexpr set_symmetric_difference_fn set_symmetric_difference{};
6893 template <
class I,
class Comp,
class Proj>
6894 static constexpr void sift_down(I first,
typename etl::iterator_traits<I>::difference_type index,
6895 typename etl::iterator_traits<I>::difference_type length, Comp& comp, Proj& proj)
6899 auto child = 2 * index + 1;
6901 if (child >= length)
6906 if ((child + 1 < length) && etl::invoke(comp, etl::invoke(proj, *(first + child)), etl::invoke(proj, *(first + (child + 1)))))
6911 if (!etl::invoke(comp, etl::invoke(proj, *(first + index)), etl::invoke(proj, *(first + child))))
6916 etl::iter_swap(first + index, first + child);
6923 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6924 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6926 I last_it = ranges::next(first, last);
6928 auto length = etl::distance(first, last_it);
6935 auto parent = (length - 2) / 2;
6939 sift_down(first, parent, length, comp, proj);
6952 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6953 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
6955 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
6959 inline constexpr make_heap_fn make_heap{};
6963 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
6964 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
6966 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"push_heap requires random access iterators");
6968 I last_it = ranges::next(first, last);
6970 auto length = etl::distance(first, last_it);
6977 auto value_index = length - 1;
6978 auto parent = (value_index - 1) / 2;
6979 auto value = etl::move(*(first + value_index));
6981 while ((value_index > 0) && etl::invoke(comp, etl::invoke(proj, *(first + parent)), etl::invoke(proj, value)))
6983 *(first + value_index) = etl::move(*(first + parent));
6984 value_index = parent;
6985 parent = (value_index - 1) / 2;
6988 *(first + value_index) = etl::move(value);
6993 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
6994 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
6996 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7000 inline constexpr push_heap_fn push_heap{};
7006 template <
class I,
class Comp,
class Proj>
7007 static constexpr void sift_down(I first,
typename etl::iterator_traits<I>::difference_type index,
7008 typename etl::iterator_traits<I>::difference_type length, Comp& comp, Proj& proj)
7012 auto child = 2 * index + 1;
7014 if (child >= length)
7019 if ((child + 1 < length) && etl::invoke(comp, etl::invoke(proj, *(first + child)), etl::invoke(proj, *(first + (child + 1)))))
7024 if (!etl::invoke(comp, etl::invoke(proj, *(first + index)), etl::invoke(proj, *(first + child))))
7029 etl::iter_swap(first + index, first + child);
7036 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7037 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7039 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"pop_heap requires random access iterators");
7043 I last_it = ranges::next(first, last);
7045 auto length = etl::distance(first, last_it);
7054 etl::iter_swap(first, last_it);
7056 sift_down(first,
decltype(length)(0), etl::distance(first, last_it), comp, proj);
7058 return ranges::next(first, last);
7063 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7064 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7066 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7070 inline constexpr pop_heap_fn pop_heap{};
7072 struct is_heap_until_fn
7074 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7075 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7077 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"is_heap_until requires random access iterators");
7079 I last_it = ranges::next(first, last);
7081 auto length = etl::distance(first, last_it);
7083 decltype(length) parent = 0;
7085 for (
decltype(length) child = 1; child < length; ++child)
7087 if (etl::invoke(comp, etl::invoke(proj, *(first + parent)), etl::invoke(proj, *(first + child))))
7089 return first + child;
7092 if ((child & 1) == 0)
7101 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7102 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7104 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7108 inline constexpr is_heap_until_fn is_heap_until{};
7112 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7113 constexpr bool operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7115 return ranges::is_heap_until(first, last, etl::ref(comp), etl::ref(proj)) == last;
7118 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7119 constexpr bool operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7121 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7125 inline constexpr is_heap_fn is_heap{};
7129 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7130 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7132 ETL_STATIC_ASSERT(etl::is_random_access_iterator<I>::value,
"sort_heap requires random access iterators");
7134 I last_it = ranges::next(first, last);
7135 I current_last = last_it;
7137 while (first != current_last)
7139 ranges::pop_heap(first, current_last, comp, proj);
7146 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7147 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7149 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7153 inline constexpr sort_heap_fn sort_heap{};
7157 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7158 constexpr const T& operator()(
const T& a,
const T& b, Comp comp = {}, Proj proj = {})
const
7160 return etl::invoke(comp, etl::invoke(proj, b), etl::invoke(proj, a)) ? b : a;
7163 #if ETL_HAS_INITIALIZER_LIST
7164 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7165 constexpr T operator()(std::initializer_list<T> r, Comp comp = {}, Proj proj = {})
const
7167 auto first = r.begin();
7168 auto last = r.end();
7170 auto smallest = first;
7171 while (++first != last)
7173 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7182 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7183 constexpr ranges::range_value_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7185 auto first = ranges::begin(r);
7186 auto last = ranges::end(r);
7188 auto smallest = first;
7189 while (++first != last)
7191 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7200 inline constexpr min_fn min{};
7202 struct min_element_fn
7204 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7205 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7215 for (; first != last; ++first)
7217 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7226 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7227 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7229 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7237 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7238 constexpr const T& operator()(
const T& a,
const T& b, Comp comp = {}, Proj proj = {})
const
7240 return etl::invoke(comp, etl::invoke(proj, a), etl::invoke(proj, b)) ? b : a;
7243 #if ETL_HAS_INITIALIZER_LIST
7244 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7245 constexpr T operator()(std::initializer_list<T> r, Comp comp = {}, Proj proj = {})
const
7247 auto first = r.begin();
7248 auto last = r.end();
7250 auto largest = first;
7251 while (++first != last)
7253 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7262 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7263 constexpr ranges::range_value_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7265 auto first = ranges::begin(r);
7266 auto last = ranges::end(r);
7268 auto largest = first;
7269 while (++first != last)
7271 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7280 inline constexpr max_fn max{};
7282 struct max_element_fn
7284 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7285 constexpr I operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7295 for (; first != last; ++first)
7297 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7306 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7307 constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7309 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7317 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7318 constexpr ranges::minmax_result<const T&> operator()(
const T& a,
const T& b, Comp comp = {}, Proj proj = {})
const
7320 if (etl::invoke(comp, etl::invoke(proj, b), etl::invoke(proj, a)))
7327 #if ETL_HAS_INITIALIZER_LIST
7328 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7329 constexpr ranges::minmax_result<T> operator()(std::initializer_list<T> r, Comp comp = {}, Proj proj = {})
const
7331 auto first = r.begin();
7332 auto last = r.end();
7334 auto smallest = first;
7335 auto largest = first;
7337 while (++first != last)
7339 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7343 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7348 return {*smallest, *largest};
7352 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7353 constexpr ranges::minmax_result<ranges::range_value_t<R>> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7355 auto first = ranges::begin(r);
7356 auto last = ranges::end(r);
7358 auto smallest = first;
7359 auto largest = first;
7361 while (++first != last)
7363 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7367 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7372 return {*smallest, *largest};
7376 inline constexpr minmax_fn
minmax{};
7378 struct minmax_element_fn
7380 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7381 constexpr ranges::minmax_element_result<I> operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7385 return {first, first};
7392 for (; first != last; ++first)
7394 if (etl::invoke(comp, etl::invoke(proj, *first), etl::invoke(proj, *smallest)))
7398 if (etl::invoke(comp, etl::invoke(proj, *largest), etl::invoke(proj, *first)))
7404 return {smallest, largest};
7407 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7408 constexpr ranges::minmax_element_result<ranges::borrowed_iterator_t<R>> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7410 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7418 template <
class T,
class Comp = ranges::less,
class Proj = etl::
identity>
7419 constexpr const T& operator()(
const T& value,
const T& low,
const T& high, Comp comp = {}, Proj proj = {})
const
7421 auto&& projected_value = etl::invoke(proj, value);
7423 return etl::invoke(comp, projected_value, etl::invoke(proj, low)) ? low
7424 : etl::invoke(comp, etl::invoke(proj, high), projected_value) ? high
7429 inline constexpr clamp_fn
clamp{};
7431 struct next_permutation_fn
7433 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7434 constexpr ranges::next_permutation_result<I> operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7436 I last_it = ranges::next(first, last);
7439 if (first == last_it)
7441 return {etl::move(last_it),
false};
7449 return {etl::move(last_it),
false};
7458 if (etl::invoke(comp, etl::invoke(proj, *i), etl::invoke(proj, *i1)))
7462 while (!etl::invoke(comp, etl::invoke(proj, *i), etl::invoke(proj, *--j)))
7466 etl::iter_swap(i, j);
7471 while (left != right && left != --right)
7473 etl::iter_swap(left, right);
7477 return {etl::move(last_it),
true};
7486 while (left != right && left != --right)
7488 etl::iter_swap(left, right);
7492 return {etl::move(last_it),
false};
7497 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7498 constexpr ranges::next_permutation_result<ranges::borrowed_iterator_t<R>> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7500 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
7506 struct prev_permutation_fn
7508 template <
class I,
class S,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<!etl::is_range_v<I>>>
7509 constexpr ranges::prev_permutation_result<I> operator()(I first, S last, Comp comp = {}, Proj proj = {})
const
7511 I last_it = ranges::next(first, last);
7514 if (first == last_it)
7516 return {etl::move(last_it),
false};
7524 return {etl::move(last_it),
false};
7533 if (etl::invoke(comp, etl::invoke(proj, *i1), etl::invoke(proj, *i)))
7537 while (!etl::invoke(comp, etl::invoke(proj, *--j), etl::invoke(proj, *i)))
7541 etl::iter_swap(i, j);
7546 while (left != right && left != --right)
7548 etl::iter_swap(left, right);
7552 return {etl::move(last_it),
true};
7561 while (left != right && left != --right)
7563 etl::iter_swap(left, right);
7567 return {etl::move(last_it),
false};
7572 template <
class R,
class Comp = ranges::less,
class Proj = etl::
identity,
typename = etl::enable_if_t<etl::is_range_v<R>>>
7573 constexpr ranges::prev_permutation_result<ranges::borrowed_iterator_t<R>> operator()(R&& r, Comp comp = {}, Proj proj = {})
const
7575 return (*
this)(ranges::begin(r), ranges::end(r), etl::move(comp), etl::move(proj));
Definition functional.h:358
Definition iterator.h:310
ETL_CONSTEXPR T clamp(const T &value, const T &low, const T &high, TCompare compare)
Definition algorithm.h:2353
ETL_CONSTEXPR20 void shell_sort(TIterator first, TIterator last)
Definition algorithm.h:3228
ETL_CONSTEXPR14 TOutputIterator copy_if(TIterator begin, TIterator end, TOutputIterator out, TUnaryPredicate predicate)
Definition algorithm.h:2177
void inplace_merge(TBidirectionalIterator first, TBidirectionalIterator middle, TBidirectionalIterator last, TCompare compare)
Definition algorithm.h:2595
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:3120
ETL_NODISCARD ETL_CONSTEXPR14 bool any_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2210
ETL_NODISCARD ETL_CONSTEXPR14 TIterator min_element(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1479
ETL_CONSTEXPR14 TOutputIterator transform_n_if(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:3072
ETL_CONSTEXPR14 T accumulate(TIterator first, TIterator last, T sum)
Definition algorithm.h:2321
ETL_CONSTEXPR14 bool next_permutation(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:1938
ETL_NODISCARD ETL_CONSTEXPR14 bool all_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2199
ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair< TIterator, TIterator > minmax_element(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1561
ETL_CONSTEXPR14 TOutputIterator transform_if(TInputIterator i_begin, const TInputIterator i_end, TOutputIterator o_begin, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:3027
ETL_CONSTEXPR14 TUnaryFunction for_each_if(TIterator begin, const TIterator end, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:2920
ETL_NODISCARD ETL_CONSTEXPR14 TIterator find_if_not(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:1748
ETL_NODISCARD ETL_CONSTEXPR14 bool is_sorted(TIterator begin, TIterator end)
Definition algorithm.h:1669
ETL_CONSTEXPR14 TOutputIterator transform_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end, TUnaryFunction function)
Definition algorithm.h:2979
ETL_CONSTEXPR14 TIterator remove(TIterator first, TIterator last, const T &value)
Definition algorithm.h:2381
ETL_CONSTEXPR14 TRandomAccessIterator partial_sort_copy(TInputIterator first, TInputIterator last, TRandomAccessIterator d_first, TRandomAccessIterator d_last, TCompare compare)
Definition algorithm.h:1136
ETL_CONSTEXPR14 TOutputIterator merge(TInputIterator1 first1, TInputIterator1 last1, TInputIterator2 first2, TInputIterator2 last2, TOutputIterator d_first, TCompare compare)
Definition algorithm.h:2543
ETL_CONSTEXPR14 void transform_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryFunction function)
Definition algorithm.h:2999
ETL_CONSTEXPR14 TOutputIterator unique_copy(TInputIterator first, TInputIterator last, TOutputIterator d_first)
Definition algorithm.h:2485
ETL_CONSTEXPR14 ETL_OR_STD::pair< TDestinationTrue, TDestinationFalse > partition_move(TSource begin, TSource end, TDestinationTrue destination_true, TDestinationFalse destination_false, TUnaryPredicate predicate)
Definition algorithm.h:2149
ETL_CONSTEXPR14 TOutputIterator copy_n_if(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TUnaryPredicate predicate)
Definition algorithm.h:2785
ETL_CONSTEXPR14 void insertion_sort(TIterator first, TIterator last)
Definition algorithm.h:3252
void sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:2277
ETL_NODISCARD ETL_CONSTEXPR14 bool is_unique_sorted(TIterator begin, TIterator end)
Definition algorithm.h:1727
ETL_CONSTEXPR14 TIterator unique(TIterator first, TIterator last)
Definition algorithm.h:2432
ETL_NODISCARD ETL_CONSTEXPR14 ETL_OR_STD::pair< const T &, const T & > minmax(const T &a, const T &b)
Definition algorithm.h:1608
ETL_NODISCARD ETL_CONSTEXPR14 TIterator is_sorted_until(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1630
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:2675
ETL_CONSTEXPR14 TIterator remove_if(TIterator first, TIterator last, TUnaryPredicate predicate)
Definition algorithm.h:2406
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:2121
ETL_CONSTEXPR14 TIterator for_each_n(TIterator begin, TSize n, TUnaryFunction function)
Definition algorithm.h:2940
ETL_NODISCARD ETL_CONSTEXPR14 TIterator binary_find(TIterator begin, TIterator end, const TValue &value)
Definition algorithm.h:2884
ETL_CONSTEXPR14 void heap_sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:3350
ETL_NODISCARD ETL_CONSTEXPR14 bool none_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2221
ETL_CONSTEXPR20 void selection_sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:3300
ETL_CONSTEXPR14 TOutputIterator copy_n_s(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TOutputIterator o_end)
Definition algorithm.h:2725
ETL_NODISCARD ETL_CONSTEXPR14 TIterator is_unique_sorted_until(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1690
TOutputIterator move_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end)
Definition algorithm.h:2870
ETL_CONSTEXPR14 TOutputIterator copy_if_s(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TOutputIterator o_end, TUnaryPredicate predicate)
Definition algorithm.h:2762
ETL_CONSTEXPR14 TIterator for_each_n_if(TIterator begin, TSize n, TUnaryFunction function, TUnaryPredicate predicate)
Definition algorithm.h:2957
void stable_sort(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:2299
ETL_NODISCARD ETL_CONSTEXPR14 bool is_partitioned(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2060
ETL_NODISCARD ETL_CONSTEXPR14 TIterator adjacent_find(TIterator first, TIterator last, TBinaryPredicate predicate)
Definition algorithm.h:1769
ETL_NODISCARD ETL_CONSTEXPR14 TIterator max_element(TIterator begin, TIterator end, TCompare compare)
Definition algorithm.h:1520
ETL_NODISCARD ETL_CONSTEXPR14 TIterator partition_point(TIterator begin, TIterator end, TUnaryPredicate predicate)
Definition algorithm.h:2091
ETL_NODISCARD ETL_CONSTEXPR14 bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2)
Definition algorithm.h:1810
ETL_CONSTEXPR14 bool prev_permutation(TIterator first, TIterator last, TCompare compare)
Definition algorithm.h:1999
ETL_CONSTEXPR14 void partial_sort(TIterator first, TIterator middle, TIterator last, TCompare compare)
Definition algorithm.h:1090
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
Definition exception.h:59
ETL_CONSTEXPR14 void iota(TIterator first, TIterator last, T value)
Definition numeric.h:58
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:3742
ETL_CONSTEXPR14 TIterator stable_partition(TIterator first, TIterator last, TPredicate predicate)
Definition algorithm.h:3592
TContainer::iterator end(TContainer &container)
Definition iterator.h:1166
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:3529
TContainer::iterator begin(TContainer &container)
Definition iterator.h:1136
Definition functional.h:305
Definition iterator.h:130
Definition functional.h:201
Definition algorithm.h:120
Definition algorithm.h:110