diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp index 73f990e..a1de8ab 100644 --- a/include/boost/container/detail/flat_tree.hpp +++ b/include/boost/container/detail/flat_tree.hpp @@ -121,6 +121,7 @@ namespace boost { namespace container { namespace dtl { + /////////////////////////////////////// // // Helper functions to merge elements @@ -138,14 +139,19 @@ template inline void flat_tree_container_inplace_merge //is_contiguous_container == true (SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp , dtl::true_) { - typedef typename SequenceContainer::value_type value_type; + typedef typename SequenceContainer::value_type value_type; + typedef typename SequenceContainer::size_type size_type; + value_type *const braw = boost::movelib::to_raw_pointer(dest.data()); value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it); //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(); + size_type dest_unused_storage_size = 0; + value_type *const dest_unused_storage_addr = + unused_storage::get(dest, dest_unused_storage_size); boost::movelib::adaptive_merge - (braw, iraw, eraw, comp, eraw, back_free_capacity::get(dest)); + (braw, iraw, eraw, comp, dest_unused_storage_addr, dest_unused_storage_size); } template @@ -164,15 +170,19 @@ template inline void flat_tree_container_inplace_sort_ending //is_contiguous_container == true (SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp, dtl::true_) { - typedef typename SequenceContainer::value_type value_type; + typedef typename SequenceContainer::value_type value_type; + typedef typename SequenceContainer::size_type size_type; + value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it); //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(); - + size_type dest_unused_storage_size; + value_type* const dest_unused_storage_addr = + unused_storage::get(dest, dest_unused_storage_size); boost::movelib::adaptive_sort - (iraw, eraw, comp, eraw, back_free_capacity::get(dest)); + (iraw, eraw, comp, dest_unused_storage_addr, dest_unused_storage_size); } template @@ -320,23 +330,24 @@ template void flat_tree_sort_contiguous_to_adopt // is_contiguous_container == true (SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp) { - if(tseq.capacity() >= (seq.capacity() - seq.size())) { - tseq.clear(); - boost::movelib::adaptive_sort - (boost::movelib::iterator_to_raw_pointer(seq.begin()) - , boost::movelib::iterator_to_raw_pointer(seq.end()) - , comp - , boost::movelib::iterator_to_raw_pointer(tseq.begin()) - , tseq.capacity()); - } - else{ - boost::movelib::adaptive_sort - (boost::movelib::iterator_to_raw_pointer(seq.begin()) - , boost::movelib::iterator_to_raw_pointer(seq.end()) - , comp - , boost::movelib::iterator_to_raw_pointer(seq.end()) - , seq.capacity() - seq.size()); - } + typedef typename SequenceContainer::value_type value_type; + typedef typename SequenceContainer::size_type size_type; + + size_type tseq_unused_storage_size, seq_unused_storage_size; + value_type* const tseq_unused_storage_addr = + unused_storage::get(tseq, tseq_unused_storage_size); + value_type* const seq_unused_storage_addr = + unused_storage::get(seq, seq_unused_storage_size); + + tseq.clear(); + const bool use_tseq_storage = tseq_unused_storage_size > seq_unused_storage_size; + + boost::movelib::adaptive_sort + ( boost::movelib::iterator_to_raw_pointer(seq.begin()) + , boost::movelib::iterator_to_raw_pointer(seq.end()) + , comp + , use_tseq_storage ? tseq_unused_storage_addr : seq_unused_storage_addr + , use_tseq_storage ? tseq_unused_storage_size : seq_unused_storage_size); } template diff --git a/include/boost/container/detail/is_contiguous_container.hpp b/include/boost/container/detail/is_contiguous_container.hpp index 2688f80..e0cf6ba 100644 --- a/include/boost/container/detail/is_contiguous_container.hpp +++ b/include/boost/container/detail/is_contiguous_container.hpp @@ -31,9 +31,9 @@ #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0 #include -//back_free_capacity -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME back_free_capacity -#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace back_free_capacity_detail { +//free_storage +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME unused_storage +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace unused_storage_detail { #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0 @@ -60,19 +60,23 @@ struct is_contiguous_container template < class Container - , bool = boost::container::back_free_capacity_detail:: - has_member_function_callable_with_back_free_capacity::value> -struct back_free_capacity + , bool = boost::container::unused_storage_detail:: + has_member_function_callable_with_unused_storage::value> +struct unused_storage { - static typename Container::size_type get(const Container &c) - { return c.back_free_capacity(); } + static typename Container::value_type* get(Container &c, typename Container::size_type &s) + { return c.unused_storage(s); } }; + template < class Container> -struct back_free_capacity +struct unused_storage { - static typename Container::size_type get(const Container &c) - { return c.capacity() - c.size(); } + static typename Container::value_type* get(Container&, typename Container::size_type &s) + { + s = 0; + return 0; + } }; } //namespace dtl {