2 * Copyright (c) 2018 Jaroslav Jindrak
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifndef LIBCPP_BITS_ALGORITHM
30 #define LIBCPP_BITS_ALGORITHM
41 * 25.2, non-modyfing sequence operations:
48 template<class InputIterator
, class Predicate
>
49 bool all_of(InputIterator first
, InputIterator last
, Predicate pred
)
64 template<class InputIterator
, class Predicate
>
65 bool any_of(InputIterator first
, InputIterator last
, Predicate pred
)
80 template<class InputIterator
, class Predicate
>
81 bool none_of(InputIterator first
, InputIterator last
, Predicate pred
)
83 return !any_of(first
, last
, pred
);
90 template<class InputIterator
, class Function
>
91 Function
for_each(InputIterator first
, InputIterator last
, Function f
)
103 template<class InputIterator
, class T
>
104 InputIterator
find(InputIterator first
, InputIterator last
, const T
& value
)
106 while (first
!= last
)
116 template<class InputIterator
, class Predicate
>
117 InputIterator
find_if(InputIterator first
, InputIterator last
, Predicate pred
)
119 while (first
!= last
)
129 template<class InputIterator
, class Predicate
>
130 InputIterator
find_if_not(InputIterator first
, InputIterator last
, Predicate pred
)
132 while (first
!= last
)
149 * 25.2.7, find_first:
155 * 25.2.8, adjacent_find:
158 template<class ForwardIterator
>
159 ForwardIterator
adjacent_find(ForwardIterator first
, ForwardIterator last
)
161 while (first
!= last
)
163 if (*first
== *(first
+ 1))
171 template<class ForwardIterator
, class Predicate
>
172 ForwardIterator
adjacent_find(ForwardIterator first
, ForwardIterator last
, Predicate pred
)
174 while (first
!= last
)
176 if (pred(*first
, *(first
+ 1)))
188 template<class InputIterator
, class T
>
189 typename iterator_traits
<InputIterator
>::difference_type
190 count(InputIterator first
, InputIterator last
, const T
& value
)
192 typename iterator_traits
<InputIterator
>::difference_type cnt
{};
194 while (first
!= last
)
196 if (*first
++ == value
)
203 template<class InputIterator
, class Predicate
>
204 typename iterator_traits
<InputIterator
>::difference_type
205 count_if(InputIterator first
, InputIterator last
, Predicate pred
)
207 typename iterator_traits
<InputIterator
>::difference_type cnt
{};
209 while (first
!= last
)
222 template<class InputIterator1
, class InputIterator2
>
223 pair
<InputIterator1
, InputIterator2
> mismatch(InputIterator1 first1
, InputIterator1 last1
,
224 InputIterator2 first2
)
226 while (first1
!= last1
&& *first1
== *first2
)
232 return make_pair(first1
, first2
);
235 template<class InputIterator1
, class InputIterator2
, class BinaryPredicate
>
236 pair
<InputIterator1
, InputIterator2
> mismatch(InputIterator1 first1
, InputIterator1 last1
,
237 InputIterator2 first2
, BinaryPredicate pred
)
239 while (first1
!= last1
&& pred(*first1
, *first2
))
245 return make_pair(first1
, first2
);
248 template<class InputIterator1
, class InputIterator2
>
249 pair
<InputIterator1
, InputIterator2
> mismatch(InputIterator1 first1
, InputIterator1 last1
,
250 InputIterator2 first2
, InputIterator2 last2
)
252 while (first1
!= last1
&& first2
!= last2
&& *first1
== *first2
)
258 return make_pair(first1
, first2
);
261 template<class InputIterator1
, class InputIterator2
, class BinaryPredicate
>
262 pair
<InputIterator1
, InputIterator2
> mismatch(InputIterator1 first1
, InputIterator1 last1
,
263 InputIterator2 first2
, InputIterator2 last2
,
264 BinaryPredicate pred
)
266 while (first1
!= last1
&& first2
!= last2
&& pred(*first1
, *first2
))
272 return make_pair(first1
, first2
);
279 template<class InputIterator1
, class InputIterator2
>
280 bool equal(InputIterator1 first1
, InputIterator1 last1
, InputIterator2 first2
)
282 while (first1
!= last1
)
284 if (*first1
++ != *first2
++)
291 template<class InputIterator1
, class InputIterator2
>
292 bool equal(InputIterator1 first1
, InputIterator1 last1
,
293 InputIterator2 first2
, InputIterator2 last2
)
295 while (first1
!= last1
&& first2
!= last2
)
297 if (*first1
++ != *first2
++)
304 template<class InputIterator1
, class InputIterator2
, class BinaryPredicate
>
305 bool equal(InputIterator1 first1
, InputIterator1 last1
,
306 InputIterator2 first2
, BinaryPredicate pred
)
308 while (first1
!= last1
)
310 if (!pred(*first1
++, *first2
++))
317 template<class InputIterator1
, class InputIterator2
, class BinaryPredicate
>
318 bool equal(InputIterator1 first1
, InputIterator1 last1
,
319 InputIterator2 first2
, InputIterator2 last2
,
320 BinaryPredicate pred
)
322 while (first1
!= last1
&& first2
!= last2
)
324 if (!pred(*first1
++, *first2
++))
332 * 25.2.12, is_permutation:
344 * 25.3, mutating sequence operations:
351 template<class InputIterator
, class OutputIterator
>
352 OutputIterator
copy(InputIterator first
, InputIterator last
, OutputIterator result
)
354 while (first
!= last
)
355 *result
++ = *first
++;
360 template<class InputIterator
, class Size
, class OutputIterator
>
361 OutputIterator
copy_n(InputIterator first
, Size count
, OutputIterator result
)
363 for (Size i
= 0; i
< count
; ++i
, ++first
, ++result
)
369 template<class InputIterator
, class OutputIterator
, class Predicate
>
370 OutputIterator
copy_if(InputIterator first
, InputIterator last
,
371 OutputIterator result
, Predicate pred
)
373 while (first
!= last
)
383 template<class BidirectionalIterator1
, class BidirectionalIterator2
>
384 BidirectionalIterator2
copy_backward(BidirectionalIterator1 first
, BidirectionalIterator1 last
,
385 BidirectionalIterator2 result
)
387 // Note: We're copying [first, last) so we need to skip the initial value of last.
388 while (last
-- != first
)
398 template<class InputIterator
, class OutputIterator
>
399 OutputIterator
move(InputIterator first
, InputIterator last
, OutputIterator result
)
401 while (first
!= last
)
402 *result
++ = move(*first
++);
407 template<class BidirectionalIterator1
, class BidirectionalIterator2
>
408 BidirectionalIterator2
move_backward(BidirectionalIterator1 first
, BidirectionalIterator1 last
,
409 BidirectionalIterator2 result
)
411 // Note: We're copying [first, last) so we need to skip the initial value of last.
412 while (last
-- != first
)
413 *result
-- = move(*last
);
420 template<class ForwardIterator1
, class ForwardIterator2
>
421 ForwardIterator2
swap_ranges(ForwardIterator1 first1
, ForwardIterator1 last1
,
422 ForwardIterator2 first2
)
424 while (first1
!= last1
)
425 swap(*first1
++, *first2
++);
430 template<class ForwardIterator1
, class ForwardIterator2
>
431 void iter_swap(ForwardIterator1 iter1
, ForwardIterator2 iter2
)
433 swap(*iter1
, *iter2
);
440 template<class InputIterator
, class OutputIterator
, class UnaryOperation
>
441 OutputIterator
transform(InputIterator first
, InputIterator last
,
442 OutputIterator result
, UnaryOperation op
)
444 while (first
!= last
)
445 *result
++ = op(*first
++);
450 template<class InputIterator1
, class InputIterator2
,
451 class OutputIterator
, class BinaryOperation
>
452 OutputIterator
transform(InputIterator1 first1
, InputIterator1 last1
,
453 InputIterator2 first2
, OutputIterator result
,
456 while (first1
!= last1
)
457 *result
++ = op(*first1
++, *first2
++);
466 template<class ForwardIterator
, class T
>
467 void replace(ForwardIterator first
, ForwardIterator last
,
468 const T
& old_value
, const T
& new_value
)
470 while (first
!= last
)
472 if (*first
== old_value
)
478 template<class ForwardIterator
, class Predicate
, class T
>
479 void replace_if(ForwardIterator first
, ForwardIterator last
,
480 Predicate pred
, const T
& new_value
)
482 while (first
!= last
)
490 template<class InputIterator
, class OutputIterator
, class T
>
491 OutputIterator
replace_copy(InputIterator first
, InputIterator last
,
492 OutputIterator result
, const T
& old_value
,
495 while (first
!= last
)
497 if (*first
== old_value
)
507 template<class InputIterator
, class OutputIterator
, class Predicate
, class T
>
508 OutputIterator
replace_copy_if(InputIterator first
, InputIterator last
,
509 OutputIterator result
, Predicate pred
,
512 while (first
!= last
)
528 template<class ForwardIterator
, class T
>
529 void fill(ForwardIterator first
, ForwardIterator last
, const T
& value
)
531 while (first
!= last
)
535 template<class InputIterator
, class Size
, class T
>
536 void fill_n(InputIterator first
, Size count
, const T
& value
)
538 for (Size i
= 0; i
< count
; ++i
)
546 template<class ForwardIterator
, class Generator
>
547 void generate(ForwardIterator first
, ForwardIterator last
,
550 while (first
!= last
)
554 template<class OutputIterator
, class Size
, class Generator
>
555 void generate(OutputIterator first
, Size count
, Generator gen
)
557 for (Size i
= 0; i
< count
; ++i
)
565 template<class ForwardIterator
, class T
>
566 ForwardIterator
remove(ForwardIterator first
, ForwardIterator last
,
573 *first
++ = move(*it
);
579 template<class ForwardIterator
, class Predicate
>
580 ForwardIterator
remove_if(ForwardIterator first
, ForwardIterator last
,
587 *first
++ = move(*it
);
593 template<class InputIterator
, class OutputIterator
, class T
>
594 OutputIterator
remove_copy(InputIterator first
, InputIterator last
,
595 OutputIterator result
, const T
& value
)
597 while (first
!= last
)
607 template<class InputIterator
, class OutputIterator
, class Predicate
>
608 OutputIterator
remove_copy_if(InputIterator first
, InputIterator last
,
609 OutputIterator result
, Predicate pred
)
611 while (first
!= last
)
631 template<class BidirectionalIterator
>
632 void reverse(BidirectionalIterator first
, BidirectionalIterator last
)
636 auto mid_count
= (last
- first
) / 2;
639 for (decltype(mid_count
) i
= 0; i
< mid_count
; ++i
)
640 iter_swap(first
++, last
--);
643 template<class BidirectionalIterator
, class OutputIterator
>
644 OutputIterator
reverse_copy(BidirectionalIterator first
,
645 BidirectionalIterator last
,
646 OutputIterator result
)
648 while (--last
!= first
)
665 * 25.3.13, partitions:
671 * 25.4, sorting and related operations:
682 template<class RandomAccessIterator
, class Compare
>
683 void make_heap(RandomAccessIterator
, RandomAccessIterator
,
686 template<class RandomAccessIterator
, class Compare
>
687 void sort_heap(RandomAccessIterator
, RandomAccessIterator
,
690 template<class RandomAccessIterator
>
691 void sort(RandomAccessIterator first
, RandomAccessIterator last
)
693 using value_type
= typename iterator_traits
<RandomAccessIterator
>::value_type
;
695 sort(first
, last
, less
<value_type
>{});
698 template<class RandomAccessIterator
, class Compare
>
699 void sort(RandomAccessIterator first
, RandomAccessIterator last
,
703 * Note: This isn't the most effective approach,
704 * but since we already have these two functions
705 * and they satisfy asymptotic limitations
706 * imposed by the standard, we're using them at
707 * the moment. Might be good to change it to qsort
708 * or merge sort later.
711 make_heap(first
, last
, comp
);
712 sort_heap(first
, last
, comp
);
716 * 25.4.1.2, stable_sort:
722 * 25.4.1.3, partial_sort:
728 * 25.4.1.4, partial_sort_copy:
734 * 25.4.1.5, is_sorted:
737 template<class ForwardIterator
>
738 bool is_sorted(ForwardIterator first
, ForwardIterator last
)
740 return is_sorted_until(first
, last
) == last
;
743 template<class ForwardIterator
, class Comp
>
744 bool is_sorted(ForwardIterator first
, ForwardIterator last
,
747 return is_sorted_until(first
, last
, comp
) == last
;
750 template<class ForwardIterator
>
751 ForwardIterator
is_sorted_until(ForwardIterator first
, ForwardIterator last
)
753 if (distance(first
, last
) < 2)
756 while (first
!= last
)
758 if (*first
> *(++first
))
765 template<class ForwardIterator
, class Comp
>
766 ForwardIterator
is_sorted_until(ForwardIterator first
, ForwardIterator last
,
769 if (distance(first
, last
) < 2)
772 while (first
!= last
)
774 if (!comp(*first
, *(++first
)))
782 * 25.4.2, nth_element:
788 * 25.4.3, binary search:
792 * 25.4.3.1, lower_bound
798 * 25.4.3.2, upper_bound
804 * 25.4.3.3, equal_range:
810 * 25.4.3.4, binary_search:
822 * 25.4.5, set operations on sorted structures:
826 * 25.4.5.1, includes:
832 * 25.4.5.2, set_union:
838 * 25.4.5.3, set_intersection:
844 * 25.4.5.4, set_difference:
850 * 25.4.5.5, set_symmetric_difference:
856 * 25.4.6, heap operations:
864 return (idx
- 1) / 2;
868 T
heap_left_child(T idx
)
874 T
heap_right_child(T idx
)
879 template<class RandomAccessIterator
, class Size
, class Compare
>
880 void correct_children(RandomAccessIterator first
,
881 Size idx
, Size count
, Compare comp
)
883 using aux::heap_left_child
;
884 using aux::heap_right_child
;
886 auto left
= heap_left_child(idx
);
887 auto right
= heap_right_child(idx
);
889 bool left_incorrect
{comp(first
[idx
], first
[left
])};
890 bool right_incorrect
{comp(first
[idx
], first
[right
])};
891 while ((left
< count
&& left_incorrect
) ||
892 (right
< count
&& right_incorrect
))
894 if (right
>= count
|| (left_incorrect
&& comp(first
[right
], first
[left
])))
896 swap(first
[idx
], first
[left
]);
900 else if (right
< count
&& right_incorrect
)
902 swap(first
[idx
], first
[right
]);
905 } // Else should not happen because of the while condition.
907 left
= heap_left_child(idx
);
908 right
= heap_right_child(idx
);
910 left_incorrect
= comp(first
[idx
], first
[left
]);
911 right_incorrect
= comp(first
[idx
], first
[right
]);
917 * 25.4.6.1, push_heap:
920 template<class RandomAccessIterator
>
921 void push_heap(RandomAccessIterator first
,
922 RandomAccessIterator last
)
924 using value_type
= typename iterator_traits
<RandomAccessIterator
>::value_type
;
926 push_heap(first
, last
, less
<value_type
>{});
929 template<class RandomAccessIterator
, class Compare
>
930 void push_heap(RandomAccessIterator first
,
931 RandomAccessIterator last
,
934 using aux::heap_parent
;
936 auto count
= distance(first
, last
);
940 auto idx
= count
- 1;
941 auto parent
= heap_parent(idx
);
942 while (idx
> 0 && comp(first
[parent
], first
[idx
]))
944 swap(first
[idx
], first
[parent
]);
947 parent
= heap_parent(idx
);
952 * 25.4.6.2, pop_heap:
955 template<class RandomAccessIterator
>
956 void pop_heap(RandomAccessIterator first
,
957 RandomAccessIterator last
)
959 using value_type
= typename iterator_traits
<RandomAccessIterator
>::value_type
;
961 pop_heap(first
, last
, less
<value_type
>{});
964 template<class RandomAccessIterator
, class Compare
>
965 void pop_heap(RandomAccessIterator first
,
966 RandomAccessIterator last
,
969 auto count
= distance(first
, last
);
973 swap(first
[0], first
[count
- 1]);
974 aux::correct_children(first
, decltype(count
){}, count
- 2, comp
);
978 * 25.4.6.3, make_heap:
981 template<class RandomAccessIterator
>
982 void make_heap(RandomAccessIterator first
,
983 RandomAccessIterator last
)
985 using value_type
= typename iterator_traits
<RandomAccessIterator
>::value_type
;
987 make_heap(first
, last
, less
<value_type
>{});
990 template<class RandomAccessIterator
, class Compare
>
991 void make_heap(RandomAccessIterator first
,
992 RandomAccessIterator last
,
995 auto count
= distance(first
, last
);
999 for (auto i
= count
; i
> 0; --i
)
1003 aux::correct_children(first
, idx
, count
, comp
);
1008 * 25.4.6.4, sort_heap:
1011 template<class RandomAccessIterator
>
1012 void sort_heap(RandomAccessIterator first
,
1013 RandomAccessIterator last
)
1015 using value_type
= typename iterator_traits
<RandomAccessIterator
>::value_type
;
1017 sort_heap(first
, last
, less
<value_type
>{});
1020 template<class RandomAccessIterator
, class Compare
>
1021 void sort_heap(RandomAccessIterator first
,
1022 RandomAccessIterator last
,
1025 while (first
!= last
)
1026 pop_heap(first
, last
--, comp
);
1030 * 25.4.6.5, is_heap:
1033 template<class RandomAccessIterator
>
1034 auto is_heap_until(RandomAccessIterator first
, RandomAccessIterator last
)
1036 using value_type
= typename iterator_traits
<RandomAccessIterator
>::value_type
;
1038 return is_heap_until(first
, last
, less
<value_type
>{});
1041 template<class RandomAccessIterator
, class Compare
>
1042 auto is_heap_until(RandomAccessIterator first
, RandomAccessIterator last
,
1045 using aux::heap_left_child
;
1046 using aux::heap_right_child
;
1048 auto count
= distance(first
, last
);
1053 for (decltype(count
) idx
= 0; idx
< count
; ++idx
)
1055 auto left
= heap_left_child(idx
);
1056 auto right
= heap_right_child(idx
);
1058 if (left
< count
&& comp(first
[idx
], first
[left
]))
1060 if (right
< count
&& comp(first
[idx
], first
[right
]))
1069 template<class RandomAccessIterator
>
1070 bool is_heap(RandomAccessIterator first
, RandomAccessIterator last
)
1072 return is_heap_until(first
, last
) == last
;
1075 template<class RandomAccessIterator
, class Compare
>
1076 bool is_heap(RandomAccessIterator first
, RandomAccessIterator last
,
1079 return is_heap_until(first
, last
, comp
) == last
;
1083 * 25.4.7, minimum and maximum:
1084 * // TODO: implement container versions when we have
1085 * numeric limits and min/max element
1086 * // TODO: versions with comparators
1091 constexpr const T
& min(const T
& lhs
, const T
& rhs
)
1093 return (lhs
< rhs
) ? lhs
: rhs
;
1097 constexpr const T
& max(const T
& lhs
, const T
& rhs
)
1099 return (lhs
> rhs
) ? lhs
: rhs
;
1103 * 25.4.8, lexicographical comparison:
1106 template<class InputIterator1
, class InputIterator2
>
1107 bool lexicographical_compare(InputIterator1 first1
,
1108 InputIterator1 last1
,
1109 InputIterator2 first2
,
1110 InputIterator2 last2
)
1112 while ((first1
!= last1
) && (first2
!= last2
))
1114 if (*first1
< *first2
)
1116 if (*first2
< *first1
)
1124 * Up until now they are same, so we have to check
1125 * if we reached the end on one.
1127 return (first1
== last1
) && (first2
!= last2
);
1130 template<class InputIterator1
, class InputIterator2
, class Compare
>
1131 bool lexicographical_compare(InputIterator1 first1
,
1132 InputIterator1 last1
,
1133 InputIterator2 first2
,
1134 InputIterator2 last2
,
1137 while ((first1
!= last1
) && (first2
!= last2
))
1139 if (comp(*first1
, *first2
))
1141 if (comp(*first2
, *first1
))
1149 * Up until now they are same, so we have to check
1150 * if we reached the end on one.
1152 return (first1
== last1
) && (first2
!= last2
);
1156 * 25.4.9, permutation generators: