mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Merge remote-tracking branch 'origin/feature/indirect_vector_algorithm_adaptor' into development
# Conflicts: # include/etl/indirect_vector.h
This commit is contained in:
parent
792cb7bcc8
commit
84cfab6b32
@ -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<T*>::iterator indirect_iterator;
|
||||
typedef typename etl::ivector<T*>::const_iterator indirect_const_iterator;
|
||||
|
||||
typedef typename etl::ivector<T*>::size_type size_type;
|
||||
typedef typename etl::ivector<T*>::difference_type difference_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Unary function adaptor.
|
||||
//*************************************************************************
|
||||
template <typename TUnaryFunction, typename TReturnType = void>
|
||||
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 <typename TUnaryFunction>
|
||||
class unary_function_adaptor<TUnaryFunction, void>
|
||||
{
|
||||
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 <typename TBinaryFunction, typename TReturnType = void>
|
||||
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 <typename TBinaryFunction>
|
||||
class binary_function_adaptor<TBinaryFunction, void>
|
||||
{
|
||||
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<T*>::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<T*>::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<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<T>());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Sorts the indirect vector using a supplied compare function.
|
||||
//*************************************************************************
|
||||
template <typename TCompare>
|
||||
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<T>());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Sorts the indirect vector between two iterators.
|
||||
//*************************************************************************
|
||||
template <typename TCompare>
|
||||
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<T>());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Sorts the indirect vector using a supplied compare function.
|
||||
//*************************************************************************
|
||||
template <typename TCompare>
|
||||
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<T>());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Sorts the indirect vector between two iterators.
|
||||
//*************************************************************************
|
||||
template <typename TCompare>
|
||||
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<T>());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Sorts the indirect vector using a supplied compare function.
|
||||
//*************************************************************************
|
||||
template <typename TCompare>
|
||||
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<T>());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Sorts the indirect vector between two iterators.
|
||||
//*************************************************************************
|
||||
template <typename TCompare>
|
||||
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 <typename TCompare>
|
||||
void sort_function(iterator first, iterator last, TCompare compare)
|
||||
{
|
||||
etl::sort(first.lookup_itr, last.lookup_itr, ObjectCompare<TCompare>(compare));
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Sorts the range.
|
||||
/// Stable
|
||||
//*********************************************************************
|
||||
template <typename TCompare>
|
||||
void stable_sort_function(iterator first, iterator last, TCompare compare)
|
||||
{
|
||||
etl::stable_sort(first.lookup_itr, last.lookup_itr, ObjectCompare<TCompare>(compare));
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Checks if the range is sorted.
|
||||
//*********************************************************************
|
||||
template <typename TCompare>
|
||||
bool is_sorted_function(const_iterator first, const_iterator last, TCompare compare) const
|
||||
{
|
||||
return etl::is_sorted(first.lookup_itr, last.lookup_itr, ObjectCompare<TCompare>(compare));
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// How to compare two objects via the lookup iterators.
|
||||
/// \tparam TCompare Type to compare two T objects.
|
||||
//*********************************************************************
|
||||
template <typename TCompare>
|
||||
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;
|
||||
|
||||
|
||||
@ -72,6 +72,15 @@ namespace
|
||||
CompareDataNDC stable_part_ordered_data;
|
||||
CompareDataNDC stable_part_greater_ordered_data;
|
||||
|
||||
template <typename TIterator, typename TFunctor>
|
||||
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<functor> 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<functor, bool> 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<functor> 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<std::less<NDC>, bool>(std::less<NDC>()));
|
||||
|
||||
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<NDC>());
|
||||
|
||||
bool is_equal = std::equal(data.begin(),
|
||||
data.end(),
|
||||
ordered_data.rbegin());
|
||||
|
||||
CHECK(is_equal);
|
||||
CHECK(data.is_sorted(std::greater<NDC>()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_sort_greater_order_from_unordered)
|
||||
{
|
||||
DataNDC data(unordered_data.begin(), unordered_data.end());
|
||||
|
||||
data.sort(std::greater<NDC>());
|
||||
|
||||
bool is_equal = std::equal(data.begin(),
|
||||
data.end(),
|
||||
ordered_data.rbegin());
|
||||
|
||||
CHECK(is_equal);
|
||||
CHECK(data.is_sorted(std::greater<NDC>()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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<NDC>());
|
||||
|
||||
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<NDC>())));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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<NDC>());
|
||||
|
||||
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<NDC>()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_stable_sort_greater_order_from_unordered)
|
||||
{
|
||||
DataNDC data(unordered_data.begin(), unordered_data.end());
|
||||
|
||||
data.stable_sort(std::greater<NDC>());
|
||||
|
||||
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<NDC>()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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<NDC>());
|
||||
|
||||
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<NDC>())));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -88,6 +88,15 @@ namespace
|
||||
CompareDataNDC stable_part_ordered_data;
|
||||
CompareDataNDC stable_part_greater_ordered_data;
|
||||
|
||||
template <typename TIterator, typename TFunctor>
|
||||
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<functor> 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<functor, bool> 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<functor> 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<std::less<NDC>, bool>(std::less<NDC>()));
|
||||
|
||||
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<NDC>());
|
||||
|
||||
bool is_equal = std::equal(data.begin(),
|
||||
data.end(),
|
||||
ordered_data.rbegin());
|
||||
|
||||
CHECK(is_equal);
|
||||
CHECK(data.is_sorted(std::greater<NDC>()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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<NDC>());
|
||||
|
||||
bool is_equal = std::equal(data.begin(),
|
||||
data.end(),
|
||||
ordered_data.rbegin());
|
||||
|
||||
CHECK(is_equal);
|
||||
CHECK(data.is_sorted(std::greater<NDC>()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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<NDC>());
|
||||
|
||||
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<NDC>())));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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<NDC>());
|
||||
|
||||
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<NDC>()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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<NDC>());
|
||||
|
||||
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<NDC>()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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<NDC>());
|
||||
|
||||
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<NDC>())));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user