diff --git a/doc/container.qbk b/doc/container.qbk index 7b571dd..ff6de42 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1413,14 +1413,9 @@ use [*Boost.Container]? There are several reasons for that: * Fixed bugs/issues: * [@https://github.com/boostorg/container/issues/232 GitHub #232: ['"Fix using pmr::polymorphic_allocator in pre-main"]]. - * [@https://github.com/boostorg/container/issues/236 GitHub #236: ['"flat_tree::erase_unique uses wrong iterator"]]. - -[endsect] - -[section:release_notes_boost_1_82_00 Boost 1.82 Release] - -* Fixed bugs/issues: * [@https://github.com/boostorg/container/issues/238 GitHub #238: ['"Containers should not be using memset to value-initialize POD types"]]. + * [@https://github.com/boostorg/container/issues/236 GitHub #236: ['"flat_tree::erase_unique uses wrong iterator"]]. + * [@https://github.com/boostorg/container/issues/240 GitHub #240: ['"_GLIBCXX_DEBUG detects issues in flat_set/map"]]. [endsect] diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp index 3c20b56..91b11bc 100644 --- a/include/boost/container/detail/flat_tree.hpp +++ b/include/boost/container/detail/flat_tree.hpp @@ -139,9 +139,11 @@ BOOST_CONTAINER_FORCEINLINE void flat_tree_container_inplace_merge //is_contiguo (SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp , dtl::true_) { typedef typename SequenceContainer::value_type value_type; - value_type *const braw = boost::movelib::iterator_to_raw_pointer(dest.begin()); + value_type *const braw = boost::movelib::to_raw_pointer(dest.data()); value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it); - value_type *const eraw = boost::movelib::iterator_to_raw_pointer(dest.end()); + //Don't use iterator_to_raw_pointer for end as debug iterators can assert when + //"operator ->" is used with the end iterator + value_type *const eraw = braw + dest.size(); boost::movelib::adaptive_merge (braw, iraw, eraw, comp, eraw, back_free_capacity::get(dest)); } @@ -164,7 +166,11 @@ BOOST_CONTAINER_FORCEINLINE void flat_tree_container_inplace_sort_ending //is_co { typedef typename SequenceContainer::value_type value_type; value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it); - value_type *const eraw = boost::movelib::iterator_to_raw_pointer(dest.end()); + //Don't use iterator_to_raw_pointer for end as debug iterators can assert when + //"operator ->" is used with the end iterator + value_type* const eraw = boost::movelib::to_raw_pointer(dest.data()) + dest.size(); + + boost::movelib::adaptive_sort (iraw, eraw, comp, eraw, back_free_capacity::get(dest)); } @@ -192,10 +198,12 @@ template BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal //has_merge_unique == false (SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::false_) { - typedef typename SequenceContainer::iterator iterator; - iterator const it = dest.insert( dest.end(), first, last ); - dtl::bool_::value> contiguous_tag; - (flat_tree_container_inplace_merge)(dest, it, comp, contiguous_tag); + if(first != last) { + typedef typename SequenceContainer::iterator iterator; + iterator const it = dest.insert( dest.end(), first, last ); + dtl::bool_::value> contiguous_tag; + (flat_tree_container_inplace_merge)(dest, it, comp, contiguous_tag); + } } /////////////////////////////////////// @@ -214,16 +222,18 @@ template BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique //has_merge_unique == false (SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::false_) { - typedef typename SequenceContainer::iterator iterator; - typedef typename SequenceContainer::size_type size_type; - typedef typename SequenceContainer::difference_type difference_type; + if (first != last) { + typedef typename SequenceContainer::iterator iterator; + typedef typename SequenceContainer::size_type size_type; + typedef typename SequenceContainer::difference_type difference_type; - size_type const old_sz = dest.size(); - iterator const first_new = dest.insert(dest.cend(), first, last ); - iterator e = boost::movelib::inplace_set_unique_difference(first_new, dest.end(), dest.begin(), first_new, comp); - dest.erase(e, dest.end()); - dtl::bool_::value> contiguous_tag; - (flat_tree_container_inplace_merge)(dest, dest.begin() + difference_type(old_sz), comp, contiguous_tag); + size_type const old_sz = dest.size(); + iterator const first_new = dest.insert(dest.cend(), first, last ); + iterator e = boost::movelib::inplace_set_unique_difference(first_new, dest.end(), dest.begin(), first_new, comp); + dest.erase(e, dest.end()); + dtl::bool_::value> contiguous_tag; + (flat_tree_container_inplace_merge)(dest, dest.begin() + difference_type(old_sz), comp, contiguous_tag); + } } /////////////////////////////////////// @@ -931,11 +941,13 @@ class flat_tree template void insert_equal(InIt first, InIt last) { - dtl::bool_::value> contiguous_tag; - container_type &seq = this->m_data.m_seq; - typename container_type::iterator const it = seq.insert(seq.cend(), first, last); - (flat_tree_container_inplace_sort_ending)(seq, it, this->priv_value_comp(), contiguous_tag); - (flat_tree_container_inplace_merge) (seq, it, this->priv_value_comp(), contiguous_tag); + if (first != last) { + dtl::bool_::value> contiguous_tag; + container_type &seq = this->m_data.m_seq; + typename container_type::iterator const it = seq.insert(seq.cend(), first, last); + (flat_tree_container_inplace_sort_ending)(seq, it, this->priv_value_comp(), contiguous_tag); + (flat_tree_container_inplace_merge) (seq, it, this->priv_value_comp(), contiguous_tag); + } } //Ordered