From 34cd4142804556221fae9012814466210f5eda94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 25 Jun 2022 20:29:16 +0200 Subject: [PATCH] Fixes #221 ("flat_set and friends should offer a const sequence_type& sequence() const method (...)") --- doc/container.qbk | 1 + include/boost/container/detail/flat_tree.hpp | 12 ++++----- include/boost/container/flat_map.hpp | 26 +++++++++++++++++--- include/boost/container/flat_set.hpp | 16 ++++++++++++ test/flat_map_test.cpp | 16 +++++++++--- test/flat_set_test.cpp | 16 +++++++++--- 6 files changed, 69 insertions(+), 18 deletions(-) diff --git a/doc/container.qbk b/doc/container.qbk index 067b555..3ad5063 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1341,6 +1341,7 @@ use [*Boost.Container]? There are several reasons for that: [section:release_notes_boost_1_80_00 Boost 1.80 Release] * Fixed bugs/issues: + * [@https://github.com/boostorg/container/issues/221 GitHub #221: ['"flat_set and friends should offer a const sequence_type& sequence() const method (...)"]]. * [@https://github.com/boostorg/container/pull/222 GitHub #222: ['"Fix incomplete type error when using list with pair"]]. * [@https://github.com/boostorg/container/issues/223 GitHub #223: ['"Possible copypaste typo"]]. diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp index 50d0768..bbc8958 100644 --- a/include/boost/container/detail/flat_tree.hpp +++ b/include/boost/container/detail/flat_tree.hpp @@ -1396,15 +1396,15 @@ class flat_tree BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE container_type extract_sequence() - { - return boost::move(m_data.m_seq); - } + { return boost::move(m_data.m_seq); } BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE container_type &get_sequence_ref() - { - return m_data.m_seq; - } + { return m_data.m_seq; } + + BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE + const container_type &get_sequence_cref() const + { return m_data.m_seq; } BOOST_CONTAINER_FORCEINLINE void adopt_sequence_equal(BOOST_RV_REF(container_type) seq) { diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp index 49e275d..0a85b9d 100644 --- a/include/boost/container/flat_map.hpp +++ b/include/boost/container/flat_map.hpp @@ -64,6 +64,10 @@ template BOOST_CONTAINER_FORCEINLINE static D &force(S &s) { return *move_detail::force_ptr(&s); } +template +BOOST_CONTAINER_FORCEINLINE static const D &force(const S &s) +{ return *move_detail::force_ptr(&s); } + template BOOST_CONTAINER_FORCEINLINE static D force_copy(const S &s) { @@ -104,7 +108,7 @@ BOOST_CONTAINER_FORCEINLINE static D force_copy(const S &s) //! - The allocator to allocate value_types (e.g. allocator< std::pair > ). //! (in this case sequence_type will be vector) //! - The SequenceContainer to be used as the underlying sequence_type. It must be a vector-like -//! sequence container with random-access iterators.. +//! sequence container with random-access iterators. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED template , class AllocatorOrContainer = new_allocator< std::pair< Key, T> > > #else @@ -1569,6 +1573,14 @@ class flat_map BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq) { this->m_flat_tree.adopt_sequence_unique(ordered_unique_range_t(), boost::move(dtl::force(seq))); } + //! Effects: Returns a const view of the underlying sequence. + //! + //! Complexity: Constant + //! + //! Throws: Nothing + BOOST_CONTAINER_FORCEINLINE const sequence_type & sequence() const BOOST_NOEXCEPT + { return dtl::force(m_flat_tree.get_sequence_cref()); } + //! Effects: Returns true if x and y are equal //! //! Complexity: Linear to the number of elements in the container. @@ -2887,9 +2899,7 @@ class flat_multimap //! Throws: If secuence_type's move constructor throws BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence() - { - return boost::move(dtl::force(m_flat_tree.get_sequence_ref())); - } + { return boost::move(dtl::force(m_flat_tree.get_sequence_ref())); } //! Effects: Discards the internally hold sequence container and adopts the //! one passed externally using the move assignment. @@ -2911,6 +2921,14 @@ class flat_multimap BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq) { this->m_flat_tree.adopt_sequence_equal(ordered_range_t(), boost::move(dtl::force(seq))); } + //! Effects: Returns a const view of the underlying sequence. + //! + //! Complexity: Constant + //! + //! Throws: Nothing + BOOST_CONTAINER_FORCEINLINE const sequence_type & sequence() const BOOST_NOEXCEPT + { return dtl::force(m_flat_tree.get_sequence_cref()); } + //! Effects: Returns true if x and y are equal //! //! Complexity: Linear to the number of elements in the container. diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp index 8d66f3e..6cbab2f 100644 --- a/include/boost/container/flat_set.hpp +++ b/include/boost/container/flat_set.hpp @@ -1122,6 +1122,14 @@ class flat_set //! Throws: If the move assignment throws BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq) { this->tree_t::adopt_sequence_unique(ordered_unique_range_t(), boost::move(seq)); } + + //! Effects: Returns a const view of the underlying sequence. + //! + //! Complexity: Constant + //! + //! Throws: Nothing + BOOST_CONTAINER_FORCEINLINE const sequence_type & sequence() const BOOST_NOEXCEPT + { return this->get_sequence_cref(); } }; #ifndef BOOST_CONTAINER_NO_CXX17_CTAD @@ -1845,6 +1853,14 @@ class flat_multiset //! Throws: If the move assignment throws BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq) { this->tree_t::adopt_sequence_equal(ordered_range_t(), boost::move(seq)); } + + //! Effects: Returns a const view of the underlying sequence. + //! + //! Complexity: Constant + //! + //! Throws: Nothing + BOOST_CONTAINER_FORCEINLINE const sequence_type & sequence() const BOOST_NOEXCEPT + { return this->get_sequence_cref(); } }; #ifndef BOOST_CONTAINER_NO_CXX17_CTAD diff --git a/test/flat_map_test.cpp b/test/flat_map_test.cpp index bb0f913..2dd17a1 100644 --- a/test/flat_map_test.cpp +++ b/test/flat_map_test.cpp @@ -306,7 +306,7 @@ bool flat_tree_extract_adopt_test() fmap.emplace(static_cast(i), -static_cast(i)); } - flat_map fmap_copy(fmap); + const flat_map fmap_copy(fmap); flat_map::sequence_type seq(fmap.extract_sequence()); if(!fmap.empty()) return false; @@ -318,6 +318,8 @@ bool flat_tree_extract_adopt_test() fmap.adopt_sequence(boost::move(seq)); if(!CheckEqualContainers(fmap, fmap_copy)) return false; + if (!CheckEqualContainers(fmap.sequence(), fmap_copy.sequence())) + return false; } //extract/adopt map, ordered_unique_range @@ -329,7 +331,7 @@ bool flat_tree_extract_adopt_test() fmap.emplace(static_cast(i), -static_cast(i)); } - flat_map fmap_copy(fmap); + const flat_map fmap_copy(fmap); flat_map::sequence_type seq(fmap.extract_sequence()); if(!fmap.empty()) return false; @@ -339,6 +341,8 @@ bool flat_tree_extract_adopt_test() fmap.adopt_sequence(ordered_unique_range, boost::move(seq)); if(!CheckEqualContainers(fmap, fmap_copy)) return false; + if (!CheckEqualContainers(fmap.sequence(), fmap_copy.sequence())) + return false; } //extract/adopt multimap @@ -351,7 +355,7 @@ bool flat_tree_extract_adopt_test() fmmap.emplace(static_cast(i), -static_cast(i)); } - flat_multimap fmmap_copy(fmmap); + const flat_multimap fmmap_copy(fmmap); flat_multimap::sequence_type seq(fmmap.extract_sequence()); if(!fmmap.empty()) return false; @@ -362,6 +366,8 @@ bool flat_tree_extract_adopt_test() fmmap.adopt_sequence(boost::move(seq)); if(!CheckEqualContainers(fmmap, fmmap_copy)) return false; + if (!CheckEqualContainers(fmmap.sequence(), fmmap_copy.sequence())) + return false; } //extract/adopt multimap, ordered_range @@ -374,7 +380,7 @@ bool flat_tree_extract_adopt_test() fmmap.emplace(static_cast(i), -static_cast(i)); } - flat_multimap fmmap_copy(fmmap); + const flat_multimap fmmap_copy(fmmap); flat_multimap::sequence_type seq(fmmap.extract_sequence()); if(!fmmap.empty()) return false; @@ -384,6 +390,8 @@ bool flat_tree_extract_adopt_test() fmmap.adopt_sequence(ordered_range, boost::move(seq)); if(!CheckEqualContainers(fmmap, fmmap_copy)) return false; + if (!CheckEqualContainers(fmmap.sequence(), fmmap_copy.sequence())) + return false; } return true; diff --git a/test/flat_set_test.cpp b/test/flat_set_test.cpp index 1326d17..00dfe07 100644 --- a/test/flat_set_test.cpp +++ b/test/flat_set_test.cpp @@ -404,7 +404,7 @@ bool flat_tree_extract_adopt_test() fset.insert(static_cast(i)); } - flat_set fset_copy(fset); + const flat_set fset_copy(fset); flat_set::sequence_type seq(fset.extract_sequence()); if(!fset.empty()) return false; @@ -416,6 +416,8 @@ bool flat_tree_extract_adopt_test() fset.adopt_sequence(boost::move(seq)); if(!CheckEqualContainers(fset, fset_copy)) return false; + if (!CheckEqualContainers(fset.sequence(), fset_copy.sequence())) + return false; } //extract/adopt set, ordered_unique_range @@ -427,7 +429,7 @@ bool flat_tree_extract_adopt_test() fset.insert(static_cast(i)); } - flat_set fset_copy(fset); + const flat_set fset_copy(fset); flat_set::sequence_type seq(fset.extract_sequence()); if(!fset.empty()) return false; @@ -437,6 +439,8 @@ bool flat_tree_extract_adopt_test() fset.adopt_sequence(ordered_unique_range, boost::move(seq)); if(!CheckEqualContainers(fset, fset_copy)) return false; + if (!CheckEqualContainers(fset.sequence(), fset_copy.sequence())) + return false; } //extract/adopt multiset @@ -449,7 +453,7 @@ bool flat_tree_extract_adopt_test() fmset.insert(static_cast(i)); } - flat_multiset fmset_copy(fmset); + const flat_multiset fmset_copy(fmset); flat_multiset::sequence_type seq(fmset.extract_sequence()); if(!fmset.empty()) return false; @@ -460,6 +464,8 @@ bool flat_tree_extract_adopt_test() fmset.adopt_sequence(boost::move(seq)); if(!CheckEqualContainers(fmset, fmset_copy)) return false; + if (!CheckEqualContainers(fmset.sequence(), fmset_copy.sequence())) + return false; } //extract/adopt multiset, ordered_range @@ -472,7 +478,7 @@ bool flat_tree_extract_adopt_test() fmset.insert(static_cast(i)); } - flat_multiset fmset_copy(fmset); + const flat_multiset fmset_copy(fmset); flat_multiset::sequence_type seq(fmset.extract_sequence()); if(!fmset.empty()) return false; @@ -482,6 +488,8 @@ bool flat_tree_extract_adopt_test() fmset.adopt_sequence(ordered_range, boost::move(seq)); if(!CheckEqualContainers(fmset, fmset_copy)) return false; + if (!CheckEqualContainers(fmset.sequence(), fmset_copy.sequence())) + return false; } return true;