Fixes #9931 ("flat_map::insert(ordered_unique_range_t...) fails with move_iterators")

This commit is contained in:
Ion Gaztañaga
2014-04-21 21:23:24 +02:00
parent 0b720f82b4
commit 5013f3fd69
2 changed files with 15 additions and 10 deletions

View File

@@ -965,6 +965,7 @@ use [*Boost.Container]? There are several reasons for that:
* [@https://svn.boost.org/trac/boost/ticket/9648 #9648: ['"string construction optimization - char_traits::copy could be used ..."]]. * [@https://svn.boost.org/trac/boost/ticket/9648 #9648: ['"string construction optimization - char_traits::copy could be used ..."]].
* [@https://svn.boost.org/trac/boost/ticket/9915 #9915: ['"Documentation issues regarding vector constructors and resize methods - value/default initialization"]]. * [@https://svn.boost.org/trac/boost/ticket/9915 #9915: ['"Documentation issues regarding vector constructors and resize methods - value/default initialization"]].
* [@https://svn.boost.org/trac/boost/ticket/9916 #9916: ['"Allocator propagation incorrect in the assignment operator of most"]]. * [@https://svn.boost.org/trac/boost/ticket/9916 #9916: ['"Allocator propagation incorrect in the assignment operator of most"]].
* [@https://svn.boost.org/trac/boost/ticket/9931 #9931: ['"flat_map::insert(ordered_unique_range_t...) fails with move_iterators"]].
* [@https://svn.boost.org/trac/boost/ticket/9932 #9932: ['"Missing assignment operator from related static_vector"]]. * [@https://svn.boost.org/trac/boost/ticket/9932 #9932: ['"Missing assignment operator from related static_vector"]].
[endsect] [endsect]

View File

@@ -481,14 +481,17 @@ class flat_tree
const const_iterator ce(this->cend()); const const_iterator ce(this->cend());
len -= burst; len -= burst;
for(size_type i = 0; i != burst; ++i){ for(size_type i = 0; i != burst; ++i){
//Get the insertion position for each key //Get the insertion position for each key, use std::iterator_traits<BidirIt>::value_type
pos = const_cast<const flat_tree&>(*this).priv_upper_bound(pos, ce, KeyOfValue()(*first)); //because it can be different from container::value_type
//(e.g. conversion between std::pair<A, B> -> boost::container::pair<A, B>
const typename std::iterator_traits<BidirIt>::value_type & val = *first;
pos = const_cast<const flat_tree&>(*this).priv_upper_bound(pos, ce, KeyOfValue()(val));
positions[i] = static_cast<size_type>(pos - b); positions[i] = static_cast<size_type>(pos - b);
++first; ++first;
} }
//Insert all in a single step in the precalculated positions //Insert all in a single step in the precalculated positions
this->m_data.m_vect.insert_ordered_at(burst, positions + burst, first); this->m_data.m_vect.insert_ordered_at(burst, positions + burst, first);
//Next search position updated //Next search position updated, iterator still valid because we've preserved the vector
pos += burst; pos += burst;
} }
} }
@@ -537,15 +540,16 @@ class flat_tree
size_type unique_burst = 0u; size_type unique_burst = 0u;
const const_iterator ce(this->cend()); const const_iterator ce(this->cend());
while(unique_burst < burst && len > 0){ while(unique_burst < burst && len > 0){
//Get the insertion position for each key //Get the insertion position for each key, use std::iterator_traits<BidirIt>::value_type
const value_type & val = *first++; //because it can be different from container::value_type
//(e.g. conversion between std::pair<A, B> -> boost::container::pair<A, B>
const typename std::iterator_traits<BidirIt>::value_type & val = *first;
++first;
--len; --len;
pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val)); pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
//Check if already present //Check if already present
if(pos != ce && !val_cmp(val, *pos)){ if (pos != ce && !val_cmp(val, *pos)){
if(unique_burst > 0){ skips[unique_burst-1] += static_cast<size_type>(unique_burst > 0);
++skips[unique_burst-1];
}
continue; continue;
} }
@@ -556,7 +560,7 @@ class flat_tree
if(unique_burst){ if(unique_burst){
//Insert all in a single step in the precalculated positions //Insert all in a single step in the precalculated positions
this->m_data.m_vect.insert_ordered_at(unique_burst, positions + unique_burst, skips + unique_burst, first); this->m_data.m_vect.insert_ordered_at(unique_burst, positions + unique_burst, skips + unique_burst, first);
//Next search position updated //Next search position updated, iterator still valid because we've preserved the vector
pos += unique_burst; pos += unique_burst;
} }
} }