diff --git a/include/etl/algorithm.h b/include/etl/algorithm.h index 65a23687..626ca838 100644 --- a/include/etl/algorithm.h +++ b/include/etl/algorithm.h @@ -1131,21 +1131,21 @@ namespace etl void sort(TIterator first, TIterator last, TCompare compare) { typedef typename std::iterator_traits::difference_type difference_t; - + difference_t n = std::distance(first, last); - for (difference_t i = n / 2; i > 0; i /= 2) + for (difference_t i = n / 2; i > 0; i /= 2) { - for (difference_t j = i; j < n; ++j) + for (difference_t j = i; j < n; ++j) { for (difference_t k = j - i; k >= 0; k -= i) { - TIterator itr1 = first; + TIterator itr1 = first; TIterator itr2 = first; - + std::advance(itr1, k); std::advance(itr2, k + i); - + if (compare(*itr2, *itr1)) { std::iter_swap(itr1, itr2); @@ -1164,6 +1164,132 @@ namespace etl { etl::sort(first, last, std::less::value_type>()); } + +#if ETL_CPP11_SUPPORTED + //*************************************************************************** + /// Returns the maximum value. + //*************************************************************************** + template + constexpr const T& multimax(const T& a, const T& b) + { + return a < b ? b : a; + } + + template + constexpr const T& multimax(const T& t, const Tx&... tx) + { + return multimax(t, multimax(tx...)); + } + + //*************************************************************************** + /// Returns the maximum value. + /// User supplied compare function. + //*************************************************************************** + template + constexpr const T& multimax_compare(TCompare compare, const T& a, const T& b) + { + return compare(a, b) ? b : a; + } + + template + constexpr const T& multimax_compare(TCompare compare, const T& t, const Tx&... tx) + { + return multimax_compare(compare, t, multimax_compare(compare, tx...)); + } + + //*************************************************************************** + /// Returns the maximum value. + //*************************************************************************** + template + constexpr const T& multimin(const T& a, const T& b) + { + return a < b ? a : b; + } + + template + constexpr const T& multimin(const T& t, const Tx&... tx) + { + return multimin(t, multimin(tx...)); + } + + //*************************************************************************** + /// Returns the minimum value. + /// User supplied compare function. + //*************************************************************************** + template + constexpr const T& multimin_compare(TCompare compare, const T& a, const T& b) + { + return compare(a, b) ? a : b; + } + + template + constexpr const T& multimin_compare(TCompare compare, const T& t, const Tx&... tx) + { + return multimin_compare(compare, t, multimin_compare(compare, tx...)); + } + + //*************************************************************************** + /// Returns the iterator to the maximum value. + //*************************************************************************** + template + constexpr const TIterator& multimax_iter(const TIterator& a, const TIterator& b) + { + return *a < *b ? b : a; + } + + template + constexpr const TIterator& multimax_iter(const TIterator& t, const TIteratorx&... tx) + { + return multimax_iter(t, multimax_iter(tx...)); + } + + //*************************************************************************** + /// Returns the iterator to the maximum value. + /// User supplied compare function. + //*************************************************************************** + template + constexpr const TIterator& multimax_iter_compare(TCompare compare, const TIterator& a, const TIterator& b) + { + return compare(*a, *b) ? b : a; + } + + template + constexpr const TIterator& multimax_iter_compare(TCompare compare, const TIterator& t, const TIteratorx&... tx) + { + return multimax_iter_compare(compare, t, multimax_iter_compare(compare, tx...)); + } + + //*************************************************************************** + /// Returns the iterator to the minimum value. + //*************************************************************************** + template + constexpr const TIterator& multimin_iter(const TIterator& a, const TIterator& b) + { + return *a < *b ? a : b; + } + + template + constexpr const TIterator& multimin_iter(const TIterator& t, const Tx&... tx) + { + return multimin_iter(t, multimin_iter(tx...)); + } + + //*************************************************************************** + /// Returns the iterator to the minimum value. + /// User supplied compare function. + //*************************************************************************** + template + constexpr const TIterator& multimin_iter_compare(TCompare compare, const TIterator& a, const TIterator& b) + { + return compare(*a, *b) ? a : b; + } + + template + constexpr const TIterator& multimin_iter_compare(TCompare compare, const TIterator& t, const Tx&... tx) + { + return multimin_iter_compare(compare, t, multimin_iter_compare(compare, tx...)); + } +#endif } #endif diff --git a/include/etl/version.h b/include/etl/version.h index ba1db1fc..8ce39421 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -38,7 +38,7 @@ SOFTWARE. ///\ingroup utilities #define ETL_VERSION_MAJOR 14 -#define ETL_VERSION_MINOR 20 +#define ETL_VERSION_MINOR 21 #define ETL_VERSION_PATCH 0 #define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) ETL_STRINGIFY(ETL_VERSION_MINOR) ETL_STRINGIFY(ETL_VERSION_PATCH) diff --git a/support/Release notes.txt b/support/Release notes.txt index f1241241..cde56ef4 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,16 @@ +=============================================================================== +14.21.0 +Added variadic min and max functions. +etl::multimin +etl::multimin_compare +etl::multimin_iter +etl::multimin_iter_compare +etl::multimax +etl::multimax_compare +etl::multimax_iter +etl::multimax_iter_compare +C++11 only. + =============================================================================== 14.20.0 Added etl::multi_array for multi-dimensional arrays. diff --git a/test/test_algorithm.cpp b/test/test_algorithm.cpp index f7eea553..bbb7f6d7 100644 --- a/test/test_algorithm.cpp +++ b/test/test_algorithm.cpp @@ -909,5 +909,41 @@ namespace CHECK(is_same); } } + + //========================================================================= + TEST(multimax) + { + CHECK_EQUAL(8, etl::multimax(1, 2, 3, 4, 5, 6, 7, 8)); + CHECK_EQUAL(8, etl::multimax_compare(std::less(), 1, 2, 3, 4, 5, 6, 7, 8)); + CHECK_EQUAL(1, etl::multimax_compare(std::greater(), 1, 2, 3, 4, 5, 6, 7, 8)); + } + + //========================================================================= + TEST(multimax_iter) + { + int i[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + + CHECK_EQUAL(8, *etl::multimax_iter(&i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7])); + CHECK_EQUAL(8, *etl::multimax_iter_compare(std::less(), &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7])); + CHECK_EQUAL(1, *etl::multimax_iter_compare(std::greater(), &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7])); + } + + //========================================================================= + TEST(multimin) + { + CHECK_EQUAL(1, etl::multimin(1, 2, 3, 4, 5, 6, 7, 8)); + CHECK_EQUAL(1, etl::multimin_compare(std::less(), 1, 2, 3, 4, 5, 6, 7, 8)); + CHECK_EQUAL(8, etl::multimin_compare(std::greater(), 1, 2, 3, 4, 5, 6, 7, 8)); + } + + //========================================================================= + TEST(multimin_iter) + { + int i[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + + CHECK_EQUAL(1, *etl::multimin_iter(&i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7])); + CHECK_EQUAL(1, *etl::multimin_iter_compare(std::less(), &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7])); + CHECK_EQUAL(8, *etl::multimin_iter_compare(std::greater(), &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7])); + } }; }