forked from boostorg/container
* Implemented merge operations for associative containers.
* Update tree-based containers to changes done in Intrusive internal utilities in order to fix Trac 12432.
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
|
||||
#include <boost/move/iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
@@ -100,7 +101,7 @@ struct get_flat_tree_iterators
|
||||
typedef boost::container::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
template <class Value, class KeyOfValue,
|
||||
class Compare, class Allocator>
|
||||
class flat_tree
|
||||
{
|
||||
@@ -185,7 +186,7 @@ class flat_tree
|
||||
typedef typename vector_t::const_pointer const_pointer;
|
||||
typedef typename vector_t::reference reference;
|
||||
typedef typename vector_t::const_reference const_reference;
|
||||
typedef Key key_type;
|
||||
typedef typename KeyOfValue::type key_type;
|
||||
typedef Compare key_compare;
|
||||
typedef typename vector_t::allocator_type allocator_type;
|
||||
typedef typename vector_t::size_type size_type;
|
||||
@@ -778,6 +779,36 @@ class flat_tree
|
||||
return n;
|
||||
}
|
||||
|
||||
template<class C2>
|
||||
void merge_unique(flat_tree<Value, KeyOfValue, C2, Allocator>& 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)
|
||||
{
|
||||
this->insert( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end()));
|
||||
}
|
||||
|
||||
void merge_unique(flat_tree& source)
|
||||
{
|
||||
this->m_data.m_vect.merge_unique
|
||||
( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end())
|
||||
, static_cast<const value_compare &>(this->m_data));
|
||||
}
|
||||
|
||||
void merge_equal(flat_tree& source)
|
||||
{
|
||||
this->m_data.m_vect.merge
|
||||
( boost::make_move_iterator(source.begin())
|
||||
, boost::make_move_iterator(source.end())
|
||||
, static_cast<const value_compare &>(this->m_data));
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& k)
|
||||
{ return this->priv_lower_bound(this->begin(), this->end(), k); }
|
||||
|
||||
@@ -1062,9 +1093,9 @@ class flat_tree
|
||||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class T, class KeyOfValue,
|
||||
template <class T, class KeyOfValue,
|
||||
class Compare, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<Key, T, KeyOfValue, Compare, Allocator> >
|
||||
struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<T, KeyOfValue, Compare, Allocator> >
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
||||
|
||||
@@ -394,12 +394,6 @@ struct node_alloc_holder
|
||||
ICont &non_const_icont() const
|
||||
{ return const_cast<ICont&>(this->members_.m_icont); }
|
||||
|
||||
ICont &icont()
|
||||
{ return this->members_.m_icont; }
|
||||
|
||||
const ICont &icont() const
|
||||
{ return this->members_.m_icont; }
|
||||
|
||||
NodeAlloc &node_alloc()
|
||||
{ return static_cast<NodeAlloc &>(this->members_); }
|
||||
|
||||
@@ -407,6 +401,13 @@ struct node_alloc_holder
|
||||
{ return static_cast<const NodeAlloc &>(this->members_); }
|
||||
|
||||
members_holder members_;
|
||||
|
||||
public:
|
||||
ICont &icont()
|
||||
{ return this->members_.m_icont; }
|
||||
|
||||
const ICont &icont() const
|
||||
{ return this->members_.m_icont; }
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
@@ -295,9 +295,9 @@ struct intrusive_tree_type
|
||||
allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename container_detail::tree_node
|
||||
< value_type, void_pointer
|
||||
, tree_type_value, OptimizeSize> node_t;
|
||||
, tree_type_value, OptimizeSize> node_t;
|
||||
typedef value_to_node_compare
|
||||
<node_t, ValueCompare> node_compare_type;
|
||||
<node_t, ValueCompare> node_compare_type;
|
||||
//Deducing the hook type from node_t (e.g. node_t::hook_type) would
|
||||
//provoke an early instantiation of node_t that could ruin recursive
|
||||
//tree definitions, so retype the complete type to avoid any problem.
|
||||
@@ -429,26 +429,28 @@ struct key_node_compare
|
||||
{ return this->key_comp()(key_of_value()(nonkey1.get_data()), key_of_value()(nonkey2.get_data())); }
|
||||
};
|
||||
|
||||
template <class Key, class T, class KeyOfValue,
|
||||
template <class T, class KeyOfValue,
|
||||
class Compare, class Allocator,
|
||||
class Options = tree_assoc_defaults>
|
||||
class tree
|
||||
: protected container_detail::node_alloc_holder
|
||||
: public container_detail::node_alloc_holder
|
||||
< Allocator
|
||||
, typename container_detail::intrusive_tree_type
|
||||
< Allocator, tree_value_compare<Compare, KeyOfValue> //ValComp
|
||||
< Allocator, tree_value_compare
|
||||
<typename allocator_traits<Allocator>::pointer, Compare, KeyOfValue>
|
||||
, Options::tree_type, Options::optimize_size>::type
|
||||
>
|
||||
{
|
||||
typedef tree_value_compare
|
||||
<Compare, KeyOfValue> ValComp;
|
||||
< typename allocator_traits<Allocator>::pointer
|
||||
, Compare, KeyOfValue> ValComp;
|
||||
typedef typename container_detail::intrusive_tree_type
|
||||
< Allocator, ValComp, Options::tree_type
|
||||
, Options::optimize_size>::type Icont;
|
||||
typedef container_detail::node_alloc_holder
|
||||
<Allocator, Icont> AllocHolder;
|
||||
typedef typename AllocHolder::NodePtr NodePtr;
|
||||
typedef tree < Key, T, KeyOfValue
|
||||
typedef tree < T, KeyOfValue
|
||||
, Compare, Allocator, Options> ThisType;
|
||||
typedef typename AllocHolder::NodeAlloc NodeAlloc;
|
||||
typedef boost::container::
|
||||
@@ -465,7 +467,7 @@ class tree
|
||||
|
||||
public:
|
||||
|
||||
typedef Key key_type;
|
||||
typedef typename KeyOfValue::type key_type;
|
||||
typedef T value_type;
|
||||
typedef Allocator allocator_type;
|
||||
typedef Compare key_compare;
|
||||
@@ -1176,6 +1178,13 @@ class tree
|
||||
}
|
||||
}
|
||||
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge_unique(tree<T, KeyOfValue, C2, Allocator, Options>& source)
|
||||
{ return this->icont().merge_unique(source.icont()); }
|
||||
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge_equal(tree<T, KeyOfValue, C2, Allocator, Options>& source)
|
||||
{ return this->icont().merge_equal(source.icont()); }
|
||||
BOOST_CONTAINER_FORCEINLINE void clear()
|
||||
{ AllocHolder::clear(alloc_version()); }
|
||||
|
||||
@@ -1265,11 +1274,11 @@ struct has_trivial_destructor_after_move;
|
||||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class T, class KeyOfValue, class Compare, class Allocator, class Options>
|
||||
template <class T, class KeyOfValue, class Compare, class Allocator, class Options>
|
||||
struct has_trivial_destructor_after_move
|
||||
<
|
||||
::boost::container::container_detail::tree
|
||||
<Key, T, KeyOfValue, Compare, Allocator, Options>
|
||||
<T, KeyOfValue, Compare, Allocator, Options>
|
||||
>
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
|
||||
@@ -53,6 +53,9 @@ namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
class flat_multimap;
|
||||
|
||||
namespace container_detail{
|
||||
|
||||
template<class D, class S>
|
||||
@@ -110,14 +113,14 @@ class flat_map
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_map)
|
||||
//This is the tree that we should store if pair was movable
|
||||
typedef container_detail::flat_tree<Key,
|
||||
typedef container_detail::flat_tree<
|
||||
std::pair<Key, T>,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
Allocator> tree_t;
|
||||
|
||||
//This is the real tree stored here. It's based on a movable pair
|
||||
typedef container_detail::flat_tree<Key,
|
||||
typedef container_detail::flat_tree<
|
||||
container_detail::pair<Key, T>,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
@@ -143,6 +146,13 @@ class flat_map
|
||||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
public:
|
||||
typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
|
||||
|
||||
impl_tree_t &tree()
|
||||
{ return m_flat_tree; }
|
||||
|
||||
const impl_tree_t &tree() const
|
||||
{ return m_flat_tree; }
|
||||
|
||||
private:
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
@@ -1056,6 +1066,39 @@ class flat_map
|
||||
{ m_flat_tree.insert_unique(ordered_unique_range, il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: this->get_allocator() == source.get_allocator().
|
||||
//!
|
||||
//! <b>Effects</b>: Attempts to extract each element in source and insert it into a using
|
||||
//! the comparison object of *this. If there is an element in a with key equivalent to the
|
||||
//! key of an element from source, then that element is not extracted from source.
|
||||
//!
|
||||
//! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
|
||||
//! to those same elements but as members of *this. Iterators referring to the transferred
|
||||
//! elements will continue to refer to their elements, but they now behave as iterators into *this,
|
||||
//! not into source.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing unless the comparison object throws.
|
||||
//!
|
||||
//! <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)
|
||||
{ m_flat_tree.merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
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)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, Allocator>& source)
|
||||
{ m_flat_tree.merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
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)); }
|
||||
|
||||
//! <b>Effects</b>: Erases the element pointed to by p.
|
||||
//!
|
||||
//! <b>Returns</b>: Returns an iterator pointing to the element immediately
|
||||
@@ -1326,13 +1369,13 @@ class flat_multimap
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
|
||||
typedef container_detail::flat_tree<Key,
|
||||
typedef container_detail::flat_tree<
|
||||
std::pair<Key, T>,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
Allocator> tree_t;
|
||||
//This is the real tree stored here. It's based on a movable pair
|
||||
typedef container_detail::flat_tree<Key,
|
||||
typedef container_detail::flat_tree<
|
||||
container_detail::pair<Key, T>,
|
||||
container_detail::select1st<Key>,
|
||||
Compare,
|
||||
@@ -1358,6 +1401,13 @@ class flat_multimap
|
||||
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
|
||||
public:
|
||||
typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
|
||||
|
||||
impl_tree_t &tree()
|
||||
{ return m_flat_tree; }
|
||||
|
||||
const impl_tree_t &tree() const
|
||||
{ return m_flat_tree; }
|
||||
|
||||
private:
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
@@ -1993,6 +2043,38 @@ class flat_multimap
|
||||
{ m_flat_tree.insert_equal(ordered_range, il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! <b>Requires</b>: this->get_allocator() == source.get_allocator().
|
||||
//!
|
||||
//! <b>Effects</b>: Extracts each element in source and insert it into a using
|
||||
//! the comparison object of *this.
|
||||
//!
|
||||
//! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
|
||||
//! to those same elements but as members of *this. Iterators referring to the transferred
|
||||
//! elements will continue to refer to their elements, but they now behave as iterators into *this,
|
||||
//! not into source.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing unless the comparison object throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
|
||||
template<class C2>
|
||||
void merge(flat_multimap<Key, T, C2, Allocator>& source)
|
||||
{ m_flat_tree.merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
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)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
void merge(flat_map<Key, T, C2, Allocator>& source)
|
||||
{ m_flat_tree.merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
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)); }
|
||||
|
||||
//! <b>Effects</b>: Erases the element pointed to by p.
|
||||
//!
|
||||
//! <b>Returns</b>: Returns an iterator pointing to the element immediately
|
||||
|
||||
@@ -47,6 +47,11 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
class flat_multimap;
|
||||
#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.
|
||||
//!
|
||||
@@ -69,13 +74,21 @@ template <class Key, class Compare, class Allocator>
|
||||
#endif
|
||||
class flat_set
|
||||
///@cond
|
||||
: public container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator>
|
||||
: public container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator>
|
||||
///@endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_set)
|
||||
typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> base_t;
|
||||
typedef container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator> base_t;
|
||||
|
||||
public:
|
||||
base_t &tree()
|
||||
{ return *this; }
|
||||
|
||||
const base_t &tree() const
|
||||
{ return *this; }
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
@@ -605,6 +618,26 @@ class flat_set
|
||||
{ this->base_t::insert_unique(ordered_unique_range, il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_set<Key, C2, Allocator>&)
|
||||
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)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_unique(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_map::merge(flat_multiset<Key, C2, Allocator>&)
|
||||
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)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Effects</b>: Erases the element pointed to by p.
|
||||
@@ -867,13 +900,20 @@ template <class Key, class Compare, class Allocator>
|
||||
#endif
|
||||
class flat_multiset
|
||||
///@cond
|
||||
: public container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator>
|
||||
: public container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator>
|
||||
///@endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(flat_multiset)
|
||||
typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> base_t;
|
||||
typedef container_detail::flat_tree<Key, container_detail::identity<Key>, Compare, Allocator> base_t;
|
||||
|
||||
public:
|
||||
base_t &tree()
|
||||
{ return *this; }
|
||||
|
||||
const base_t &tree() const
|
||||
{ return *this; }
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
@@ -1233,6 +1273,26 @@ class flat_multiset
|
||||
{ this->base_t::insert_equal(ordered_range, il.begin(), il.end()); }
|
||||
#endif
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_multimap<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_multiset<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multiset::merge(flat_multiset<Key, C2, Allocator>&)
|
||||
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)); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multimap::merge(flat_map<Key, T, C2, Allocator>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(flat_set<Key, C2, Allocator>& source)
|
||||
{ this->base_t::merge_equal(source.tree()); }
|
||||
|
||||
//! @copydoc ::boost::container::flat_multiset::merge(flat_set<Key, C2, Allocator>&)
|
||||
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)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! @copydoc ::boost::container::flat_set::erase(const_iterator)
|
||||
|
||||
@@ -96,18 +96,18 @@ struct pair_key_mapped_of_value
|
||||
//! \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<const Key, T> > </i>).
|
||||
//! \tparam MapOptions is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template < class Key, class T, class Compare = std::less<Key>
|
||||
, class Allocator = new_allocator< std::pair< const Key, T> >, class MapOptions = tree_assoc_defaults >
|
||||
, class Allocator = new_allocator< std::pair< const Key, T> >, class Options = tree_assoc_defaults >
|
||||
#else
|
||||
template <class Key, class T, class Compare, class Allocator, class MapOptions>
|
||||
template <class Key, class T, class Compare, class Allocator, class Options>
|
||||
#endif
|
||||
class map
|
||||
///@cond
|
||||
: public container_detail::tree
|
||||
< Key, std::pair<const Key, T>
|
||||
< std::pair<const Key, T>
|
||||
, container_detail::select1st<Key>
|
||||
, Compare, Allocator, MapOptions>
|
||||
, Compare, Allocator, Options>
|
||||
///@endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
@@ -117,10 +117,9 @@ class map
|
||||
typedef container_detail::select1st<Key> select_1st_t;
|
||||
typedef std::pair<const Key, T> value_type_impl;
|
||||
typedef container_detail::tree
|
||||
<Key, value_type_impl, select_1st_t, Compare, Allocator, MapOptions> base_t;
|
||||
<value_type_impl, select_1st_t, Compare, Allocator, Options> base_t;
|
||||
typedef container_detail::pair <Key, T> movable_value_type_impl;
|
||||
typedef container_detail::tree_value_compare
|
||||
<Compare, select_1st_t> value_compare_impl;
|
||||
typedef typename base_t::value_compare value_compare_impl;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
@@ -975,6 +974,47 @@ class map
|
||||
return BOOST_MOVE_RET(node_type, nh);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: this->get_allocator() == source.get_allocator().
|
||||
//!
|
||||
//! <b>Effects</b>: Attempts to extract each element in source and insert it into a using
|
||||
//! the comparison object of *this. If there is an element in a with key equivalent to the
|
||||
//! key of an element from source, then that element is not extracted from source.
|
||||
//!
|
||||
//! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
|
||||
//! to those same elements but as members of *this. Iterators referring to the transferred
|
||||
//! elements will continue to refer to their elements, but they now behave as iterators into *this,
|
||||
//! not into source.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing unless the comparison object throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(map<Key, T, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<value_type_impl, select_1st_t, C2, Allocator, Options> base2_t;
|
||||
this->merge_unique(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::map::merge(map<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG map<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<map<Key, T, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::map::merge(map<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(multimap<Key, T, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<value_type_impl, select_1st_t, C2, Allocator, Options> base2_t;
|
||||
this->base_t::merge_unique(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::map::merge(map<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multimap<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<multimap<Key, T, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
//! <b>Effects</b>: Swaps the contents of *this and x.
|
||||
//!
|
||||
@@ -1148,18 +1188,18 @@ namespace container {
|
||||
//! \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<const Key, T> > </i>).
|
||||
//! \tparam MultiMapOptions is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template < class Key, class T, class Compare = std::less<Key>
|
||||
, class Allocator = new_allocator< std::pair< const Key, T> >, class MultiMapOptions = tree_assoc_defaults>
|
||||
, class Allocator = new_allocator< std::pair< const Key, T> >, class Options = tree_assoc_defaults>
|
||||
#else
|
||||
template <class Key, class T, class Compare, class Allocator, class MultiMapOptions>
|
||||
template <class Key, class T, class Compare, class Allocator, class Options>
|
||||
#endif
|
||||
class multimap
|
||||
///@cond
|
||||
: public container_detail::tree
|
||||
< Key, std::pair<const Key, T>
|
||||
< std::pair<const Key, T>
|
||||
, container_detail::select1st<Key>
|
||||
, Compare, Allocator, MultiMapOptions>
|
||||
, Compare, Allocator, Options>
|
||||
///@endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
@@ -1169,10 +1209,9 @@ class multimap
|
||||
typedef container_detail::select1st<Key> select_1st_t;
|
||||
typedef std::pair<const Key, T> value_type_impl;
|
||||
typedef container_detail::tree
|
||||
<Key, value_type_impl, select_1st_t, Compare, Allocator, MultiMapOptions> base_t;
|
||||
<value_type_impl, select_1st_t, Compare, Allocator, Options> base_t;
|
||||
typedef container_detail::pair <Key, T> movable_value_type_impl;
|
||||
typedef container_detail::tree_value_compare
|
||||
<Compare, select_1st_t> value_compare_impl;
|
||||
typedef typename base_t::value_compare value_compare_impl;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||
@@ -1655,6 +1694,46 @@ class multimap
|
||||
return node_type (boost::move(base_nh));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: this->get_allocator() == source.get_allocator().
|
||||
//!
|
||||
//! <b>Effects</b>: Extracts each element in source and insert it into a using
|
||||
//! the comparison object of *this.
|
||||
//!
|
||||
//! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
|
||||
//! to those same elements but as members of *this. Iterators referring to the transferred
|
||||
//! elements will continue to refer to their elements, but they now behave as iterators into *this,
|
||||
//! not into source.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing unless the comparison object throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
|
||||
template<class C2>
|
||||
void merge(multimap<Key, T, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<value_type_impl, select_1st_t, C2, Allocator, Options> base2_t;
|
||||
this->base_t::merge_equal(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
void merge(BOOST_RV_REF_BEG multimap<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<multimap<Key, T, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
void merge(map<Key, T, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<value_type_impl, select_1st_t, C2, Allocator, Options> base2_t;
|
||||
this->base_t::merge_equal(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
void merge(BOOST_RV_REF_BEG map<Key, T, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<map<Key, T, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
//! @copydoc ::boost::container::set::swap
|
||||
void swap(multiset& x)
|
||||
|
||||
@@ -59,22 +59,22 @@ namespace container {
|
||||
//! \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 SetOptions is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class SetOptions = tree_assoc_defaults >
|
||||
//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = tree_assoc_defaults >
|
||||
#else
|
||||
template <class Key, class Compare, class Allocator, class SetOptions>
|
||||
template <class Key, class Compare, class Allocator, class Options>
|
||||
#endif
|
||||
class set
|
||||
///@cond
|
||||
: public container_detail::tree
|
||||
< Key, Key, container_detail::identity<Key>, Compare, Allocator, SetOptions>
|
||||
< Key, container_detail::identity<Key>, Compare, Allocator, Options>
|
||||
///@endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(set)
|
||||
typedef container_detail::tree
|
||||
< Key, Key, container_detail::identity<Key>, Compare, Allocator, SetOptions> base_t;
|
||||
< Key, container_detail::identity<Key>, Compare, Allocator, Options> base_t;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
@@ -533,6 +533,34 @@ class set
|
||||
insert_return_type insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
|
||||
{ return this->base_t::insert_unique_node(hint, boost::move(nh)); }
|
||||
|
||||
//! @copydoc ::boost::container::map::merge(map<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<Key, container_detail::identity<Key>, C2, Allocator, Options> base2_t;
|
||||
this->base_t::merge_unique(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::set::merge(set<Key, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<set<Key, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::map::merge(multimap<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<Key, container_detail::identity<Key>, C2, Allocator, Options> base2_t;
|
||||
this->base_t::merge_unique(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::set::merge(multiset<Key, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Effects</b>: Erases the element pointed to by p.
|
||||
@@ -724,8 +752,8 @@ class set
|
||||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class Compare, class SetOptions, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::set<Key, Compare, Allocator, SetOptions> >
|
||||
template <class Key, class Compare, class Options, class Allocator>
|
||||
struct has_trivial_destructor_after_move<boost::container::set<Key, Compare, Allocator, Options> >
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
||||
@@ -750,22 +778,22 @@ namespace container {
|
||||
//! \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 MultiSetOptions is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class MultiSetOptions = tree_assoc_defaults >
|
||||
//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = tree_assoc_defaults >
|
||||
#else
|
||||
template <class Key, class Compare, class Allocator, class MultiSetOptions>
|
||||
template <class Key, class Compare, class Allocator, class Options>
|
||||
#endif
|
||||
class multiset
|
||||
/// @cond
|
||||
: public container_detail::tree
|
||||
<Key, Key,container_detail::identity<Key>, Compare, Allocator, MultiSetOptions>
|
||||
<Key,container_detail::identity<Key>, Compare, Allocator, Options>
|
||||
/// @endcond
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(multiset)
|
||||
typedef container_detail::tree
|
||||
<Key, Key,container_detail::identity<Key>, Compare, Allocator, MultiSetOptions> base_t;
|
||||
<Key,container_detail::identity<Key>, Compare, Allocator, Options> base_t;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
@@ -1068,6 +1096,34 @@ class multiset
|
||||
iterator insert(const_iterator hint, BOOST_RV_REF_BEG_IF_CXX11 node_type BOOST_RV_REF_END_IF_CXX11 nh)
|
||||
{ return this->base_t::insert_equal_node(hint, boost::move(nh)); }
|
||||
|
||||
//! @copydoc ::boost::container::multimap::merge(multimap<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(multiset<Key, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<Key, container_detail::identity<Key>, C2, Allocator, Options> base2_t;
|
||||
this->base_t::merge_equal(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::multiset::merge(multiset<Key, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG multiset<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<multiset<Key, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
//! @copydoc ::boost::container::multimap::merge(map<Key, T, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(set<Key, C2, Allocator, Options>& source)
|
||||
{
|
||||
typedef container_detail::tree
|
||||
<Key, container_detail::identity<Key>, C2, Allocator, Options> base2_t;
|
||||
this->base_t::merge_equal(static_cast<base2_t&>(source));
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::container::multiset::merge(set<Key, C2, Allocator, Options>&)
|
||||
template<class C2>
|
||||
BOOST_CONTAINER_FORCEINLINE void merge(BOOST_RV_REF_BEG set<Key, C2, Allocator, Options> BOOST_RV_REF_END source)
|
||||
{ return this->merge(static_cast<set<Key, C2, Allocator, Options>&>(source)); }
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! @copydoc ::boost::container::set::erase(const_iterator)
|
||||
@@ -1179,8 +1235,8 @@ class multiset
|
||||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class Key, class Compare, class Allocator, class MultiSetOptions>
|
||||
struct has_trivial_destructor_after_move<boost::container::multiset<Key, Compare, Allocator, MultiSetOptions> >
|
||||
template <class Key, class Compare, class Allocator, class Options>
|
||||
struct has_trivial_destructor_after_move<boost::container::multiset<Key, Compare, Allocator, Options> >
|
||||
{
|
||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
|
||||
|
||||
Reference in New Issue
Block a user