From 84cfab6b3280ad10bada6f6dd7c721c8ec886e45 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 4 Dec 2019 16:23:35 +0000 Subject: [PATCH] Merge remote-tracking branch 'origin/feature/indirect_vector_algorithm_adaptor' into development # Conflicts: # include/etl/indirect_vector.h --- include/etl/indirect_vector.h | 296 ++++------- test/test_indirect_vector.cpp | 398 +++++---------- test/test_indirect_vector_external_buffer.cpp | 482 ++++++------------ 3 files changed, 409 insertions(+), 767 deletions(-) diff --git a/include/etl/indirect_vector.h b/include/etl/indirect_vector.h index 3aff627d..238030be 100644 --- a/include/etl/indirect_vector.h +++ b/include/etl/indirect_vector.h @@ -83,20 +83,103 @@ namespace etl { public: - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; #if ETL_CPP11_SUPPORTED - typedef T&& rvalue_reference; + typedef T&& rvalue_reference; #endif - typedef T* pointer; - typedef const T* const_pointer; - typedef pointer const * indirect_pointer; - typedef const_pointer const * indirect_const_pointer; + typedef T* pointer; + typedef const T* const_pointer; + + typedef typename etl::ivector::iterator indirect_iterator; + typedef typename etl::ivector::const_iterator indirect_const_iterator; typedef typename etl::ivector::size_type size_type; typedef typename etl::ivector::difference_type difference_type; + //************************************************************************* + /// Unary function adaptor. + //************************************************************************* + template + class unary_function_adaptor + { + public: + + unary_function_adaptor(TUnaryFunction unary_function_) + : unary_function(unary_function_) + { + } + + TReturnType operator()(const_pointer indirect_itr) + { + return unary_function(*indirect_itr); + } + + TUnaryFunction unary_function; + }; + + //************************************************************************* + template + class unary_function_adaptor + { + public: + + unary_function_adaptor(TUnaryFunction unary_function_) + : unary_function(unary_function_) + { + } + + void operator()(const_pointer indirect_itr) + { + unary_function(*indirect_itr); + } + + TUnaryFunction unary_function; + }; + + //************************************************************************* + /// Binary function adaptor. + //************************************************************************* + template + class binary_function_adaptor + { + public: + + binary_function_adaptor(TBinaryFunction binary_function_) + : binary_function(binary_function_) + { + } + + TReturnType operator()(const_pointer indirect_itr_lhs, + const_pointer indirect_itr_rhs) + { + return binary_function(*indirect_itr_lhs, *indirect_itr_rhs); + } + + TBinaryFunction binary_function; + }; + + //************************************************************************* + template + class binary_function_adaptor + { + public: + + binary_function_adaptor(TBinaryFunction binary_function_) + : binary_function(binary_function_) + { + } + + void operator()(const_pointer indirect_itr_lhs, + const_pointer indirect_itr_rhs) + { + binary_function(*indirect_itr_lhs, *indirect_itr_rhs); + } + + TBinaryFunction binary_function; + }; + //************************************************************************* /// iterator. //************************************************************************* @@ -203,6 +286,16 @@ namespace etl return result; } + indirect_iterator indirection() + { + return lookup_itr; + } + + indirect_const_iterator indirection() const + { + return lookup_itr; + } + friend difference_type operator -(const iterator& lhs, const iterator& rhs) { return lhs.lookup_itr - rhs.lookup_itr; @@ -225,14 +318,12 @@ namespace etl private: - typedef typename etl::ivector::iterator lookup_itr_t; - - iterator(lookup_itr_t itr_) + iterator(indirect_iterator itr_) : lookup_itr(itr_) { } - lookup_itr_t lookup_itr; + indirect_iterator lookup_itr; }; //************************************************************************* @@ -317,6 +408,11 @@ namespace etl return &(**lookup_itr); } + indirect_const_iterator indirection() const + { + return lookup_itr; + } + friend const_iterator operator +(const const_iterator& lhs, difference_type offset) { const_iterator result(lhs); @@ -355,12 +451,12 @@ namespace etl typedef typename etl::ivector::const_iterator lookup_itr_t; - const_iterator(lookup_itr_t itr_) + const_iterator(indirect_const_iterator itr_) : lookup_itr(itr_) { } - lookup_itr_t lookup_itr; + indirect_const_iterator lookup_itr; }; typedef ETL_STD::reverse_iterator reverse_iterator; @@ -611,26 +707,6 @@ namespace etl return *(lookup.back()); } - //********************************************************************* - /// Returns a pointer to the beginning of the internal lookup vector data. - /// These are a list of pointers to objects - ///\return An indirect pointer to the beginning of the internal lookup vector data. - //********************************************************************* - indirect_pointer data() - { - return lookup.data(); - } - - //********************************************************************* - /// Returns a pointer to the beginning of the internal lookup vector data. - /// These are a list of pointers to objects - ///\return An indirect pointer to the beginning of the internal lookup vector data. - //********************************************************************* - indirect_const_pointer data() const - { - return lookup.data(); - } - //********************************************************************* /// Assigns values to the indirect_vector. /// If asserts or exceptions are enabled, emits vector_full if the indirect_vector does not have enough free space. @@ -1014,7 +1090,7 @@ namespace etl //************************************************************************* /// Gets the current capacity of the indirect_vector. ///\return The capacity of the indirect_vector. -//************************************************************************* + //************************************************************************* size_type capacity() const { return lookup.capacity(); @@ -1056,108 +1132,6 @@ namespace etl return lookup.available(); } - //************************************************************************* - /// Sorts the indirect vector using the default 'less'. - //************************************************************************* - void sort() - { - sort_function(begin(), end(), ETL_STD::less()); - } - - //************************************************************************* - /// Sorts the indirect vector using a supplied compare function. - //************************************************************************* - template - void sort(TCompare compare) - { - sort_function(begin(), end(), compare); - } - - //************************************************************************* - /// Sorts the indirect vector between two iterators. - //************************************************************************* - void sort(iterator first, iterator last) - { - sort_function(first, last, ETL_STD::less()); - } - - //************************************************************************* - /// Sorts the indirect vector between two iterators. - //************************************************************************* - template - void sort(iterator first, iterator last, TCompare compare) - { - sort_function(first, last, compare); - } - - //************************************************************************* - /// Sorts the indirect vector using the default 'less'. - //************************************************************************* - void stable_sort() - { - stable_sort_function(begin(), end(), ETL_STD::less()); - } - - //************************************************************************* - /// Sorts the indirect vector using a supplied compare function. - //************************************************************************* - template - void stable_sort(TCompare compare) - { - stable_sort_function(begin(), end(), compare); - } - - //************************************************************************* - /// Sorts the indirect vector between two iterators. - //************************************************************************* - void stable_sort(iterator first, iterator last) - { - stable_sort_function(first, last, ETL_STD::less()); - } - - //************************************************************************* - /// Sorts the indirect vector between two iterators. - //************************************************************************* - template - void stable_sort(iterator first, iterator last, TCompare compare) - { - stable_sort_function(first, last, compare); - } - - //************************************************************************* - /// Checks to see if the vector is sorted, using the default 'less'. - //************************************************************************* - bool is_sorted() const - { - return is_sorted_function(cbegin(), cend(), ETL_STD::less()); - } - - //************************************************************************* - /// Sorts the indirect vector using a supplied compare function. - //************************************************************************* - template - bool is_sorted(TCompare compare) const - { - return is_sorted_function(cbegin(), cend(), compare); - } - - //************************************************************************* - /// Sorts the indirect vector between two iterators. - //************************************************************************* - bool is_sorted(const_iterator first, const_iterator last) const - { - return is_sorted_function(first, last, ETL_STD::less()); - } - - //************************************************************************* - /// Sorts the indirect vector between two iterators. - //************************************************************************* - template - bool is_sorted(const_iterator first, const_iterator last, TCompare compare) const - { - return is_sorted_function(first, last, compare); - } - protected: //********************************************************************* @@ -1211,54 +1185,6 @@ namespace etl private: - //********************************************************************* - /// Sorts the range. - //********************************************************************* - template - void sort_function(iterator first, iterator last, TCompare compare) - { - etl::sort(first.lookup_itr, last.lookup_itr, ObjectCompare(compare)); - } - - //********************************************************************* - /// Sorts the range. - /// Stable - //********************************************************************* - template - void stable_sort_function(iterator first, iterator last, TCompare compare) - { - etl::stable_sort(first.lookup_itr, last.lookup_itr, ObjectCompare(compare)); - } - - //********************************************************************* - /// Checks if the range is sorted. - //********************************************************************* - template - bool is_sorted_function(const_iterator first, const_iterator last, TCompare compare) const - { - return etl::is_sorted(first.lookup_itr, last.lookup_itr, ObjectCompare(compare)); - } - - //********************************************************************* - /// How to compare two objects via the lookup iterators. - /// \tparam TCompare Type to compare two T objects. - //********************************************************************* - template - struct ObjectCompare - { - ObjectCompare(TCompare compare_) - : compare(compare_) - { - } - - bool operator ()(const T* lhs, const T* rhs) const - { - return compare(*lhs, *rhs); - } - - TCompare compare; - }; - // Disable copy construction. iindirect_vector(const iindirect_vector&) ETL_DELETE; diff --git a/test/test_indirect_vector.cpp b/test/test_indirect_vector.cpp index 823e2bfc..bff833a8 100644 --- a/test/test_indirect_vector.cpp +++ b/test/test_indirect_vector.cpp @@ -72,6 +72,15 @@ namespace CompareDataNDC stable_part_ordered_data; CompareDataNDC stable_part_greater_ordered_data; + template + void test_algorithm(TIterator first1, TIterator last1, TIterator first2, TFunctor functor) + { + while (first1 != last1) + { + functor(*first1++, *first2++); + } + } + //************************************************************************* struct SetupFixture { @@ -568,34 +577,6 @@ namespace CHECK(data.back() == compare_data.back()); } - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_data) - { - DataNDC data(initial_data.begin(), initial_data.end()); - - DataNDC::indirect_pointer p = data.data(); - - for (size_t i = 0U; i < data.size(); ++i) - { - CHECK(data[i] == **p); - ++p; - } - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_data_const) - { - const DataNDC data(initial_data.begin(), initial_data.end()); - - DataNDC::indirect_const_pointer p = data.data(); - - for (size_t i = 0U; i < data.size(); ++i) - { - CHECK(data[i] == **p); - ++p; - } - } - //************************************************************************* TEST_FIXTURE(SetupFixture, test_assign_range) { @@ -1330,251 +1311,140 @@ namespace } //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_order_from_unordered_std_sort) + TEST_FIXTURE(SetupFixture, test_indirect_algorithm) + { + DataNDC data1(initial_data.begin(), initial_data.end()); + DataNDC data2(initial_data.rbegin(), initial_data.rend()); + + std::reverse(data1.begin().indirection(), data1.end().indirection()); + + bool is_equal = std::equal(data1.begin(), + data1.end(), + data2.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_indirect_algorithm_void_unary_function) + { + struct functor + { + void operator()(const NDC& ndc) + { + result += ndc.value; + } + + std::string result; + }; + + const DataNDC data(ordered_data.begin(), ordered_data.end()); + + typedef typename DataNDC::unary_function_adaptor wrapped_functor; + + functor unwrapped; + wrapped_functor wrapped(unwrapped); + + functor direct = std::for_each(data.begin(), + data.end(), + unwrapped); + + functor indirect = std::for_each(data.begin().indirection(), + data.end().indirection(), + wrapped).unary_function; + + CHECK_EQUAL(direct.result, indirect.result); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_indirect_algorithm_bool_unary_function) + { + struct functor + { + bool operator()(const NDC& ndc) + { + return ndc.value == "4"; + } + + std::string result; + }; + + DataNDC data1(unordered_data.begin(), unordered_data.end()); + DataNDC data2(unordered_data.begin(), unordered_data.end()); + + typedef typename DataNDC::unary_function_adaptor wrapped_functor; + + functor unwrapped; + wrapped_functor wrapped(unwrapped); + + typename DataNDC::iterator direct = std::partition(data1.begin(), + data1.end(), + unwrapped); + + typename DataNDC::indirect_iterator indirect = std::partition(data2.begin().indirection(), + data2.end().indirection(), + wrapped); + + bool is_equal = std::equal(data1.begin(), + data1.end(), + data2.begin()); + + CHECK(is_equal); + CHECK(*direct == **indirect); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_indirect_algorithm_void_binary_function) + { + struct functor + { + void operator()(const NDC& lhs, const NDC& rhs) + { + result += lhs.value; + result += rhs.value; + } + + std::string result; + }; + + typedef typename DataNDC::binary_function_adaptor wrapped_functor; + + functor unwrapped; + wrapped_functor wrapped(unwrapped); + + const DataNDC data1(ordered_data.begin(), ordered_data.end()); + const DataNDC data2(ordered_data.begin(), ordered_data.end()); + + DataNDC direct_data; + DataNDC indirect_data; + + test_algorithm(data1.begin(), + data1.end(), + data2.begin(), + unwrapped); + + test_algorithm(data1.begin().indirection(), + data1.end().indirection(), + data2.begin().indirection(), + wrapped); + + CHECK_EQUAL(unwrapped.result, wrapped.binary_function.result); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_indirect_algorithm_bool_binary_function) { DataNDC data(unordered_data.begin(), unordered_data.end()); - std::sort(data.begin(), data.end()); + std::sort(data.begin().indirection(), + data.end().indirection(), + typename DataNDC::binary_function_adaptor, bool>(std::less())); bool is_equal = std::equal(data.begin(), data.end(), ordered_data.begin()); CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_order_from_unordered_std_stable_sort) - { - DataNDC data(unordered_data.begin(), unordered_data.end()); - - std::stable_sort(data.begin(), data.end()); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_default_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_order_from_ordered) - { - DataNDC data(ordered_data.begin(), ordered_data.end()); - - data.sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - ordered_data.begin()); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_order_from_reverse_ordered) - { - DataNDC data(ordered_data.rbegin(), ordered_data.rend()); - - data.sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - ordered_data.begin()); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_order_from_unordered) - { - DataNDC data(unordered_data.begin(), unordered_data.end()); - - data.sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - ordered_data.begin()); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_greater_order_from_reverse_ordered) - { - DataNDC data(ordered_data.rbegin(), ordered_data.rend()); - - data.sort(std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - ordered_data.rbegin()); - - CHECK(is_equal); - CHECK(data.is_sorted(std::greater())); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_greater_order_from_unordered) - { - DataNDC data(unordered_data.begin(), unordered_data.end()); - - data.sort(std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - ordered_data.rbegin()); - - CHECK(is_equal); - CHECK(data.is_sorted(std::greater())); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_partial_order_from_unordered) - { - DataNDC data(unordered_data.begin(), unordered_data.end()); - - data.sort(data.begin() + 2, data.end() - 2); - - bool is_equal = std::equal(data.begin(), - data.end(), - part_ordered_data.begin()); - - CHECK(is_equal); - CHECK((data.is_sorted(data.cbegin() + 2, data.cend() - 2))); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_greater_partial_order_from_unordered) - { - DataNDC data(unordered_data.begin(), unordered_data.end()); - - data.sort(data.begin() + 2, data.end() - 2, std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - part_reverse_ordered_data.begin()); - - CHECK(is_equal); - CHECK((data.is_sorted(data.begin() + 2, data.end() - 2, std::greater()))); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_default_order_from_ordered) - { - DataNDC data(stable_default_ordered_data.begin(), stable_default_ordered_data.end()); - - data.stable_sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_default_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_default_order_from_reverse_ordered) - { - DataNDC data(stable_default_ordered_data.rbegin(), stable_default_ordered_data.rend()); - - data.stable_sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_reverse_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_default_order_from_unordered) - { - DataNDC data(unordered_data.begin(), unordered_data.end()); - - data.stable_sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_default_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_greater_order_from_reverse_ordered) - { - DataNDC data(stable_default_ordered_data.rbegin(), stable_default_ordered_data.rend()); - - data.stable_sort(std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_greater_reverse_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted(std::greater())); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_greater_order_from_unordered) - { - DataNDC data(unordered_data.begin(), unordered_data.end()); - - data.stable_sort(std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_greater_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted(std::greater())); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_default_partial_order_from_unordered) - { - DataNDC data(unordered_data.begin(), unordered_data.end()); - - data.stable_sort(data.begin() + 2, data.end() - 2); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_part_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK((data.is_sorted(data.cbegin() + 2, data.cend() - 2))); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_greater_partial_order_from_unordered) - { - DataNDC data(unordered_data.begin(), unordered_data.end()); - - data.stable_sort(data.begin() + 2, data.end() - 2, std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_part_greater_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK((data.is_sorted(data.begin() + 2, data.end() - 2, std::greater()))); } }; } diff --git a/test/test_indirect_vector_external_buffer.cpp b/test/test_indirect_vector_external_buffer.cpp index e8edd154..90278dc1 100644 --- a/test/test_indirect_vector_external_buffer.cpp +++ b/test/test_indirect_vector_external_buffer.cpp @@ -88,6 +88,15 @@ namespace CompareDataNDC stable_part_ordered_data; CompareDataNDC stable_part_greater_ordered_data; + template + void test_algorithm(TIterator first1, TIterator last1, TIterator first2, TFunctor functor) + { + while (first1 != last1) + { + functor(*first1++, *first2++); + } + } + //************************************************************************* struct SetupFixture { @@ -716,40 +725,6 @@ namespace CHECK(data.back() == compare_data.back()); } - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_data) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(initial_data.begin(), initial_data.end(), lookup, pool); - - DataNDC::indirect_pointer p = data.data(); - - for (size_t i = 0U; i < data.size(); ++i) - { - CHECK(data[i] == **p); - ++p; - } - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_data_const) - { - LookupNDC lookup; - PoolNDC pool; - - const DataNDC data(initial_data.begin(), initial_data.end(), lookup, pool); - - DataNDC::indirect_const_pointer p = data.data(); - - for (size_t i = 0U; i < data.size(); ++i) - { - CHECK(data[i] == **p); - ++p; - } - } - //************************************************************************* TEST_FIXTURE(SetupFixture, test_assign_range) { @@ -1539,299 +1514,170 @@ namespace } //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_order_from_unordered_std_sort) + TEST_FIXTURE(SetupFixture, test_indirect_algorithm) { - LookupNDC lookup; - PoolNDC pool; + LookupNDC lookup1; + PoolNDC pool1; - DataNDC data(unordered_data.begin(), unordered_data.end(), lookup, pool); + LookupNDC lookup2; + PoolNDC pool2; - std::sort(data.begin(), data.end()); + DataNDC data1(initial_data.begin(), initial_data.end(), lookup1, pool1); + DataNDC data2(initial_data.rbegin(), initial_data.rend(), lookup2, pool2); + + std::reverse(data1.begin().indirection(), data1.end().indirection()); + + bool is_equal = std::equal(data1.begin(), + data1.end(), + data2.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_indirect_algorithm_void_unary_function) + { + struct functor + { + void operator()(const NDC& ndc) + { + result += ndc.value; + } + + std::string result; + }; + + LookupNDC lookup1; + PoolNDC pool1; + + const DataNDC data(ordered_data.begin(), ordered_data.end(), lookup1, pool1); + + typedef typename DataNDC::unary_function_adaptor wrapped_functor; + + functor unwrapped; + wrapped_functor wrapped(unwrapped); + + functor direct = std::for_each(data.begin(), + data.end(), + unwrapped); + + functor indirect = std::for_each(data.begin().indirection(), + data.end().indirection(), + wrapped).unary_function; + + CHECK_EQUAL(direct.result, indirect.result); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_indirect_algorithm_bool_unary_function) + { + struct functor + { + bool operator()(const NDC& ndc) + { + return ndc.value == "4"; + } + + std::string result; + }; + + LookupNDC lookup1; + PoolNDC pool1; + + LookupNDC lookup2; + PoolNDC pool2; + + DataNDC data1(unordered_data.begin(), unordered_data.end(), lookup1, pool1); + DataNDC data2(unordered_data.begin(), unordered_data.end(), lookup2, pool2); + + typedef typename DataNDC::unary_function_adaptor wrapped_functor; + + functor unwrapped; + wrapped_functor wrapped(unwrapped); + + typename DataNDC::iterator direct = std::partition(data1.begin(), + data1.end(), + unwrapped); + + typename DataNDC::indirect_iterator indirect = std::partition(data2.begin().indirection(), + data2.end().indirection(), + wrapped); + + bool is_equal = std::equal(data1.begin(), + data1.end(), + data2.begin()); + + CHECK(is_equal); + CHECK(*direct == **indirect); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_indirect_algorithm_void_binary_function) + { + struct functor + { + void operator()(const NDC& lhs, const NDC& rhs) + { + result += lhs.value; + result += rhs.value; + } + + std::string result; + }; + + typedef typename DataNDC::binary_function_adaptor wrapped_functor; + + functor unwrapped; + wrapped_functor wrapped(unwrapped); + + LookupNDC lookup1; + PoolNDC pool1; + + LookupNDC lookup2; + PoolNDC pool2; + + LookupNDC lookup3; + PoolNDC pool3; + + LookupNDC lookup4; + PoolNDC pool4; + + const DataNDC data1(ordered_data.begin(), ordered_data.end(), lookup1, pool1); + const DataNDC data2(ordered_data.begin(), ordered_data.end(), lookup2, pool2); + + DataNDC direct_data(lookup3, pool3); + DataNDC indirect_data(lookup4, pool4); + + test_algorithm(data1.begin(), + data1.end(), + data2.begin(), + unwrapped); + + test_algorithm(data1.begin().indirection(), + data1.end().indirection(), + data2.begin().indirection(), + wrapped); + + CHECK_EQUAL(unwrapped.result, wrapped.binary_function.result); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_indirect_algorithm_bool_binary_function) + { + LookupNDC lookup1; + PoolNDC pool1; + + DataNDC data(unordered_data.begin(), unordered_data.end(), lookup1, pool1); + + std::sort(data.begin().indirection(), + data.end().indirection(), + typename DataNDC::binary_function_adaptor, bool>(std::less())); bool is_equal = std::equal(data.begin(), data.end(), ordered_data.begin()); CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_order_from_unordered_std_stable_sort) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(unordered_data.begin(), unordered_data.end(), lookup, pool); - - std::stable_sort(data.begin(), data.end()); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_default_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_order_from_ordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(ordered_data.begin(), ordered_data.end(), lookup, pool); - - data.sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - ordered_data.begin()); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_order_from_reverse_ordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(ordered_data.rbegin(), ordered_data.rend(), lookup, pool); - - data.sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - ordered_data.begin()); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_order_from_unordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(unordered_data.begin(), unordered_data.end(), lookup, pool); - - data.sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - ordered_data.begin()); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_greater_order_from_reverse_ordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(ordered_data.rbegin(), ordered_data.rend(), lookup, pool); - - data.sort(std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - ordered_data.rbegin()); - - CHECK(is_equal); - CHECK(data.is_sorted(std::greater())); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_greater_order_from_unordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(unordered_data.begin(), unordered_data.end(), lookup, pool); - - data.sort(std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - ordered_data.rbegin()); - - CHECK(is_equal); - CHECK(data.is_sorted(std::greater())); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_default_partial_order_from_unordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(unordered_data.begin(), unordered_data.end(), lookup, pool); - - data.sort(data.begin() + 2, data.end() - 2); - - bool is_equal = std::equal(data.begin(), - data.end(), - part_ordered_data.begin()); - - CHECK(is_equal); - CHECK((data.is_sorted(data.cbegin() + 2, data.cend() - 2))); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_sort_greater_partial_order_from_unordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(unordered_data.begin(), unordered_data.end(), lookup, pool); - - data.sort(data.begin() + 2, data.end() - 2, std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - part_reverse_ordered_data.begin()); - - CHECK(is_equal); - CHECK((data.is_sorted(data.begin() + 2, data.end() - 2, std::greater()))); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_default_order_from_ordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(stable_default_ordered_data.begin(), stable_default_ordered_data.end(), lookup, pool); - - data.stable_sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_default_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_default_order_from_reverse_ordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(stable_default_ordered_data.rbegin(), stable_default_ordered_data.rend(), lookup, pool); - - data.stable_sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_reverse_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_default_order_from_unordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(unordered_data.begin(), unordered_data.end(), lookup, pool); - - data.stable_sort(); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_default_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted()); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_greater_order_from_reverse_ordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(stable_default_ordered_data.rbegin(), stable_default_ordered_data.rend(), lookup, pool); - - data.stable_sort(std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_greater_reverse_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted(std::greater())); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_greater_order_from_unordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(unordered_data.begin(), unordered_data.end(), lookup, pool); - - data.stable_sort(std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_greater_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK(data.is_sorted(std::greater())); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_default_partial_order_from_unordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(unordered_data.begin(), unordered_data.end(), lookup, pool); - - data.stable_sort(data.begin() + 2, data.end() - 2); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_part_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK((data.is_sorted(data.cbegin() + 2, data.cend() - 2))); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_stable_sort_greater_partial_order_from_unordered) - { - LookupNDC lookup; - PoolNDC pool; - - DataNDC data(unordered_data.begin(), unordered_data.end(), lookup, pool); - - data.stable_sort(data.begin() + 2, data.end() - 2, std::greater()); - - bool is_equal = std::equal(data.begin(), - data.end(), - stable_part_greater_ordered_data.begin(), - NDC::are_identical); - - CHECK(is_equal); - CHECK((data.is_sorted(data.begin() + 2, data.end() - 2, std::greater()))); } }; }