From 97abf6ccc045158ca00401a6b76a473c92f0b1c9 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 12 Jan 2020 16:25:37 +0000 Subject: [PATCH] Added min_element & max_element --- include/etl/algorithm.h | 167 ++++++++++++++++++++++++++++++++++++++-- test/test_algorithm.cpp | 32 ++++++++ 2 files changed, 191 insertions(+), 8 deletions(-) diff --git a/include/etl/algorithm.h b/include/etl/algorithm.h index 1fd6f927..0c7f2043 100644 --- a/include/etl/algorithm.h +++ b/include/etl/algorithm.h @@ -74,14 +74,14 @@ namespace etl //***************************************************************************** namespace etl { -// We can't have std::swap and etl::swap templates coexisting in the unit tests -// as the compiler will be unable to decide of which one to use, due to ADL. + // We can't have std::swap and etl::swap templates coexisting in the unit tests + // as the compiler will be unable to decide of which one to use, due to ADL. #if defined(ETL_NO_STL) && !defined(ETL_IN_UNIT_TEST) //*************************************************************************** // swap #if ETL_CPP11_SUPPORTED template - void swap(T& a, T& b) + void swap(T& a, T& b) ETL_NOEXCEPT { T temp(etl::move(a)); a = etl::move(b); @@ -89,13 +89,22 @@ namespace etl } #else template - void swap(T& a, T& b) + void swap(T& a, T& b) ETL_NOEXCEPT { T temp(a); a = b; b = temp; } #endif + + template< class T, size_t N > + void swap(T(&a)[N], T(&b)[N]) ETL_NOEXCEPT + { + for (size_t i = 0; i < N; ++i) + { + swap(a[i], b[i]); + } +} #endif #if defined(ETL_NO_STL) @@ -104,9 +113,8 @@ namespace etl template void iter_swap(TIterator1 a, TIterator2 b) { - typename etl::iterator_traits::value_type c = *a; - *a = *b; - *b = c; + using ETL_OR_STD::swap; // Allow ADL + swap(*a, *b); } #else //*************************************************************************** @@ -296,6 +304,7 @@ namespace etl } #endif +#if ETL_CPP11_SUPPORTED #if defined(ETL_NO_STL) //*************************************************************************** // move @@ -318,7 +327,9 @@ namespace etl return std::move(sb, se, db); } #endif +#endif +#if ETL_CPP11_SUPPORTED #if defined(ETL_NO_STL) //*************************************************************************** // move_backward @@ -341,6 +352,7 @@ namespace etl return std::move_backward(sb, se, de); } #endif +#endif #if defined(ETL_NO_STL) //*************************************************************************** @@ -1330,6 +1342,146 @@ namespace etl } #endif +#if defined(ETL_NO_STL) + //*************************************************************************** + /// Finds the iterator to the smallest element in the range (begin, end).
+ /// + ///\ingroup algorithm + //*************************************************************************** + template + ETL_NODISCARD + TIterator min_element(TIterator begin, + TIterator end, + TCompare compare) + { + TIterator minimum = begin; + + while (begin != end) + { + if (compare(*begin, *minimum)) + { + minimum = begin; + } + + ++begin; + } + + return minimum; + } + + //*************************************************************************** + /// min_element + ///\ingroup algorithm + /// + //*************************************************************************** + template + ETL_NODISCARD + TIterator min_element(TIterator begin, + TIterator end) + { + typedef typename etl::iterator_traits::value_type value_t; + + return etl::min_element(begin, end, etl::less()); + } +#else + //*************************************************************************** + /// Finds the iterator to the smallest element in the range (begin, end).
+ /// + ///\ingroup algorithm + //*************************************************************************** + template + ETL_NODISCARD + TIterator min_element(TIterator begin, + TIterator end, + TCompare compare) + { + return std::min_element(begin, end, compare); + } + + //*************************************************************************** + /// min_element + ///\ingroup algorithm + /// + //*************************************************************************** + template + ETL_NODISCARD + TIterator min_element(TIterator begin, + TIterator end) + { + return std::min_element(begin, end); + } +#endif + +#if defined(ETL_NO_STL) + //*************************************************************************** + /// Finds the iterator to the largest element in the range (begin, end).
+ /// + ///\ingroup algorithm + //*************************************************************************** + template + ETL_NODISCARD + TIterator max_element(TIterator begin, + TIterator end, + TCompare compare) + { + TIterator maximum = begin; + + while (begin != end) + { + if (!compare(*begin, *maximum)) + { + maximum = begin; + } + + ++begin; + } + + return maximum; + } + + //*************************************************************************** + /// max_element + ///\ingroup algorithm + /// + //*************************************************************************** + template + ETL_NODISCARD + TIterator max_element(TIterator begin, + TIterator end) + { + typedef typename etl::iterator_traits::value_type value_t; + + return etl::max_element(begin, end, etl::less()); + } +#else + //*************************************************************************** + /// Finds the iterator to the largest element in the range (begin, end).
+ /// + ///\ingroup algorithm + //*************************************************************************** + template + ETL_NODISCARD + TIterator max_element(TIterator begin, + TIterator end, + TCompare compare) + { + return std::max_element(begin, end, compare); + } + + //*************************************************************************** + /// max_element + ///\ingroup algorithm + /// + //*************************************************************************** + template + ETL_NODISCARD + TIterator max_element(TIterator begin, + TIterator end) + { + return std::max_element(begin, end); + } +#endif + #if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED //*************************************************************************** /// Finds the greatest and the smallest element in the range (begin, end).
@@ -1392,7 +1544,6 @@ namespace etl return std::minmax_element(begin, end, compare); } - //*************************************************************************** /// minmax_element ///\ingroup algorithm diff --git a/test/test_algorithm.cpp b/test/test_algorithm.cpp index bdabd4ce..e5238719 100644 --- a/test/test_algorithm.cpp +++ b/test/test_algorithm.cpp @@ -169,6 +169,38 @@ namespace CHECK_EQUAL((std::max(b, a, Greater())), (etl::max(b, a, Greater()))); } + //************************************************************************* + TEST(min_element) + { + Vector::iterator expected = std::min_element(data.begin(), data.end()); + Vector::iterator result = etl::min_element(data.begin(), data.end()); + CHECK_EQUAL(std::distance(data.begin(), expected), std::distance(data.begin(), result)); + } + + //************************************************************************* + TEST(min_element_compare) + { + Vector::iterator expected = std::min_element(data.begin(), data.end(), std::greater()); + Vector::iterator result = etl::min_element(data.begin(), data.end(), std::greater()); + CHECK_EQUAL(std::distance(data.begin(), expected), std::distance(data.begin(), result)); + } + + //************************************************************************* + TEST(max_element) + { + Vector::iterator expected = std::max_element(data.begin(), data.end()); + Vector::iterator result = etl::max_element(data.begin(), data.end()); + CHECK_EQUAL(std::distance(data.begin(), expected), std::distance(data.begin(), result)); + } + + //************************************************************************* + TEST(max_element_compare) + { + Vector::iterator expected = std::max_element(data.begin(), data.end(), std::greater()); + Vector::iterator result = etl::max_element(data.begin(), data.end(), std::greater()); + CHECK_EQUAL(std::distance(data.begin(), expected), std::distance(data.begin(), result)); + } + //************************************************************************* TEST(minmax_element) {