/* mbed Microcontroller Library * Copyright (c) 2019 ARM Limited * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MSTD_ALGORITHM_ #define MSTD_ALGORITHM_ /* * * - provides * - For ARM C 5, standard C++11/14 features: * - std::min, std::max for std::initializer_list * - std::all_of, std::any_of, std::none_of * - std::find_if_not * - std::equal (2-range forms) * - std::copy_n, std::move, std::move_backward * - mstd::min, mstd::max constexpr replacements */ #include #ifdef __CC_ARM #include #endif namespace mstd { #ifdef __CC_ARM // Really want basic min/max to be constexpr as per C++14 template constexpr const T &max(const T &a, const T &b) { return a < b ? b : a; } template constexpr const T &max(const T &a, const T &b, Compare comp) { return comp(a, b) ? b : a; } template constexpr const T &min(const T &a, const T &b) { return b < a ? b : a; } template constexpr const T &min(const T &a, const T &b, Compare comp) { return comp(b, a) ? b : a; } // Maybe sort out C++14 constexpr for these later - these are C++11 at least template T max(initializer_list il) { return *std::max_element(begin(il), end(il)); } template T max(initializer_list il, Compare comp) { return *std::max_element(begin(il), end(il), comp); } template T min(initializer_list il) { return *std::min_element(begin(il), end(il)); } template T min(initializer_list il, Compare comp) { return *std::min_element(begin(il), end(il), comp); } template class pair; template constexpr pair minmax(const T &a, const T &b) { if (b < a) { return pair(b, a); } else { return pair(a, b); } } template constexpr pair minmax(const T &a, const T &b, Compare comp) { if (comp(b, a)) { return pair(b, a); } else { return pair(a, b); } } #else using std::min; using std::max; using std::minmax; #endif } #ifdef __CC_ARM namespace std { // [alg.all_of] template bool all_of(InputIterator first, InputIterator last, Predicate pred) { for (; first != last; ++first) { if (!pred(*first)) { return false; } } return true; } // [alg.any_of] template bool any_of(InputIterator first, InputIterator last, Predicate pred) { for (; first != last; ++first) { if (pred(*first)) { return true; } } return false; } // [alg.none_of] template bool none_of(InputIterator first, InputIterator last, Predicate pred) { for (; first != last; ++first) { if (pred(*first)) { return false; } } return true; } // [alg.find] template InputIterator find_if_not(InputIterator first, InputIterator last, Predicate pred) { for (; first != last; ++first) { if (!pred(*first)) { return first; } } return first; } // [alg.equal] namespace impl { template bool equal(RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, RandomAccessIterator2 last2, random_access_iterator_tag, random_access_iterator_tag) { if (last1 - first1 != last2 - first2) { return false; } return equal(first1, last1, first2); } template bool equal(RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred, random_access_iterator_tag, random_access_iterator_tag) { if (last1 - first1 != last2 - first2) { return false; } return equal(first1, last1, first2, pred); } template bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, input_iterator_tag, input_iterator_tag) { for (; first1 != last1 && first2 != last2; ++first1, ++first2) { if (!(*first1 == *first2)) { return false; } } return first1 == last1 && first2 == last2; } template bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred, input_iterator_tag, input_iterator_tag) { for (; first1 != last1 && first2 != last2; ++first1, ++first2) { if (!pred(*first1, *first2)) { return false; } } return first1 == last1 && first2 == last2; } } template bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) { return impl::equal(first1, last1, first2, last2, typename iterator_traits::iterator_category(), typename iterator_traits::iterator_category()); } template bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred) { return impl::equal(first1, last1, first2, last2, pred, typename iterator_traits::iterator_category(), typename iterator_traits::iterator_category()); } // [alg.copy] namespace impl { template OutputIterator copy_n(RandomAccessIterator first, Size n, OutputIterator result, random_access_iterator_tag) { // presumably this should have memcpy etc optimisations return std::copy(first, first + n, result); } template OutputIterator copy_n(InputIterator first, Size n, OutputIterator result, input_iterator_tag) { for (Size i = 0; i < n; ++i) { *result++ = *first++; } return result; } } template OutputIterator copy_n(InputIterator first, Size n, OutputIterator result) { return impl::copy_n(first, n, result, typename iterator_traits::iterator_category()); } template OutputIterator copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred) { for (; first != last; ++first) { if (pred(*first)) { *result++ = *first; } } return result; } // [alg.move] template OutputIterator move(InputIterator first, InputIterator last, OutputIterator result) { while (first != last) { *result++ = std::move(*first++); } return result; } template BidirectionalIterator2 move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result) { while (last != first) { *--result = std::move(*--last); } return result; } } #endif // __CC_ARM namespace mstd { using std::initializer_list; using std::all_of; using std::any_of; using std::none_of; using std::for_each; using std::find; using std::find_if; using std::find_if_not; using std::find_end; using std::find_first_of; using std::adjacent_find; using std::count; using std::count_if; using std::mismatch; using std::equal; using std::search; using std::search_n; using std::copy; using std::copy_n; using std::copy_if; using std::move; using std::move_backward; using std::swap_ranges; using std::iter_swap; using std::transform; using std::replace; using std::replace_if; using std::replace_copy; using std::replace_copy_if; using std::fill; using std::fill_n; using std::generate; using std::generate_n; using std::remove; using std::remove_if; using std::remove_copy; using std::remove_copy_if; using std::unique; using std::unique_copy; using std::reverse; using std::reverse_copy; using std::rotate; using std::rotate_copy; using std::partition; using std::stable_partition; using std::sort; using std::stable_sort; using std::partial_sort; using std::partial_sort_copy; using std::nth_element; using std::lower_bound; using std::upper_bound; using std::equal_range; using std::binary_search; using std::merge; using std::inplace_merge; using std::includes; using std::set_union; using std::set_intersection; using std::set_difference; using std::set_symmetric_difference; using std::push_heap; using std::pop_heap; using std::make_heap; using std::sort_heap; using std::min_element; using std::max_element; using std::lexicographical_compare; using std::next_permutation; using std::prev_permutation; } #endif // MSTD_ALGORITHM_