/****************************************************************************** The MIT License(MIT) Embedded Template Library. https://github.com/ETLCPP/etl https://www.etlcpp.com Copyright(c) 2014 John Wellbelove Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ #include "unit_test_framework.h" #include "etl/algorithm.h" #include "etl/container.h" #include "etl/binary.h" #include "data.h" #include "iterators_for_unit_tests.h" #include #include #include #include #include #include #include #include #include namespace { using NDC = TestDataNDC; using ItemM = TestDataM; std::random_device rng; std::mt19937 urng(rng()); using Vector = std::vector; Vector data = { 2, 1, 1, 4, 3, 6, 5, 8, 7, 10, 10, 9 }; using VectorM = std::vector; constexpr size_t SIZE = 10; int dataA[SIZE] = { 2, 1, 4, 3, 6, 5, 8, 7, 10, 9 }; int dataS[SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; std::list dataSL = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; using List = std::list; List dataL = { 2, 1, 4, 3, 6, 5, 8, 7, 10, 9 }; int dataEQ[SIZE] = { 1, 1, 3, 3, 5, 5, 7, 7, 9, 9 }; std::list dataEQL = { 1, 1, 3, 3, 5, 5, 7, 7, 9, 9 }; Vector dataV = { 2, 1, 4, 3, 6, 5, 8, 7, 10, 9 }; int dataD1[SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int dataD2[SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; class Data { public: Data() : a(0) , b(0) { } Data(int a_, int b_) : a(a_) , b(b_) { } int a; int b; }; bool operator ==(const Data& lhs, const Data& rhs) { return (lhs.a == rhs.a) && (lhs.b == rhs.b); } struct DataPredicate { bool operator ()(const Data& lhs, const Data& rhs) const { return lhs.a < rhs.a; } }; struct DataEquality { bool operator ()(const Data& lhs, const Data& rhs) const { return lhs.a == rhs.a; } }; struct DataEquivalenceByA : public etl::binary_function { bool operator ()(const Data& lhs, const Data& rhs) const { return lhs.a == rhs.a; } }; Data dataD[10] = { Data(1, 2), Data(2, 1), Data(3, 4), Data(4, 3), Data(5, 6), Data(6, 5), Data(7, 8), Data(8, 7), Data(9, 10), Data(10, 9) }; struct Greater : public etl::binary_function { bool operator()(int a, int b) const { return a > b; } }; std::ostream& operator << (std::ostream& os, const Data& data_) { os << data_.a << "," << data_.b; return os; } SUITE(test_algorithm) { //************************************************************************* TEST(min) { int a = 1; int b = 2; CHECK_EQUAL((std::min(a, b)), (etl::min(a, b))); CHECK_EQUAL((std::min(b, a)), (etl::min(b, a))); } //************************************************************************* TEST(min_compare) { int a = 1; int b = 2; CHECK_EQUAL((std::min(a, b, Greater())), (etl::min(a, b, Greater()))); CHECK_EQUAL((std::min(b, a, Greater())), (etl::min(b, a, Greater()))); } //************************************************************************* TEST(max) { int a = 1; int b = 2; CHECK_EQUAL((std::max(a, b)), (etl::max(a, b))); CHECK_EQUAL((std::max(b, a)), (etl::max(b, a))); } //************************************************************************* TEST(max_compare) { int a = 1; int b = 2; CHECK_EQUAL((std::max(a, b, Greater())), (etl::max(a, b, Greater()))); 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(min_element_empty) { Vector dataEmpty; Vector::iterator expected = std::min_element(dataEmpty.begin(), dataEmpty.end()); Vector::iterator result = etl::min_element(dataEmpty.begin(), dataEmpty.end()); CHECK_EQUAL(std::distance(dataEmpty.end(), expected), std::distance(dataEmpty.end(), 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(max_element_empty) { Vector dataEmpty; Vector::iterator expected = std::max_element(dataEmpty.begin(), dataEmpty.end()); Vector::iterator result = etl::max_element(dataEmpty.begin(), dataEmpty.end()); CHECK_EQUAL(std::distance(dataEmpty.end(), expected), std::distance(dataEmpty.end(), result)); } //************************************************************************* TEST(minmax_element) { std::pair expected = std::minmax_element(data.begin(), data.end()); std::pair result = etl::minmax_element(data.begin(), data.end()); CHECK_EQUAL(std::distance(data.begin(), expected.first), std::distance(data.begin(), result.first)); CHECK_EQUAL(std::distance(data.begin(), expected.second), std::distance(data.begin(), result.second)); } //************************************************************************* TEST(minmax_element_compare) { std::pair expected = std::minmax_element(data.begin(), data.end(), std::greater()); std::pair result = etl::minmax_element(data.begin(), data.end(), std::greater()); CHECK_EQUAL(std::distance(data.begin(), expected.first), std::distance(data.begin(), result.first)); CHECK_EQUAL(std::distance(data.begin(), expected.second), std::distance(data.begin(), result.second)); } //************************************************************************* TEST(minmax_element_empty) { Vector dataEmpty; std::pair expected = std::minmax_element(dataEmpty.begin(), dataEmpty.end()); std::pair result = etl::minmax_element(dataEmpty.begin(), dataEmpty.end()); CHECK_EQUAL(std::distance(dataEmpty.begin(), expected.first), std::distance(dataEmpty.begin(), result.first)); CHECK_EQUAL(std::distance(dataEmpty.begin(), expected.second), std::distance(dataEmpty.begin(), result.second)); } //************************************************************************* TEST(minmax) { int a = 1; int b = 2; std::pair expected = std::minmax(a, b); std::pair result = etl::minmax(a, b); CHECK_EQUAL(expected.first, result.first); CHECK_EQUAL(expected.second, result.second); result = etl::minmax(b, a); expected = std::minmax(b, a); CHECK_EQUAL(expected.first, result.first); CHECK_EQUAL(expected.second, result.second); } //************************************************************************* TEST(minmax_compare) { int a = 1; int b = 2; std::pair expected = std::minmax(a, b, std::greater()); std::pair result = etl::minmax(a, b, std::greater()); CHECK_EQUAL(expected.first, result.first); CHECK_EQUAL(expected.second, result.second); result = etl::minmax(b, a, std::greater()); expected = std::minmax(b, a, std::greater()); CHECK_EQUAL(expected.first, result.first); CHECK_EQUAL(expected.second, result.second); } //************************************************************************* TEST(is_sorted_until) { int data[] = { 1, 2, 3, 4, 6, 5, 7, 8, 9, 10 }; int* p1 = std::is_sorted_until(std::begin(data), std::end(data)); int* p2 = etl::is_sorted_until(std::begin(data), std::end(data)); CHECK_EQUAL(std::distance(std::begin(data), p1), std::distance(std::begin(data), p2)); } //************************************************************************* TEST(is_sorted_until_compare) { int data[] = { 10, 9, 8, 7, 5, 6, 4, 3, 4, 2, 1 }; int* p1 = std::is_sorted_until(std::begin(data), std::end(data), std::greater()); int* p2 = etl::is_sorted_until(std::begin(data), std::end(data), std::greater()); CHECK_EQUAL(std::distance(std::begin(data), p1), std::distance(std::begin(data), p2)); } //************************************************************************* TEST(is_sorted) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; bool is_sorted = etl::is_sorted(std::begin(data1), std::end(data1)); CHECK(is_sorted); int data2[] = { 1, 2, 3, 4, 6, 5, 7, 8 , 9, 10 }; is_sorted = etl::is_sorted(std::begin(data2), std::end(data2)); CHECK(!is_sorted); } //************************************************************************* TEST(is_sorted_compare) { int data1[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; bool is_sorted = etl::is_sorted(std::begin(data1), std::end(data1), std::greater()); CHECK(is_sorted); int data2[] = { 10, 9, 8, 7, 5, 6, 4, 3, 2, 1 }; is_sorted = etl::is_sorted(std::begin(data2), std::end(data2), std::greater()); CHECK(!is_sorted); } //************************************************************************* TEST(is_unique_sorted_until) { int sorted_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int not_sorted_data[] = { 1, 2, 3, 4, 6, 5, 7, 8, 9, 10 }; int not_unique_data[] = { 1, 2, 3, 4, 4, 5, 6, 8, 9, 10 }; int* p_sorted = etl::is_unique_sorted_until(std::begin(sorted_data), std::end(sorted_data)); int* p_not_sorted = etl::is_unique_sorted_until(std::begin(not_sorted_data), std::end(not_sorted_data)); int* p_not_unique = etl::is_unique_sorted_until(std::begin(not_unique_data), std::end(not_unique_data)); CHECK_EQUAL(10, std::distance(sorted_data, p_sorted)); CHECK_EQUAL(5, std::distance(not_sorted_data, p_not_sorted)); CHECK_EQUAL(4, std::distance(not_unique_data, p_not_unique)); } //************************************************************************* TEST(is_unique_sorted_until_compare) { int sorted_data[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; int not_sorted_data[] = { 10, 9, 8, 7, 5, 6, 4, 3, 2, 1 }; int not_unique_data[] = { 10, 9, 8, 6, 5, 4, 4, 3, 2, 1 }; int* p_sorted = etl::is_unique_sorted_until(std::begin(sorted_data), std::end(sorted_data), std::greater()); int* p_not_sorted = etl::is_unique_sorted_until(std::begin(not_sorted_data), std::end(not_sorted_data), std::greater()); int* p_not_unique = etl::is_unique_sorted_until(std::begin(not_unique_data), std::end(not_unique_data), std::greater()); CHECK_EQUAL(10, std::distance(sorted_data, p_sorted)); CHECK_EQUAL(5, std::distance(not_sorted_data, p_not_sorted)); CHECK_EQUAL(6, std::distance(not_unique_data, p_not_unique)); } //************************************************************************* TEST(is_unique_sorted) { int sorted_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int not_sorted_data[] = { 1, 2, 3, 4, 6, 5, 7, 8, 9, 10 }; int not_unique_data[] = { 1, 2, 3, 4, 4, 5, 6, 8, 9, 10 }; CHECK_TRUE((etl::is_unique_sorted(std::begin(sorted_data), std::end(sorted_data)))); CHECK_FALSE((etl::is_unique_sorted(std::begin(not_sorted_data), std::end(not_sorted_data)))); CHECK_FALSE((etl::is_unique_sorted(std::begin(not_unique_data), std::end(not_unique_data)))); } //************************************************************************* TEST(is_unique_sorted_compare) { int sorted_data[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; int not_sorted_data[] = { 10, 9, 8, 7, 5, 6, 4, 3, 2, 1 }; int not_unique_data[] = { 10, 9, 8, 6, 5, 4, 4, 3, 2, 1 }; CHECK_TRUE((etl::is_unique_sorted(std::begin(sorted_data), std::end(sorted_data), std::greater()))); CHECK_FALSE((etl::is_unique_sorted(std::begin(not_sorted_data), std::end(not_sorted_data), std::greater()))); CHECK_FALSE((etl::is_unique_sorted(std::begin(not_unique_data), std::end(not_unique_data), std::greater()))); } //************************************************************************* TEST(copy_pod_pointer) { int data1[10]; int data2[10]; int* pstl = std::copy(std::begin(dataA), std::end(dataA), std::begin(data1)); int* petl = etl::copy(std::begin(dataA), std::end(dataA), std::begin(data2)); using difference_type_t = std::iterator_traits::difference_type; difference_type_t dstl = std::distance(data1, pstl); difference_type_t detl = std::distance(data2, petl); CHECK_EQUAL(dstl, detl); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(copy_non_pod_pointer) { Data data1[10]; Data data2[10]; Data* pstl = std::copy(std::begin(dataD), std::end(dataD), std::begin(data1)); Data* petl = etl::copy(std::begin(dataD), std::end(dataD), std::begin(data2)); using difference_type_t = std::iterator_traits::difference_type; difference_type_t dstl = std::distance(data1, pstl); difference_type_t detl = std::distance(data2, petl); CHECK_EQUAL(dstl, detl); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(copy_non_random_iterator) { List data1(dataL.size()); List data2(dataL.size()); List::iterator pstl = std::copy(std::begin(dataA), std::end(dataA), std::begin(data1)); List::iterator petl = etl::copy(std::begin(dataA), std::end(dataA), std::begin(data2)); using difference_type_t = List::difference_type; difference_type_t dstl = std::distance(data1.begin(), pstl); difference_type_t detl = std::distance(data2.begin(), petl); CHECK_EQUAL(dstl, detl); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(copy_n_random_iterator) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int data2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int data3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int* result; std::copy_n(std::begin(data1), 4, std::begin(data2)); result = etl::copy_n(std::begin(data1), 4, std::begin(data3)); CHECK_EQUAL(std::begin(data3) + 4, result); bool is_same = std::equal(std::begin(data2), std::end(data2), std::begin(data3)); CHECK(is_same); } //************************************************************************* TEST(copy_n_non_random_iterator) { std::list data1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int data2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int data3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int* result; std::copy_n(std::begin(data1), 4, std::begin(data2)); result = etl::copy_n(std::begin(data1), 4, std::begin(data3)); CHECK_EQUAL(std::begin(data3) + 4, result); bool is_same = std::equal(std::begin(data2), std::end(data2), std::begin(data3)); CHECK(is_same); } //************************************************************************* TEST(copy_if) { int data1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int data2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int data3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Copy everything less than 5. std::copy_if(std::begin(data1), std::end(data1), std::begin(data2), std::bind(std::less(), std::placeholders::_1, 5)); etl::copy_if(std::begin(data1), std::end(data1), std::begin(data3), std::bind(std::less(), std::placeholders::_1, 5)); bool is_same = std::equal(std::begin(data2), std::end(data2), std::begin(data3)); CHECK(is_same); } //************************************************************************* TEST(reverse_copy_pod_pointer) { int data1[10]; int data2[10]; int* pstl = std::reverse_copy(std::begin(dataA), std::end(dataA), std::begin(data1)); int* petl = etl::reverse_copy(std::begin(dataA), std::end(dataA), std::begin(data2)); using difference_type_t = std::iterator_traits::difference_type; difference_type_t dstl = std::distance(data1, pstl); difference_type_t detl = std::distance(data2, petl); CHECK_EQUAL(dstl, detl); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(copy_n_pod_pointer) { int data1[10]; int data2[10]; int* pstl = std::copy_n(std::begin(dataA), 10, std::begin(data1)); int* petl = etl::copy_n(std::begin(dataA), 10, std::begin(data2)); using difference_type_t = std::iterator_traits::difference_type; difference_type_t dstl = std::distance(data1, pstl); difference_type_t detl = std::distance(data2, petl); CHECK_EQUAL(dstl, detl); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(copy_n_non_pod_pointer) { Data data1[10]; Data data2[10]; Data* pstl = std::copy_n(std::begin(dataD), 10, std::begin(data1)); Data* petl = etl::copy_n(std::begin(dataD), 10, std::begin(data2)); using difference_type_t = std::iterator_traits::difference_type; difference_type_t dstl = std::distance(data1, pstl); difference_type_t detl = std::distance(data2, petl); CHECK_EQUAL(dstl, detl); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(copy_backward_pod_pointer) { int data1[10]; int data2[10]; int* pstl = std::copy_backward(std::begin(dataA), std::end(dataA), std::end(data1)); int* petl = etl::copy_backward(std::begin(dataA), std::end(dataA), std::end(data2)); using difference_type_t = std::iterator_traits::difference_type; difference_type_t dstl = std::distance(data1, pstl); difference_type_t detl = std::distance(data2, petl); CHECK_EQUAL(dstl, detl); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(copy_backward_non_pod_pointer) { Data data1[10]; Data data2[10]; Data* pstl = std::copy_backward(std::begin(dataD), std::end(dataD), std::end(data1)); Data* petl = etl::copy_backward(std::begin(dataD), std::end(dataD), std::end(data2)); using difference_type_t = std::iterator_traits::difference_type; difference_type_t dstl = std::distance(data1, pstl); difference_type_t detl = std::distance(data2, petl); CHECK_EQUAL(dstl, detl); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(copy_backward_non_random_iterator) { List data1(dataL.size()); List data2(dataL.size()); List::iterator pstl = copy_backward(std::begin(dataA), std::end(dataA), std::end(data1)); List::iterator petl = etl::copy_backward(std::begin(dataA), std::end(dataA), std::end(data2)); using difference_type_t = std::iterator_traits::difference_type; difference_type_t dstl = std::distance(data1.begin(), pstl); difference_type_t detl = std::distance(data2.begin(), petl); CHECK_EQUAL(dstl, detl); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(test_reverse_even_non_pointer) { std::array data1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; std::array data2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; std::reverse(data1.begin(), data1.end()); etl::reverse(data2.begin(), data2.end()); bool isEqual = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(isEqual); } //************************************************************************* TEST(test_reverse_odd_non_pointer) { std::array data1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; std::array data2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; std::reverse(data1.begin(), data1.end()); etl::reverse(data2.begin(), data2.end()); bool isEqual = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(isEqual); } //************************************************************************* TEST(test_reverse_even_pointer) { int data1[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int data2[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; std::reverse(std::begin(data1), std::end(data1)); etl::reverse(std::begin(data2), std::end(data2)); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(test_reverse_odd_pointer) { int data1[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; int data2[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; std::reverse(std::begin(data1), std::end(data1)); etl::reverse(std::begin(data2), std::end(data2)); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(lower_bound_random_iterator) { for (int i = 0; i < 11; ++i) { int* lb1 = std::lower_bound(std::begin(dataS), std::end(dataS), i); int* lb2 = etl::lower_bound(random_iterator(std::begin(dataS)), random_iterator(std::end(dataS)), i); CHECK_EQUAL(lb1, lb2); } } //************************************************************************* TEST(lower_bound_non_random_iterator) { for (int i = 0; i < 11; ++i) { int* lb1 = std::lower_bound(std::begin(dataS), std::end(dataS), i); int* lb2 = etl::lower_bound(non_random_iterator(std::begin(dataS)), non_random_iterator(std::end(dataS)), i); CHECK_EQUAL(std::distance(std::begin(dataS), lb1), std::distance(std::begin(dataS), lb2)); } } //************************************************************************* TEST(upper_bound_random_iterator) { for (int i = 0; i < 11; ++i) { int* lb1 = std::upper_bound(std::begin(dataS), std::end(dataS), i); int* lb2 = etl::upper_bound(random_iterator(std::begin(dataS)), random_iterator(std::end(dataS)), i); CHECK_EQUAL(std::distance(std::begin(dataS), lb1), std::distance(std::begin(dataS), lb2)); } } //************************************************************************* TEST(upper_bound_non_random_iterator) { for (int i = 0; i < 11; ++i) { int* lb1 = std::upper_bound(std::begin(dataS), std::end(dataS), i); int* lb2 = etl::upper_bound(non_random_iterator(std::begin(dataS)), non_random_iterator(std::end(dataS)), i); CHECK_EQUAL(std::distance(std::begin(dataS), lb1), std::distance(std::begin(dataS), lb2)); } } //************************************************************************* TEST(equal_range_random_iterator) { for (int i = 0; i < 11; ++i) { ETL_OR_STD::pair lb1 = std::equal_range(std::begin(dataEQ), std::end(dataEQ), i); ETL_OR_STD::pair, random_iterator> lb2 = etl::equal_range(random_iterator(std::begin(dataEQ)), random_iterator(std::end(dataEQ)), i); CHECK_EQUAL(std::distance(std::begin(dataEQ), lb1.first), std::distance(std::begin(dataEQ), lb2.first)); CHECK_EQUAL(std::distance(lb1.first, lb1.second), std::distance(lb2.first, lb2.second)); } } //************************************************************************* TEST(equal_range_non_random_iterator) { for (int i = 0; i < 11; ++i) { ETL_OR_STD::pair lb1 = std::equal_range(std::begin(dataEQ), std::end(dataEQ), i); ETL_OR_STD::pair, non_random_iterator> lb2 = etl::equal_range(non_random_iterator(std::begin(dataEQ)), non_random_iterator(std::end(dataEQ)), i); CHECK_EQUAL(std::distance(std::begin(dataEQ), lb1.first), std::distance(std::begin(dataEQ), lb2.first)); CHECK_EQUAL(std::distance(lb1.first, lb1.second), std::distance(lb2.first, lb2.second)); } } //************************************************************************* TEST(binary_search_random_iterator) { for (int i = 0; i < 11; ++i) { bool expected = std::binary_search(std::begin(dataS), std::end(dataS), i); bool result = etl::binary_search(std::begin(dataS), std::end(dataS), i); CHECK_EQUAL(expected, result); } } //************************************************************************* TEST(binary_search_with_compare) { for (int i = 0; i < 11; ++i) { bool expected = std::binary_search(std::begin(dataS), std::end(dataS), i, etl::less()); bool result = etl::binary_search(std::begin(dataS), std::end(dataS), i, etl::less()); CHECK_EQUAL(expected, result); } } //************************************************************************* TEST(binary_search_duplicates) { for (int i = 0; i < 11; ++i) { bool expected = std::binary_search(std::begin(dataEQ), std::end(dataEQ), i); bool result = etl::binary_search(std::begin(dataEQ), std::end(dataEQ), i); CHECK_EQUAL(expected, result); } } //************************************************************************* TEST(binary_search_empty_range) { int empty[] = { 0 }; bool result = etl::binary_search(std::begin(empty), std::begin(empty), 1); CHECK_EQUAL(false, result); } //************************************************************************* TEST(binary_search_single_element) { int single[] = { 5 }; CHECK_EQUAL(true, etl::binary_search(std::begin(single), std::end(single), 5)); CHECK_EQUAL(false, etl::binary_search(std::begin(single), std::end(single), 3)); CHECK_EQUAL(false, etl::binary_search(std::begin(single), std::end(single), 7)); } //************************************************************************* TEST(fill_non_char) { int data1[10]; int data2[10]; std::fill(std::begin(data1), std::end(data1), 0x12345678UL); etl::fill(std::begin(data2), std::end(data2), 0x12345678UL); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(fill_char) { unsigned char data1[10]; unsigned char data2[10]; std::fill(std::begin(data1), std::end(data1), char(0x12U)); etl::fill(std::begin(data2), std::end(data2), char(0x12U)); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(iter_swap_same_types) { int a = 1; int b = 2; etl::iter_swap(&a, &b); CHECK_EQUAL(2, a); CHECK_EQUAL(1, b); } //************************************************************************* TEST(iter_swap_differnt_types) { int a = 1; long b = 2; etl::iter_swap(&a, &b); CHECK_EQUAL(2, a); CHECK_EQUAL(1, b); } //************************************************************************* TEST(swap_ranges_pod_pointer) { int data1[] = { 1, 2, 3, 4, 5 }; int data2[] = { 6, 7, 8, 9, 10 }; int expected1[] = { 6, 7, 8, 9, 10 }; int expected2[] = { 1, 2, 3, 4, 5 }; int* result = etl::swap_ranges(std::begin(data1), std::end(data1), std::begin(data2)); CHECK_EQUAL(std::end(data2), result); bool isEqual1 = std::equal(std::begin(data1), std::end(data1), std::begin(expected1)); CHECK(isEqual1); bool isEqual2 = std::equal(std::begin(data2), std::end(data2), std::begin(expected2)); CHECK(isEqual2); } //************************************************************************* TEST(swap_ranges_non_pod_pointer) { Data data1[] = { Data(1, 2), Data(3, 4), Data(5, 6) }; Data data2[] = { Data(7, 8), Data(9, 10), Data(11, 12) }; Data expected1[] = { Data(7, 8), Data(9, 10), Data(11, 12) }; Data expected2[] = { Data(1, 2), Data(3, 4), Data(5, 6) }; Data* result = etl::swap_ranges(std::begin(data1), std::end(data1), std::begin(data2)); CHECK_EQUAL(std::end(data2), result); bool isEqual1 = std::equal(std::begin(data1), std::end(data1), std::begin(expected1)); CHECK(isEqual1); bool isEqual2 = std::equal(std::begin(data2), std::end(data2), std::begin(expected2)); CHECK(isEqual2); } //************************************************************************* TEST(swap_ranges_non_random_iterator) { List data1 = { 1, 2, 3, 4, 5 }; List data2 = { 6, 7, 8, 9, 10 }; List expected1 = { 6, 7, 8, 9, 10 }; List expected2 = { 1, 2, 3, 4, 5 }; List::iterator result = etl::swap_ranges(data1.begin(), data1.end(), data2.begin()); CHECK(data2.end() == result); bool isEqual1 = std::equal(data1.begin(), data1.end(), expected1.begin()); CHECK(isEqual1); bool isEqual2 = std::equal(data2.begin(), data2.end(), expected2.begin()); CHECK(isEqual2); } //************************************************************************* TEST(swap_ranges_empty_range) { int data1[] = { 1, 2, 3 }; int data2[] = { 4, 5, 6 }; int expected1[] = { 1, 2, 3 }; int expected2[] = { 4, 5, 6 }; int* result = etl::swap_ranges(std::begin(data1), std::begin(data1), std::begin(data2)); CHECK_EQUAL(std::begin(data2), result); bool isEqual1 = std::equal(std::begin(data1), std::end(data1), std::begin(expected1)); CHECK(isEqual1); bool isEqual2 = std::equal(std::begin(data2), std::end(data2), std::begin(expected2)); CHECK(isEqual2); } //************************************************************************* TEST(swap_ranges_partial_range) { int data1[] = { 1, 2, 3, 4, 5 }; int data2[] = { 6, 7, 8, 9, 10 }; int expected1[] = { 6, 7, 8, 4, 5 }; int expected2[] = { 1, 2, 3, 9, 10 }; int* result = etl::swap_ranges(std::begin(data1), std::begin(data1) + 3, std::begin(data2)); CHECK_EQUAL(std::begin(data2) + 3, result); bool isEqual1 = std::equal(std::begin(data1), std::end(data1), std::begin(expected1)); CHECK(isEqual1); bool isEqual2 = std::equal(std::begin(data2), std::end(data2), std::begin(expected2)); CHECK(isEqual2); } //************************************************************************* TEST(swap_ranges_same_data) { int data1[] = { 1, 2, 3, 4, 5 }; int expected[] = { 1, 2, 3, 4, 5 }; etl::swap_ranges(std::begin(data1), std::end(data1), std::begin(data1)); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(expected)); CHECK(isEqual); } //************************************************************************* TEST(swap_ranges_matches_std) { int data1_std[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int data2_std[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; int data1_etl[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int data2_etl[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; int* pstl = std::swap_ranges(std::begin(data1_std), std::end(data1_std), std::begin(data2_std)); int* petl = etl::swap_ranges(std::begin(data1_etl), std::end(data1_etl), std::begin(data2_etl)); using difference_type_t = std::iterator_traits::difference_type; difference_type_t dstl = std::distance(data2_std, pstl); difference_type_t detl = std::distance(data2_etl, petl); CHECK_EQUAL(dstl, detl); bool isEqual1 = std::equal(std::begin(data1_std), std::end(data1_std), std::begin(data1_etl)); CHECK(isEqual1); bool isEqual2 = std::equal(std::begin(data2_std), std::end(data2_std), std::begin(data2_etl)); CHECK(isEqual2); } //************************************************************************* TEST(equal) { CHECK(etl::equal(std::begin(dataV), std::end(dataV), std::begin(dataL))); CHECK(!etl::equal(std::begin(dataSL), std::end(dataSL), std::begin(dataL))); int small[] = { dataS[0] }; CHECK(etl::equal(std::begin(dataV), std::end(dataV), std::begin(dataL), std::end(dataL))); CHECK(!etl::equal(std::begin(dataS), std::end(dataS), std::begin(small), std::end(small))); } //************************************************************************* TEST(lexicographical_compare) { std::string text1("Hello World"); std::string text2("Hello Xorld"); bool t1 = std::lexicographical_compare(text1.begin(), text1.end(), text2.begin(), text2.begin() + 7); bool t2 = etl::lexicographical_compare(text1.begin(), text1.end(), text2.begin(), text2.begin() + 7); CHECK(t1 == t2); } //************************************************************************* TEST(lexicographical_compare_greater) { std::string text1("Hello World"); std::string text2("Hello Xorld"); bool t1 = std::lexicographical_compare(text1.begin(), text1.end(), text2.begin(), text2.begin() + 7, Greater()); bool t2 = etl::lexicographical_compare(text1.begin(), text1.end(), text2.begin(), text2.begin() + 7, Greater()); CHECK(t1 == t2); } //************************************************************************* TEST(search) { std::string haystack = "ABCDFEGHIJKLMNOPQRSTUVWXYZ"; std::string needle = "KLMNO"; std::string::iterator itr1 = std::search(haystack.begin(), haystack.end(), needle.begin(), needle.begin()); std::string::iterator itr2 = etl::search(haystack.begin(), haystack.end(), needle.begin(), needle.begin()); CHECK(itr1 == itr2); } //************************************************************************* TEST(search_predicate) { std::string haystack = "ABCDFEGHIJKLMNOPQRSTUVWXYZ"; std::string needle = "KLMNO"; std::string::iterator itr1 = std::search(haystack.begin(), haystack.end(), needle.begin(), needle.begin(), std::equal_to()); std::string::iterator itr2 = etl::search(haystack.begin(), haystack.end(), needle.begin(), needle.begin(), std::equal_to()); CHECK(itr1 == itr2); } //************************************************************************* TEST(find_end_default) { int data[] = { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4 }; int pattern[] = { 1, 2, 3 }; int* expected = std::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); int* result = etl::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(find_end_predicate) { int data[] = { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4 }; int pattern[] = { 1, 2, 3 }; int* expected = std::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern), std::equal_to()); int* result = etl::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern), std::equal_to()); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(find_end_single_occurrence) { int data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int pattern[] = { 5, 6, 7 }; int* expected = std::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); int* result = etl::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(find_end_no_match) { int data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int pattern[] = { 11, 12 }; int* expected = std::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); int* result = etl::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(find_end_empty_sequence) { int data[] = { 1, 2, 3, 4, 5 }; int pattern[] = { 0 }; int* expected = std::find_end(std::begin(data), std::end(data), std::begin(pattern), std::begin(pattern)); int* result = etl::find_end(std::begin(data), std::end(data), std::begin(pattern), std::begin(pattern)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(find_end_pattern_at_end) { int data[] = { 1, 2, 3, 4, 5, 6, 7 }; int pattern[] = { 5, 6, 7 }; int* expected = std::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); int* result = etl::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(find_end_pattern_at_start) { int data[] = { 1, 2, 3, 4, 5, 6, 7 }; int pattern[] = { 1, 2, 3 }; int* expected = std::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); int* result = etl::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(find_end_entire_range_matches) { int data[] = { 1, 2, 3, 4, 5 }; int pattern[] = { 1, 2, 3, 4, 5 }; int* expected = std::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); int* result = etl::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(find_end_overlapping_occurrences) { int data[] = { 1, 1, 1, 1, 1 }; int pattern[] = { 1, 1 }; int* expected = std::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); int* result = etl::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(find_end_single_element_pattern) { int data[] = { 1, 2, 3, 2, 5, 2, 7 }; int pattern[] = { 2 }; int* expected = std::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); int* result = etl::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(find_end_non_random_iterator) { int data_array[] = { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4 }; int pattern_array[] = { 1, 2, 3 }; List data(std::begin(data_array), std::end(data_array)); List pattern(std::begin(pattern_array), std::end(pattern_array)); List::iterator expected = std::find_end(data.begin(), data.end(), pattern.begin(), pattern.end(), std::equal_to()); List::iterator result = etl::find_end(data.begin(), data.end(), pattern.begin(), pattern.end(), std::equal_to()); CHECK(expected == result); } //************************************************************************* TEST(find_end_non_random_iterator_predicate) { int data_array[] = { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4 }; int pattern_array[] = { 1, 2, 3 }; List data(std::begin(data_array), std::end(data_array)); List pattern(std::begin(pattern_array), std::end(pattern_array)); List::iterator expected = std::find_end(data.begin(), data.end(), pattern.begin(), pattern.end(), std::equal_to()); List::iterator result = etl::find_end(data.begin(), data.end(), pattern.begin(), pattern.end(), std::equal_to()); CHECK(expected == result); } //************************************************************************* TEST(find_end_pattern_longer_than_data) { int data[] = { 1, 2, 3 }; int pattern[] = { 1, 2, 3, 4, 5 }; int* expected = std::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); int* result = etl::find_end(std::begin(data), std::end(data), std::begin(pattern), std::end(pattern)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(adjacent_find_default) { int data[] = { 1, 2, 3, 3, 4, 5 }; int* expected = std::adjacent_find(std::begin(data), std::end(data)); int* result = etl::adjacent_find(std::begin(data), std::end(data)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(adjacent_find_predicate) { int data[] = { 1, 2, 3, 3, 4, 5 }; int* expected = std::adjacent_find(std::begin(data), std::end(data), std::equal_to()); int* result = etl::adjacent_find(std::begin(data), std::end(data), std::equal_to()); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(adjacent_find_no_match) { int data[] = { 1, 2, 3, 4, 5, 6 }; int* expected = std::adjacent_find(std::begin(data), std::end(data)); int* result = etl::adjacent_find(std::begin(data), std::end(data)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(adjacent_find_at_beginning) { int data[] = { 1, 1, 2, 3, 4, 5 }; int* expected = std::adjacent_find(std::begin(data), std::end(data)); int* result = etl::adjacent_find(std::begin(data), std::end(data)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(adjacent_find_at_end) { int data[] = { 1, 2, 3, 4, 5, 5 }; int* expected = std::adjacent_find(std::begin(data), std::end(data)); int* result = etl::adjacent_find(std::begin(data), std::end(data)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(adjacent_find_multiple_pairs) { int data[] = { 1, 1, 2, 2, 3, 3 }; int* expected = std::adjacent_find(std::begin(data), std::end(data)); int* result = etl::adjacent_find(std::begin(data), std::end(data)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(adjacent_find_single_element) { int data[] = { 1 }; int* expected = std::adjacent_find(std::begin(data), std::end(data)); int* result = etl::adjacent_find(std::begin(data), std::end(data)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(adjacent_find_empty_range) { int data[] = { 1 }; int* expected = std::adjacent_find(std::begin(data), std::begin(data)); int* result = etl::adjacent_find(std::begin(data), std::begin(data)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(adjacent_find_all_same) { int data[] = { 5, 5, 5, 5, 5 }; int* expected = std::adjacent_find(std::begin(data), std::end(data)); int* result = etl::adjacent_find(std::begin(data), std::end(data)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(adjacent_find_predicate_less) { int data[] = { 5, 4, 3, 2, 1 }; int* expected = std::adjacent_find(std::begin(data), std::end(data), std::greater()); int* result = etl::adjacent_find(std::begin(data), std::end(data), std::greater()); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(adjacent_find_non_random_iterator) { int data_array[] = { 1, 2, 3, 3, 4, 5 }; List data(std::begin(data_array), std::end(data_array)); List::iterator expected = std::adjacent_find(data.begin(), data.end()); List::iterator result = etl::adjacent_find(data.begin(), data.end()); CHECK(expected == result); } //************************************************************************* TEST(adjacent_find_non_random_iterator_predicate) { int data_array[] = { 1, 2, 3, 3, 4, 5 }; List data(std::begin(data_array), std::end(data_array)); List::iterator expected = std::adjacent_find(data.begin(), data.end(), std::equal_to()); List::iterator result = etl::adjacent_find(data.begin(), data.end(), std::equal_to()); CHECK(expected == result); } //************************************************************************* TEST(adjacent_find_non_random_iterator_no_match) { int data_array[] = { 1, 2, 3, 4, 5, 6 }; List data(std::begin(data_array), std::end(data_array)); List::iterator expected = std::adjacent_find(data.begin(), data.end()); List::iterator result = etl::adjacent_find(data.begin(), data.end()); CHECK(expected == result); } //************************************************************************* TEST(heap) { using Vector = std::vector; std::string a("A"), b("B"), c("C"), d("D"), e("E"), f("F"), g("G"), h("H"), i("I"), j("J"); Vector data1 = { a, b, c, d, e, f, g, h, i, j }; Vector data2 = { a, b, c, d, e, f, g, h, i, j }; std::make_heap(data1.begin(), data1.end()); etl::make_heap(data2.begin(), data2.end()); bool isEqual; CHECK(std::is_heap(data2.begin(), data2.end())); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); std::pop_heap(data1.begin(), data1.end()); etl::pop_heap(data2.begin(), data2.end()); data1.pop_back(); data2.pop_back(); CHECK(std::is_heap(data1.begin(), data1.end())); CHECK(std::is_heap(data2.begin(), data2.end())); CHECK_EQUAL(data1.size(), data2.size()); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); CHECK(std::is_heap(data2.begin(), data2.end())); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); data1.push_back(std::string("K")); data2.push_back(std::string("K")); std::push_heap(data1.begin(), data1.end()); etl::push_heap(data2.begin(), data2.end()); CHECK(std::is_heap(data2.begin(), data2.end())); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(heap_movable) { ItemM a("A"), b("B"), c("C"), d("D"), e("E"), f("F"), g("G"), h("H"), i("I"), j("J"); VectorM data1; data1.emplace_back(std::move(b)); data1.emplace_back(std::move(a)); data1.emplace_back(std::move(d)); data1.emplace_back(std::move(c)); data1.emplace_back(std::move(f)); data1.emplace_back(std::move(e)); data1.emplace_back(std::move(h)); data1.emplace_back(std::move(g)); data1.emplace_back(std::move(j)); data1.emplace_back(std::move(i)); VectorM data2; data2.emplace_back(ItemM("B")); data2.emplace_back(ItemM("A")); data2.emplace_back(ItemM("D")); data2.emplace_back(ItemM("C")); data2.emplace_back(ItemM("F")); data2.emplace_back(ItemM("E")); data2.emplace_back(ItemM("H")); data2.emplace_back(ItemM("G")); data2.emplace_back(ItemM("J")); data2.emplace_back(ItemM("I")); std::make_heap(data1.begin(), data1.end()); etl::make_heap(data2.begin(), data2.end()); bool isEqual; CHECK(std::is_heap(data1.begin(), data1.end())); CHECK(std::is_heap(data2.begin(), data2.end())); CHECK_EQUAL(data1.size(), data2.size()); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); std::pop_heap(data1.begin(), data1.end()); etl::pop_heap(data2.begin(), data2.end()); data1.pop_back(); data2.pop_back(); CHECK(std::is_heap(data1.begin(), data1.end())); CHECK(std::is_heap(data2.begin(), data2.end())); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); CHECK(std::is_heap(data2.begin(), data2.end())); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); data1.push_back(ItemM("K")); data2.push_back(ItemM("K")); std::push_heap(data1.begin(), data1.end()); etl::push_heap(data2.begin(), data2.end()); CHECK(std::is_heap(data2.begin(), data2.end())); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(heap_greater) { Vector data1 = dataV; Vector data2 = dataV; std::make_heap(data1.begin(), data1.end(), Greater()); etl::make_heap(data2.begin(), data2.end(), Greater()); bool isEqual; CHECK(std::is_heap(data2.begin(), data2.end(), Greater())); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); std::pop_heap(data1.begin(), data1.end(), Greater()); etl::pop_heap(data2.begin(), data2.end(), Greater()); data1.pop_back(); data2.pop_back(); CHECK(std::is_heap(data1.begin(), data1.end(), Greater())); CHECK(std::is_heap(data2.begin(), data2.end(), Greater())); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); CHECK(std::is_heap(data2.begin(), data2.end(), Greater())); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); data1.push_back(5); data2.push_back(5); std::push_heap(data1.begin(), data1.end(), Greater()); etl::push_heap(data2.begin(), data2.end(), Greater()); CHECK(std::is_heap(data2.begin(), data2.end(), Greater())); isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(is_heap_default_true) { std::vector data = { 9, 8, 7, 6, 5, 4, 3, 2, 1 }; std::make_heap(data.begin(), data.end()); bool expected = std::is_heap(data.begin(), data.end()); bool result = etl::is_heap(data.begin(), data.end()); CHECK_EQUAL(expected, result); CHECK(result); } //************************************************************************* TEST(is_heap_default_false) { std::vector data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; bool expected = std::is_heap(data.begin(), data.end()); bool result = etl::is_heap(data.begin(), data.end()); CHECK_EQUAL(expected, result); CHECK(!result); } //************************************************************************* TEST(is_heap_compare_true) { std::vector data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; std::make_heap(data.begin(), data.end(), Greater()); bool expected = std::is_heap(data.begin(), data.end(), Greater()); bool result = etl::is_heap(data.begin(), data.end(), Greater()); CHECK_EQUAL(expected, result); CHECK(result); } //************************************************************************* TEST(is_heap_compare_false) { std::vector data = { 9, 8, 7, 6, 5, 4, 3, 2, 1 }; bool expected = std::is_heap(data.begin(), data.end(), Greater()); bool result = etl::is_heap(data.begin(), data.end(), Greater()); CHECK_EQUAL(expected, result); CHECK(!result); } //************************************************************************* TEST(is_heap_empty) { std::vector data; bool expected = std::is_heap(data.begin(), data.end()); bool result = etl::is_heap(data.begin(), data.end()); CHECK_EQUAL(expected, result); CHECK(result); } //************************************************************************* TEST(is_heap_single_element) { std::vector data = { 42 }; bool expected = std::is_heap(data.begin(), data.end()); bool result = etl::is_heap(data.begin(), data.end()); CHECK_EQUAL(expected, result); CHECK(result); } //************************************************************************* TEST(is_heap_two_elements) { std::vector data1 = { 5, 3 }; std::vector data2 = { 3, 5 }; CHECK_EQUAL(std::is_heap(data1.begin(), data1.end()), etl::is_heap(data1.begin(), data1.end())); CHECK_EQUAL(std::is_heap(data2.begin(), data2.end()), etl::is_heap(data2.begin(), data2.end())); } //************************************************************************* TEST(is_heap_pointer) { int data[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; bool expected = std::is_heap(std::begin(data), std::end(data)); bool result = etl::is_heap(std::begin(data), std::end(data)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(is_heap_after_make_heap) { // Test all permutations of a small dataset std::vector data = { 1, 2, 3, 4, 5 }; do { std::vector test_data(data); etl::make_heap(test_data.begin(), test_data.end()); CHECK(etl::is_heap(test_data.begin(), test_data.end())); } while (std::next_permutation(data.begin(), data.end())); } //************************************************************************* TEST(sort_heap_default) { std::vector data1 = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::vector data2(data1); std::make_heap(data1.begin(), data1.end()); etl::make_heap(data2.begin(), data2.end()); std::sort_heap(data1.begin(), data1.end()); etl::sort_heap(data2.begin(), data2.end()); bool isEqual = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(isEqual); // Verify sorted ascending CHECK(std::is_sorted(data2.begin(), data2.end())); } //************************************************************************* TEST(sort_heap_compare) { std::vector data1 = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::vector data2(data1); std::make_heap(data1.begin(), data1.end(), Greater()); etl::make_heap(data2.begin(), data2.end(), Greater()); std::sort_heap(data1.begin(), data1.end(), Greater()); etl::sort_heap(data2.begin(), data2.end(), Greater()); bool isEqual = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(isEqual); // Verify sorted descending CHECK(std::is_sorted(data2.begin(), data2.end(), Greater())); } //************************************************************************* TEST(sort_heap_empty) { std::vector data; etl::sort_heap(data.begin(), data.end()); CHECK(data.empty()); } //************************************************************************* TEST(sort_heap_single_element) { std::vector data = { 42 }; etl::sort_heap(data.begin(), data.end()); CHECK_EQUAL(1U, data.size()); CHECK_EQUAL(42, data[0]); } //************************************************************************* TEST(sort_heap_pointer) { int data1[] = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; int data2[] = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::make_heap(std::begin(data1), std::end(data1)); etl::make_heap(std::begin(data2), std::end(data2)); std::sort_heap(std::begin(data1), std::end(data1)); etl::sort_heap(std::begin(data2), std::end(data2)); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(sort_heap_all_permutations) { std::vector initial = { 1, 2, 3, 4, 5 }; do { std::vector data1(initial); std::vector data2(initial); std::make_heap(data1.begin(), data1.end()); etl::make_heap(data2.begin(), data2.end()); std::sort_heap(data1.begin(), data1.end()); etl::sort_heap(data2.begin(), data2.end()); bool isEqual = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(isEqual); } while (std::next_permutation(initial.begin(), initial.end())); } //************************************************************************* TEST(sort_heap_duplicates) { std::vector data1 = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5 }; std::vector data2(data1); std::make_heap(data1.begin(), data1.end()); etl::make_heap(data2.begin(), data2.end()); std::sort_heap(data1.begin(), data1.end()); etl::sort_heap(data2.begin(), data2.end()); bool isEqual = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(isEqual); } //************************************************************************* TEST(partial_sort_default) { std::vector data1 = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::vector data2(data1); std::partial_sort(data1.begin(), data1.begin() + 5, data1.end()); etl::partial_sort(data2.begin(), data2.begin() + 5, data2.end()); // The first 5 elements should be sorted and match std bool isEqual = std::equal(data1.begin(), data1.begin() + 5, data2.begin()); CHECK(isEqual); // Verify sorted range CHECK(std::is_sorted(data2.begin(), data2.begin() + 5)); } //************************************************************************* TEST(partial_sort_compare) { std::vector data1 = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::vector data2(data1); std::partial_sort(data1.begin(), data1.begin() + 5, data1.end(), Greater()); etl::partial_sort(data2.begin(), data2.begin() + 5, data2.end(), Greater()); // The first 5 elements should be sorted descending and match std bool isEqual = std::equal(data1.begin(), data1.begin() + 5, data2.begin()); CHECK(isEqual); // Verify sorted range (descending) CHECK(std::is_sorted(data2.begin(), data2.begin() + 5, Greater())); } //************************************************************************* TEST(partial_sort_empty) { std::vector data; etl::partial_sort(data.begin(), data.begin(), data.end()); CHECK(data.empty()); } //************************************************************************* TEST(partial_sort_middle_equals_first) { std::vector data = { 5, 3, 8, 1, 9 }; std::vector original(data); etl::partial_sort(data.begin(), data.begin(), data.end()); // Nothing should change when middle == first bool isEqual = std::equal(data.begin(), data.end(), original.begin()); CHECK(isEqual); } //************************************************************************* TEST(partial_sort_middle_equals_last) { std::vector data1 = { 5, 3, 8, 1, 9 }; std::vector data2(data1); std::partial_sort(data1.begin(), data1.end(), data1.end()); etl::partial_sort(data2.begin(), data2.end(), data2.end()); // Full sort bool isEqual = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(isEqual); CHECK(std::is_sorted(data2.begin(), data2.end())); } //************************************************************************* TEST(partial_sort_single_element) { std::vector data = { 42 }; etl::partial_sort(data.begin(), data.end(), data.end()); CHECK_EQUAL(1U, data.size()); CHECK_EQUAL(42, data[0]); } //************************************************************************* TEST(partial_sort_first_one) { std::vector data1 = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::vector data2(data1); std::partial_sort(data1.begin(), data1.begin() + 1, data1.end()); etl::partial_sort(data2.begin(), data2.begin() + 1, data2.end()); // The first element should be the minimum CHECK_EQUAL(data1[0], data2[0]); CHECK_EQUAL(1, data2[0]); } //************************************************************************* TEST(partial_sort_duplicates) { std::vector data1 = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5 }; std::vector data2(data1); std::partial_sort(data1.begin(), data1.begin() + 6, data1.end()); etl::partial_sort(data2.begin(), data2.begin() + 6, data2.end()); bool isEqual = std::equal(data1.begin(), data1.begin() + 6, data2.begin()); CHECK(isEqual); CHECK(std::is_sorted(data2.begin(), data2.begin() + 6)); } //************************************************************************* TEST(partial_sort_already_sorted) { std::vector data1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; std::vector data2(data1); std::partial_sort(data1.begin(), data1.begin() + 5, data1.end()); etl::partial_sort(data2.begin(), data2.begin() + 5, data2.end()); bool isEqual = std::equal(data1.begin(), data1.begin() + 5, data2.begin()); CHECK(isEqual); CHECK(std::is_sorted(data2.begin(), data2.begin() + 5)); } //************************************************************************* TEST(partial_sort_reverse_sorted) { std::vector data1 = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; std::vector data2(data1); std::partial_sort(data1.begin(), data1.begin() + 5, data1.end()); etl::partial_sort(data2.begin(), data2.begin() + 5, data2.end()); bool isEqual = std::equal(data1.begin(), data1.begin() + 5, data2.begin()); CHECK(isEqual); CHECK(std::is_sorted(data2.begin(), data2.begin() + 5)); } //************************************************************************* TEST(partial_sort_pointer) { int data1[] = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; int data2[] = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::partial_sort(std::begin(data1), std::begin(data1) + 5, std::end(data1)); etl::partial_sort(std::begin(data2), std::begin(data2) + 5, std::end(data2)); bool isEqual = std::equal(std::begin(data1), std::begin(data1) + 5, std::begin(data2)); CHECK(isEqual); } //************************************************************************* TEST(partial_sort_all_permutations) { std::vector initial = { 1, 2, 3, 4, 5 }; do { std::vector data1(initial); std::vector data2(initial); std::partial_sort(data1.begin(), data1.begin() + 3, data1.end()); etl::partial_sort(data2.begin(), data2.begin() + 3, data2.end()); bool isEqual = std::equal(data1.begin(), data1.begin() + 3, data2.begin()); CHECK(isEqual); } while (std::next_permutation(initial.begin(), initial.end())); } //************************************************************************* TEST(partial_sort_all_equal) { std::vector data = { 5, 5, 5, 5, 5, 5 }; etl::partial_sort(data.begin(), data.begin() + 3, data.end()); CHECK(std::is_sorted(data.begin(), data.begin() + 3)); for (size_t i = 0; i < data.size(); ++i) { CHECK_EQUAL(5, data[i]); } } //************************************************************************* TEST(partial_sort_copy_default) { std::vector input = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::vector output1(5); std::vector output2(5); std::partial_sort_copy(input.begin(), input.end(), output1.begin(), output1.end()); etl::partial_sort_copy(input.begin(), input.end(), output2.begin(), output2.end()); bool isEqual = std::equal(output1.begin(), output1.end(), output2.begin()); CHECK(isEqual); CHECK(std::is_sorted(output2.begin(), output2.end())); } //************************************************************************* TEST(partial_sort_copy_compare) { std::vector input = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::vector output1(5); std::vector output2(5); std::partial_sort_copy(input.begin(), input.end(), output1.begin(), output1.end(), Greater()); etl::partial_sort_copy(input.begin(), input.end(), output2.begin(), output2.end(), Greater()); bool isEqual = std::equal(output1.begin(), output1.end(), output2.begin()); CHECK(isEqual); CHECK(std::is_sorted(output2.begin(), output2.end(), Greater())); } //************************************************************************* TEST(partial_sort_copy_empty_input) { std::vector input; std::vector output(5, 99); auto result = etl::partial_sort_copy(input.begin(), input.end(), output.begin(), output.end()); CHECK(result == output.begin()); // Output should be unchanged for (size_t i = 0; i < output.size(); ++i) { CHECK_EQUAL(99, output[i]); } } //************************************************************************* TEST(partial_sort_copy_empty_output) { std::vector input = { 5, 3, 8, 1, 9 }; std::vector output; auto result = etl::partial_sort_copy(input.begin(), input.end(), output.begin(), output.end()); CHECK(result == output.begin()); } //************************************************************************* TEST(partial_sort_copy_output_larger_than_input) { std::vector input = { 5, 3, 1 }; std::vector output1(6, 99); std::vector output2(6, 99); auto result1 = std::partial_sort_copy(input.begin(), input.end(), output1.begin(), output1.end()); auto result2 = etl::partial_sort_copy(input.begin(), input.end(), output2.begin(), output2.end()); CHECK_EQUAL(std::distance(output1.begin(), result1), std::distance(output2.begin(), result2)); bool isEqual = std::equal(output1.begin(), result1, output2.begin()); CHECK(isEqual); CHECK(std::is_sorted(output2.begin(), result2)); } //************************************************************************* TEST(partial_sort_copy_output_smaller_than_input) { std::vector input = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::vector output1(3); std::vector output2(3); std::partial_sort_copy(input.begin(), input.end(), output1.begin(), output1.end()); etl::partial_sort_copy(input.begin(), input.end(), output2.begin(), output2.end()); bool isEqual = std::equal(output1.begin(), output1.end(), output2.begin()); CHECK(isEqual); CHECK(std::is_sorted(output2.begin(), output2.end())); } //************************************************************************* TEST(partial_sort_copy_output_same_size_as_input) { std::vector input = { 5, 3, 8, 1, 9 }; std::vector output1(5); std::vector output2(5); auto result1 = std::partial_sort_copy(input.begin(), input.end(), output1.begin(), output1.end()); auto result2 = etl::partial_sort_copy(input.begin(), input.end(), output2.begin(), output2.end()); CHECK(result1 == output1.end()); CHECK(result2 == output2.end()); bool isEqual = std::equal(output1.begin(), output1.end(), output2.begin()); CHECK(isEqual); CHECK(std::is_sorted(output2.begin(), output2.end())); } //************************************************************************* TEST(partial_sort_copy_single_element_input) { std::vector input = { 42 }; std::vector output(3, 0); auto result = etl::partial_sort_copy(input.begin(), input.end(), output.begin(), output.end()); CHECK(result == output.begin() + 1); CHECK_EQUAL(42, output[0]); } //************************************************************************* TEST(partial_sort_copy_single_element_output) { std::vector input = { 5, 3, 8, 1, 9 }; std::vector output1(1); std::vector output2(1); std::partial_sort_copy(input.begin(), input.end(), output1.begin(), output1.end()); etl::partial_sort_copy(input.begin(), input.end(), output2.begin(), output2.end()); CHECK_EQUAL(output1[0], output2[0]); CHECK_EQUAL(1, output2[0]); } //************************************************************************* TEST(partial_sort_copy_duplicates) { std::vector input = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5 }; std::vector output1(6); std::vector output2(6); std::partial_sort_copy(input.begin(), input.end(), output1.begin(), output1.end()); etl::partial_sort_copy(input.begin(), input.end(), output2.begin(), output2.end()); bool isEqual = std::equal(output1.begin(), output1.end(), output2.begin()); CHECK(isEqual); CHECK(std::is_sorted(output2.begin(), output2.end())); } //************************************************************************* TEST(partial_sort_copy_already_sorted) { std::vector input = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; std::vector output1(5); std::vector output2(5); std::partial_sort_copy(input.begin(), input.end(), output1.begin(), output1.end()); etl::partial_sort_copy(input.begin(), input.end(), output2.begin(), output2.end()); bool isEqual = std::equal(output1.begin(), output1.end(), output2.begin()); CHECK(isEqual); CHECK(std::is_sorted(output2.begin(), output2.end())); } //************************************************************************* TEST(partial_sort_copy_reverse_sorted) { std::vector input = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; std::vector output1(5); std::vector output2(5); std::partial_sort_copy(input.begin(), input.end(), output1.begin(), output1.end()); etl::partial_sort_copy(input.begin(), input.end(), output2.begin(), output2.end()); bool isEqual = std::equal(output1.begin(), output1.end(), output2.begin()); CHECK(isEqual); CHECK(std::is_sorted(output2.begin(), output2.end())); } //************************************************************************* TEST(partial_sort_copy_pointer) { int input[] = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; int output1[5] = {}; int output2[5] = {}; std::partial_sort_copy(std::begin(input), std::end(input), std::begin(output1), std::end(output1)); etl::partial_sort_copy(std::begin(input), std::end(input), std::begin(output2), std::end(output2)); bool isEqual = std::equal(std::begin(output1), std::end(output1), std::begin(output2)); CHECK(isEqual); } //************************************************************************* TEST(partial_sort_copy_all_equal) { std::vector input = { 5, 5, 5, 5, 5, 5 }; std::vector output(3); etl::partial_sort_copy(input.begin(), input.end(), output.begin(), output.end()); CHECK(std::is_sorted(output.begin(), output.end())); for (size_t i = 0; i < output.size(); ++i) { CHECK_EQUAL(5, output[i]); } } //************************************************************************* TEST(partial_sort_copy_input_not_modified) { std::vector input = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::vector original(input); std::vector output(5); etl::partial_sort_copy(input.begin(), input.end(), output.begin(), output.end()); // Input should not be modified bool isEqual = std::equal(input.begin(), input.end(), original.begin()); CHECK(isEqual); } //************************************************************************* TEST(partial_sort_copy_from_list) { std::list input = { 5, 3, 8, 1, 9, 2, 7, 4, 6, 10 }; std::vector output1(5); std::vector output2(5); std::partial_sort_copy(input.begin(), input.end(), output1.begin(), output1.end()); etl::partial_sort_copy(input.begin(), input.end(), output2.begin(), output2.end()); bool isEqual = std::equal(output1.begin(), output1.end(), output2.begin()); CHECK(isEqual); CHECK(std::is_sorted(output2.begin(), output2.end())); } //************************************************************************* TEST(find) { int* itr1 = std::find(std::begin(dataA), std::end(dataA), 5); int* itr2 = etl::find(std::begin(dataA), std::end(dataA), 5); CHECK(itr1 == itr2); } //************************************************************************* TEST(find_if) { struct predicate { bool operator()(int i) const { return (i == 5); } }; int* itr1 = std::find_if(std::begin(dataA), std::end(dataA), predicate()); int* itr2 = etl::find_if(std::begin(dataA), std::end(dataA), predicate()); CHECK(itr1 == itr2); } //************************************************************************* TEST(count) { size_t c1 = std::count(std::begin(dataEQ), std::end(dataEQ), 5); size_t c2 = etl::count(std::begin(dataEQ), std::end(dataEQ), 5); CHECK(c1 == c2); } //************************************************************************* TEST(count_if) { struct predicate { bool operator()(int i) const { return (i == 5); } }; size_t c1 = std::count_if(std::begin(dataEQ), std::end(dataEQ), predicate()); size_t c2 = etl::count_if(std::begin(dataEQ), std::end(dataEQ), predicate()); CHECK(c1 == c2); } //************************************************************************* TEST(fill_n) { (void) std::fill_n(std::begin(dataD1), SIZE, 5); int* p2 = etl::fill_n(std::begin(dataD2), SIZE, 5); CHECK(p2 == std::end(dataD2)); bool isEqual = std::equal(std::begin(dataD1), std::end(dataD1), std::begin(dataD2)); CHECK(isEqual); } //************************************************************************* TEST(transform1) { struct Function { int operator()(int d) const { return d * 2; } }; (void) std::transform(std::begin(dataS), std::end(dataS), std::begin(dataD1), Function()); int* p2 = etl::transform(std::begin(dataS), std::end(dataS), std::begin(dataD2), Function()); CHECK(p2 == std::end(dataD2)); bool isEqual = std::equal(std::begin(dataD1), std::end(dataD1), std::begin(dataD2)); CHECK(isEqual); } //************************************************************************* TEST(move) { typedef std::vector> Data; Data data1; // Create some data. std::unique_ptr p1(new uint32_t(1U)); std::unique_ptr p2(new uint32_t(2U)); std::unique_ptr p3(new uint32_t(3U)); std::unique_ptr p4(new uint32_t(4U)); std::unique_ptr p5(new uint32_t(5U)); // Fill data1. data1.push_back(std::move(p1)); data1.push_back(std::move(p2)); data1.push_back(std::move(p3)); data1.push_back(std::move(p4)); data1.push_back(std::move(p5)); Data data2; // Move to data2. etl::move(data1.begin(), data1.end(), std::back_inserter(data2)); // Old data now empty. CHECK(!bool(p1)); CHECK(!bool(p2)); CHECK(!bool(p3)); CHECK(!bool(p4)); CHECK(!bool(p5)); CHECK_EQUAL(1U, *(data2[0])); CHECK_EQUAL(2U, *(data2[1])); CHECK_EQUAL(3U, *(data2[2])); CHECK_EQUAL(4U, *(data2[3])); CHECK_EQUAL(5U, *(data2[4])); } //************************************************************************* TEST(move_backward) { typedef std::vector> Data; Data data1; // Create some data. std::unique_ptr p1(new uint32_t(1U)); std::unique_ptr p2(new uint32_t(2U)); std::unique_ptr p3(new uint32_t(3U)); std::unique_ptr p4(new uint32_t(4U)); std::unique_ptr p5(new uint32_t(5U)); // Fill data1. data1.push_back(std::move(p1)); data1.push_back(std::move(p2)); data1.push_back(std::move(p3)); data1.push_back(std::move(p4)); data1.push_back(std::move(p5)); Data data2; // Create some data. std::unique_ptr p6(new uint32_t(6U)); std::unique_ptr p7(new uint32_t(7U)); std::unique_ptr p8(new uint32_t(8U)); std::unique_ptr p9(new uint32_t(9U)); std::unique_ptr p10(new uint32_t(10U)); // Fill data2. data2.push_back(std::move(p6)); data2.push_back(std::move(p7)); data2.push_back(std::move(p8)); data2.push_back(std::move(p9)); data2.push_back(std::move(p10)); // Overwrite data2 with data1. etl::move_backward(data1.begin(), data1.end(), data2.end()); // Old data now empty. CHECK(!bool(p1)); CHECK(!bool(p2)); CHECK(!bool(p3)); CHECK(!bool(p4)); CHECK(!bool(p5)); CHECK_EQUAL(1U, *(data2[0])); CHECK_EQUAL(2U, *(data2[1])); CHECK_EQUAL(3U, *(data2[2])); CHECK_EQUAL(4U, *(data2[3])); CHECK_EQUAL(5U, *(data2[4])); } //************************************************************************* TEST(move_s_random_iterator_same_size) { typedef std::vector> Data; Data data1; data1.push_back(std::unique_ptr(new uint32_t(1U))); data1.push_back(std::unique_ptr(new uint32_t(2U))); data1.push_back(std::unique_ptr(new uint32_t(3U))); data1.push_back(std::unique_ptr(new uint32_t(4U))); data1.push_back(std::unique_ptr(new uint32_t(5U))); Data data2(5); Data::iterator result = etl::move_s(data1.begin(), data1.end(), data2.begin(), data2.end()); CHECK(data2.end() == result); CHECK_EQUAL(1U, *(data2[0])); CHECK_EQUAL(2U, *(data2[1])); CHECK_EQUAL(3U, *(data2[2])); CHECK_EQUAL(4U, *(data2[3])); CHECK_EQUAL(5U, *(data2[4])); } //************************************************************************* TEST(move_s_random_iterator_destination_smaller) { typedef std::vector> Data; Data data1; data1.push_back(std::unique_ptr(new uint32_t(1U))); data1.push_back(std::unique_ptr(new uint32_t(2U))); data1.push_back(std::unique_ptr(new uint32_t(3U))); data1.push_back(std::unique_ptr(new uint32_t(4U))); data1.push_back(std::unique_ptr(new uint32_t(5U))); Data data2(3); Data::iterator result = etl::move_s(data1.begin(), data1.end(), data2.begin(), data2.end()); CHECK(data2.end() == result); CHECK_EQUAL(1U, *(data2[0])); CHECK_EQUAL(2U, *(data2[1])); CHECK_EQUAL(3U, *(data2[2])); } //************************************************************************* TEST(move_s_random_iterator_source_smaller) { typedef std::vector> Data; Data data1; data1.push_back(std::unique_ptr(new uint32_t(1U))); data1.push_back(std::unique_ptr(new uint32_t(2U))); data1.push_back(std::unique_ptr(new uint32_t(3U))); Data data2(5); Data::iterator result = etl::move_s(data1.begin(), data1.end(), data2.begin(), data2.end()); CHECK(data2.begin() + 3 == result); CHECK_EQUAL(1U, *(data2[0])); CHECK_EQUAL(2U, *(data2[1])); CHECK_EQUAL(3U, *(data2[2])); } //************************************************************************* TEST(move_s_non_random_iterator_same_size) { typedef std::list> Data; Data data1; data1.push_back(std::unique_ptr(new uint32_t(1U))); data1.push_back(std::unique_ptr(new uint32_t(2U))); data1.push_back(std::unique_ptr(new uint32_t(3U))); data1.push_back(std::unique_ptr(new uint32_t(4U))); data1.push_back(std::unique_ptr(new uint32_t(5U))); Data data2(5); Data::iterator result = etl::move_s(data1.begin(), data1.end(), data2.begin(), data2.end()); CHECK(data2.end() == result); Data::iterator itr = data2.begin(); CHECK_EQUAL(1U, **(itr++)); CHECK_EQUAL(2U, **(itr++)); CHECK_EQUAL(3U, **(itr++)); CHECK_EQUAL(4U, **(itr++)); CHECK_EQUAL(5U, **(itr++)); } //************************************************************************* TEST(move_s_non_random_iterator_destination_smaller) { typedef std::list> Data; Data data1; data1.push_back(std::unique_ptr(new uint32_t(1U))); data1.push_back(std::unique_ptr(new uint32_t(2U))); data1.push_back(std::unique_ptr(new uint32_t(3U))); data1.push_back(std::unique_ptr(new uint32_t(4U))); data1.push_back(std::unique_ptr(new uint32_t(5U))); Data data2(3); Data::iterator result = etl::move_s(data1.begin(), data1.end(), data2.begin(), data2.end()); CHECK(data2.end() == result); Data::iterator itr = data2.begin(); CHECK_EQUAL(1U, **(itr++)); CHECK_EQUAL(2U, **(itr++)); CHECK_EQUAL(3U, **(itr++)); } //************************************************************************* TEST(move_s_non_random_iterator_source_smaller) { typedef std::list> Data; Data data1; data1.push_back(std::unique_ptr(new uint32_t(1U))); data1.push_back(std::unique_ptr(new uint32_t(2U))); data1.push_back(std::unique_ptr(new uint32_t(3U))); Data data2(5); Data::iterator result = etl::move_s(data1.begin(), data1.end(), data2.begin(), data2.end()); Data::iterator expected_pos = data2.begin(); std::advance(expected_pos, 3); CHECK(expected_pos == result); Data::iterator itr = data2.begin(); CHECK_EQUAL(1U, **(itr++)); CHECK_EQUAL(2U, **(itr++)); CHECK_EQUAL(3U, **(itr++)); } //************************************************************************* TEST(move_s_empty_source) { typedef std::vector> Data; Data data1; Data data2(3); Data::iterator result = etl::move_s(data1.begin(), data1.end(), data2.begin(), data2.end()); CHECK(data2.begin() == result); } //************************************************************************* TEST(move_s_empty_destination) { typedef std::vector> Data; Data data1; data1.push_back(std::unique_ptr(new uint32_t(1U))); data1.push_back(std::unique_ptr(new uint32_t(2U))); data1.push_back(std::unique_ptr(new uint32_t(3U))); Data data2; Data::iterator result = etl::move_s(data1.begin(), data1.end(), data2.begin(), data2.end()); CHECK(data2.begin() == result); } //************************************************************************* TEST(move_s_pod_random_iterator) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int data2[] = { 1, 2, 3, 4, 5 }; int out1[10]; int out2[5]; int check1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int check2[] = { 1, 2, 3, 4, 5 }; int check3[] = { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 }; int* result; // Same size. std::fill(std::begin(out1), std::end(out1), 0); result = etl::move_s(std::begin(data1), std::end(data1), std::begin(out1), std::end(out1)); CHECK_EQUAL(std::end(out1), result); bool is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check1)); CHECK(is_same); // Destination smaller. std::fill(std::begin(out2), std::end(out2), 0); result = etl::move_s(std::begin(data1), std::end(data1), std::begin(out2), std::end(out2)); CHECK_EQUAL(std::end(out2), result); is_same = std::equal(std::begin(out2), std::end(out2), std::begin(check2)); CHECK(is_same); // Source smaller. std::fill(std::begin(out1), std::end(out1), 0); result = etl::move_s(std::begin(data2), std::end(data2), std::begin(out1), std::end(out1)); CHECK_EQUAL(std::begin(out1) + 5, result); is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check3)); CHECK(is_same); } //************************************************************************* TEST(rotate_pod) { std::vector initial_data = { 1, 2, 3, 4, 5, 6, 7 }; for (size_t i = 0UL; i < initial_data.size(); ++i) { std::vector data1(initial_data); std::vector data2(initial_data); std::rotate(data1.data(), data1.data() + i, data1.data() + data1.size()); etl::rotate(data2.data(), data2.data() + i, data2.data() + data2.size()); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } } //************************************************************************* TEST(rotate_non_pod) { std::vector initial_data = { NDC(1), NDC(2), NDC(3), NDC(4), NDC(5), NDC(6), NDC(7) }; for (size_t i = 0UL; i < initial_data.size(); ++i) { std::vector data1(initial_data); std::vector data2(initial_data); std::rotate(data1.data(), data1.data() + i, data1.data() + data1.size()); etl::rotate(data2.data(), data2.data() + i, data2.data() + data2.size()); bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } } //************************************************************************* TEST(rotate_return_value) { // Verify that etl::rotate returns the same iterator as std::rotate // in all cases, including the degenerate first==middle and middle==last cases. std::vector initial_data = { 1, 2, 3, 4, 5 }; for (size_t i = 0UL; i <= initial_data.size(); ++i) { std::vector data1(initial_data); std::vector data2(initial_data); auto std_result = std::rotate(data1.data(), data1.data() + i, data1.data() + data1.size()); auto etl_result = etl::rotate(data2.data(), data2.data() + i, data2.data() + data2.size()); // Check that the return value offset matches ptrdiff_t std_offset = std_result - data1.data(); ptrdiff_t etl_offset = etl_result - data2.data(); CHECK_EQUAL(std_offset, etl_offset); } // Explicitly test first == middle (empty left half): should return last { std::vector data = { 1, 2, 3 }; auto result = etl::rotate(data.data(), data.data(), data.data() + data.size()); CHECK(result == data.data() + data.size()); } // Explicitly test middle == last (empty right half): should return first { std::vector data = { 1, 2, 3 }; auto result = etl::rotate(data.data(), data.data() + data.size(), data.data() + data.size()); CHECK(result == data.data()); } } //************************************************************************* TEST(rotate_return_value_non_random_iterator) { // Verify that etl::rotate returns the correct iterator when called with // non-random (bidirectional) iterators, exercising rotate_general for // bidirectional iterators rather than the random-access overload. std::vector initial_data = { 1, 2, 3, 4, 5 }; for (size_t i = 0UL; i <= initial_data.size(); ++i) { std::vector data1(initial_data); std::vector data2(initial_data); auto std_result = std::rotate(data1.data(), data1.data() + i, data1.data() + data1.size()); non_random_iterator nr_first(data2.data()); non_random_iterator nr_middle(data2.data() + i); non_random_iterator nr_last(data2.data() + data2.size()); auto etl_result = etl::rotate(nr_first, nr_middle, nr_last); // Check that the data was rotated correctly bool isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); // Check that the return value offset matches ptrdiff_t std_offset = std_result - data1.data(); ptrdiff_t etl_offset = etl_result.ptr - data2.data(); CHECK_EQUAL(std_offset, etl_offset); } // Explicitly test first == middle (empty left half): should return last { std::vector data = { 1, 2, 3 }; non_random_iterator nr_first(data.data()); non_random_iterator nr_middle(data.data()); non_random_iterator nr_last(data.data() + data.size()); auto result = etl::rotate(nr_first, nr_middle, nr_last); CHECK(result.ptr == data.data() + data.size()); } // Explicitly test middle == last (empty right half): should return first { std::vector data = { 1, 2, 3 }; non_random_iterator nr_first(data.data()); non_random_iterator nr_middle(data.data() + data.size()); non_random_iterator nr_last(data.data() + data.size()); auto result = etl::rotate(nr_first, nr_middle, nr_last); CHECK(result.ptr == data.data()); } } //************************************************************************* TEST(any_of) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; bool expected = std::any_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); bool result = etl::any_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); CHECK_EQUAL(expected, result); expected = std::any_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 0)); result = etl::any_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 0)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(all_of) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; bool expected = std::all_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 0)); bool result = etl::all_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 0)); CHECK_EQUAL(expected, result); expected = std::all_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); result = etl::all_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(none_of) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; bool expected = std::none_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 8)); bool result = etl::none_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 8)); CHECK_EQUAL(expected, result); expected = std::none_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); result = etl::none_of(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); CHECK_EQUAL(expected, result); } struct Compare { bool operator()(int a, int b) const { return a == b; } }; //************************************************************************* TEST(is_permutation) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; int permutation[] = { 1, 3, 2, 4, 7, 6, 5, 8 }; int not_permutation[] = { 1, 2, 3, 4, 5, 6, 7, 7 }; bool is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(permutation)); CHECK(is_permutation); is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(not_permutation)); CHECK(!is_permutation); is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(permutation), etl::equal_to()); CHECK(is_permutation); is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(not_permutation), etl::equal_to()); CHECK(!is_permutation); is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(permutation), std::end(permutation)); CHECK(is_permutation); is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(not_permutation), std::end(not_permutation)); CHECK(!is_permutation); is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(permutation), std::end(permutation), etl::equal_to()); CHECK(is_permutation); is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(not_permutation), std::end(not_permutation), etl::equal_to()); CHECK(!is_permutation); } //************************************************************************* TEST(is_permutation_different_lengths) { int shorter[] = { 1, 2 }; int longer[] = { 1, 2, 3 }; // Four-iterator: range2 longer than range1 (extra elements only in range2) bool result = etl::is_permutation(std::begin(shorter), std::end(shorter), std::begin(longer), std::end(longer)); CHECK(!result); // Four-iterator: range1 longer than range2 result = etl::is_permutation(std::begin(longer), std::end(longer), std::begin(shorter), std::end(shorter)); CHECK(!result); // Four-iterator with predicate: range2 longer than range1 result = etl::is_permutation(std::begin(shorter), std::end(shorter), std::begin(longer), std::end(longer), etl::equal_to()); CHECK(!result); // Four-iterator with predicate: range1 longer than range2 result = etl::is_permutation(std::begin(longer), std::end(longer), std::begin(shorter), std::end(shorter), etl::equal_to()); CHECK(!result); } //************************************************************************* TEST(is_partitioned) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; bool expected = std::is_partitioned(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); bool result = etl::is_partitioned(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); CHECK_EQUAL(expected, result); std::partition(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); expected = std::is_partitioned(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); result = etl::is_partitioned(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(partition_point) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; std::partition(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); int* partition1 = std::partition_point(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); int* partition2 = etl::partition_point(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 4)); CHECK_EQUAL(std::distance(std::begin(data1), partition1), std::distance(std::begin(data1), partition2)); std::partition(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 8)); partition1 = std::partition_point(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 0)); partition2 = etl::partition_point(std::begin(data1), std::end(data1), std::bind(std::greater(), std::placeholders::_1, 0)); CHECK_EQUAL(std::distance(std::begin(data1), partition1), std::distance(std::begin(data1), partition2)); } //************************************************************************* TEST(partition_copy) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; int data2[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int data3[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int data4[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int data5[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; std::partition_copy(std::begin(data1), std::end(data1), std::begin(data2), std::begin(data3), std::bind(std::greater(), std::placeholders::_1, 4)); etl::partition_copy(std::begin(data1), std::end(data1), std::begin(data4), std::begin(data5), std::bind(std::greater(), std::placeholders::_1, 4)); bool are_equal; are_equal = std::equal(std::begin(data2), std::end(data2), std::begin(data4)); CHECK(are_equal); are_equal = std::equal(std::begin(data3), std::end(data3), std::begin(data5)); CHECK(are_equal); } //************************************************************************* TEST(find_if_not) { int data1[] = { 1, 2, 3, 5, 6, 7, 8 }; // Find the element not less than 4. int* p = etl::find_if_not(std::begin(data1), std::end(data1), std::bind(std::less(), std::placeholders::_1, 4)); CHECK_EQUAL(5, *p); } //************************************************************************* TEST(copy_4_parameter_random_iterator) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int data2[] = { 1, 2, 3, 4, 5 }; int out1[10]; int out2[5]; int check1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int check2[] = { 1, 2, 3, 4, 5 }; int check3[] = { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 }; int* result; // Same size. std::fill(std::begin(out1), std::end(out1), 0); result = etl::copy_s(std::begin(data1), std::end(data1), std::begin(out1), std::end(out1)); CHECK_EQUAL(std::end(out1), result); bool is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check1)); CHECK(is_same); // Destination smaller. std::fill(std::begin(out2), std::end(out2), 0); result = etl::copy_s(std::begin(data1), std::end(data1), std::begin(out2), std::end(out2)); CHECK_EQUAL(std::end(out2), result); is_same = std::equal(std::begin(out2), std::end(out2), std::begin(check2)); CHECK(is_same); // Source smaller. std::fill(std::begin(out1), std::end(out1), 0); result = etl::copy_s(std::begin(data2), std::end(data2), std::begin(out1), std::end(out1)); CHECK_EQUAL(std::begin(out1) + 5, result); is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check3)); CHECK(is_same); } //************************************************************************* TEST(copy_4_parameter_non_random_iterator) { std::list data1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; std::list data2 = { 1, 2, 3, 4, 5 }; int out1[10]; int out2[5]; int check1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int check2[] = { 1, 2, 3, 4, 5 }; int check3[] = { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 }; int* result; // Same size. std::fill(std::begin(out1), std::end(out1), 0); result = etl::copy_s(std::begin(data1), std::end(data1), std::begin(out1), std::end(out1)); CHECK_EQUAL(std::end(out1), result); bool is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check1)); CHECK(is_same); // Destination smaller. std::fill(std::begin(out2), std::end(out2), 0); result = etl::copy_s(std::begin(data1), std::end(data1), std::begin(out2), std::end(out2)); CHECK_EQUAL(std::end(out2), result); is_same = std::equal(std::begin(out2), std::end(out2), std::begin(check2)); CHECK(is_same); // Source smaller. std::fill(std::begin(out1), std::end(out1), 0); result = etl::copy_s(std::begin(data2), std::end(data2), std::begin(out1), std::end(out1)); CHECK_EQUAL(std::begin(out1) + 5, result); is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check3)); CHECK(is_same); } //************************************************************************* TEST(copy_n_4_parameter) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int out1[10]; int out2[5]; int check1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int check2[] = { 1, 2, 3, 4, 5 }; int check3[] = { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 }; int* result; // Same size. std::fill(std::begin(out1), std::end(out1), 0); result = etl::copy_n_s(std::begin(data1), 10, std::begin(out1), std::end(out1)); CHECK_EQUAL(std::end(out1), result); bool is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check1)); CHECK(is_same); // Destination smaller. std::fill(std::begin(out2), std::end(out2), 0); result = etl::copy_n_s(std::begin(data1), 10, std::begin(out2), std::end(out2)); CHECK_EQUAL(std::end(out2), result); is_same = std::equal(std::begin(out2), std::end(out2), std::begin(check2)); CHECK(is_same); // Source smaller. std::fill(std::begin(out1), std::end(out1), 0); result = etl::copy_n_s(std::begin(data1), 5, std::begin(out1), std::end(out1)); CHECK_EQUAL(std::begin(out1) + 5, result); is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check3)); CHECK(is_same); } //************************************************************************* TEST(copy_2n_4_parameter) { int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int out1[10]; int out2[5]; int check1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int check2[] = { 1, 2, 3, 4, 5 }; int check3[] = { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 }; int* result; // Same size. std::fill(std::begin(out1), std::end(out1), 0); result = etl::copy_n_s(std::begin(data1), 10, std::begin(out1), 10); CHECK_EQUAL(std::end(out1), result); bool is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check1)); CHECK(is_same); // Destination smaller. std::fill(std::begin(out2), std::end(out2), 0); result = etl::copy_n_s(std::begin(data1), 10, std::begin(out2), 5); CHECK_EQUAL(std::end(out2), result); is_same = std::equal(std::begin(out2), std::end(out2), std::begin(check2)); CHECK(is_same); // Source smaller. std::fill(std::begin(out1), std::end(out1), 0); result = etl::copy_n_s(std::begin(data1), 5, std::begin(out1), 10); CHECK_EQUAL(std::begin(out1) + 5, result); is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check3)); CHECK(is_same); } //************************************************************************* TEST(copy_n_if) { int data1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int data2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int data3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Copy everything less than 5. int *pout = data2; for (int* pin = std::begin(data1); pin != std::begin(data1) + 6; ++pin) { if (*pin < 5) { *pout++ = *pin; } } etl::copy_n_if(std::begin(data1), 6, std::begin(data3), std::bind(std::less(), std::placeholders::_1, 5)); bool is_same = std::equal(std::begin(data2), std::end(data2), std::begin(data3)); CHECK(is_same); } //************************************************************************* TEST(copy_if_4_parameter) { int data1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int out1[4]; int out2[2]; int out3[10]; int check1[] = { 1, 2, 3, 4 }; int check2[] = { 1, 2 }; int check3[] = { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0 }; int* result; // Exact size. std::fill(std::begin(out1), std::end(out1), 0); result = etl::copy_if_s(std::begin(data1), std::end(data1), std::begin(out1), std::end(out1), std::bind(std::less(), std::placeholders::_1, 5)); CHECK_EQUAL(std::end(out1), result); bool is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check1)); CHECK(is_same); // Destination smaller. std::fill(std::begin(out2), std::end(out2), 0); result = etl::copy_if_s(std::begin(data1), std::end(data1), std::begin(out2), std::end(out2), std::bind(std::less(), std::placeholders::_1, 5)); CHECK_EQUAL(std::end(out2), result); is_same = std::equal(std::begin(out2), std::end(out2), std::begin(check2)); CHECK(is_same); // Destination larger. std::fill(std::begin(out3), std::end(out3), 0); result = etl::copy_if_s(std::begin(data1), std::end(data1), std::begin(out3), std::end(out3), std::bind(std::less(), std::placeholders::_1, 5)); CHECK_EQUAL(std::begin(out3) + 4, result); is_same = std::equal(std::begin(out3), std::end(out3), std::begin(check3)); CHECK(is_same); } //************************************************************************* TEST(binary_find) { int data1[] = { 1, 2, 3, 5, 6, 7, 8 }; // Find the element of value 5. int* p = etl::binary_find(std::begin(data1), std::end(data1), 5); CHECK_EQUAL(5, *p); // Find the element of value 4. p = etl::binary_find(std::begin(data1), std::end(data1), 4); CHECK_EQUAL(std::end(data1), p); } //************************************************************************* TEST(binary_find_StructDataPredicate_StructDataEquality) { Data data1[] = { { 1, 8 }, { 2, 7 }, { 3, 6 },{ 4, 5 },{ 5, 4 },{ 6, 3 },{ 7, 2 },{ 8, 1 } }; Data test1 = { 4, 5 }; Data test2 = { 9, 0 }; // Find the element of value 5. Data* p = etl::binary_find(std::begin(data1), std::end(data1), test1, DataPredicate(), DataEquality()); CHECK_EQUAL(test1, *p); // Find the element of value 4. p = etl::binary_find(std::begin(data1), std::end(data1), test2, DataPredicate(), DataEquality()); CHECK_EQUAL(std::end(data1), p); } //************************************************************************* TEST(for_each_if) { int data1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; struct Sum { Sum() : sum(0) { } Sum& operator()(int i) { sum += i; return *this; } int sum; } accumulator; // For each if everything less than 5. accumulator = etl::for_each_if(std::begin(data1), std::end(data1), accumulator, std::bind(std::less(), std::placeholders::_1, 5)); CHECK_EQUAL(10, accumulator.sum); } //************************************************************************* TEST(for_each_n) { int data1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int data2[] = { 2, 16, 4, 14, 6, 6, 4, 5, 10, 9 }; struct Multiply { void operator()(int& i) { i *= 2; } } multiplier; etl::for_each_n(std::begin(data1), 5, multiplier); bool are_equal = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(are_equal); } //************************************************************************* TEST(for_each_n_if) { int data1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int data2[] = { 2, 8, 4, 7, 6, 6, 4, 5, 10, 9 }; struct Multiply { void operator()(int& i) { i *= 2; } } multiplier; etl::for_each_n_if(std::begin(data1), 5, multiplier, std::bind(std::less(), std::placeholders::_1, 5)); bool are_equal = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(are_equal); } //************************************************************************* TEST(transform_4_parameter) { int input[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int compare[] = { 2, 16, 4, 14, 6, 0, 0, 0, 0, 0 }; // Double everything and copy to output. etl::transform_s(std::begin(input), std::end(input), std::begin(output), std::begin(output) + (ETL_OR_STD17::size(output) / 2), std::bind(std::multiplies(), std::placeholders::_1, 2)); bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); CHECK(is_same); std::fill(std::begin(output), std::end(output), 0); etl::transform_s(std::begin(input), std::begin(input) + (ETL_OR_STD17::size(input) / 2), std::begin(output), std::end(output), std::bind(std::multiplies(), std::placeholders::_1, 2)); is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); CHECK(is_same); } //************************************************************************* TEST(transform_n_random_iterator) { int input[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int compare[] = { 2, 16, 4, 14, 6, 12, 8, 0, 0, 0 }; etl::transform_n(std::begin(input), 7, std::begin(output), std::bind(std::multiplies(), std::placeholders::_1, 2)); bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); CHECK(is_same); } //************************************************************************* TEST(transform_n_non_random_iterator) { std::list input = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int compare[] = { 2, 16, 4, 14, 6, 12, 8, 0, 0, 0 }; etl::transform_n(std::begin(input), 7, std::begin(output), std::bind(std::multiplies(), std::placeholders::_1, 2)); bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); CHECK(is_same); } //************************************************************************* TEST(transform_n_two_ranges_random_iterator) { int input1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int input2[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int compare[] = { 2, 16, 4, 14, 6, 12, 8, 0, 0, 0 }; etl::transform_n(std::begin(input1), std::begin(input2), 7, std::begin(output), std::plus()); bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); CHECK(is_same); } //************************************************************************* TEST(transform_n_two_ranges_non_random_iterator) { std::list input1 = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; std::list input2 = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int compare[] = { 2, 16, 4, 14, 6, 12, 8, 0, 0, 0 }; etl::transform_n(std::begin(input1), std::begin(input2), 7, std::begin(output), std::plus()); bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); CHECK(is_same); } //************************************************************************* TEST(transform_if) { int input[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int compare[] = { 2, 4, 6, 8, 0, 0, 0, 0, 0, 0 }; // Double everything less than 5 and copy to output. etl::transform_if(std::begin(input), std::end(input), std::begin(output), std::bind(std::multiplies(), std::placeholders::_1, 2), std::bind(std::less(), std::placeholders::_1, 5)); bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); CHECK(is_same); } //************************************************************************* TEST(transform_if_2_input_ranges) { int input1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int input2[] = { 8, 7, 6, 5, 4, 10, 9, 3, 2, 1 }; int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int compare[] = { 8, 12, 12, 60, 36, 0, 0, 0, 0, 0 }; // Multiply together everything where input1 is less than input2 and copy to output. etl::transform_if(std::begin(input1), std::end(input1), std::begin(input2), std::begin(output), std::multiplies(), std::less()); bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); CHECK(is_same); } //************************************************************************* TEST(transform_n_if) { int input[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int compare[] = { 2, 4, 6, 0, 0, 0, 0, 0, 0, 0 }; // Double everything less than 5 and copy to output. etl::transform_n_if(std::begin(input), 5, std::begin(output), std::bind(std::multiplies(), std::placeholders::_1, 2), std::bind(std::less(), std::placeholders::_1, 5)); bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); CHECK(is_same); } //************************************************************************* TEST(transform_n_if_2_input_ranges) { int input1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int input2[] = { 8, 7, 6, 5, 4, 10, 9, 3, 2, 1 }; int output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int compare[] = { 8, 12, 12, 0, 0, 0, 0, 0, 0, 0 }; // Multiply together everything where input1 is less than input2 and copy to output. etl::transform_n_if(std::begin(input1), std::begin(input2), 5, std::begin(output), std::multiplies(), std::less()); bool is_same = std::equal(std::begin(output), std::end(output), std::begin(compare)); CHECK(is_same); } //************************************************************************* TEST(partition_transform) { int input[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int output_true[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int output_false[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int compare_true[] = { 2, 4, 6, 8, 0, 0, 0, 0, 0, 0 }; int compare_false[] = { -16, -14, -12, -10, -20, -18, 0, 0, 0, 0 }; // Multiply everything less than 5 by 2 and copy to output_true. // Multiply everything not less than 5 by -2 and copy to output_false. etl::partition_transform(std::begin(input), std::end(input), std::begin(output_true), std::begin(output_false), std::bind(std::multiplies(), std::placeholders::_1, 2), std::bind(std::multiplies(), std::placeholders::_1, -2), std::bind(std::less(), std::placeholders::_1, 5)); bool is_same = std::equal(std::begin(output_true), std::end(output_true), std::begin(compare_true)); CHECK(is_same); is_same = std::equal(std::begin(output_false), std::end(output_false), std::begin(compare_false)); CHECK(is_same); } //************************************************************************* TEST(partition_transform_2_input_ranges) { int input1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int input2[] = { 8, 7, 6, 5, 4, 10, 9, 3, 2, 1 }; int output_true[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int output_false[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int compare_true[] = { 8, 12, 12, 60, 36, 0, 0, 0, 0, 0 }; int compare_false[] = { 15, 12, 8, 12, 10, 0, 0, 0, 0, 0 }; // If input1 < input2 multiply else add. etl::partition_transform(std::begin(input1), std::end(input1), std::begin(input2), std::begin(output_true), std::begin(output_false), std::multiplies(), std::plus(), std::less()); bool is_same = std::equal(std::begin(output_true), std::end(output_true), std::begin(compare_true)); CHECK(is_same); is_same = std::equal(std::begin(output_false), std::end(output_false), std::begin(compare_false)); CHECK(is_same); } //************************************************************************* TEST(sort_default) { std::vector data(100, 0); std::iota(data.begin(), data.end(), 1); for (int i = 0; i < 100; ++i) { std::shuffle(data.begin(), data.end(), urng); std::vector data1 = data; std::vector data2 = data; std::sort(data1.begin(), data1.end()); etl::sort(data2.begin(), data2.end()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(is_same); } } //************************************************************************* TEST(sort_greater) { std::vector data(100, 0); std::iota(data.begin(), data.end(), 1); for (int i = 0; i < 100; ++i) { std::shuffle(data.begin(), data.end(), urng); std::vector data1 = data; std::vector data2 = data; std::sort(data1.begin(), data1.end(), std::greater()); etl::sort(data2.begin(), data2.end(), std::greater()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(is_same); } } //************************************************************************* TEST(stable_sort_default) { std::vector initial_data = { NDC(1, 1), NDC(2, 1), NDC(3, 1), NDC(2, 2), NDC(3, 2), NDC(4, 1), NDC(2, 3), NDC(3, 3), NDC(5, 1) }; std::vector data1(initial_data); std::vector data2(initial_data); std::stable_sort(data1.begin(), data1.end()); etl::stable_sort(data2.begin(), data2.end()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin(), NDC::are_identical); CHECK(is_same); } //************************************************************************* TEST(next_permutation) { std::array expected = { 1, 1, 2, 2 }; std::array result = expected; for (size_t i = 0U; i < 8U; ++i) { bool expected_has_next = std::next_permutation(expected.begin(), expected.end()); bool result_has_next = etl::next_permutation(result.begin(), result.end()); CHECK_EQUAL(expected_has_next, result_has_next); CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size()); } // Check one past the end. bool expected_has_next = std::next_permutation(expected.begin(), expected.end()); bool result_has_next = etl::next_permutation(result.begin(), result.end()); CHECK_EQUAL(expected_has_next, result_has_next); CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size()); int single_expected[] = { 1 }; int single_result[] = { 1 }; expected_has_next = std::next_permutation(std::begin(single_expected), std::end(single_expected)); result_has_next = etl::next_permutation(std::begin(single_result), std::end(single_result)); CHECK_EQUAL(expected_has_next, result_has_next); CHECK_ARRAY_EQUAL(single_expected, single_result, 1U); // Check for what happens if the beginning and end are the same. expected_has_next = std::next_permutation(std::begin(single_expected), std::begin(single_expected)); result_has_next = etl::next_permutation(std::begin(single_result), std::begin(single_result)); CHECK_EQUAL(expected_has_next, result_has_next); } //************************************************************************* TEST(next_permutation_compare) { std::array expected = { 3, 2, 2, 1 }; std::array result = expected; for (size_t i = 0U; i < 8U; ++i) { bool expected_has_next = std::next_permutation(expected.begin(), expected.end(), std::greater()); bool result_has_next = etl::next_permutation(result.begin(), result.end(), std::greater()); CHECK_EQUAL(expected_has_next, result_has_next); CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size()); } // Check one past the end. bool expected_has_next = std::next_permutation(expected.begin(), expected.end(), std::greater()); bool result_has_next = etl::next_permutation(result.begin(), result.end(), std::greater()); CHECK_EQUAL(expected_has_next, result_has_next); CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size()); int single_expected[] = { 1 }; int single_result[] = { 1 }; // Check for what happens if the beginning and end are the same. expected_has_next = std::next_permutation(std::begin(single_expected), std::begin(single_expected), std::greater()); result_has_next = etl::next_permutation(std::begin(single_result), std::begin(single_result), std::greater()); CHECK_EQUAL(expected_has_next, result_has_next); CHECK_ARRAY_EQUAL(single_expected, single_result, 1U); } //************************************************************************* TEST(prev_permutation) { std::array expected = { 2, 2, 1, 1 }; std::array result = expected; for (size_t i = 0U; i < 8U; ++i) { bool expected_has_prev = std::prev_permutation(expected.begin(), expected.end()); bool result_has_prev = etl::prev_permutation(result.begin(), result.end()); CHECK_EQUAL(expected_has_prev, result_has_prev); CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size()); } // Check one past the end. bool expected_has_prev = std::prev_permutation(expected.begin(), expected.end()); bool result_has_prev = etl::prev_permutation(result.begin(), result.end()); CHECK_EQUAL(expected_has_prev, result_has_prev); CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size()); int single_expected[] = { 1 }; int single_result[] = { 1 }; expected_has_prev = std::prev_permutation(std::begin(single_expected), std::end(single_expected)); result_has_prev = etl::prev_permutation(std::begin(single_result), std::end(single_result)); CHECK_EQUAL(expected_has_prev, result_has_prev); CHECK_ARRAY_EQUAL(single_expected, single_result, 1U); // Check for what happens if the beginning and end are the same. expected_has_prev = std::prev_permutation(std::begin(single_expected), std::begin(single_expected)); result_has_prev = etl::prev_permutation(std::begin(single_result), std::begin(single_result)); CHECK_EQUAL(expected_has_prev, result_has_prev); } //************************************************************************* TEST(prev_permutation_compare) { std::array expected = { 1, 1, 2, 3 }; std::array result = expected; for (size_t i = 0U; i < 8U; ++i) { bool expected_has_prev = std::prev_permutation(expected.begin(), expected.end(), std::greater()); bool result_has_prev = etl::prev_permutation(result.begin(), result.end(), std::greater()); CHECK_EQUAL(expected_has_prev, result_has_prev); CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size()); } // Check one past the end. bool expected_has_prev = std::prev_permutation(expected.begin(), expected.end(), std::greater()); bool result_has_prev = etl::prev_permutation(result.begin(), result.end(), std::greater()); CHECK_EQUAL(expected_has_prev, result_has_prev); CHECK_ARRAY_EQUAL(expected.data(), result.data(), result.size()); int single_expected[] = { 1 }; int single_result[] = { 1 }; // Check for what happens if the beginning and end are the same. expected_has_prev = std::prev_permutation(std::begin(single_expected), std::begin(single_expected), std::greater()); result_has_prev = etl::prev_permutation(std::begin(single_result), std::begin(single_result), std::greater()); CHECK_EQUAL(expected_has_prev, result_has_prev); CHECK_ARRAY_EQUAL(single_expected, single_result, 1U); } //************************************************************************* TEST(is_permutation_length_mismatch) { int data1[] = { 1, 2, 3 }; int data2[] = { 1, 2, 3, 4 }; bool is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(data2), std::end(data2)); CHECK_FALSE(is_permutation); is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(data2), std::end(data2), etl::equal_to()); CHECK_FALSE(is_permutation); } //************************************************************************* TEST(is_permutation_predicate) { Data data1[] = { Data(1, 10), Data(2, 20), Data(2, 30), Data(3, 40) }; Data permutation[] = { Data(2, 200), Data(1, 100), Data(3, 300), Data(2, 400) }; Data not_permutation[] = { Data(2, 200), Data(1, 100), Data(4, 300), Data(2, 400) }; bool is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(permutation), DataEquivalenceByA()); CHECK_TRUE(is_permutation); is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(not_permutation), DataEquivalenceByA()); CHECK_FALSE(is_permutation); is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(permutation), std::end(permutation), DataEquivalenceByA()); CHECK_TRUE(is_permutation); is_permutation = etl::is_permutation(std::begin(data1), std::end(data1), std::begin(not_permutation), std::end(not_permutation), DataEquivalenceByA()); CHECK_FALSE(is_permutation); } //************************************************************************* TEST(shell_sort_default) { std::vector data(100, 0); std::iota(data.begin(), data.end(), 1); for (int i = 0; i < 100; ++i) { std::shuffle(data.begin(), data.end(), urng); std::vector data1 = data; std::vector data2 = data; std::sort(data1.begin(), data1.end()); etl::shell_sort(data2.begin(), data2.end()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(is_same); } } //************************************************************************* TEST(shell_sort_greater) { std::vector data(100, 0); std::iota(data.begin(), data.end(), 1); for (int i = 0; i < 100; ++i) { std::shuffle(data.begin(), data.end(), urng); std::vector data1 = data; std::vector data2 = data; std::sort(data1.begin(), data1.end(), std::greater()); etl::shell_sort(data2.begin(), data2.end(), std::greater()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(is_same); } } //************************************************************************* TEST(insertion_sort_default) { std::vector initial_data = { NDC(1, 1), NDC(2, 1), NDC(3, 1), NDC(2, 2), NDC(3, 2), NDC(4, 1), NDC(2, 3), NDC(3, 3), NDC(5, 1) }; std::vector data1(initial_data); std::vector data2(initial_data); std::stable_sort(data1.begin(), data1.end()); etl::insertion_sort(data2.begin(), data2.end()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin(), NDC::are_identical); CHECK(is_same); } //************************************************************************* TEST(insertion_sort_greater) { std::vector initial_data = { NDC(1, 1), NDC(2, 1), NDC(3, 1), NDC(2, 2), NDC(3, 2), NDC(4, 1), NDC(2, 3), NDC(3, 3), NDC(5, 1) }; std::vector data1(initial_data); std::vector data2(initial_data); std::stable_sort(data1.begin(), data1.end(), std::greater()); etl::insertion_sort(data2.begin(), data2.end(), std::greater()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin(), NDC::are_identical); CHECK(is_same); } //************************************************************************* TEST(selection_sort_default_forward_iterators) { std::vector data(100, 0); std::iota(data.begin(), data.end(), 1); for (int i = 0; i < 100; ++i) { std::shuffle(data.begin(), data.end(), urng); std::vector data1(data.begin(), data.end()); std::forward_list data2(data.begin(), data.end()); std::sort(data1.begin(), data1.end()); etl::selection_sort(data2.begin(), data2.end()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(is_same); } } //************************************************************************* TEST(selection_sort_default_bidirectional_iterators) { std::vector data(100, 0); std::iota(data.begin(), data.end(), 1); for (int i = 0; i < 100; ++i) { std::shuffle(data.begin(), data.end(), urng); std::list data1(data.begin(), data.end()); std::list data2(data.begin(), data.end()); data1.sort(); etl::selection_sort(data2.begin(), data2.end()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(is_same); } } //************************************************************************* TEST(selection_sort_default_random_access_iterators) { std::vector data(100, 0); std::iota(data.begin(), data.end(), 1); for (int i = 0; i < 100; ++i) { std::shuffle(data.begin(), data.end(), urng); std::vector data1 = data; std::vector data2 = data; std::sort(data1.begin(), data1.end()); etl::selection_sort(data2.begin(), data2.end()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(is_same); } } //************************************************************************* TEST(selection_sort_greater) { std::vector data(100, 0); std::iota(data.begin(), data.end(), 1); for (int i = 0; i < 100; ++i) { std::shuffle(data.begin(), data.end(), urng); std::vector data1 = data; std::vector data2 = data; std::sort(data1.begin(), data1.end(), std::greater()); etl::selection_sort(data2.begin(), data2.end(), std::greater()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(is_same); } } //************************************************************************* TEST(selection_sort_empty_range) { // Forward iterators std::forward_list fwd_data; etl::selection_sort(fwd_data.begin(), fwd_data.end()); CHECK(fwd_data.empty()); // Bidirectional iterators std::list bidir_data; etl::selection_sort(bidir_data.begin(), bidir_data.end()); CHECK(bidir_data.empty()); // Random access iterators std::vector ra_data; etl::selection_sort(ra_data.begin(), ra_data.end()); CHECK(ra_data.empty()); // With comparator std::forward_list fwd_data2; etl::selection_sort(fwd_data2.begin(), fwd_data2.end(), std::greater()); CHECK(fwd_data2.empty()); } //************************************************************************* TEST(heap_sort_default) { std::vector initial_data = { NDC(1, 1), NDC(2, 1), NDC(3, 1), NDC(2, 2), NDC(3, 2), NDC(4, 1), NDC(2, 3), NDC(3, 3), NDC(5, 1) }; std::vector data1(initial_data); std::vector data2(initial_data); std::sort(data1.begin(), data1.end()); etl::heap_sort(data2.begin(), data2.end()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin()); CHECK(is_same); } //************************************************************************* TEST(heap_sort_greater) { std::vector initial_data = { NDC(1, 1), NDC(2, 1), NDC(3, 1), NDC(2, 2), NDC(3, 2), NDC(4, 1), NDC(2, 3), NDC(3, 3), NDC(5, 1) }; std::vector data1(initial_data); std::vector data2(initial_data); std::sort(data1.begin(), data1.end(), std::greater()); etl::heap_sort(data2.begin(), data2.end(), std::greater()); bool is_same = std::equal(data1.begin(), data1.end(), data2.begin()); 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)); int temp[etl::multimax(1, 2, 3, 4, 5, 6, 7, 8)] = { 1, 2, 3, 4, 5, 6, 7, 8 }; (void)temp; } //************************************************************************* 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])); } //************************************************************************* TEST(replace) { int data[] = { 1, 8, 2, 7, 2, 6, 2, 2, 10, 9 }; int expected[] = { 1, 8, 0, 7, 0, 6, 0, 0, 10, 9 }; // Replace 2 with 0 etl::replace(std::begin(data), std::end(data), 2, 0); bool is_same = std::equal(std::begin(data), std::end(data), std::begin(expected)); CHECK(is_same); } //************************************************************************* TEST(replace_if) { int data[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; int expected[] = { 0, 8, 0, 7, 0, 6, 0, 0, 10, 9 }; // Replace <=5 with 0 etl::replace_if(std::begin(data), std::end(data), std::bind(std::less_equal(), std::placeholders::_1, 5), 0); bool is_same = std::equal(std::begin(data), std::end(data), std::begin(expected)); CHECK(is_same); } //************************************************************************* TEST(for_each) { int data[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 }; struct Sum { void operator()(int i) { value += i; } Sum() : value(0) { } int value; }; Sum sum; sum = etl::for_each(std::begin(data), std::end(data), sum); CHECK_EQUAL(std::accumulate(std::begin(data), std::end(data), 0), sum.value); } //************************************************************************* TEST(remove) { std::array data = { 1, 8, 2, 7, 7, 7, 4, 5, 10, 9 }; std::array expected = { 1, 8, 2, 4, 5, 10, 9 }; etl::remove(data.begin(), data.end(), 7); bool is_same = std::equal(expected.begin(), expected.end(), data.begin()); CHECK(is_same); } //************************************************************************* TEST(remove_if) { std::array data = { 1, 8, 2, 7, 7, 7, 4, 5, 10, 9 }; std::array expected = { 1, 2, 4, 5 }; etl::remove_if(data.begin(), data.end(), [](int value) { return value >= 7; }); bool is_same = std::equal(expected.begin(), expected.end(), data.begin()); CHECK(is_same); } //************************************************************************* TEST(unique) { std::array data = { 1, 1, 2, 3, 3, 3, 4, 4, 5, 5 }; std::array expected = { 1, 2, 3, 4, 5 }; auto end = etl::unique(data.begin(), data.end()); CHECK_EQUAL(5, std::distance(data.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), data.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_empty_range) { std::array data = {}; auto end = etl::unique(data.begin(), data.end()); CHECK(end == data.end()); } //************************************************************************* TEST(unique_single_element) { std::array data = { 42 }; std::array expected = { 42 }; auto end = etl::unique(data.begin(), data.end()); CHECK_EQUAL(1, std::distance(data.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), data.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_no_duplicates) { std::array data = { 1, 2, 3, 4, 5 }; std::array expected = { 1, 2, 3, 4, 5 }; auto end = etl::unique(data.begin(), data.end()); CHECK_EQUAL(5, std::distance(data.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), data.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_all_same) { std::array data = { 7, 7, 7, 7, 7 }; std::array expected = { 7 }; auto end = etl::unique(data.begin(), data.end()); CHECK_EQUAL(1, std::distance(data.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), data.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_with_predicate) { std::array data = { 1, 1, 2, 3, 3, 3, 4, 4, 5, 5 }; std::array expected = { 1, 2, 3, 4, 5 }; auto end = etl::unique(data.begin(), data.end(), std::equal_to()); CHECK_EQUAL(5, std::distance(data.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), data.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_with_predicate_custom) { // Group elements that are close to each other (differ by less than 3) std::array data = { 1, 2, 3, 7, 8, 9, 20, 21 }; std::array expected = { 1, 7, 20 }; auto end = etl::unique(data.begin(), data.end(), [](int a, int b) { return (b - a) < 3; }); CHECK_EQUAL(3, std::distance(data.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), data.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_matches_std) { std::array data1 = { 1, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5, 5 }; std::array data2 = data1; auto std_end = std::unique(data1.begin(), data1.end()); auto etl_end = etl::unique(data2.begin(), data2.end()); size_t std_size = std::distance(data1.begin(), std_end); size_t etl_size = std::distance(data2.begin(), etl_end); CHECK_EQUAL(std_size, etl_size); bool is_same = std::equal(data1.begin(), std_end, data2.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_with_predicate_matches_std) { std::array data1 = { 1, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5, 5 }; std::array data2 = data1; auto std_end = std::unique(data1.begin(), data1.end(), std::equal_to()); auto etl_end = etl::unique(data2.begin(), data2.end(), std::equal_to()); size_t std_size = std::distance(data1.begin(), std_end); size_t etl_size = std::distance(data2.begin(), etl_end); CHECK_EQUAL(std_size, etl_size); bool is_same = std::equal(data1.begin(), std_end, data2.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_copy) { std::array data = { 1, 1, 2, 3, 3, 3, 4, 4, 5, 5 }; std::array expected = { 1, 2, 3, 4, 5 }; std::array result = {}; auto end = etl::unique_copy(data.begin(), data.end(), result.begin()); CHECK_EQUAL(5, std::distance(result.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), result.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_copy_empty_range) { std::array data = {}; std::array result = { 99 }; auto end = etl::unique_copy(data.begin(), data.end(), result.begin()); CHECK(end == result.begin()); CHECK_EQUAL(99, result[0]); // output unchanged } //************************************************************************* TEST(unique_copy_single_element) { std::array data = { 42 }; std::array expected = { 42 }; std::array result = {}; auto end = etl::unique_copy(data.begin(), data.end(), result.begin()); CHECK_EQUAL(1, std::distance(result.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), result.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_copy_no_duplicates) { std::array data = { 1, 2, 3, 4, 5 }; std::array expected = { 1, 2, 3, 4, 5 }; std::array result = {}; auto end = etl::unique_copy(data.begin(), data.end(), result.begin()); CHECK_EQUAL(5, std::distance(result.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), result.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_copy_all_same) { std::array data = { 7, 7, 7, 7, 7 }; std::array expected = { 7 }; std::array result = {}; auto end = etl::unique_copy(data.begin(), data.end(), result.begin()); CHECK_EQUAL(1, std::distance(result.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), result.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_copy_source_unchanged) { std::array data = { 1, 1, 2, 3, 3, 3, 4, 4, 5, 5 }; std::array original = data; std::array result = {}; etl::unique_copy(data.begin(), data.end(), result.begin()); bool is_same = std::equal(original.begin(), original.end(), data.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_copy_with_predicate) { std::array data = { 1, 1, 2, 3, 3, 3, 4, 4, 5, 5 }; std::array expected = { 1, 2, 3, 4, 5 }; std::array result = {}; auto end = etl::unique_copy(data.begin(), data.end(), result.begin(), std::equal_to()); CHECK_EQUAL(5, std::distance(result.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), result.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_copy_with_predicate_custom) { // Group elements that are close to each other (differ by less than 3) std::array data = { 1, 2, 3, 7, 8, 9, 20, 21 }; std::array expected = { 1, 7, 20 }; std::array result = {}; auto end = etl::unique_copy(data.begin(), data.end(), result.begin(), [](int a, int b) { return (b - a) < 3; }); CHECK_EQUAL(3, std::distance(result.begin(), end)); bool is_same = std::equal(expected.begin(), expected.end(), result.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_copy_matches_std) { std::array data = { 1, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5, 5 }; std::array std_result = {}; std::array etl_result = {}; auto std_end = std::unique_copy(data.begin(), data.end(), std_result.begin()); auto etl_end = etl::unique_copy(data.begin(), data.end(), etl_result.begin()); size_t std_size = std::distance(std_result.begin(), std_end); size_t etl_size = std::distance(etl_result.begin(), etl_end); CHECK_EQUAL(std_size, etl_size); bool is_same = std::equal(std_result.begin(), std_end, etl_result.begin()); CHECK(is_same); } //************************************************************************* TEST(unique_copy_with_predicate_matches_std) { std::array data = { 1, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5, 5 }; std::array std_result = {}; std::array etl_result = {}; auto std_end = std::unique_copy(data.begin(), data.end(), std_result.begin(), std::equal_to()); auto etl_end = etl::unique_copy(data.begin(), data.end(), etl_result.begin(), std::equal_to()); size_t std_size = std::distance(std_result.begin(), std_end); size_t etl_size = std::distance(etl_result.begin(), etl_end); CHECK_EQUAL(std_size, etl_size); bool is_same = std::equal(std_result.begin(), std_end, etl_result.begin()); CHECK(is_same); } //************************************************************************* struct generator { generator(int value_) : value(value_) { } int operator()() { return value++; } int value; }; TEST(generate) { std::array expected = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; std::array actual; etl::generate(actual.begin(), actual.end(), generator(2)); CHECK_ARRAY_EQUAL(expected.data(), actual.data(), expected.size()); } //************************************************************************* TEST(partition_forward_iterator_container) { // 40,320 permutations. std::array origin = { 0, 1, 2, 3, 4, 5, 6, 7 }; std::forward_list compare(origin.begin(), origin.end()); std::forward_list data(origin.begin(), origin.end()); bool complete = false; while (!complete) { auto pivot1 = std::partition(compare.begin(), compare.end(), [](int i) { return etl::is_even(i); }); auto pivot2 = etl::partition(data.begin(), data.end(), [](int i) { return etl::is_even(i); }); auto distance1 = std::distance(compare.begin(), pivot1); auto distance2 = std::distance(data.begin(), pivot2); CHECK_EQUAL(*pivot1, *pivot2); CHECK_EQUAL(distance1, distance2); for (auto itr = compare.begin(); itr != pivot1; ++itr) { CHECK_TRUE((etl::is_even(*itr))); } for (auto itr = pivot1; itr != compare.end(); ++itr) { CHECK_FALSE((etl::is_even(*itr))); } complete = !std::next_permutation(origin.begin(), origin.end()); compare.assign(origin.begin(), origin.end()); data.assign(origin.begin(), origin.end()); } } //************************************************************************* TEST(partition_bidirectional_iterator_container) { // 40,320 permutations. std::array initial = { 0, 1, 2, 3, 4, 5, 6, 7 }; std::array compare = initial; std::array data = initial; bool complete = false; while (!complete) { auto pivot1 = std::partition(compare.begin(), compare.end(), [](int i) { return etl::is_even(i); }); auto pivot2 = etl::partition(data.begin(), data.end(), [](int i) { return etl::is_even(i); }); auto distance1 = std::distance(compare.begin(), pivot1); auto distance2 = std::distance(data.begin(), pivot2); CHECK_EQUAL(*pivot1, *pivot2); CHECK_EQUAL(distance1, distance2); for (auto itr = compare.begin(); itr != pivot1; ++itr) { CHECK_TRUE((etl::is_even(*itr))); } for (auto itr = pivot1; itr != compare.end(); ++itr) { CHECK_FALSE((etl::is_even(*itr))); } complete = !std::next_permutation(initial.begin(), initial.end()); compare = initial; data = initial; } } //************************************************************************* TEST(nth_element_with_default_less_than_comparison) { // 40,320 permutations. std::array initial = { 0, 1, 2, 3, 4, 5, 6, 7 }; std::array compare = initial; std::array data = initial; bool complete = false; // For each nth position of each permutation. while (!complete) { // Try each nth position. for (size_t i = 0; i < initial.size(); ++i) { std::sort(compare.begin(), compare.end()); etl::nth_element(data.begin(), data.begin() + i, data.end()); CHECK_EQUAL(compare[i], data[i]); } complete = !std::next_permutation(initial.begin(), initial.end()); compare = initial; data = initial; } } #if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST)) //************************************************************************* constexpr int MakeNth(int nth_index) { std::array data = { 5, 1, 3, 7, 6, 2, 4, 0 }; etl::nth_element(data.begin(), data.begin() + nth_index, data.end()); return data[nth_index]; } TEST(constexpr_nth_element_with_default_less_than_comparison) { std::array compare = { 0, 1, 2, 3, 4, 5, 6, 7 }; constexpr int nth = MakeNth(3); CHECK_EQUAL(compare[3], nth); } #endif //************************************************************************* TEST(nth_element_with_custom_comparison) { // 40,320 permutations. std::array initial = { 0, 1, 2, 3, 4, 5, 6, 7 }; std::array compare = initial; std::array data = initial; bool complete = false; // For each nth position of each permutation. while (!complete) { // Try each nth position. for (size_t i = 0; i < initial.size(); ++i) { std::sort(compare.begin(), compare.end(), std::greater()); etl::nth_element(data.begin(), data.begin() + i, data.end(), std::greater()); CHECK_EQUAL(compare[i], data[i]); } complete = !std::next_permutation(initial.begin(), initial.end()); compare = initial; data = initial; } } //************************************************************************* TEST(accumulate_default) { int data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int expected = std::accumulate(std::begin(data), std::end(data), 0); int result = etl::accumulate(std::begin(data), std::end(data), 0); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(accumulate_with_initial_value) { int data[] = { 1, 2, 3, 4, 5 }; int expected = std::accumulate(std::begin(data), std::end(data), 100); int result = etl::accumulate(std::begin(data), std::end(data), 100); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(accumulate_custom_operation) { int data[] = { 1, 2, 3, 4, 5 }; int expected = std::accumulate(std::begin(data), std::end(data), 1, std::multiplies()); int result = etl::accumulate(std::begin(data), std::end(data), 1, std::multiplies()); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(accumulate_empty_range) { int data[] = { 1 }; int expected = std::accumulate(std::begin(data), std::begin(data), 42); int result = etl::accumulate(std::begin(data), std::begin(data), 42); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(accumulate_single_element) { int data[] = { 7 }; int expected = std::accumulate(std::begin(data), std::end(data), 0); int result = etl::accumulate(std::begin(data), std::end(data), 0); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(accumulate_negative_values) { int data[] = { -3, -2, -1, 0, 1, 2, 3 }; int expected = std::accumulate(std::begin(data), std::end(data), 0); int result = etl::accumulate(std::begin(data), std::end(data), 0); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(accumulate_custom_operation_subtraction) { int data[] = { 1, 2, 3, 4, 5 }; int expected = std::accumulate(std::begin(data), std::end(data), 100, std::minus()); int result = etl::accumulate(std::begin(data), std::end(data), 100, std::minus()); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(accumulate_non_random_iterator) { List data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int expected = std::accumulate(data.begin(), data.end(), 0); int result = etl::accumulate(data.begin(), data.end(), 0); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(accumulate_non_random_iterator_custom_operation) { List data = { 1, 2, 3, 4, 5 }; int expected = std::accumulate(data.begin(), data.end(), 1, std::multiplies()); int result = etl::accumulate(data.begin(), data.end(), 1, std::multiplies()); CHECK_EQUAL(expected, result); } //************************************************************************* TEST(accumulate_double) { double data[] = { 1.5, 2.5, 3.5, 4.5, 5.5 }; double expected = std::accumulate(std::begin(data), std::end(data), 0.0); double result = etl::accumulate(std::begin(data), std::end(data), 0.0); CHECK_CLOSE(expected, result, 1e-10); } //************************************************************************* TEST(clamp_run_time) { CHECK_EQUAL(5, etl::clamp(5, 0, 10)); CHECK_EQUAL(0, etl::clamp(-5, 0, 10)); CHECK_EQUAL(10, etl::clamp(15, 0, 10)); } //************************************************************************* TEST(clamp_compile_time) { CHECK_EQUAL(5, (etl::clamp(5))); CHECK_EQUAL(0, (etl::clamp(-5))); CHECK_EQUAL(10, (etl::clamp(15))); } //************************************************************************* TEST(clamp_constexpr) { constexpr int result1 = etl::clamp(5, 0, 10); constexpr int result2 = etl::clamp(-5, 0, 10); constexpr int result3 = etl::clamp(15, 0, 10); constexpr int result4 = etl::clamp(5); constexpr int result5 = etl::clamp(-5); constexpr int result6 = etl::clamp(15); CHECK_EQUAL(5, result1); CHECK_EQUAL(0, result2); CHECK_EQUAL(10, result3); CHECK_EQUAL(5, result4); CHECK_EQUAL(0, result5); CHECK_EQUAL(10, result6); } //************************************************************************* TEST(merge_default_comparator) { int input1[] = { 1, 3, 5, 7, 9 }; int input2[] = { 2, 4, 6, 8, 10 }; int output[10]; int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int* result = etl::merge(std::begin(input1), std::end(input1), std::begin(input2), std::end(input2), std::begin(output)); CHECK_EQUAL(std::end(output), result); CHECK_ARRAY_EQUAL(expected, output, 10); } //************************************************************************* TEST(merge_custom_comparator) { int input1[] = { 9, 7, 5, 3, 1 }; int input2[] = { 10, 8, 6, 4, 2 }; int output[10]; int expected[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; int* result = etl::merge(std::begin(input1), std::end(input1), std::begin(input2), std::end(input2), std::begin(output), Greater()); CHECK_EQUAL(std::end(output), result); CHECK_ARRAY_EQUAL(expected, output, 10); } //************************************************************************* TEST(merge_first_range_empty) { int input1[] = { 0 }; // dummy, won't be used int input2[] = { 1, 2, 3 }; int output[3]; int expected[] = { 1, 2, 3 }; int* result = etl::merge(input1, input1, // empty range std::begin(input2), std::end(input2), std::begin(output)); CHECK_EQUAL(std::end(output), result); CHECK_ARRAY_EQUAL(expected, output, 3); } //************************************************************************* TEST(merge_second_range_empty) { int input1[] = { 1, 2, 3 }; int input2[] = { 0 }; // dummy, won't be used int output[3]; int expected[] = { 1, 2, 3 }; int* result = etl::merge(std::begin(input1), std::end(input1), input2, input2, // empty range std::begin(output)); CHECK_EQUAL(std::end(output), result); CHECK_ARRAY_EQUAL(expected, output, 3); } //************************************************************************* TEST(merge_both_ranges_empty) { int input1[] = { 0 }; int output[] = { 99 }; int* result = etl::merge(input1, input1, input1, input1, std::begin(output)); CHECK_EQUAL(std::begin(output), result); CHECK_EQUAL(99, output[0]); // output should be unchanged } //************************************************************************* TEST(merge_with_duplicates) { int input1[] = { 1, 3, 3, 5 }; int input2[] = { 2, 3, 4, 5 }; int output[8]; int expected[] = { 1, 2, 3, 3, 3, 4, 5, 5 }; int* result = etl::merge(std::begin(input1), std::end(input1), std::begin(input2), std::end(input2), std::begin(output)); CHECK_EQUAL(std::end(output), result); CHECK_ARRAY_EQUAL(expected, output, 8); } //************************************************************************* TEST(merge_different_sizes) { int input1[] = { 1, 5 }; int input2[] = { 2, 3, 4, 6, 7, 8 }; int output[8]; int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; int* result = etl::merge(std::begin(input1), std::end(input1), std::begin(input2), std::end(input2), std::begin(output)); CHECK_EQUAL(std::end(output), result); CHECK_ARRAY_EQUAL(expected, output, 8); } //************************************************************************* TEST(merge_single_elements) { int input1[] = { 1 }; int input2[] = { 2 }; int output[2]; int expected[] = { 1, 2 }; int* result = etl::merge(std::begin(input1), std::end(input1), std::begin(input2), std::end(input2), std::begin(output)); CHECK_EQUAL(std::end(output), result); CHECK_ARRAY_EQUAL(expected, output, 2); } //************************************************************************* TEST(merge_with_list_iterators) { std::list input1 = { 1, 3, 5, 7 }; std::list input2 = { 2, 4, 6, 8 }; std::vector output(8); std::vector expected = { 1, 2, 3, 4, 5, 6, 7, 8 }; std::vector::iterator result = etl::merge(input1.begin(), input1.end(), input2.begin(), input2.end(), output.begin()); CHECK(output.end() == result); CHECK_ARRAY_EQUAL(expected.data(), output.data(), 8); } //************************************************************************* TEST(merge_matches_std) { int input1[] = { 1, 4, 7, 8, 10 }; int input2[] = { 2, 3, 5, 6, 9 }; int etl_output[10]; int std_output[10]; etl::merge(std::begin(input1), std::end(input1), std::begin(input2), std::end(input2), std::begin(etl_output)); std::merge(std::begin(input1), std::end(input1), std::begin(input2), std::end(input2), std::begin(std_output)); CHECK_ARRAY_EQUAL(std_output, etl_output, 10); } //************************************************************************* TEST(merge_matches_std_with_comparator) { int input1[] = { 10, 8, 7, 4, 1 }; int input2[] = { 9, 6, 5, 3, 2 }; int etl_output[10]; int std_output[10]; etl::merge(std::begin(input1), std::end(input1), std::begin(input2), std::end(input2), std::begin(etl_output), Greater()); std::merge(std::begin(input1), std::end(input1), std::begin(input2), std::end(input2), std::begin(std_output), Greater()); CHECK_ARRAY_EQUAL(std_output, etl_output, 10); } //************************************************************************* TEST(merge_stability) { // Test that merge is stable: equivalent elements from the first range // come before those from the second range. Data input1[] = { Data(1, 1), Data(3, 1), Data(5, 1) }; Data input2[] = { Data(1, 2), Data(3, 2), Data(5, 2) }; Data output[6]; etl::merge(std::begin(input1), std::end(input1), std::begin(input2), std::end(input2), std::begin(output), DataPredicate()); // Elements from input1 (b==1) should come before elements from input2 (b==2) // for equivalent keys. CHECK_EQUAL(1, output[0].a); CHECK_EQUAL(1, output[0].b); // from input1 CHECK_EQUAL(1, output[1].a); CHECK_EQUAL(2, output[1].b); // from input2 CHECK_EQUAL(3, output[2].a); CHECK_EQUAL(1, output[2].b); // from input1 CHECK_EQUAL(3, output[3].a); CHECK_EQUAL(2, output[3].b); // from input2 CHECK_EQUAL(5, output[4].a); CHECK_EQUAL(1, output[4].b); // from input1 CHECK_EQUAL(5, output[5].a); CHECK_EQUAL(2, output[5].b); // from input2 } //************************************************************************* TEST(inplace_merge_default_comparator) { int data[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 }; int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; etl::inplace_merge(std::begin(data), std::begin(data) + 5, std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 10); } //************************************************************************* TEST(inplace_merge_custom_comparator) { int data[] = { 9, 7, 5, 3, 1, 10, 8, 6, 4, 2 }; int expected[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; etl::inplace_merge(std::begin(data), std::begin(data) + 5, std::end(data), Greater()); CHECK_ARRAY_EQUAL(expected, data, 10); } //************************************************************************* TEST(inplace_merge_first_range_empty) { int data[] = { 1, 2, 3, 4, 5 }; int expected[] = { 1, 2, 3, 4, 5 }; etl::inplace_merge(std::begin(data), std::begin(data), std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 5); } //************************************************************************* TEST(inplace_merge_second_range_empty) { int data[] = { 1, 2, 3, 4, 5 }; int expected[] = { 1, 2, 3, 4, 5 }; etl::inplace_merge(std::begin(data), std::end(data), std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 5); } //************************************************************************* TEST(inplace_merge_both_ranges_empty) { int data[] = { 99 }; etl::inplace_merge(data, data, data); // empty range CHECK_EQUAL(99, data[0]); // unchanged } //************************************************************************* TEST(inplace_merge_with_duplicates) { int data[] = { 1, 3, 3, 5, 2, 3, 4, 5 }; int expected[] = { 1, 2, 3, 3, 3, 4, 5, 5 }; etl::inplace_merge(std::begin(data), std::begin(data) + 4, std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 8); } //************************************************************************* TEST(inplace_merge_different_sizes) { int data[] = { 1, 5, 2, 3, 4, 6, 7, 8 }; int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; etl::inplace_merge(std::begin(data), std::begin(data) + 2, std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 8); } //************************************************************************* TEST(inplace_merge_single_elements) { int data[] = { 2, 1 }; int expected[] = { 1, 2 }; etl::inplace_merge(std::begin(data), std::begin(data) + 1, std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 2); } //************************************************************************* TEST(inplace_merge_single_element_halves_already_sorted) { int data[] = { 1, 2 }; int expected[] = { 1, 2 }; etl::inplace_merge(std::begin(data), std::begin(data) + 1, std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 2); } //************************************************************************* TEST(inplace_merge_already_sorted) { int data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; etl::inplace_merge(std::begin(data), std::begin(data) + 5, std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 10); } //************************************************************************* TEST(inplace_merge_reverse_halves) { // Second half all less than first half int data[] = { 6, 7, 8, 9, 10, 1, 2, 3, 4, 5 }; int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; etl::inplace_merge(std::begin(data), std::begin(data) + 5, std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 10); } //************************************************************************* TEST(inplace_merge_with_list_iterators) { std::vector data = { 1, 3, 5, 7, 2, 4, 6, 8 }; std::vector expected = { 1, 2, 3, 4, 5, 6, 7, 8 }; etl::inplace_merge(data.begin(), data.begin() + 4, data.end()); CHECK(expected == data); } //************************************************************************* TEST(inplace_merge_matches_std) { int etl_data[] = { 1, 4, 7, 8, 10, 2, 3, 5, 6, 9 }; int std_data[] = { 1, 4, 7, 8, 10, 2, 3, 5, 6, 9 }; etl::inplace_merge(std::begin(etl_data), std::begin(etl_data) + 5, std::end(etl_data)); std::inplace_merge(std::begin(std_data), std::begin(std_data) + 5, std::end(std_data)); CHECK_ARRAY_EQUAL(std_data, etl_data, 10); } //************************************************************************* TEST(inplace_merge_matches_std_with_comparator) { int etl_data[] = { 10, 8, 7, 4, 1, 9, 6, 5, 3, 2 }; int std_data[] = { 10, 8, 7, 4, 1, 9, 6, 5, 3, 2 }; etl::inplace_merge(std::begin(etl_data), std::begin(etl_data) + 5, std::end(etl_data), Greater()); std::inplace_merge(std::begin(std_data), std::begin(std_data) + 5, std::end(std_data), Greater()); CHECK_ARRAY_EQUAL(std_data, etl_data, 10); } //************************************************************************* TEST(inplace_merge_stability) { // Test that inplace_merge is stable: equivalent elements from the first // range come before those from the second range. Data data[] = { Data(1, 1), Data(3, 1), Data(5, 1), Data(1, 2), Data(3, 2), Data(5, 2) }; etl::inplace_merge(std::begin(data), std::begin(data) + 3, std::end(data), DataPredicate()); // Elements from first half (b==1) should come before elements from second half (b==2) // for equivalent keys. CHECK_EQUAL(1, data[0].a); CHECK_EQUAL(1, data[0].b); // from first half CHECK_EQUAL(1, data[1].a); CHECK_EQUAL(2, data[1].b); // from second half CHECK_EQUAL(3, data[2].a); CHECK_EQUAL(1, data[2].b); // from first half CHECK_EQUAL(3, data[3].a); CHECK_EQUAL(2, data[3].b); // from second half CHECK_EQUAL(5, data[4].a); CHECK_EQUAL(1, data[4].b); // from first half CHECK_EQUAL(5, data[5].a); CHECK_EQUAL(2, data[5].b); // from second half } //************************************************************************* TEST(inplace_merge_single_element_first_half) { int data[] = { 5, 1, 2, 3, 4 }; int expected[] = { 1, 2, 3, 4, 5 }; etl::inplace_merge(std::begin(data), std::begin(data) + 1, std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 5); } //************************************************************************* TEST(inplace_merge_single_element_second_half) { int data[] = { 1, 2, 3, 4, 5, 3 }; int expected[] = { 1, 2, 3, 3, 4, 5 }; etl::inplace_merge(std::begin(data), std::begin(data) + 5, std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 6); } //************************************************************************* TEST(inplace_merge_all_equal) { int data[] = { 5, 5, 5, 5, 5, 5 }; int expected[] = { 5, 5, 5, 5, 5, 5 }; etl::inplace_merge(std::begin(data), std::begin(data) + 3, std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 6); } //************************************************************************* TEST(inplace_merge_interleaved) { int data[] = { 1, 3, 5, 7, 9, 11, 2, 4, 6, 8, 10, 12 }; int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; etl::inplace_merge(std::begin(data), std::begin(data) + 6, std::end(data)); CHECK_ARRAY_EQUAL(expected, data, 12); } } }