From 419b1e9f09ba7d1c1bedb8238fcf4553450df948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 8 Sep 2024 00:47:43 +0200 Subject: [PATCH] Fix merge[_unique] handling of input iterators. It was not handled at compile time, leading to compilation errors. --- include/boost/container/vector.hpp | 62 +++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp index 0914176..b6fe317 100644 --- a/include/boost/container/vector.hpp +++ b/include/boost/container/vector.hpp @@ -2315,6 +2315,7 @@ private: return cp >= new_cap || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(size_type(new_cap - cp))); } + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //Absolutely experimental. This function might change, disappear or simply crash! template inline void insert_ordered_at(const size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it) @@ -2328,32 +2329,48 @@ private: { this->merge(first, last, value_less_t()); } template - inline void merge(InputIt first, InputIt last, Compare comp) + inline + typename dtl::enable_if_c + < !dtl::is_input_iterator::value && + dtl::is_same::value_type>::value + , void>::type + merge(InputIt first, InputIt last, Compare comp) { size_type const s = this->size(); size_type const c = this->capacity(); size_type n = 0; size_type const free_cap = c - s; //If not input iterator and new elements don't fit in the remaining capacity, merge in new buffer - if(!dtl::is_input_iterator::value && - free_cap < (n = boost::container::iterator_udistance(first, last))){ + if(free_cap < (n = boost::container::iterator_udistance(first, last))){ this->priv_merge_in_new_buffer(first, n, comp, alloc_version()); } else{ - this->insert(this->cend(), first, last); - T *const raw_beg = this->priv_raw_begin(); - T *const raw_end = this->priv_raw_end(); - T *const raw_pos = raw_beg + s; - boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, free_cap - n); + this->priv_merge_generic(first, last, comp); } } + template + inline + typename dtl::enable_if_c + < dtl::is_input_iterator::value || + !dtl::is_same::value_type>::value + , void>::type + merge(InputIt first, InputIt last, Compare comp) + { + this->priv_merge_generic(first, last, comp); + } + template inline void merge_unique(InputIt first, InputIt last) { this->merge_unique(first, last, value_less_t()); } template - inline void merge_unique(InputIt first, InputIt last, Compare comp) + inline + typename dtl::enable_if_c + < !dtl::is_input_iterator::value && + dtl::is_same::value_type>::value + , void>::type + merge_unique(InputIt first, InputIt last, Compare comp) { size_type const old_size = this->size(); this->priv_set_difference_back(first, last, comp); @@ -2363,7 +2380,34 @@ private: boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, this->capacity() - this->size()); } + template + inline + typename dtl::enable_if_c + < dtl::is_input_iterator::value || + !dtl::is_same::value_type>::value + , void>::type + merge_unique(InputIt first, InputIt last, Compare comp) + { + iterator pos = this->insert(this->end(), first, last); + const iterator e = boost::movelib::inplace_set_unique_difference(pos, this->end(), this->begin(), pos, comp); + this->erase(e, this->end()); + boost::movelib::adaptive_merge( this->begin(), pos, e, comp + , this->priv_raw_end(), this->capacity() - this->size()); + } + #endif + private: + template + inline void priv_merge_generic(InputIt first, InputIt last, Compare comp) + { + size_type const old_s = this->size(); + this->insert(this->cend(), first, last); + T* const raw_beg = this->priv_raw_begin(); + T* const raw_end = this->priv_raw_end(); + T* const raw_pos = raw_beg + old_s; + boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, this->capacity() - this->size()); + } + template void priv_insert_ordered_at(const size_type element_count, PositionValue position_value) {