diff --git a/lib/coveo/linq/detail/linq_detail.h b/lib/coveo/linq/detail/linq_detail.h index 0132332..da8062f 100644 --- a/lib/coveo/linq/detail/linq_detail.h +++ b/lib/coveo/linq/detail/linq_detail.h @@ -1967,13 +1967,13 @@ class order_by_impl_with_seq template friend class order_by_impl; private: - Seq seq_; // Sequence we're ordering. - std::unique_ptr upcmp_; // Comparator used to order a sequence. - coveo::enumerable::const_value_type> enum_; // Enumerator of ordered elements. - bool init_flag_; // Whether enum_ and size_ have been initialized. + Seq seq_; // Sequence we're ordering. + std::unique_ptr upcmp_; // Comparator used to order a sequence. + mutable coveo::enumerable::const_value_type> enum_; // Enumerator of ordered elements. + mutable bool init_flag_; // Whether enum_ and size_ have been initialized. // Called to initialize enum_ and size_ before using them. - void init() { + void init() const { std::vector::raw_value_type> ordered; try_reserve(ordered, seq_); ordered.insert(ordered.end(), std::begin(seq_), std::end(seq_)); @@ -1988,8 +1988,9 @@ class order_by_impl_with_seq } public: - // Type of iterator used for the ordered sequence. - typedef typename coveo::enumerable::const_value_type>::iterator iterator; + // Type of iterators used for the ordered sequence. + typedef typename coveo::enumerable::const_value_type>::iterator iterator; + typedef typename coveo::enumerable::const_value_type>::const_iterator const_iterator; // Constructor called by the impl without sequence. order_by_impl_with_seq(Seq&& seq, std::unique_ptr&& upcmp) @@ -2002,13 +2003,13 @@ class order_by_impl_with_seq order_by_impl_with_seq& operator=(order_by_impl_with_seq&&) = default; // Support for ordered sequence. - iterator begin() { + iterator begin() const { if (!init_flag_) { init(); } return enum_.begin(); } - iterator end() { + iterator end() const { if (!init_flag_) { init(); } @@ -2016,13 +2017,13 @@ class order_by_impl_with_seq } // Support for sequence size (a bit like the enumerable API) - bool has_fast_size() { + bool has_fast_size() const { if (!init_flag_) { init(); } return enum_.has_fast_size(); } - std::size_t size() { + std::size_t size() const { if (!init_flag_) { init(); } diff --git a/tests/coveo/linq/all_tests.cpp b/tests/coveo/linq/all_tests.cpp index 3dd8f1b..706de45 100644 --- a/tests/coveo/linq/all_tests.cpp +++ b/tests/coveo/linq/all_tests.cpp @@ -20,6 +20,7 @@ void all_tests() linq_tests(); chaining_tests(); dangling_ref_tests(); + bugs_tests(); } // Runs all benchmarks for coveo::enumerable and coveo::linq diff --git a/tests/coveo/linq/linq_tests.cpp b/tests/coveo/linq/linq_tests.cpp index 1d5d058..862c7af 100644 --- a/tests/coveo/linq/linq_tests.cpp +++ b/tests/coveo/linq/linq_tests.cpp @@ -1712,6 +1712,23 @@ void dangling_ref_tests() } } +// Runs tests for specific bugs +void bugs_tests() +{ + using namespace coveo::linq; + + // sequence_equal used not to work with the product of order_by + { + const std::vector v = { 42, 23, 66 }; + auto e1 = from(v) + | order_by([](int i) { return i; }); + auto e2 = from(v) + | order_by([](int i) { return i; }); + COVEO_ASSERT(from(e1) + | sequence_equal(e2)); + } +} + // Runs all benchmarks for coveo::linq operators void linq_benchmarks() { diff --git a/tests/coveo/linq/linq_tests.h b/tests/coveo/linq/linq_tests.h index dbbc5e0..24351a6 100644 --- a/tests/coveo/linq/linq_tests.h +++ b/tests/coveo/linq/linq_tests.h @@ -10,6 +10,7 @@ namespace linq { void linq_tests(); void chaining_tests(); void dangling_ref_tests(); +void bugs_tests(); void linq_benchmarks();