mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
flat_set/map: workaround for gcc-4.8 C++11 defect
The STL shipped with gcc-4.8 does not provide vector::erase(const_iterator) for C++11, instead only taking a mutable iterator. This causes problems with flat_set/map if we don't have Boost small_vector available and we fall back to std::vector. We work around this by providing a function to construct a mutable iterator given a const_iterator for internal use.
This commit is contained in:
parent
87469d4775
commit
09f5699df7
@ -55,6 +55,9 @@ using small_vector = boost::container::small_vector<T, N, Allocator>;
|
||||
template <class T, std::size_t N, typename Allocator = std::allocator<T>>
|
||||
using small_vector = std::vector<T, Allocator>;
|
||||
|
||||
// Support workarounds for flat_set/flat_map and GCC 4.8.
|
||||
#define SMALL_VECTOR_IS_STL_VECTOR 1
|
||||
|
||||
#endif // HAVE_BOOST_CONTAINER_SMALL_VECTOR
|
||||
|
||||
} // namespace ue2
|
||||
|
@ -162,9 +162,19 @@ class flat_set
|
||||
public totally_ordered<flat_set<T, Compare, Allocator>> {
|
||||
using base_type = flat_detail::flat_base<T, Compare, Allocator>;
|
||||
using storage_type = typename base_type::storage_type;
|
||||
using storage_iterator = typename storage_type::iterator;
|
||||
using storage_const_iterator = typename storage_type::const_iterator;
|
||||
using base_type::data;
|
||||
using base_type::comp;
|
||||
|
||||
#if defined(SMALL_VECTOR_IS_STL_VECTOR)
|
||||
// Construct a non-const iterator from a const iterator. Used in flat_map
|
||||
// and flat_set erase() calls to work around g++-4.8 compatibility issues.
|
||||
storage_iterator mutable_iterator(storage_const_iterator it) {
|
||||
return data().begin() + std::distance(data().cbegin(), it);
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Member types.
|
||||
using key_type = T;
|
||||
@ -282,11 +292,27 @@ public:
|
||||
}
|
||||
|
||||
void erase(const_iterator pos) {
|
||||
data().erase(pos.get());
|
||||
#if defined(SMALL_VECTOR_IS_STL_VECTOR)
|
||||
// Cope with libstdc++ 4.8's incomplete STL (it's missing C++11
|
||||
// vector::erase(const_iterator)) by explicitly using a non-const
|
||||
// iterator.
|
||||
auto pos_it = mutable_iterator(pos.get());
|
||||
#else
|
||||
auto pos_it = pos.get();
|
||||
#endif
|
||||
data().erase(pos_it);
|
||||
}
|
||||
|
||||
void erase(const_iterator first, const_iterator last) {
|
||||
data().erase(first.get(), last.get());
|
||||
#if defined(SMALL_VECTOR_IS_STL_VECTOR)
|
||||
// As above, work around libstdc++ 4.8's incomplete C++11 support.
|
||||
auto first_it = mutable_iterator(first.get());
|
||||
auto last_it = mutable_iterator(last.get());
|
||||
#else
|
||||
auto first_it = first.get();
|
||||
auto last_it = last.get();
|
||||
#endif
|
||||
data().erase(first_it, last_it);
|
||||
}
|
||||
|
||||
void erase(const key_type &key) {
|
||||
@ -374,9 +400,19 @@ private:
|
||||
flat_detail::flat_base<std::pair<Key, T>, Compare, Allocator>;
|
||||
using keyval_storage_type = std::pair<key_type, mapped_type>;
|
||||
using storage_type = typename base_type::storage_type;
|
||||
using storage_iterator = typename storage_type::iterator;
|
||||
using storage_const_iterator = typename storage_type::const_iterator;
|
||||
using base_type::data;
|
||||
using base_type::comp;
|
||||
|
||||
#if defined(SMALL_VECTOR_IS_STL_VECTOR)
|
||||
// Construct a non-const iterator from a const iterator. Used in flat_map
|
||||
// and flat_set erase() calls to work around g++-4.8 compatibility issues.
|
||||
storage_iterator mutable_iterator(storage_const_iterator it) {
|
||||
return data().begin() + std::distance(data().cbegin(), it);
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
// More Member types.
|
||||
using size_type = typename storage_type::size_type;
|
||||
@ -444,9 +480,6 @@ public:
|
||||
const_reverse_iterator rend() const { return crend(); }
|
||||
|
||||
private:
|
||||
using storage_iterator = typename storage_type::iterator;
|
||||
using storage_const_iterator = typename storage_type::const_iterator;
|
||||
|
||||
storage_iterator data_lower_bound(const key_type &key) {
|
||||
return std::lower_bound(
|
||||
data().begin(), data().end(), key,
|
||||
@ -526,11 +559,27 @@ public:
|
||||
}
|
||||
|
||||
void erase(const_iterator pos) {
|
||||
data().erase(pos.get());
|
||||
#if defined(SMALL_VECTOR_IS_STL_VECTOR)
|
||||
// Cope with libstdc++ 4.8's incomplete STL (it's missing C++11
|
||||
// vector::erase(const_iterator)) by explicitly using a non-const
|
||||
// iterator.
|
||||
auto pos_it = mutable_iterator(pos.get());
|
||||
#else
|
||||
auto pos_it = pos.get();
|
||||
#endif
|
||||
data().erase(pos_it);
|
||||
}
|
||||
|
||||
void erase(const_iterator first, const_iterator last) {
|
||||
data().erase(first.get(), last.get());
|
||||
#if defined(SMALL_VECTOR_IS_STL_VECTOR)
|
||||
// As above, work around libstdc++ 4.8's incomplete C++11 support.
|
||||
auto first_it = mutable_iterator(first.get());
|
||||
auto last_it = mutable_iterator(last.get());
|
||||
#else
|
||||
auto first_it = first.get();
|
||||
auto last_it = last.get();
|
||||
#endif
|
||||
data().erase(first_it, last_it);
|
||||
}
|
||||
|
||||
void erase(const key_type &key) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user