mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 14:04:26 +02:00
Modify flat associative containers to be adaptors if the allocator argument is a container. This allows using stable_vector, small_vector, static_vector as underlying containers.
This commit is contained in:
@@ -426,11 +426,10 @@ functions), implemented on top of std::vector. AssocVector differs from a map in
|
||||
its erase functions (AssocVector::erase invalidates all iterators into the object) and in the
|
||||
complexity guarantees of insert and erase (linear as opposed to constant). ]]
|
||||
|
||||
[*Boost.Container] `flat_[multi]map/set` containers are ordered-vector based associative containers
|
||||
based on Austern's and Alexandrescu's guidelines. These ordered vector containers have also
|
||||
benefited recently with the addition of `move semantics` to C++, speeding up insertion
|
||||
and erasure times considerably. Flat associative containers have the following
|
||||
attributes:
|
||||
[*Boost.Container] `flat_[multi]map/set` containers are ordered, vector-like container based, associative
|
||||
containers following Austern's and Alexandrescu's guidelines. These ordered vector containers have also
|
||||
benefited with the addition of `move semantics` to C++11, speeding up insertion and
|
||||
erasure times considerably. Flat associative containers have the following attributes:
|
||||
|
||||
* Faster lookup than standard associative containers
|
||||
* Much faster iteration than standard associative containers.
|
||||
@@ -1213,6 +1212,14 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
|
||||
[section:release_notes Release Notes]
|
||||
|
||||
[section:release_notes_boost_1_66_00 Boost 1.66 Release]
|
||||
|
||||
* ['flat_[multi]map/set] can now work as container adaptors, as proposed in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0429r1.pdf P0429R1].
|
||||
The allocator argument is checked for ['size()] and ['empty()] members. If so, the argument is interpreted as the required underlying container.
|
||||
This means that ['static_vector], ['stable_vector] and ['small_vector] can be used now with flat associative containers.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:release_notes_boost_1_65_00 Boost 1.65 Release]
|
||||
|
||||
* Implemented `extract_sequence`, `adopt_sequence` functions for flat_[multi]map/set associative containers.
|
||||
@@ -1246,7 +1253,6 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
|
||||
[endsect]
|
||||
|
||||
https://svn.boost.org/trac/boost/ticket/12577#comment:1
|
||||
[section:release_notes_boost_1_62_00 Boost 1.62 Release]
|
||||
|
||||
* Fixed bugs:
|
||||
|
@@ -163,7 +163,7 @@ struct insert_copy_proxy
|
||||
void copy_n_and_update(Allocator &, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
*p =v_;
|
||||
*p = v_;
|
||||
}
|
||||
|
||||
const value_type &v_;
|
||||
|
@@ -270,12 +270,12 @@ class scoped_destructor
|
||||
};
|
||||
|
||||
|
||||
template<class Allocator>
|
||||
template<class Allocator, class Value = typename Allocator::value_type>
|
||||
class value_destructor
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
||||
public:
|
||||
typedef typename Allocator::value_type value_type;
|
||||
typedef Value value_type;
|
||||
value_destructor(Allocator &a, value_type &rv)
|
||||
: rv_(rv), a_(a)
|
||||
{}
|
||||
|
@@ -37,10 +37,10 @@
|
||||
#include <boost/container/detail/is_sorted.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/is_contiguous_container.hpp>
|
||||
#include <boost/container/detail/is_container.hpp>
|
||||
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#endif
|
||||
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
|
||||
|
||||
#include <boost/move/make_unique.hpp>
|
||||
@@ -52,11 +52,152 @@
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//merge_unique
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME merge_unique
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 3
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 3
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
//merge_equal
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME merge
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 3
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 3
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
//index_of
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME index_of
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
//nth
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME nth
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
|
||||
template<class SequenceContainer, class Iterator, class Compare>
|
||||
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal
|
||||
(SequenceContainer& dest, Iterator begin, Iterator end, Compare comp, container_detail::false_)
|
||||
{
|
||||
typedef typename SequenceContainer::iterator iterator;
|
||||
typedef typename SequenceContainer::value_type value_type;
|
||||
|
||||
iterator it = dest.insert( dest.end(), boost::make_move_iterator(begin), boost::make_move_iterator(end) );
|
||||
|
||||
if (is_contiguous_container<SequenceContainer>::value){
|
||||
value_type *const braw = boost::movelib::iterator_to_raw_pointer(dest.begin());
|
||||
value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
|
||||
value_type *const eraw = boost::movelib::iterator_to_raw_pointer(dest.end());
|
||||
value_type *const sraw = boost::movelib::iterator_to_raw_pointer(dest.begin()+dest.size());
|
||||
boost::movelib::adaptive_sort(iraw, eraw, comp, sraw, dest.capacity());
|
||||
boost::movelib::adaptive_merge(braw, iraw, eraw, comp, sraw, dest.capacity()- dest.size());
|
||||
}
|
||||
else{
|
||||
boost::movelib::adaptive_sort(it, dest.end(), comp);
|
||||
boost::movelib::adaptive_merge(dest.begin(), it, dest.end(), comp);
|
||||
}
|
||||
}
|
||||
|
||||
template<class SequenceContainer, class Iterator, class Compare>
|
||||
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique
|
||||
(SequenceContainer& dest, Iterator begin, Iterator end, Compare comp, container_detail::false_)
|
||||
{
|
||||
(flat_tree_merge_equal)(dest, begin, end, comp, container_detail::false_());
|
||||
dest.erase(boost::movelib::unique
|
||||
(dest.begin(), dest.end(), boost::movelib::negate<Compare>(comp)), dest.cend());
|
||||
}
|
||||
|
||||
template<class SequenceContainer, class Iterator, class Compare>
|
||||
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal
|
||||
(SequenceContainer& dest, Iterator begin, Iterator end, Compare comp, container_detail::true_)
|
||||
{
|
||||
dest.merge(begin, end, comp);
|
||||
}
|
||||
|
||||
template<class SequenceContainer, class Iterator, class Compare>
|
||||
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique
|
||||
(SequenceContainer& dest, Iterator begin, Iterator end, Compare comp, container_detail::true_)
|
||||
{
|
||||
dest.merge_unique(begin, end, comp);
|
||||
}
|
||||
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(stored_allocator_type)
|
||||
|
||||
template<class SequenceContainer, class Iterator>
|
||||
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
|
||||
flat_tree_index_of
|
||||
(SequenceContainer& cont, Iterator p, container_detail::true_)
|
||||
{
|
||||
return cont.index_of(p);
|
||||
}
|
||||
|
||||
template<class SequenceContainer, class Iterator>
|
||||
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
|
||||
flat_tree_index_of
|
||||
(SequenceContainer& cont, Iterator p, container_detail::false_)
|
||||
{
|
||||
typedef typename SequenceContainer::size_type size_type;
|
||||
return static_cast<size_type>(p - cont.begin());
|
||||
}
|
||||
|
||||
template<class Iterator, class SequenceContainer>
|
||||
BOOST_CONTAINER_FORCEINLINE Iterator
|
||||
flat_tree_nth
|
||||
(SequenceContainer& cont, typename SequenceContainer::size_type n, container_detail::true_)
|
||||
{
|
||||
return cont.nth(n);
|
||||
}
|
||||
|
||||
template<class Iterator, class SequenceContainer>
|
||||
BOOST_CONTAINER_FORCEINLINE Iterator
|
||||
flat_tree_nth
|
||||
(SequenceContainer& cont, typename SequenceContainer::size_type n, container_detail::false_)
|
||||
{
|
||||
return cont.begin()+ n;
|
||||
}
|
||||
|
||||
template<class SequenceContainer>
|
||||
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::stored_allocator_type &
|
||||
flat_tree_get_stored_allocator
|
||||
(SequenceContainer& cont, container_detail::true_)
|
||||
{
|
||||
return cont.get_stored_allocator();
|
||||
}
|
||||
|
||||
template<class SequenceContainer>
|
||||
BOOST_CONTAINER_FORCEINLINE const typename SequenceContainer::stored_allocator_type &
|
||||
flat_tree_get_stored_allocator
|
||||
(const SequenceContainer& cont, container_detail::true_)
|
||||
{
|
||||
return cont.get_stored_allocator();
|
||||
}
|
||||
|
||||
template<class SequenceContainer>
|
||||
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::allocator_type
|
||||
flat_tree_get_stored_allocator
|
||||
(SequenceContainer& cont, container_detail::false_)
|
||||
{
|
||||
return cont.get_allocator();
|
||||
}
|
||||
|
||||
template<class Compare, class Value, class KeyOfValue>
|
||||
class flat_tree_value_compare
|
||||
: private Compare
|
||||
@@ -85,37 +226,43 @@ class flat_tree_value_compare
|
||||
Compare &get_comp()
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
/*
|
||||
template<class Pointer>
|
||||
struct get_flat_tree_iterators
|
||||
{
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
|
||||
typedef Pointer iterator;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<Pointer>::element_type iterator_element_type;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<Pointer>:: template
|
||||
rebind_pointer<const iterator_element_type>::type const_iterator;
|
||||
#else //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
|
||||
typedef typename boost::container::container_detail::
|
||||
vec_iterator<Pointer, false> iterator;
|
||||
typedef typename boost::container::container_detail::
|
||||
vec_iterator<Pointer, true > const_iterator;
|
||||
#endif //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
|
||||
typedef boost::container::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef boost::container::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
};
|
||||
*/
|
||||
|
||||
template < class Value, class AllocatorOrContainer
|
||||
, bool = boost::container::container_detail::is_container<AllocatorOrContainer>::value >
|
||||
struct select_container_type
|
||||
{
|
||||
typedef AllocatorOrContainer type;
|
||||
};
|
||||
|
||||
template <class Value, class AllocatorOrContainer>
|
||||
struct select_container_type<Value, AllocatorOrContainer, false>
|
||||
{
|
||||
typedef boost::container::vector<Value, AllocatorOrContainer> type;
|
||||
};
|
||||
|
||||
template <class Value, class KeyOfValue,
|
||||
class Compare, class Allocator>
|
||||
class Compare, class AllocatorOrContainer>
|
||||
class flat_tree
|
||||
{
|
||||
public:
|
||||
typedef boost::container::vector<Value, Allocator> sequence_type;
|
||||
typedef typename select_container_type<Value, AllocatorOrContainer>::type container_type;
|
||||
typedef container_type sequence_type; //For backwards compatibility
|
||||
|
||||
private:
|
||||
typedef Allocator allocator_t;
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef typename container_type::allocator_type allocator_t;
|
||||
typedef allocator_traits<allocator_t> allocator_traits_type;
|
||||
|
||||
public:
|
||||
typedef flat_tree_value_compare<Compare, Value, KeyOfValue> value_compare;
|
||||
@@ -152,11 +299,11 @@ class flat_tree
|
||||
: value_compare(boost::move(static_cast<value_compare&>(d))), m_seq(boost::move(d.m_seq))
|
||||
{}
|
||||
|
||||
Data(const Data &d, const Allocator &a)
|
||||
Data(const Data &d, const allocator_t &a)
|
||||
: value_compare(static_cast<const value_compare&>(d)), m_seq(d.m_seq, a)
|
||||
{}
|
||||
|
||||
Data(BOOST_RV_REF(Data) d, const Allocator &a)
|
||||
Data(BOOST_RV_REF(Data) d, const allocator_t &a)
|
||||
: value_compare(boost::move(static_cast<value_compare&>(d))), m_seq(boost::move(d.m_seq), a)
|
||||
{}
|
||||
|
||||
@@ -181,7 +328,7 @@ class flat_tree
|
||||
this->m_seq.swap(d.m_seq);
|
||||
}
|
||||
|
||||
sequence_type m_seq;
|
||||
container_type m_seq;
|
||||
};
|
||||
|
||||
Data m_data;
|
||||
@@ -189,26 +336,36 @@ class flat_tree
|
||||
|
||||
public:
|
||||
|
||||
typedef typename sequence_type::value_type value_type;
|
||||
typedef typename sequence_type::pointer pointer;
|
||||
typedef typename sequence_type::const_pointer const_pointer;
|
||||
typedef typename sequence_type::reference reference;
|
||||
typedef typename sequence_type::const_reference const_reference;
|
||||
typedef typename container_type::value_type value_type;
|
||||
typedef typename container_type::pointer pointer;
|
||||
typedef typename container_type::const_pointer const_pointer;
|
||||
typedef typename container_type::reference reference;
|
||||
typedef typename container_type::const_reference const_reference;
|
||||
typedef typename KeyOfValue::type key_type;
|
||||
typedef Compare key_compare;
|
||||
typedef typename sequence_type::allocator_type allocator_type;
|
||||
typedef typename sequence_type::size_type size_type;
|
||||
typedef typename sequence_type::difference_type difference_type;
|
||||
typedef typename sequence_type::iterator iterator;
|
||||
typedef typename sequence_type::const_iterator const_iterator;
|
||||
typedef typename sequence_type::reverse_iterator reverse_iterator;
|
||||
typedef typename sequence_type::const_reverse_iterator const_reverse_iterator;
|
||||
typedef typename container_type::allocator_type allocator_type;
|
||||
typedef typename container_type::size_type size_type;
|
||||
typedef typename container_type::difference_type difference_type;
|
||||
typedef typename container_type::iterator iterator;
|
||||
typedef typename container_type::const_iterator const_iterator;
|
||||
typedef typename container_type::reverse_iterator reverse_iterator;
|
||||
typedef typename container_type::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
//!Standard extension
|
||||
typedef allocator_type stored_allocator_type;
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||
(boost::container::container_detail::, container_type
|
||||
,stored_allocator_type, allocator_type) stored_allocator_type;
|
||||
|
||||
static const bool has_stored_allocator_type =
|
||||
BOOST_INTRUSIVE_HAS_TYPE(boost::container::container_detail::, container_type, stored_allocator_type);
|
||||
|
||||
private:
|
||||
typedef allocator_traits<stored_allocator_type> stored_allocator_traits;
|
||||
typedef typename container_detail::if_c
|
||||
<has_stored_allocator_type, const stored_allocator_type &, allocator_type>::type get_stored_allocator_const_return_t;
|
||||
|
||||
typedef typename container_detail::if_c
|
||||
<has_stored_allocator_type, stored_allocator_type &, allocator_type>::type get_stored_allocator_noconst_return_t;
|
||||
|
||||
public:
|
||||
BOOST_CONTAINER_FORCEINLINE flat_tree()
|
||||
@@ -357,6 +514,11 @@ class flat_tree
|
||||
BOOST_CONTAINER_FORCEINLINE key_compare &priv_key_comp()
|
||||
{ return this->priv_value_comp().get_comp(); }
|
||||
|
||||
struct insert_commit_data
|
||||
{
|
||||
const_iterator position;
|
||||
};
|
||||
|
||||
public:
|
||||
// accessors:
|
||||
BOOST_CONTAINER_FORCEINLINE Compare key_comp() const
|
||||
@@ -368,11 +530,15 @@ class flat_tree
|
||||
BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const
|
||||
{ return this->m_data.m_seq.get_allocator(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const
|
||||
{ return this->m_data.m_seq.get_stored_allocator(); }
|
||||
BOOST_CONTAINER_FORCEINLINE get_stored_allocator_const_return_t get_stored_allocator() const
|
||||
{
|
||||
return flat_tree_get_stored_allocator(this->m_data.m_seq, container_detail::bool_<has_stored_allocator_type>());
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator()
|
||||
{ return this->m_data.m_seq.get_stored_allocator(); }
|
||||
BOOST_CONTAINER_FORCEINLINE get_stored_allocator_noconst_return_t get_stored_allocator()
|
||||
{
|
||||
return flat_tree_get_stored_allocator(this->m_data.m_seq, container_detail::bool_<has_stored_allocator_type>());
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator begin()
|
||||
{ return this->m_data.m_seq.begin(); }
|
||||
@@ -432,7 +598,8 @@ class flat_tree
|
||||
insert_commit_data data;
|
||||
ret.second = this->priv_insert_unique_prepare(KeyOfValue()(val), data);
|
||||
ret.first = ret.second ? this->priv_insert_commit(data, val)
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
: this->begin() + (data.position - this->cbegin());
|
||||
//: iterator(vector_iterator_get_ptr(data.position));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -442,7 +609,8 @@ class flat_tree
|
||||
insert_commit_data data;
|
||||
ret.second = this->priv_insert_unique_prepare(KeyOfValue()(val), data);
|
||||
ret.first = ret.second ? this->priv_insert_commit(data, boost::move(val))
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
: this->begin() + (data.position - this->cbegin());
|
||||
//: iterator(vector_iterator_get_ptr(data.position));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -466,7 +634,8 @@ class flat_tree
|
||||
insert_commit_data data;
|
||||
return this->priv_insert_unique_prepare(hint, KeyOfValue()(val), data)
|
||||
? this->priv_insert_commit(data, val)
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
: this->begin() + (data.position - this->cbegin());
|
||||
//: iterator(vector_iterator_get_ptr(data.position));
|
||||
}
|
||||
|
||||
iterator insert_unique(const_iterator hint, BOOST_RV_REF(value_type) val)
|
||||
@@ -475,7 +644,8 @@ class flat_tree
|
||||
insert_commit_data data;
|
||||
return this->priv_insert_unique_prepare(hint, KeyOfValue()(val), data)
|
||||
? this->priv_insert_commit(data, boost::move(val))
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
: this->begin() + (data.position - this->cbegin());
|
||||
//: iterator(vector_iterator_get_ptr(data.position));
|
||||
}
|
||||
|
||||
iterator insert_equal(const_iterator hint, const value_type& val)
|
||||
@@ -563,7 +733,11 @@ class flat_tree
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{ this->m_data.m_seq.merge(first, last, static_cast<const value_compare &>(this->m_data)); }
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_merge_unique<container_type, iterator, iterator, value_compare>::value;
|
||||
(flat_tree_merge_equal)(this->m_data.m_seq, first, last, this->priv_value_comp(), container_detail::bool_<value>());
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
void insert_unique(ordered_unique_range_t, InIt first, InIt last
|
||||
@@ -592,7 +766,11 @@ class flat_tree
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{ this->m_data.m_seq.merge_unique(first, last, static_cast<const value_compare &>(this->m_data)); }
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_merge_unique<container_type, iterator, iterator, value_compare>::value;
|
||||
(flat_tree_merge_unique)(this->m_data.m_seq, first, last, this->priv_value_comp(), container_detail::bool_<value>());
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
@@ -601,9 +779,9 @@ class flat_tree
|
||||
{
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||
stored_allocator_type &a = this->get_stored_allocator();
|
||||
get_stored_allocator_noconst_return_t a = this->get_stored_allocator();
|
||||
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
|
||||
value_destructor<stored_allocator_type> d(a, val);
|
||||
value_destructor<stored_allocator_type, value_type> d(a, val);
|
||||
return this->insert_unique(::boost::move(val));
|
||||
}
|
||||
|
||||
@@ -613,9 +791,9 @@ class flat_tree
|
||||
//hint checked in insert_unique
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||
stored_allocator_type &a = this->get_stored_allocator();
|
||||
get_stored_allocator_noconst_return_t a = this->get_stored_allocator();
|
||||
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
|
||||
value_destructor<stored_allocator_type> d(a, val);
|
||||
value_destructor<stored_allocator_type, value_type> d(a, val);
|
||||
return this->insert_unique(hint, ::boost::move(val));
|
||||
}
|
||||
|
||||
@@ -624,9 +802,9 @@ class flat_tree
|
||||
{
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||
stored_allocator_type &a = this->get_stored_allocator();
|
||||
get_stored_allocator_noconst_return_t a = this->get_stored_allocator();
|
||||
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
|
||||
value_destructor<stored_allocator_type> d(a, val);
|
||||
value_destructor<stored_allocator_type, value_type> d(a, val);
|
||||
return this->insert_equal(::boost::move(val));
|
||||
}
|
||||
|
||||
@@ -636,9 +814,9 @@ class flat_tree
|
||||
//hint checked in insert_equal
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||
stored_allocator_type &a = this->get_stored_allocator();
|
||||
get_stored_allocator_noconst_return_t a = this->get_stored_allocator();
|
||||
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
|
||||
value_destructor<stored_allocator_type> d(a, val);
|
||||
value_destructor<stored_allocator_type, value_type> d(a, val);
|
||||
return this->insert_equal(hint, ::boost::move(val));
|
||||
}
|
||||
|
||||
@@ -673,9 +851,9 @@ class flat_tree
|
||||
{\
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
|
||||
stored_allocator_type &a = this->get_stored_allocator();\
|
||||
get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\
|
||||
stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
value_destructor<stored_allocator_type> d(a, val);\
|
||||
value_destructor<stored_allocator_type, value_type> d(a, val);\
|
||||
return this->insert_unique(::boost::move(val));\
|
||||
}\
|
||||
\
|
||||
@@ -684,9 +862,9 @@ class flat_tree
|
||||
{\
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
|
||||
stored_allocator_type &a = this->get_stored_allocator();\
|
||||
get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\
|
||||
stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
value_destructor<stored_allocator_type> d(a, val);\
|
||||
value_destructor<stored_allocator_type, value_type> d(a, val);\
|
||||
return this->insert_unique(hint, ::boost::move(val));\
|
||||
}\
|
||||
\
|
||||
@@ -695,9 +873,9 @@ class flat_tree
|
||||
{\
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
|
||||
stored_allocator_type &a = this->get_stored_allocator();\
|
||||
get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\
|
||||
stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
value_destructor<stored_allocator_type> d(a, val);\
|
||||
value_destructor<stored_allocator_type, value_type> d(a, val);\
|
||||
return this->insert_equal(::boost::move(val));\
|
||||
}\
|
||||
\
|
||||
@@ -706,9 +884,9 @@ class flat_tree
|
||||
{\
|
||||
typename aligned_storage <sizeof(value_type), alignment_of<value_type>::value>::type v;\
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
|
||||
stored_allocator_type &a = this->get_stored_allocator();\
|
||||
get_stored_allocator_noconst_return_t a = this->get_stored_allocator();\
|
||||
stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
value_destructor<stored_allocator_type> d(a, val);\
|
||||
value_destructor<stored_allocator_type, value_type> d(a, val);\
|
||||
return this->insert_equal(hint, ::boost::move(val));\
|
||||
}\
|
||||
template <class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
|
||||
@@ -790,16 +968,32 @@ class flat_tree
|
||||
{ this->m_data.m_seq.shrink_to_fit(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_seq.nth(n); }
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_nth<container_type, size_type>::value;
|
||||
return flat_tree_nth<iterator>(this->m_data.m_seq, n, container_detail::bool_<value>());
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_seq.nth(n); }
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_nth<container_type, size_type>::value;
|
||||
return flat_tree_nth<const_iterator>(this->m_data.m_seq, n, container_detail::bool_<value>());
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_seq.index_of(p); }
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_index_of<container_type, iterator>::value;
|
||||
return flat_tree_index_of(this->m_data.m_seq, p, container_detail::bool_<value>());
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_data.m_seq.index_of(p); }
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_index_of<container_type, const_iterator>::value;
|
||||
return flat_tree_index_of(this->m_data.m_seq, p, container_detail::bool_<value>());
|
||||
}
|
||||
|
||||
// set operations:
|
||||
iterator find(const key_type& k)
|
||||
@@ -832,33 +1026,41 @@ class flat_tree
|
||||
}
|
||||
|
||||
template<class C2>
|
||||
void merge_unique(flat_tree<Value, KeyOfValue, C2, Allocator>& source)
|
||||
BOOST_CONTAINER_FORCEINLINE void merge_unique(flat_tree<Value, KeyOfValue, C2, AllocatorOrContainer>& source)
|
||||
{
|
||||
this->insert( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end()));
|
||||
}
|
||||
|
||||
template<class C2>
|
||||
void merge_equal(flat_tree<Value, KeyOfValue, C2, Allocator>& source)
|
||||
BOOST_CONTAINER_FORCEINLINE void merge_equal(flat_tree<Value, KeyOfValue, C2, AllocatorOrContainer>& source)
|
||||
{
|
||||
this->insert( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end()));
|
||||
}
|
||||
|
||||
void merge_unique(flat_tree& source)
|
||||
BOOST_CONTAINER_FORCEINLINE void merge_unique(flat_tree& source)
|
||||
{
|
||||
this->m_data.m_seq.merge_unique
|
||||
( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end())
|
||||
, static_cast<const value_compare &>(this->m_data));
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_merge_unique<container_type, iterator, iterator, value_compare>::value;
|
||||
(flat_tree_merge_unique)
|
||||
( this->m_data.m_seq
|
||||
, boost::make_move_iterator(source.m_data.m_seq.begin())
|
||||
, boost::make_move_iterator(source.m_data.m_seq.end())
|
||||
, this->priv_value_comp()
|
||||
, container_detail::bool_<value>());
|
||||
}
|
||||
|
||||
void merge_equal(flat_tree& source)
|
||||
BOOST_CONTAINER_FORCEINLINE void merge_equal(flat_tree& source)
|
||||
{
|
||||
this->m_data.m_seq.merge
|
||||
( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end())
|
||||
, static_cast<const value_compare &>(this->m_data));
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_merge<container_type, iterator, iterator, value_compare>::value;
|
||||
(flat_tree_merge_equal)
|
||||
( this->m_data.m_seq
|
||||
, boost::make_move_iterator(source.m_data.m_seq.begin())
|
||||
, boost::make_move_iterator(source.m_data.m_seq.end())
|
||||
, this->priv_value_comp()
|
||||
, container_detail::bool_<value>());
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& k)
|
||||
@@ -891,54 +1093,66 @@ class flat_tree
|
||||
BOOST_CONTAINER_FORCEINLINE void reserve(size_type cnt)
|
||||
{ this->m_data.m_seq.reserve(cnt); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE sequence_type extract_sequence()
|
||||
BOOST_CONTAINER_FORCEINLINE container_type extract_sequence()
|
||||
{
|
||||
return boost::move(m_data.m_seq);
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE sequence_type &get_sequence_ref()
|
||||
BOOST_CONTAINER_FORCEINLINE container_type &get_sequence_ref()
|
||||
{
|
||||
return m_data.m_seq;
|
||||
}
|
||||
|
||||
void adopt_sequence_equal(BOOST_RV_REF(sequence_type) seq)
|
||||
void adopt_sequence_equal(BOOST_RV_REF(container_type) seq)
|
||||
{
|
||||
sequence_type &tseq = m_data.m_seq;
|
||||
boost::movelib::adaptive_sort
|
||||
( boost::movelib::iterator_to_raw_pointer(seq.begin())
|
||||
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
||||
, this->priv_value_comp()
|
||||
, boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size())
|
||||
, tseq.capacity() - tseq.size());
|
||||
container_type &tseq = m_data.m_seq;
|
||||
if (is_contiguous_container<container_type>::value){
|
||||
boost::movelib::adaptive_sort
|
||||
( boost::movelib::iterator_to_raw_pointer(seq.begin())
|
||||
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
||||
, this->priv_value_comp()
|
||||
, boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size())
|
||||
, tseq.capacity() - tseq.size());
|
||||
}
|
||||
else{
|
||||
boost::movelib::adaptive_sort
|
||||
(seq.begin(), seq.end(), this->priv_value_comp());
|
||||
}
|
||||
tseq = boost::move(seq);
|
||||
}
|
||||
|
||||
void adopt_sequence_equal(ordered_range_t, BOOST_RV_REF(sequence_type) seq)
|
||||
void adopt_sequence_unique(BOOST_RV_REF(container_type) seq)
|
||||
{
|
||||
BOOST_ASSERT((is_sorted)(seq.cbegin(), seq.cend(), this->priv_value_comp()));
|
||||
sequence_type &tseq = m_data.m_seq;
|
||||
tseq = boost::move(seq);
|
||||
}
|
||||
|
||||
void adopt_sequence_unique(BOOST_RV_REF(sequence_type) seq)
|
||||
{
|
||||
sequence_type &tseq = m_data.m_seq;
|
||||
boost::movelib::adaptive_sort
|
||||
( boost::movelib::iterator_to_raw_pointer(seq.begin())
|
||||
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
||||
, this->priv_value_comp()
|
||||
, boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size())
|
||||
, tseq.capacity() - tseq.size());
|
||||
container_type &tseq = m_data.m_seq;
|
||||
if (is_contiguous_container<container_type>::value){
|
||||
boost::movelib::adaptive_sort
|
||||
( boost::movelib::iterator_to_raw_pointer(seq.begin())
|
||||
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
||||
, this->priv_value_comp()
|
||||
, boost::movelib::iterator_to_raw_pointer(tseq.begin() + tseq.size())
|
||||
, tseq.capacity() - tseq.size());
|
||||
}
|
||||
else{
|
||||
boost::movelib::adaptive_sort
|
||||
( seq.begin(), seq.end(), this->priv_value_comp());
|
||||
}
|
||||
seq.erase( boost::movelib::unique
|
||||
(seq.begin(), seq.end(), boost::movelib::negate<value_compare>(this->m_data.get_comp()))
|
||||
, seq.cend());
|
||||
tseq = boost::move(seq);
|
||||
}
|
||||
|
||||
void adopt_sequence_unique(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq)
|
||||
void adopt_sequence_equal(ordered_range_t, BOOST_RV_REF(container_type) seq)
|
||||
{
|
||||
BOOST_ASSERT((is_sorted)(seq.cbegin(), seq.cend(), this->priv_value_comp()));
|
||||
container_type &tseq = m_data.m_seq;
|
||||
tseq = boost::move(seq);
|
||||
}
|
||||
|
||||
void adopt_sequence_unique(ordered_unique_range_t, BOOST_RV_REF(container_type) seq)
|
||||
{
|
||||
BOOST_ASSERT((is_sorted_and_unique)(seq.cbegin(), seq.cend(), this->priv_value_comp()));
|
||||
sequence_type &tseq = m_data.m_seq;
|
||||
container_type &tseq = m_data.m_seq;
|
||||
tseq = boost::move(seq);
|
||||
}
|
||||
|
||||
@@ -993,11 +1207,6 @@ class flat_tree
|
||||
return (this->begin() <= pos) && (pos <= this->end());
|
||||
}
|
||||
|
||||
struct insert_commit_data
|
||||
{
|
||||
const_iterator position;
|
||||
};
|
||||
|
||||
// insert/erase
|
||||
void priv_insert_equal_prepare
|
||||
(const_iterator pos, const value_type& val, insert_commit_data &data)
|
||||
@@ -1216,11 +1425,13 @@ class flat_tree
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class T, class KeyOfValue,
|
||||
class Compare, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<T, KeyOfValue, Compare, Allocator> >
|
||||
class Compare, class AllocatorOrContainer>
|
||||
struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<T, KeyOfValue, Compare, AllocatorOrContainer> >
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
||||
typedef typename boost::container::container_detail::select_container_type<T, AllocatorOrContainer>::type container_type;
|
||||
typedef typename container_type::allocator_type allocator_t;
|
||||
typedef typename ::boost::container::allocator_traits<allocator_t>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<allocator_t>::value &&
|
||||
::boost::has_trivial_destructor_after_move<pointer>::value;
|
||||
};
|
||||
|
||||
|
55
include/boost/container/detail/is_container.hpp
Normal file
55
include/boost/container/detail/is_container.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//empty
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME empty
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_container_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
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
//size
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME size
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_container_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
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template <class Container>
|
||||
struct is_container
|
||||
{
|
||||
static const bool value =
|
||||
boost::container::is_container_detail::
|
||||
has_member_function_callable_with_size <const Container>::value &&
|
||||
boost::container::is_container_detail::
|
||||
has_member_function_callable_with_empty<const Container>::value;
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP
|
47
include/boost/container/detail/is_contiguous_container.hpp
Normal file
47
include/boost/container/detail/is_contiguous_container.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_DETAIL_IS_CONTIGUOUS_CONTAINER_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_IS_CONTIGUOUS_CONTAINER_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//data
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME data
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_contiguous_container_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
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template <class Container>
|
||||
struct is_contiguous_container
|
||||
{
|
||||
static const bool value =
|
||||
boost::container::is_contiguous_container_detail::
|
||||
has_member_function_callable_with_data<Container>::value &&
|
||||
boost::container::is_contiguous_container_detail::
|
||||
has_member_function_callable_with_data<const Container>::value;
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_IS_CONTIGUOUS_CONTAINER_HPP
|
@@ -53,7 +53,7 @@ namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
template <class Key, class T, class Compare, class AllocatorOrContainer>
|
||||
class flat_multimap;
|
||||
|
||||
namespace container_detail{
|
||||
@@ -76,37 +76,37 @@ BOOST_CONTAINER_FORCEINLINE static D force_copy(const S &s)
|
||||
|
||||
//! A flat_map is a kind of associative container that supports unique keys (contains at
|
||||
//! most one of each key value) and provides for fast retrieval of values of another
|
||||
//! type T based on the keys. The flat_map class supports random-access iterators.
|
||||
//! type T based on the keys.
|
||||
//!
|
||||
//! A flat_map satisfies all of the requirements of a container and of a reversible
|
||||
//! container and of an associative container. A flat_map also provides
|
||||
//! A flat_map satisfies all of the requirements of a container, a reversible
|
||||
//! container and an associative container. A flat_map also provides
|
||||
//! most operations described for unique keys. For a
|
||||
//! flat_map<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
|
||||
//! (unlike std::map<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
|
||||
//!
|
||||
//! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//! flat_map is similar to std::map but it's implemented by as an ordered sequence container.
|
||||
//! The underlying sequence container is by default <i>vector</i> but it can also work
|
||||
//! user-provided vector-like SequenceContainers (like <i>static_vector</i> or <i>small_vector</i>).
|
||||
//!
|
||||
//! Allocator is the allocator to allocate the value_types
|
||||
//! (e.g. <i>allocator< std::pair<Key, T> ></i>).
|
||||
//!
|
||||
//! flat_map is similar to std::map but it's implemented like an ordered vector.
|
||||
//! This means that inserting a new element into a flat_map invalidates
|
||||
//! previous iterators and references
|
||||
//!
|
||||
//! Erasing an element invalidates iterators and references
|
||||
//! pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//! Using vector-like sequence containers means that inserting a new element into a flat_map might invalidate
|
||||
//! previous iterators and references (unless that sequence container is <i>stable_vector</i> or a similar
|
||||
//! container that offers stable pointers and references). Similarly, erasing an element might invalidate
|
||||
//! iterators and references pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//!
|
||||
//! This container provides random-access iterators.
|
||||
//!
|
||||
//! \tparam Key is the key_type of the map
|
||||
//! \tparam Value is the <code>mapped_type</code>
|
||||
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
|
||||
//! (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
||||
//! \tparam AllocatorOrContainer is either:
|
||||
//! - The allocator to allocate <code>value_type</code>s (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
||||
//! (in this case <i>sequence_type</i> will be vector<value_type, AllocatorOrContainer>)
|
||||
//! - The SequenceContainer to be used as the underlying <i>sequence_type</i>. It must be a vector-like
|
||||
//! sequence container with random-access iterators..
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Compare = std::less<Key>, class Allocator = new_allocator< std::pair< Key, T> > >
|
||||
template <class Key, class T, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator< std::pair< Key, T> > >
|
||||
#else
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
template <class Key, class T, class Compare, class AllocatorOrContainer>
|
||||
#endif
|
||||
class flat_map
|
||||
{
|
||||
@@ -118,14 +118,14 @@ class flat_map
|
||||
std::pair<Key, T>,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
Allocator> tree_t;
|
||||
AllocatorOrContainer> tree_t;
|
||||
|
||||
//This is the real tree stored here. It's based on a movable pair
|
||||
typedef container_detail::flat_tree<
|
||||
container_detail::pair<Key, T>,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
typename allocator_traits<Allocator>::template portable_rebind_alloc
|
||||
typename allocator_traits<AllocatorOrContainer>::template portable_rebind_alloc
|
||||
<container_detail::pair<Key, T> >::type> impl_tree_t;
|
||||
impl_tree_t m_flat_tree; // flat tree representing flat_map
|
||||
|
||||
@@ -133,18 +133,18 @@ class flat_map
|
||||
typedef typename impl_tree_t::const_iterator impl_const_iterator;
|
||||
typedef typename impl_tree_t::iterator impl_iterator;
|
||||
typedef typename impl_tree_t::allocator_type impl_allocator_type;
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
typedef std::initializer_list<impl_value_type> impl_initializer_list;
|
||||
#endif
|
||||
|
||||
typedef container_detail::flat_tree_value_compare
|
||||
< Compare
|
||||
, container_detail::select1st<Key>
|
||||
, std::pair<Key, T> > value_compare_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::iterator iterator_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::const_iterator const_iterator_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
, std::pair<Key, T> > value_compare_t;
|
||||
typedef typename tree_t::iterator iterator_t;
|
||||
typedef typename tree_t::const_iterator const_iterator_t;
|
||||
typedef typename tree_t::reverse_iterator reverse_iterator_t;
|
||||
typedef typename tree_t::const_reverse_iterator const_reverse_iterator_t;
|
||||
|
||||
public:
|
||||
typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
|
||||
@@ -168,27 +168,28 @@ class flat_map
|
||||
//////////////////////////////////////////////
|
||||
typedef Key key_type;
|
||||
typedef T mapped_type;
|
||||
typedef std::pair<Key, T> value_type;
|
||||
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
|
||||
typedef Allocator allocator_type;
|
||||
typedef BOOST_CONTAINER_IMPDEF(Allocator) stored_allocator_type;
|
||||
typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare;
|
||||
typedef Compare key_compare;
|
||||
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
|
||||
typedef std::pair<Key, T> value_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type;
|
||||
typedef typename sequence_type::allocator_type allocator_type;
|
||||
typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type;
|
||||
typedef typename sequence_type::pointer pointer;
|
||||
typedef typename sequence_type::const_pointer const_pointer;
|
||||
typedef typename sequence_type::reference reference;
|
||||
typedef typename sequence_type::const_reference const_reference;
|
||||
typedef typename sequence_type::size_type size_type;
|
||||
typedef typename sequence_type::difference_type difference_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare;
|
||||
|
||||
//Allocator::value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
typedef typename sequence_type::iterator iterator;
|
||||
typedef typename sequence_type::const_iterator const_iterator;
|
||||
typedef typename sequence_type::reverse_iterator reverse_iterator;
|
||||
typedef typename sequence_type::const_reverse_iterator const_reverse_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
|
||||
|
||||
//AllocatorOrContainer::value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename allocator_type::value_type>::value));
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//
|
||||
@@ -199,7 +200,7 @@ class flat_map
|
||||
//! <b>Effects</b>: Default constructs an empty flat_map.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_map() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
BOOST_CONTAINER_FORCEINLINE flat_map() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
|
||||
container_detail::is_nothrow_default_constructible<Compare>::value)
|
||||
: m_flat_tree()
|
||||
{}
|
||||
@@ -309,7 +310,7 @@ class flat_map
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_map(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
|
||||
: m_flat_tree(ordered_range, first, last, comp, a)
|
||||
: m_flat_tree(ordered_range, first, last, comp, container_detail::force<const impl_allocator_type>(a))
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
@@ -319,7 +320,9 @@ class flat_map
|
||||
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
||||
//! the predicate and otherwise N logN, where N is last - first.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il)
|
||||
: m_flat_tree(true, il.begin(), il.end())
|
||||
: m_flat_tree( true
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end())
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified
|
||||
@@ -328,7 +331,10 @@ class flat_map
|
||||
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
||||
//! the predicate and otherwise N logN, where N is last - first.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const allocator_type& a)
|
||||
: m_flat_tree(true, il.begin(), il.end(), container_detail::force<const impl_allocator_type>(a))
|
||||
: m_flat_tree( true
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end()
|
||||
, container_detail::force<const impl_allocator_type>(a))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
||||
@@ -337,7 +343,10 @@ class flat_map
|
||||
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
||||
//! the predicate and otherwise N logN, where N is last - first.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const Compare& comp)
|
||||
: m_flat_tree(true, il.begin(), il.end(), comp)
|
||||
: m_flat_tree(true
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end()
|
||||
, comp)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
||||
@@ -346,7 +355,11 @@ class flat_map
|
||||
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
||||
//! the predicate and otherwise N logN, where N is last - first.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_map(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
|
||||
: m_flat_tree(true, il.begin(), il.end(), comp, container_detail::force<const impl_allocator_type>(a))
|
||||
: m_flat_tree(true
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end()
|
||||
, comp
|
||||
, container_detail::force<const impl_allocator_type>(a))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using and
|
||||
@@ -360,7 +373,9 @@ class flat_map
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il)
|
||||
: m_flat_tree(ordered_unique_range, il.begin(), il.end())
|
||||
: m_flat_tree(ordered_unique_range
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end())
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
||||
@@ -374,7 +389,10 @@ class flat_map
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
|
||||
: m_flat_tree(ordered_unique_range, il.begin(), il.end(), comp)
|
||||
: m_flat_tree(ordered_unique_range
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end()
|
||||
, comp)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
||||
@@ -388,7 +406,11 @@ class flat_map
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
|
||||
: m_flat_tree(ordered_unique_range, il.begin(), il.end(), comp, a)
|
||||
: m_flat_tree( ordered_unique_range
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end()
|
||||
, comp
|
||||
, container_detail::force<const impl_allocator_type>(a))
|
||||
{}
|
||||
#endif
|
||||
|
||||
@@ -414,7 +436,7 @@ class flat_map
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
BOOST_CONTAINER_FORCEINLINE flat_map(const flat_map& x, const allocator_type &a)
|
||||
: m_flat_tree(x.m_flat_tree, a)
|
||||
: m_flat_tree(x.m_flat_tree, container_detail::force<const impl_allocator_type>(a))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
|
||||
@@ -422,7 +444,7 @@ class flat_map
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if x.get_allocator() == a, linear otherwise.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree), a)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree), container_detail::force<const impl_allocator_type>(a))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
@@ -1114,7 +1136,10 @@ class flat_map
|
||||
//!
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
|
||||
{ m_flat_tree.insert_unique(il.begin(), il.end()); }
|
||||
{
|
||||
m_flat_tree.insert_unique( container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
|
||||
//! unique values.
|
||||
@@ -1130,7 +1155,11 @@ class flat_map
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, std::initializer_list<value_type> il)
|
||||
{ m_flat_tree.insert_unique(ordered_unique_range, il.begin(), il.end()); }
|
||||
{
|
||||
m_flat_tree.insert_unique(ordered_unique_range
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end());
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: this->get_allocator() == source.get_allocator().
|
||||
@@ -1148,23 +1177,23 @@ class flat_map
|
||||
//!
|
||||
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, Allocator>& source)
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, AllocatorOrContainer>& source)
|
||||
{ m_flat_tree.merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_map<Key, T, C2, Allocator>&>(source)); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_map<Key, T, C2, AllocatorOrContainer>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, Allocator>& source)
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, AllocatorOrContainer>& source)
|
||||
{ m_flat_tree.merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multimap<Key, T, C2, Allocator>&>(source)); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multimap<Key, T, C2, AllocatorOrContainer>&>(source)); }
|
||||
|
||||
//! <b>Effects</b>: Erases the element pointed to by p.
|
||||
//!
|
||||
@@ -1417,11 +1446,11 @@ class flat_map
|
||||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::flat_map<Key, T, Compare, Allocator> >
|
||||
template <class Key, class T, class Compare, class AllocatorOrContainer>
|
||||
struct has_trivial_destructor_after_move<boost::container::flat_map<Key, T, Compare, AllocatorOrContainer> >
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
||||
typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
|
||||
::boost::has_trivial_destructor_after_move<pointer>::value &&
|
||||
::boost::has_trivial_destructor_after_move<Compare>::value;
|
||||
};
|
||||
@@ -1432,37 +1461,36 @@ namespace container {
|
||||
|
||||
//! A flat_multimap is a kind of associative container that supports equivalent keys
|
||||
//! (possibly containing multiple copies of the same key value) and provides for
|
||||
//! fast retrieval of values of another type T based on the keys. The flat_multimap
|
||||
//! class supports random-access iterators.
|
||||
//! fast retrieval of values of another type T based on the keys.
|
||||
//!
|
||||
//! A flat_multimap satisfies all of the requirements of a container and of a reversible
|
||||
//! container and of an associative container. For a
|
||||
//! flat_multimap<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
|
||||
//! (unlike std::multimap<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
|
||||
//!
|
||||
//! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//! flat_multimap is similar to std::multimap but it's implemented by as an ordered sequence container.
|
||||
//! The underlying sequence container is by default <i>vector</i> but it can also work
|
||||
//! user-provided vector-like SequenceContainers (like <i>static_vector</i> or <i>small_vector</i>).
|
||||
//!
|
||||
//! Allocator is the allocator to allocate the value_types
|
||||
//! (e.g. <i>allocator< std::pair<Key, T> ></i>).
|
||||
//!
|
||||
//! flat_multimap is similar to std::multimap but it's implemented like an ordered vector.
|
||||
//! This means that inserting a new element into a flat_map invalidates
|
||||
//! previous iterators and references
|
||||
//!
|
||||
//! Erasing an element invalidates iterators and references
|
||||
//! pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//! Using vector-like sequence containers means that inserting a new element into a flat_multimap might invalidate
|
||||
//! previous iterators and references (unless that sequence container is <i>stable_vector</i> or a similar
|
||||
//! container that offers stable pointers and references). Similarly, erasing an element might invalidate
|
||||
//! iterators and references pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//!
|
||||
//! This container provides random-access iterators.
|
||||
//!
|
||||
//! \tparam Key is the key_type of the map
|
||||
//! \tparam Value is the <code>mapped_type</code>
|
||||
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
|
||||
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
|
||||
//! (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
||||
//! \tparam AllocatorOrContainer is either:
|
||||
//! - The allocator to allocate <code>value_type</code>s (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
||||
//! (in this case <i>sequence_type</i> will be vector<value_type, AllocatorOrContainer>)
|
||||
//! - The SequenceContainer to be used as the underlying <i>sequence_type</i>. It must be a vector-like
|
||||
//! sequence container with random-access iterators.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class T, class Compare = std::less<Key>, class Allocator = new_allocator< std::pair< Key, T> > >
|
||||
template <class Key, class T, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator< std::pair< Key, T> > >
|
||||
#else
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
template <class Key, class T, class Compare, class AllocatorOrContainer>
|
||||
#endif
|
||||
class flat_multimap
|
||||
{
|
||||
@@ -1473,13 +1501,13 @@ class flat_multimap
|
||||
std::pair<Key, T>,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
Allocator> tree_t;
|
||||
AllocatorOrContainer> tree_t;
|
||||
//This is the real tree stored here. It's based on a movable pair
|
||||
typedef container_detail::flat_tree<
|
||||
container_detail::pair<Key, T>,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
typename allocator_traits<Allocator>::template portable_rebind_alloc
|
||||
typename allocator_traits<AllocatorOrContainer>::template portable_rebind_alloc
|
||||
<container_detail::pair<Key, T> >::type> impl_tree_t;
|
||||
impl_tree_t m_flat_tree; // flat tree representing flat_map
|
||||
|
||||
@@ -1487,21 +1515,22 @@ class flat_multimap
|
||||
typedef typename impl_tree_t::const_iterator impl_const_iterator;
|
||||
typedef typename impl_tree_t::iterator impl_iterator;
|
||||
typedef typename impl_tree_t::allocator_type impl_allocator_type;
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
typedef std::initializer_list<impl_value_type> impl_initializer_list;
|
||||
#endif
|
||||
|
||||
typedef container_detail::flat_tree_value_compare
|
||||
< Compare
|
||||
, container_detail::select1st<Key>
|
||||
, std::pair<Key, T> > value_compare_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::iterator iterator_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::const_iterator const_iterator_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
|
||||
typedef typename container_detail::get_flat_tree_iterators
|
||||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
, std::pair<Key, T> > value_compare_t;
|
||||
typedef typename tree_t::iterator iterator_t;
|
||||
typedef typename tree_t::const_iterator const_iterator_t;
|
||||
typedef typename tree_t::reverse_iterator reverse_iterator_t;
|
||||
typedef typename tree_t::const_reverse_iterator const_reverse_iterator_t;
|
||||
|
||||
public:
|
||||
typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
|
||||
typedef typename impl_tree_t::sequence_type impl_sequence_type;
|
||||
typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
|
||||
typedef typename impl_tree_t::sequence_type impl_sequence_type;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE impl_tree_t &tree()
|
||||
{ return m_flat_tree; }
|
||||
@@ -1521,27 +1550,28 @@ class flat_multimap
|
||||
//////////////////////////////////////////////
|
||||
typedef Key key_type;
|
||||
typedef T mapped_type;
|
||||
typedef std::pair<Key, T> value_type;
|
||||
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type;
|
||||
typedef Allocator allocator_type;
|
||||
typedef BOOST_CONTAINER_IMPDEF(Allocator) stored_allocator_type;
|
||||
typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare;
|
||||
typedef Compare key_compare;
|
||||
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(reverse_iterator_impl) reverse_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(const_reverse_iterator_impl) const_reverse_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
|
||||
typedef std::pair<Key, T> value_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type;
|
||||
typedef typename sequence_type::allocator_type allocator_type;
|
||||
typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type;
|
||||
typedef typename sequence_type::pointer pointer;
|
||||
typedef typename sequence_type::const_pointer const_pointer;
|
||||
typedef typename sequence_type::reference reference;
|
||||
typedef typename sequence_type::const_reference const_reference;
|
||||
typedef typename sequence_type::size_type size_type;
|
||||
typedef typename sequence_type::difference_type difference_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare;
|
||||
|
||||
//Allocator::value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
|
||||
typedef typename sequence_type::iterator iterator;
|
||||
typedef typename sequence_type::const_iterator const_iterator;
|
||||
typedef typename sequence_type::reverse_iterator reverse_iterator;
|
||||
typedef typename sequence_type::const_reverse_iterator const_reverse_iterator;
|
||||
typedef BOOST_CONTAINER_IMPDEF(impl_value_type) movable_value_type;
|
||||
|
||||
//AllocatorOrContainer::value_type must be std::pair<Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename AllocatorOrContainer::value_type>::value));
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//
|
||||
@@ -1553,7 +1583,7 @@ class flat_multimap
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multimap()
|
||||
BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
|
||||
container_detail::is_nothrow_default_constructible<Compare>::value)
|
||||
: m_flat_tree()
|
||||
{}
|
||||
@@ -1679,7 +1709,9 @@ class flat_multimap
|
||||
//! the predicate and otherwise N logN, where N is last - first.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_multimap(std::initializer_list<value_type> il)
|
||||
: m_flat_tree(false, il.begin(), il.end())
|
||||
: m_flat_tree( false
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end())
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified
|
||||
@@ -1689,7 +1721,10 @@ class flat_multimap
|
||||
//! the predicate and otherwise N logN, where N is last - first.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_multimap(std::initializer_list<value_type> il, const allocator_type& a)
|
||||
: m_flat_tree(false, il.begin(), il.end(), container_detail::force<const impl_allocator_type>(a))
|
||||
: m_flat_tree(false
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end()
|
||||
, container_detail::force<const impl_allocator_type>(a))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
||||
@@ -1699,7 +1734,9 @@ class flat_multimap
|
||||
//! the predicate and otherwise N logN, where N is last - first.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_multimap(std::initializer_list<value_type> il, const Compare& comp)
|
||||
: m_flat_tree(false, il.begin(), il.end(), comp)
|
||||
: m_flat_tree(false
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end(), comp)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
|
||||
@@ -1709,7 +1746,10 @@ class flat_multimap
|
||||
//! the predicate and otherwise N logN, where N is last - first.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_multimap(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
|
||||
: m_flat_tree(false, il.begin(), il.end(), comp, container_detail::force<const impl_allocator_type>(a))
|
||||
: m_flat_tree( false
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end()
|
||||
, comp, container_detail::force<const impl_allocator_type>(a))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multimap and
|
||||
@@ -1723,7 +1763,9 @@ class flat_multimap
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_multimap(ordered_range_t, std::initializer_list<value_type> il)
|
||||
: m_flat_tree(ordered_range, il.begin(), il.end())
|
||||
: m_flat_tree( ordered_range
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end())
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
|
||||
@@ -1737,7 +1779,9 @@ class flat_multimap
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
|
||||
: m_flat_tree(ordered_range, il.begin(), il.end(), comp)
|
||||
: m_flat_tree( ordered_range
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end(), comp)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
|
||||
@@ -1751,7 +1795,10 @@ class flat_multimap
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
|
||||
: m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
|
||||
: m_flat_tree( ordered_range
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end()
|
||||
, comp, a)
|
||||
{}
|
||||
#endif
|
||||
|
||||
@@ -2235,7 +2282,10 @@ class flat_multimap
|
||||
//!
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
|
||||
{ m_flat_tree.insert_equal(il.begin(), il.end()); }
|
||||
{
|
||||
m_flat_tree.insert_equal( container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
|
||||
//!
|
||||
@@ -2250,7 +2300,11 @@ class flat_multimap
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, std::initializer_list<value_type> il)
|
||||
{ m_flat_tree.insert_equal(ordered_range, il.begin(), il.end()); }
|
||||
{
|
||||
m_flat_tree.insert_equal( ordered_range
|
||||
, container_detail::force<impl_initializer_list>(il).begin()
|
||||
, container_detail::force<impl_initializer_list>(il).end());
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: this->get_allocator() == source.get_allocator().
|
||||
@@ -2267,23 +2321,23 @@ class flat_multimap
|
||||
//!
|
||||
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, Allocator>& source)
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, AllocatorOrContainer>& source)
|
||||
{ m_flat_tree.merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multimap<Key, T, C2, Allocator>&>(source)); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multimap<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multimap<Key, T, C2, AllocatorOrContainer>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, Allocator>& source)
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, AllocatorOrContainer>& source)
|
||||
{ m_flat_tree.merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_map<Key, T, C2, Allocator>&>(source)); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_map<Key, T, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_map<Key, T, C2, AllocatorOrContainer>&>(source)); }
|
||||
|
||||
//! <b>Effects</b>: Erases the element pointed to by p.
|
||||
//!
|
||||
@@ -2512,11 +2566,11 @@ namespace boost {
|
||||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
struct has_trivial_destructor_after_move< boost::container::flat_multimap<Key, T, Compare, Allocator> >
|
||||
template <class Key, class T, class Compare, class AllocatorOrContainer>
|
||||
struct has_trivial_destructor_after_move< boost::container::flat_multimap<Key, T, Compare, AllocatorOrContainer> >
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
||||
typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
|
||||
::boost::has_trivial_destructor_after_move<pointer>::value &&
|
||||
::boost::has_trivial_destructor_after_move<Compare>::value;
|
||||
};
|
||||
|
@@ -48,45 +48,51 @@ namespace boost {
|
||||
namespace container {
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
class flat_multimap;
|
||||
template <class Key, class Compare, class AllocatorOrContainer>
|
||||
class flat_multiset;
|
||||
#endif
|
||||
|
||||
//! flat_set is a Sorted Associative Container that stores objects of type Key.
|
||||
//! It is also a Unique Associative Container, meaning that no two elements are the same.
|
||||
//!
|
||||
//! flat_set is similar to std::set but it's implemented like an ordered vector.
|
||||
//! This means that inserting a new element into a flat_set invalidates
|
||||
//! previous iterators and references
|
||||
//! flat_set is similar to std::set but it's implemented by as an ordered sequence container.
|
||||
//! The underlying sequence container is by default <i>vector</i> but it can also work
|
||||
//! user-provided vector-like SequenceContainers (like <i>static_vector</i> or <i>small_vector</i>).
|
||||
//!
|
||||
//! Erasing an element of a flat_set invalidates iterators and references
|
||||
//! pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//! Using vector-like sequence containers means that inserting a new element into a flat_set might invalidate
|
||||
//! previous iterators and references (unless that sequence container is <i>stable_vector</i> or a similar
|
||||
//! container that offers stable pointers and references). Similarly, erasing an element might invalidate
|
||||
//! iterators and references pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//!
|
||||
//! This container provides random-access iterators.
|
||||
//!
|
||||
//! \tparam Key is the type to be inserted in the set, which is also the key_type
|
||||
//! \tparam Compare is the comparison functor used to order keys
|
||||
//! \tparam Allocator is the allocator to be used to allocate memory for this container
|
||||
//! \tparam AllocatorOrContainer is either:
|
||||
//! - The allocator to allocate <code>value_type</code>s (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
||||
//! (in this case <i>sequence_type</i> will be vector<value_type, AllocatorOrContainer>)
|
||||
//! - The SequenceContainer to be used as the underlying <i>sequence_type</i>. It must be a vector-like
|
||||
//! sequence container with random-access iterators.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key> >
|
||||
template <class Key, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator<Key> >
|
||||
#else
|
||||
template <class Key, class Compare, class Allocator>
|
||||
template <class Key, class Compare, class AllocatorOrContainer>
|
||||
#endif
|
||||
class flat_set
|
||||
///@cond
|
||||
: public container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator>
|
||||
: public container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, AllocatorOrContainer>
|
||||
///@endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_set)
|
||||
typedef container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator> base_t;
|
||||
typedef container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, AllocatorOrContainer> tree_t;
|
||||
|
||||
public:
|
||||
base_t &tree()
|
||||
tree_t &tree()
|
||||
{ return *this; }
|
||||
|
||||
const base_t &tree() const
|
||||
const tree_t &tree() const
|
||||
{ return *this; }
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
@@ -97,24 +103,25 @@ class flat_set
|
||||
// types
|
||||
//
|
||||
//////////////////////////////////////////////
|
||||
typedef Key key_type;
|
||||
typedef Key value_type;
|
||||
typedef Compare key_compare;
|
||||
typedef Compare value_compare;
|
||||
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
|
||||
typedef Allocator allocator_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::sequence_type) sequence_type;
|
||||
typedef Key key_type;
|
||||
typedef Compare key_compare;
|
||||
typedef Key value_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type;
|
||||
typedef typename sequence_type::allocator_type allocator_type;
|
||||
typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type;
|
||||
typedef typename sequence_type::pointer pointer;
|
||||
typedef typename sequence_type::const_pointer const_pointer;
|
||||
typedef typename sequence_type::reference reference;
|
||||
typedef typename sequence_type::const_reference const_reference;
|
||||
typedef typename sequence_type::size_type size_type;
|
||||
typedef typename sequence_type::difference_type difference_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare;
|
||||
|
||||
typedef typename sequence_type::iterator iterator;
|
||||
typedef typename sequence_type::const_iterator const_iterator;
|
||||
typedef typename sequence_type::reverse_iterator reverse_iterator;
|
||||
typedef typename sequence_type::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////
|
||||
@@ -127,9 +134,9 @@ class flat_set
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_set() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
flat_set() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
|
||||
container_detail::is_nothrow_default_constructible<Compare>::value)
|
||||
: base_t()
|
||||
: tree_t()
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified
|
||||
@@ -138,7 +145,7 @@ class flat_set
|
||||
//! <b>Complexity</b>: Constant.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
explicit flat_set(const Compare& comp)
|
||||
: base_t(comp)
|
||||
: tree_t(comp)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified allocator.
|
||||
@@ -146,7 +153,7 @@ class flat_set
|
||||
//! <b>Complexity</b>: Constant.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
explicit flat_set(const allocator_type& a)
|
||||
: base_t(a)
|
||||
: tree_t(a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified
|
||||
@@ -155,7 +162,7 @@ class flat_set
|
||||
//! <b>Complexity</b>: Constant.
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_set(const Compare& comp, const allocator_type& a)
|
||||
: base_t(comp, a)
|
||||
: tree_t(comp, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container and
|
||||
@@ -166,7 +173,7 @@ class flat_set
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_set(InputIterator first, InputIterator last)
|
||||
: base_t(true, first, last)
|
||||
: tree_t(true, first, last)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified
|
||||
@@ -177,7 +184,7 @@ class flat_set
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_set(InputIterator first, InputIterator last, const allocator_type& a)
|
||||
: base_t(true, first, last, a)
|
||||
: tree_t(true, first, last, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
@@ -188,7 +195,7 @@ class flat_set
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_set(InputIterator first, InputIterator last, const Compare& comp)
|
||||
: base_t(true, first, last, comp)
|
||||
: tree_t(true, first, last, comp)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
@@ -199,7 +206,7 @@ class flat_set
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_set(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
|
||||
: base_t(true, first, last, comp, a)
|
||||
: tree_t(true, first, last, comp, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container and
|
||||
@@ -215,7 +222,7 @@ class flat_set
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_set(ordered_unique_range_t, InputIterator first, InputIterator last)
|
||||
: base_t(ordered_unique_range, first, last)
|
||||
: tree_t(ordered_unique_range, first, last)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
@@ -231,7 +238,7 @@ class flat_set
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp)
|
||||
: base_t(ordered_unique_range, first, last, comp)
|
||||
: tree_t(ordered_unique_range, first, last, comp)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
@@ -247,7 +254,7 @@ class flat_set
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
|
||||
: base_t(ordered_unique_range, first, last, comp, a)
|
||||
: tree_t(ordered_unique_range, first, last, comp, a)
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
@@ -257,7 +264,7 @@ class flat_set
|
||||
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
||||
//! comp and otherwise N logN, where N is il.begin() - il.end().
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il)
|
||||
: base_t(true, il.begin(), il.end())
|
||||
: tree_t(true, il.begin(), il.end())
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified
|
||||
@@ -266,7 +273,7 @@ class flat_set
|
||||
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
||||
//! comp and otherwise N logN, where N is il.begin() - il.end().
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il, const allocator_type& a)
|
||||
: base_t(true, il.begin(), il.end(), a)
|
||||
: tree_t(true, il.begin(), il.end(), a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
@@ -275,7 +282,7 @@ class flat_set
|
||||
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
||||
//! comp and otherwise N logN, where N is il.begin() - il.end().
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il, const Compare& comp)
|
||||
: base_t(true, il.begin(), il.end(), comp)
|
||||
: tree_t(true, il.begin(), il.end(), comp)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
@@ -284,7 +291,7 @@ class flat_set
|
||||
//! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
|
||||
//! comp and otherwise N logN, where N is il.begin() - il.end().
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
|
||||
: base_t(true, il.begin(), il.end(), comp, a)
|
||||
: tree_t(true, il.begin(), il.end(), comp, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
@@ -298,7 +305,7 @@ class flat_set
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list<value_type> il)
|
||||
: base_t(ordered_unique_range, il.begin(), il.end())
|
||||
: tree_t(ordered_unique_range, il.begin(), il.end())
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
@@ -312,7 +319,7 @@ class flat_set
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp)
|
||||
: base_t(ordered_unique_range, il.begin(), il.end(), comp)
|
||||
: tree_t(ordered_unique_range, il.begin(), il.end(), comp)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
@@ -326,7 +333,7 @@ class flat_set
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
|
||||
: base_t(ordered_unique_range, il.begin(), il.end(), comp, a)
|
||||
: tree_t(ordered_unique_range, il.begin(), il.end(), comp, a)
|
||||
{}
|
||||
#endif
|
||||
|
||||
@@ -334,7 +341,7 @@ class flat_set
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set(const flat_set& x)
|
||||
: base_t(static_cast<const base_t&>(x))
|
||||
: tree_t(static_cast<const tree_t&>(x))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Move constructs thecontainer. Constructs *this using x's resources.
|
||||
@@ -344,14 +351,14 @@ class flat_set
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set(BOOST_RV_REF(flat_set) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: base_t(BOOST_MOVE_BASE(base_t, x))
|
||||
: tree_t(BOOST_MOVE_BASE(tree_t, x))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a container using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set(const flat_set& x, const allocator_type &a)
|
||||
: base_t(static_cast<const base_t&>(x), a)
|
||||
: tree_t(static_cast<const tree_t&>(x), a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a container using the specified allocator.
|
||||
@@ -359,14 +366,14 @@ class flat_set
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set(BOOST_RV_REF(flat_set) x, const allocator_type &a)
|
||||
: base_t(BOOST_MOVE_BASE(base_t, x), a)
|
||||
: tree_t(BOOST_MOVE_BASE(tree_t, x), a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
BOOST_CONTAINER_FORCEINLINE flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
|
||||
{ return static_cast<flat_set&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
|
||||
{ return static_cast<flat_set&>(this->tree_t::operator=(static_cast<const tree_t&>(x))); }
|
||||
|
||||
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
||||
//! is false and (allocation throws or value_type's move constructor throws)
|
||||
@@ -378,7 +385,7 @@ class flat_set
|
||||
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
|
||||
allocator_traits_type::is_always_equal::value) &&
|
||||
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
|
||||
{ return static_cast<flat_set&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
|
||||
{ return static_cast<flat_set&>(this->tree_t::operator=(BOOST_MOVE_BASE(tree_t, x))); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! <b>Effects</b>: Copy all elements from il to *this.
|
||||
@@ -579,7 +586,7 @@ class flat_set
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
template <class... Args>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
|
||||
{ return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
|
||||
{ return this->tree_t::emplace_unique(boost::forward<Args>(args)...); }
|
||||
|
||||
//! <b>Effects</b>: Inserts an object of type Key constructed with
|
||||
//! std::forward<Args>(args)... in the container if and only if there is
|
||||
@@ -595,18 +602,18 @@ class flat_set
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
template <class... Args>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
|
||||
{ return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
|
||||
{ return this->tree_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE(N) \
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
|
||||
{ return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
|
||||
{ return this->tree_t::emplace_unique(BOOST_MOVE_FWD##N); }\
|
||||
\
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{ return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
|
||||
{ return this->tree_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE)
|
||||
#undef BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE
|
||||
@@ -685,7 +692,7 @@ class flat_set
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
|
||||
{ this->base_t::insert_unique(first, last); }
|
||||
{ this->tree_t::insert_unique(first, last); }
|
||||
|
||||
//! <b>Requires</b>: first, last are not iterators into *this and
|
||||
//! must be ordered according to the predicate and must be
|
||||
@@ -700,7 +707,7 @@ class flat_set
|
||||
//! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
|
||||
{ this->base_t::insert_unique(ordered_unique_range, first, last); }
|
||||
{ this->tree_t::insert_unique(ordered_unique_range, first, last); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()) if and only
|
||||
@@ -711,7 +718,7 @@ class flat_set
|
||||
//!
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
|
||||
{ this->base_t::insert_unique(il.begin(), il.end()); }
|
||||
{ this->tree_t::insert_unique(il.begin(), il.end()); }
|
||||
|
||||
//! <b>Requires</b>: Range [il.begin(), il.end()) must be ordered according to the predicate
|
||||
//! and must be unique values.
|
||||
@@ -724,28 +731,28 @@ class flat_set
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(ordered_unique_range_t, std::initializer_list<value_type> il)
|
||||
{ this->base_t::insert_unique(ordered_unique_range, il.begin(), il.end()); }
|
||||
{ this->tree_t::insert_unique(ordered_unique_range, il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_unique(source.tree()); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, AllocatorOrContainer>& source)
|
||||
{ this->tree_t::merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::merge(flat_set<Key, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_set::merge(flat_set<Key, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set<Key, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_set<Key, C2, Allocator>&>(source)); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set<Key, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_set<Key, C2, AllocatorOrContainer>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_multimap<Key, T, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_unique(source.tree()); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, AllocatorOrContainer>& source)
|
||||
{ this->tree_t::merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::merge(flat_multiset<Key, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_set::merge(flat_multiset<Key, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset<Key, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multiset<Key, C2, Allocator>&>(source)); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset<Key, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multiset<Key, C2, AllocatorOrContainer>&>(source)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
@@ -875,7 +882,7 @@ class flat_set
|
||||
//!
|
||||
//! <b>Complexity</b>: log(size())+count(k)
|
||||
BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& x) const
|
||||
{ return static_cast<size_type>(this->base_t::find(x) != this->base_t::cend()); }
|
||||
{ return static_cast<size_type>(this->tree_t::find(x) != this->tree_t::cend()); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
//! <b>Returns</b>: An iterator pointing to the first element with key not less
|
||||
@@ -908,13 +915,13 @@ class flat_set
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
|
||||
{ return this->base_t::lower_bound_range(x); }
|
||||
{ return this->tree_t::lower_bound_range(x); }
|
||||
|
||||
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator,iterator> equal_range(const key_type& x)
|
||||
{ return this->base_t::lower_bound_range(x); }
|
||||
{ return this->tree_t::lower_bound_range(x); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
@@ -971,7 +978,7 @@ class flat_set
|
||||
//!
|
||||
//! <b>Throws</b>: If the comparison or the move constructor throws
|
||||
BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->base_t::adopt_sequence_unique(boost::move(seq)); }
|
||||
{ this->tree_t::adopt_sequence_unique(boost::move(seq)); }
|
||||
|
||||
//! <b>Requires</b>: seq shall be ordered according to this->compare()
|
||||
//! and shall contain unique elements.
|
||||
@@ -983,17 +990,17 @@ class flat_set
|
||||
//!
|
||||
//! <b>Throws</b>: If the move assignment throws
|
||||
BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_unique_range_t, BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->base_t::adopt_sequence_unique(ordered_unique_range_t(), boost::move(seq)); }
|
||||
{ this->tree_t::adopt_sequence_unique(ordered_unique_range_t(), boost::move(seq)); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
template<class KeyType>
|
||||
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> priv_insert(BOOST_FWD_REF(KeyType) x)
|
||||
{ return this->base_t::insert_unique(::boost::forward<KeyType>(x)); }
|
||||
{ return this->tree_t::insert_unique(::boost::forward<KeyType>(x)); }
|
||||
|
||||
template<class KeyType>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
|
||||
{ return this->base_t::insert_unique(p, ::boost::forward<KeyType>(x)); }
|
||||
{ return this->tree_t::insert_unique(p, ::boost::forward<KeyType>(x)); }
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
@@ -1003,11 +1010,11 @@ class flat_set
|
||||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class Compare, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::flat_set<Key, Compare, Allocator> >
|
||||
template <class Key, class Compare, class AllocatorOrContainer>
|
||||
struct has_trivial_destructor_after_move<boost::container::flat_set<Key, Compare, AllocatorOrContainer> >
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
||||
typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
|
||||
::boost::has_trivial_destructor_after_move<pointer>::value &&
|
||||
::boost::has_trivial_destructor_after_move<Compare>::value;
|
||||
};
|
||||
@@ -1016,42 +1023,47 @@ namespace container {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! flat_multiset is a Sorted Associative Container that stores objects of type Key.
|
||||
//! flat_multiset is a Sorted Associative Container that stores objects of type Key and
|
||||
//! can store multiple copies of the same key value.
|
||||
//!
|
||||
//! flat_multiset can store multiple copies of the same key value.
|
||||
//! flat_multiset is similar to std::multiset but it's implemented by as an ordered sequence container.
|
||||
//! The underlying sequence container is by default <i>vector</i> but it can also work
|
||||
//! user-provided vector-like SequenceContainers (like <i>static_vector</i> or <i>small_vector</i>).
|
||||
//!
|
||||
//! flat_multiset is similar to std::multiset but it's implemented like an ordered vector.
|
||||
//! This means that inserting a new element into a flat_multiset invalidates
|
||||
//! previous iterators and references
|
||||
//!
|
||||
//! Erasing an element invalidates iterators and references
|
||||
//! pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//! Using vector-like sequence containers means that inserting a new element into a flat_multiset might invalidate
|
||||
//! previous iterators and references (unless that sequence container is <i>stable_vector</i> or a similar
|
||||
//! container that offers stable pointers and references). Similarly, erasing an element might invalidate
|
||||
//! iterators and references pointing to elements that come after (their keys are bigger) the erased element.
|
||||
//!
|
||||
//! This container provides random-access iterators.
|
||||
//!
|
||||
//! \tparam Key is the type to be inserted in the multiset, which is also the key_type
|
||||
//! \tparam Compare is the comparison functor used to order keys
|
||||
//! \tparam Allocator is the allocator to be used to allocate memory for this container
|
||||
//! \tparam AllocatorOrContainer is either:
|
||||
//! - The allocator to allocate <code>value_type</code>s (e.g. <i>allocator< std::pair<Key, T> > </i>).
|
||||
//! (in this case <i>sequence_type</i> will be vector<value_type, AllocatorOrContainer>)
|
||||
//! - The SequenceContainer to be used as the underlying <i>sequence_type</i>. It must be a vector-like
|
||||
//! sequence container with random-access iterators.
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key> >
|
||||
template <class Key, class Compare = std::less<Key>, class AllocatorOrContainer = new_allocator<Key> >
|
||||
#else
|
||||
template <class Key, class Compare, class Allocator>
|
||||
template <class Key, class Compare, class AllocatorOrContainer>
|
||||
#endif
|
||||
class flat_multiset
|
||||
///@cond
|
||||
: public container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator>
|
||||
: public container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, AllocatorOrContainer>
|
||||
///@endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_multiset)
|
||||
typedef container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator> base_t;
|
||||
typedef container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, AllocatorOrContainer> tree_t;
|
||||
|
||||
public:
|
||||
base_t &tree()
|
||||
tree_t &tree()
|
||||
{ return *this; }
|
||||
|
||||
const base_t &tree() const
|
||||
const tree_t &tree() const
|
||||
{ return *this; }
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
@@ -1061,68 +1073,69 @@ class flat_multiset
|
||||
// types
|
||||
//
|
||||
//////////////////////////////////////////////
|
||||
typedef Key key_type;
|
||||
typedef Key value_type;
|
||||
typedef Compare key_compare;
|
||||
typedef Compare value_compare;
|
||||
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
|
||||
typedef Allocator allocator_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(base_t::sequence_type) sequence_type;
|
||||
typedef Key key_type;
|
||||
typedef Compare key_compare;
|
||||
typedef Key value_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::sequence_type) sequence_type;
|
||||
typedef typename sequence_type::allocator_type allocator_type;
|
||||
typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_type;
|
||||
typedef typename sequence_type::pointer pointer;
|
||||
typedef typename sequence_type::const_pointer const_pointer;
|
||||
typedef typename sequence_type::reference reference;
|
||||
typedef typename sequence_type::const_reference const_reference;
|
||||
typedef typename sequence_type::size_type size_type;
|
||||
typedef typename sequence_type::difference_type difference_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type;
|
||||
typedef typename BOOST_CONTAINER_IMPDEF(tree_t::value_compare) value_compare;
|
||||
|
||||
typedef typename sequence_type::iterator iterator;
|
||||
typedef typename sequence_type::const_iterator const_iterator;
|
||||
typedef typename sequence_type::reverse_iterator reverse_iterator;
|
||||
typedef typename sequence_type::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set()
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value &&
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset() BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<AllocatorOrContainer>::value &&
|
||||
container_detail::is_nothrow_default_constructible<Compare>::value)
|
||||
: base_t()
|
||||
: tree_t()
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(const Compare&)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit flat_multiset(const Compare& comp)
|
||||
: base_t(comp)
|
||||
: tree_t(comp)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(const allocator_type&)
|
||||
BOOST_CONTAINER_FORCEINLINE explicit flat_multiset(const allocator_type& a)
|
||||
: base_t(a)
|
||||
: tree_t(a)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(const Compare&, const allocator_type&)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(const Compare& comp, const allocator_type& a)
|
||||
: base_t(comp, a)
|
||||
: tree_t(comp, a)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator)
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last)
|
||||
: base_t(false, first, last)
|
||||
: tree_t(false, first, last)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const allocator_type&)
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const allocator_type& a)
|
||||
: base_t(false, first, last, a)
|
||||
: tree_t(false, first, last, a)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const Compare& comp)
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const Compare& comp)
|
||||
: base_t(false, first, last, comp)
|
||||
: tree_t(false, first, last, comp)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const Compare& comp, const allocator_type&)
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
|
||||
: base_t(false, first, last, comp, a)
|
||||
: tree_t(false, first, last, comp, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multiset and
|
||||
@@ -1136,7 +1149,7 @@ class flat_multiset
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last)
|
||||
: base_t(ordered_range, first, last)
|
||||
: tree_t(ordered_range, first, last)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and
|
||||
@@ -1150,7 +1163,7 @@ class flat_multiset
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp)
|
||||
: base_t(ordered_range, first, last, comp)
|
||||
: tree_t(ordered_range, first, last, comp)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and
|
||||
@@ -1164,28 +1177,28 @@ class flat_multiset
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp, const allocator_type& a)
|
||||
: base_t(ordered_range, first, last, comp, a)
|
||||
: tree_t(ordered_range, first, last, comp, a)
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il)
|
||||
: base_t(false, il.begin(), il.end())
|
||||
: tree_t(false, il.begin(), il.end())
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type>, const allocator_type&)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il, const allocator_type& a)
|
||||
: base_t(false, il.begin(), il.end(), a)
|
||||
: tree_t(false, il.begin(), il.end(), a)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type>, const Compare& comp)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il, const Compare& comp)
|
||||
: base_t(false, il.begin(), il.end(), comp)
|
||||
: tree_t(false, il.begin(), il.end(), comp)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type>, const Compare& comp, const allocator_type&)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
|
||||
: base_t(false, il.begin(), il.end(), comp, a)
|
||||
: tree_t(false, il.begin(), il.end(), comp, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty containerand
|
||||
@@ -1198,7 +1211,7 @@ class flat_multiset
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list<value_type> il)
|
||||
: base_t(ordered_range, il.begin(), il.end())
|
||||
: tree_t(ordered_range, il.begin(), il.end())
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
@@ -1211,7 +1224,7 @@ class flat_multiset
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp)
|
||||
: base_t(ordered_range, il.begin(), il.end(), comp)
|
||||
: tree_t(ordered_range, il.begin(), il.end(), comp)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
|
||||
@@ -1224,41 +1237,41 @@ class flat_multiset
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp, const allocator_type& a)
|
||||
: base_t(ordered_range, il.begin(), il.end(), comp, a)
|
||||
: tree_t(ordered_range, il.begin(), il.end(), comp, a)
|
||||
{}
|
||||
#endif
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(const flat_set &)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(const flat_multiset& x)
|
||||
: base_t(static_cast<const base_t&>(x))
|
||||
: tree_t(static_cast<const tree_t&>(x))
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(flat_set &&)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(BOOST_RV_REF(flat_multiset) x)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<Compare>::value)
|
||||
: base_t(boost::move(static_cast<base_t&>(x)))
|
||||
: tree_t(boost::move(static_cast<tree_t&>(x)))
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(const flat_set &, const allocator_type &)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(const flat_multiset& x, const allocator_type &a)
|
||||
: base_t(static_cast<const base_t&>(x), a)
|
||||
: tree_t(static_cast<const tree_t&>(x), a)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::flat_set(flat_set &&, const allocator_type &)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset(BOOST_RV_REF(flat_multiset) x, const allocator_type &a)
|
||||
: base_t(BOOST_MOVE_BASE(base_t, x), a)
|
||||
: tree_t(BOOST_MOVE_BASE(tree_t, x), a)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::operator=(const flat_set &)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
|
||||
{ return static_cast<flat_multiset&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
|
||||
{ return static_cast<flat_multiset&>(this->tree_t::operator=(static_cast<const tree_t&>(x))); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::operator=(flat_set &&)
|
||||
BOOST_CONTAINER_FORCEINLINE flat_multiset& operator=(BOOST_RV_REF(flat_multiset) x)
|
||||
BOOST_NOEXCEPT_IF( (allocator_traits_type::propagate_on_container_move_assignment::value ||
|
||||
allocator_traits_type::is_always_equal::value) &&
|
||||
boost::container::container_detail::is_nothrow_move_assignable<Compare>::value)
|
||||
{ return static_cast<flat_multiset&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
|
||||
{ return static_cast<flat_multiset&>(this->tree_t::operator=(BOOST_MOVE_BASE(tree_t, x))); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! @copydoc ::boost::container::flat_set::operator=(std::initializer_list<value_type>)
|
||||
@@ -1355,7 +1368,7 @@ class flat_multiset
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
template <class... Args>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_FWD_REF(Args)... args)
|
||||
{ return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
|
||||
{ return this->tree_t::emplace_equal(boost::forward<Args>(args)...); }
|
||||
|
||||
//! <b>Effects</b>: Inserts an object of type Key constructed with
|
||||
//! std::forward<Args>(args)... in the container.
|
||||
@@ -1370,18 +1383,18 @@ class flat_multiset
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
template <class... Args>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
|
||||
{ return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
|
||||
{ return this->tree_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE(N) \
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
BOOST_CONTAINER_FORCEINLINE iterator emplace(BOOST_MOVE_UREF##N)\
|
||||
{ return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
|
||||
{ return this->tree_t::emplace_equal(BOOST_MOVE_FWD##N); }\
|
||||
\
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
BOOST_CONTAINER_FORCEINLINE iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{ return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
|
||||
{ return this->tree_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE)
|
||||
#undef BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE
|
||||
@@ -1448,7 +1461,7 @@ class flat_multiset
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(InputIterator first, InputIterator last)
|
||||
{ this->base_t::insert_equal(first, last); }
|
||||
{ this->tree_t::insert_equal(first, last); }
|
||||
|
||||
//! <b>Requires</b>: first, last are not iterators into *this and
|
||||
//! must be ordered according to the predicate.
|
||||
@@ -1462,7 +1475,7 @@ class flat_multiset
|
||||
//! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
|
||||
template <class InputIterator>
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, InputIterator first, InputIterator last)
|
||||
{ this->base_t::insert_equal(ordered_range, first, last); }
|
||||
{ this->tree_t::insert_equal(ordered_range, first, last); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! <b>Effects</b>: inserts each element from the range [il.begin(), il.end()).
|
||||
@@ -1472,7 +1485,7 @@ class flat_multiset
|
||||
//!
|
||||
//! <b>Note</b>: If an element is inserted it might invalidate elements.
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(std::initializer_list<value_type> il)
|
||||
{ this->base_t::insert_equal(il.begin(), il.end()); }
|
||||
{ this->tree_t::insert_equal(il.begin(), il.end()); }
|
||||
|
||||
//! <b>Requires</b>: Range [il.begin(), il.end()) must be ordered according to the predicate.
|
||||
//!
|
||||
@@ -1484,28 +1497,28 @@ class flat_multiset
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
|
||||
BOOST_CONTAINER_FORCEINLINE void insert(ordered_range_t, std::initializer_list<value_type> il)
|
||||
{ this->base_t::insert_equal(ordered_range, il.begin(), il.end()); }
|
||||
{ this->tree_t::insert_equal(ordered_range, il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_equal(source.tree()); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, AllocatorOrContainer>& source)
|
||||
{ this->tree_t::merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multiset::merge(flat_multiset<Key, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_multiset::merge(flat_multiset<Key, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset<Key, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multiset<Key, C2, Allocator>&>(source)); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_multiset<Key, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_multiset<Key, C2, AllocatorOrContainer>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_map<Key, T, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_equal(source.tree()); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, AllocatorOrContainer>& source)
|
||||
{ this->tree_t::merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multiset::merge(flat_set<Key, C2, Allocator>&)
|
||||
//! @copydoc ::boost::container::flat_multiset::merge(flat_set<Key, C2, AllocatorOrContainer>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set<Key, C2, Allocator> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_set<Key, C2, Allocator>&>(source)); }
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG flat_set<Key, C2, AllocatorOrContainer> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<flat_set<Key, C2, AllocatorOrContainer>&>(source)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
@@ -1624,7 +1637,7 @@ class flat_multiset
|
||||
//!
|
||||
//! <b>Throws</b>: If the comparison or the move constructor throws
|
||||
BOOST_CONTAINER_FORCEINLINE void adopt_sequence(BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->base_t::adopt_sequence_equal(boost::move(seq)); }
|
||||
{ this->tree_t::adopt_sequence_equal(boost::move(seq)); }
|
||||
|
||||
//! <b>Requires</b>: seq shall be ordered according to this->compare()
|
||||
//!
|
||||
@@ -1635,17 +1648,17 @@ class flat_multiset
|
||||
//!
|
||||
//! <b>Throws</b>: If the move assignment throws
|
||||
BOOST_CONTAINER_FORCEINLINE void adopt_sequence(ordered_range_t, BOOST_RV_REF(sequence_type) seq)
|
||||
{ this->base_t::adopt_sequence_equal(ordered_range_t(), boost::move(seq)); }
|
||||
{ this->tree_t::adopt_sequence_equal(ordered_range_t(), boost::move(seq)); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
template <class KeyType>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator priv_insert(BOOST_FWD_REF(KeyType) x)
|
||||
{ return this->base_t::insert_equal(::boost::forward<KeyType>(x)); }
|
||||
{ return this->tree_t::insert_equal(::boost::forward<KeyType>(x)); }
|
||||
|
||||
template <class KeyType>
|
||||
BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
|
||||
{ return this->base_t::insert_equal(p, ::boost::forward<KeyType>(x)); }
|
||||
{ return this->tree_t::insert_equal(p, ::boost::forward<KeyType>(x)); }
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
@@ -1655,11 +1668,11 @@ class flat_multiset
|
||||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class Compare, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, Compare, Allocator> >
|
||||
template <class Key, class Compare, class AllocatorOrContainer>
|
||||
struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, Compare, AllocatorOrContainer> >
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
||||
typedef typename ::boost::container::allocator_traits<AllocatorOrContainer>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<AllocatorOrContainer>::value &&
|
||||
::boost::has_trivial_destructor_after_move<pointer>::value &&
|
||||
::boost::has_trivial_destructor_after_move<Compare>::value;
|
||||
};
|
||||
|
@@ -113,6 +113,8 @@ class static_vector
|
||||
template<class U, std::size_t OtherCapacity>
|
||||
friend class static_vector;
|
||||
|
||||
public:
|
||||
typedef container_detail::static_storage_allocator<Value, Capacity> allocator_type;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
@@ -252,6 +254,19 @@ public:
|
||||
: base_t(other)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector(static_vector const& other, const allocator_type &)
|
||||
: base_t(other)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF(static_vector) other, const allocator_type &)
|
||||
BOOST_NOEXCEPT_IF(boost::container::container_detail::is_nothrow_move_constructible<value_type>::value)
|
||||
: base_t(BOOST_MOVE_BASE(base_t, other))
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit static_vector(const allocator_type &)
|
||||
: base_t()
|
||||
{}
|
||||
|
||||
//! @pre <tt>other.size() <= capacity()</tt>.
|
||||
//!
|
||||
//! @brief Constructs a copy of other static_vector.
|
||||
|
@@ -315,6 +315,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tree_test", "tree_test.vcpr
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flat_tree_test", "flat_tree_test.vcproj", "{DE1834C3-2609-FE38-4FA5-0BA0D3CD0796}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@@ -637,6 +641,10 @@ Global
|
||||
{5CE185C3-2609-4FA5-FE38-792BA0D3A606}.Debug.Build.0 = Debug|Win32
|
||||
{5CE185C3-2609-4FA5-FE38-792BA0D3A606}.Release.ActiveCfg = Release|Win32
|
||||
{5CE185C3-2609-4FA5-FE38-792BA0D3A606}.Release.Build.0 = Release|Win32
|
||||
{DE1834C3-2609-FE38-4FA5-0BA0D3CD0796}.Debug.ActiveCfg = Debug|Win32
|
||||
{DE1834C3-2609-FE38-4FA5-0BA0D3CD0796}.Debug.Build.0 = Debug|Win32
|
||||
{DE1834C3-2609-FE38-4FA5-0BA0D3CD0796}.Release.ActiveCfg = Release|Win32
|
||||
{DE1834C3-2609-FE38-4FA5-0BA0D3CD0796}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
|
@@ -245,6 +245,12 @@
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\function_detector.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\is_container.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\is_contiguous_container.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\boost\container\detail\is_sorted.hpp">
|
||||
</File>
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/detail/flat_tree.hpp>
|
||||
#include <boost/container/stable_vector.hpp>
|
||||
|
||||
#include "print_container.hpp"
|
||||
#include "dummy_test_allocator.hpp"
|
||||
@@ -336,9 +337,25 @@ bool flat_tree_extract_adopt_test()
|
||||
|
||||
}}}
|
||||
|
||||
template<class VoidAllocatorOrContainer, class ValueType, bool = boost::container::container_detail::is_container<VoidAllocatorOrContainer>::value>
|
||||
struct RebindAllocatorOrContainer
|
||||
{
|
||||
typedef typename allocator_traits<VoidAllocatorOrContainer>
|
||||
::template portable_rebind_alloc< std::pair<ValueType, ValueType> >::type type;
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
struct GetAllocatorMap
|
||||
template<class SomeType, class ValueType, template <class> class Allocator>
|
||||
struct RebindAllocatorOrContainer< boost::container::stable_vector<SomeType, Allocator<SomeType> >, ValueType, true>
|
||||
{
|
||||
typedef std::pair<ValueType, ValueType> type_t;
|
||||
typedef typename allocator_traits< Allocator<SomeType> >
|
||||
::template portable_rebind_alloc< type_t >::type allocator_t;
|
||||
typedef typename boost::container::stable_vector<type_t, allocator_t> type;
|
||||
};
|
||||
|
||||
|
||||
template<class VoidAllocatorOrContainer>
|
||||
struct GetMapContainer
|
||||
{
|
||||
template<class ValueType>
|
||||
struct apply
|
||||
@@ -346,15 +363,13 @@ struct GetAllocatorMap
|
||||
typedef flat_map< ValueType
|
||||
, ValueType
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc< std::pair<ValueType, ValueType> >::type
|
||||
, typename RebindAllocatorOrContainer<VoidAllocatorOrContainer, ValueType>::type
|
||||
> map_type;
|
||||
|
||||
typedef flat_multimap< ValueType
|
||||
, ValueType
|
||||
, std::less<ValueType>
|
||||
, typename allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc< std::pair<ValueType, ValueType> >::type
|
||||
, typename RebindAllocatorOrContainer<VoidAllocatorOrContainer, ValueType>::type
|
||||
> multimap_type;
|
||||
};
|
||||
};
|
||||
@@ -402,18 +417,18 @@ struct get_real_stored_allocator<flat_multimap<Key, T, Compare, Allocator> >
|
||||
|
||||
}}} //namespace boost::container::test
|
||||
|
||||
template<class VoidAllocator>
|
||||
template<class VoidAllocatorOrContainer>
|
||||
int test_map_variants()
|
||||
{
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<int>::map_type MyMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_int>::map_type MyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_and_copyable_int>::map_type MyCopyMoveMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::copyable_int>::map_type MyCopyMap;
|
||||
typedef typename GetMapContainer<VoidAllocatorOrContainer>::template apply<int>::map_type MyMap;
|
||||
typedef typename GetMapContainer<VoidAllocatorOrContainer>::template apply<test::movable_int>::map_type MyMoveMap;
|
||||
typedef typename GetMapContainer<VoidAllocatorOrContainer>::template apply<test::movable_and_copyable_int>::map_type MyCopyMoveMap;
|
||||
typedef typename GetMapContainer<VoidAllocatorOrContainer>::template apply<test::copyable_int>::map_type MyCopyMap;
|
||||
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<int>::multimap_type MyMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_int>::multimap_type MyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::movable_and_copyable_int>::multimap_type MyCopyMoveMultiMap;
|
||||
typedef typename GetAllocatorMap<VoidAllocator>::template apply<test::copyable_int>::multimap_type MyCopyMultiMap;
|
||||
typedef typename GetMapContainer<VoidAllocatorOrContainer>::template apply<int>::multimap_type MyMultiMap;
|
||||
typedef typename GetMapContainer<VoidAllocatorOrContainer>::template apply<test::movable_int>::multimap_type MyMoveMultiMap;
|
||||
typedef typename GetMapContainer<VoidAllocatorOrContainer>::template apply<test::movable_and_copyable_int>::multimap_type MyCopyMoveMultiMap;
|
||||
typedef typename GetMapContainer<VoidAllocatorOrContainer>::template apply<test::copyable_int>::multimap_type MyCopyMultiMap;
|
||||
|
||||
typedef std::map<int, int> MyStdMap;
|
||||
typedef std::multimap<int, int> MyStdMultiMap;
|
||||
|
@@ -57,25 +57,6 @@ template class flat_multiset
|
||||
, allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
//Instantiate base class as previous instantiations don't instantiate inherited members
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
} //container_detail {
|
||||
|
||||
//As flat container iterators are typedefs for vector::[const_]iterator,
|
||||
//no need to explicit instantiate them
|
||||
|
||||
|
124
test/flat_tree_test.cpp
Normal file
124
test/flat_tree_test.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/container/detail/flat_tree.hpp>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <boost/container/stable_vector.hpp>
|
||||
#include <boost/container/static_vector.hpp>
|
||||
|
||||
#include "movable_int.hpp"
|
||||
#include "dummy_test_allocator.hpp"
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
typedef boost::container::container_detail::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> pair_t;
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Explicit instantiation to detect compilation errors
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template class flat_tree
|
||||
< pair_t
|
||||
, select1st<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<pair_t>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< pair_t
|
||||
, select1st<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<pair_t>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< pair_t
|
||||
, select1st<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, small_vector<pair_t, 10>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< pair_t
|
||||
, select1st<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, stable_vector<pair_t>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, test::simple_allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::allocator<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, small_vector<test::movable_and_copyable_int, 10>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, stable_vector<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, static_vector<test::movable_and_copyable_int, 10>
|
||||
>;
|
||||
|
||||
} //container_detail {
|
||||
}} //boost::container
|
||||
|
||||
#if (__cplusplus >= 201402L)
|
||||
#include <vector>
|
||||
|
||||
namespace boost{
|
||||
namespace container{
|
||||
namespace container_detail{
|
||||
|
||||
template class flat_tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::vector<test::movable_and_copyable_int>
|
||||
>;
|
||||
|
||||
template class flat_tree
|
||||
< pair_t
|
||||
, select1st<test::movable_and_copyable_int>
|
||||
, std::less<test::movable_and_copyable_int>
|
||||
, std::vector<pair_t>
|
||||
>;
|
||||
|
||||
} //container_detail {
|
||||
}} //boost::container
|
||||
|
||||
#endif
|
||||
|
||||
int main ()
|
||||
{
|
||||
return 0;
|
||||
}
|
@@ -886,14 +886,14 @@ int map_test()
|
||||
for(int i = 0; i < MaxElem; ++i){
|
||||
stdmultimap.insert(StdPairType(MaxElem/2+i, MaxElem-i));
|
||||
}
|
||||
boostmultimap.merge(boost::move(boostmultimap2));
|
||||
boostmultimap.merge(boostmultimap2);
|
||||
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
|
||||
|
||||
for(int i = 0; i < MaxElem; ++i){
|
||||
stdmultimap.insert(StdPairType(MaxElem*2/2+i, MaxElem*2+i));
|
||||
}
|
||||
|
||||
boostmultimap.merge(boost::move(boostmap2));
|
||||
boostmultimap.merge(boostmap2);
|
||||
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
|
||||
}
|
||||
|
||||
|
@@ -49,7 +49,6 @@ template class tree
|
||||
, tree_assoc_defaults
|
||||
>;
|
||||
|
||||
//Instantiate base class as previous instantiations don't instantiate inherited members
|
||||
template class tree
|
||||
< test::movable_and_copyable_int
|
||||
, identity<test::movable_and_copyable_int>
|
||||
|
Reference in New Issue
Block a user