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/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/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"]].
[endsect]

View File

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