mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 14:04:26 +02:00
Fixes for scoped_allocator
[SVN r78148]
This commit is contained in:
@@ -32,6 +32,8 @@
|
|||||||
#include <boost/container/vector.hpp>
|
#include <boost/container/vector.hpp>
|
||||||
#include <boost/container/detail/value_init.hpp>
|
#include <boost/container/detail/value_init.hpp>
|
||||||
#include <boost/container/detail/destroyers.hpp>
|
#include <boost/container/detail/destroyers.hpp>
|
||||||
|
#include <boost/container/allocator_traits.hpp>
|
||||||
|
#include <boost/aligned_storage.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
@@ -173,6 +175,10 @@ class flat_tree
|
|||||||
//!Standard extension
|
//!Standard extension
|
||||||
typedef allocator_type stored_allocator_type;
|
typedef allocator_type stored_allocator_type;
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef allocator_traits<stored_allocator_type> stored_allocator_traits;
|
||||||
|
|
||||||
|
public:
|
||||||
flat_tree()
|
flat_tree()
|
||||||
: m_data()
|
: m_data()
|
||||||
{ }
|
{ }
|
||||||
@@ -377,44 +383,65 @@ class flat_tree
|
|||||||
template <class... Args>
|
template <class... Args>
|
||||||
std::pair<iterator, bool> emplace_unique(Args&&... args)
|
std::pair<iterator, bool> emplace_unique(Args&&... args)
|
||||||
{
|
{
|
||||||
value_type && val = value_type(boost::forward<Args>(args)...);
|
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
|
||||||
|
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||||
|
stored_allocator_type &a = this->get_stored_allocator();
|
||||||
|
stored_allocator_traits::construct(a, &val, ::boost::forward(args)... );
|
||||||
|
scoped_destructor<stored_allocator_type> d(a, &val);
|
||||||
insert_commit_data data;
|
insert_commit_data data;
|
||||||
std::pair<iterator,bool> ret =
|
std::pair<iterator,bool> ret =
|
||||||
priv_insert_unique_prepare(val, data);
|
priv_insert_unique_prepare(val, data);
|
||||||
if(ret.second){
|
if(ret.second){
|
||||||
ret.first = priv_insert_commit(data, boost::move(val));
|
ret.first = priv_insert_commit(data, boost::move(val));
|
||||||
}
|
}
|
||||||
|
d.release();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
iterator emplace_hint_unique(const_iterator hint, Args&&... args)
|
iterator emplace_hint_unique(const_iterator hint, Args&&... args)
|
||||||
{
|
{
|
||||||
value_type && val = value_type(boost::forward<Args>(args)...);
|
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
|
||||||
|
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||||
|
stored_allocator_type &a = this->get_stored_allocator();
|
||||||
|
stored_allocator_traits::construct(a, &val, ::boost::forward(args)... );
|
||||||
|
scoped_destructor<stored_allocator_type> d(a, &val);
|
||||||
insert_commit_data data;
|
insert_commit_data data;
|
||||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
|
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
|
||||||
if(ret.second){
|
if(ret.second){
|
||||||
ret.first = priv_insert_commit(data, boost::move(val));
|
ret.first = priv_insert_commit(data, boost::move(val));
|
||||||
}
|
}
|
||||||
|
d.release();
|
||||||
return ret.first;
|
return ret.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
iterator emplace_equal(Args&&... args)
|
iterator emplace_equal(Args&&... args)
|
||||||
{
|
{
|
||||||
value_type &&val = value_type(boost::forward<Args>(args)...);
|
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
|
||||||
|
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||||
|
stored_allocator_type &a = this->get_stored_allocator();
|
||||||
|
stored_allocator_traits::construct(a, &val, ::boost::forward(args)... );
|
||||||
|
scoped_destructor<stored_allocator_type> d(a, &val);
|
||||||
iterator i = this->upper_bound(KeyOfValue()(val));
|
iterator i = this->upper_bound(KeyOfValue()(val));
|
||||||
i = this->m_data.m_vect.insert(i, boost::move(val));
|
i = this->m_data.m_vect.insert(i, boost::move(val));
|
||||||
|
d.release();
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
iterator emplace_hint_equal(const_iterator hint, Args&&... args)
|
iterator emplace_hint_equal(const_iterator hint, Args&&... args)
|
||||||
{
|
{
|
||||||
value_type &&val = value_type(boost::forward<Args>(args)...);
|
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
|
||||||
|
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||||
|
stored_allocator_type &a = this->get_stored_allocator();
|
||||||
|
stored_allocator_traits::construct(a, &val, ::boost::forward(args)... );
|
||||||
|
scoped_destructor<stored_allocator_type> d(a, &val);
|
||||||
insert_commit_data data;
|
insert_commit_data data;
|
||||||
this->priv_insert_equal_prepare(hint, val, data);
|
this->priv_insert_equal_prepare(hint, val, data);
|
||||||
return priv_insert_commit(data, boost::move(val));
|
iterator i = priv_insert_commit(data, boost::move(val));
|
||||||
|
d.release();
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||||
@@ -424,15 +451,18 @@ class flat_tree
|
|||||||
std::pair<iterator, bool> \
|
std::pair<iterator, bool> \
|
||||||
emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||||
{ \
|
{ \
|
||||||
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type \
|
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
|
||||||
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n) \
|
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
|
||||||
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n); \
|
stored_allocator_type &a = this->get_stored_allocator(); \
|
||||||
value_type &val = vval; \
|
stored_allocator_traits::construct(a, &val \
|
||||||
|
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
|
||||||
|
scoped_destructor<stored_allocator_type> d(a, &val); \
|
||||||
insert_commit_data data; \
|
insert_commit_data data; \
|
||||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
|
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
|
||||||
if(ret.second){ \
|
if(ret.second){ \
|
||||||
ret.first = priv_insert_commit(data, boost::move(val)); \
|
ret.first = priv_insert_commit(data, boost::move(val)); \
|
||||||
} \
|
} \
|
||||||
|
d.release(); \
|
||||||
return ret; \
|
return ret; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -440,27 +470,33 @@ class flat_tree
|
|||||||
iterator emplace_hint_unique(const_iterator hint \
|
iterator emplace_hint_unique(const_iterator hint \
|
||||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||||
{ \
|
{ \
|
||||||
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type \
|
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
|
||||||
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n) \
|
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
|
||||||
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n); \
|
stored_allocator_type &a = this->get_stored_allocator(); \
|
||||||
value_type &val = vval; \
|
stored_allocator_traits::construct(a, &val \
|
||||||
|
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
|
||||||
|
scoped_destructor<stored_allocator_type> d(a, &val); \
|
||||||
insert_commit_data data; \
|
insert_commit_data data; \
|
||||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
|
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
|
||||||
if(ret.second){ \
|
if(ret.second){ \
|
||||||
ret.first = priv_insert_commit(data, boost::move(val)); \
|
ret.first = priv_insert_commit(data, boost::move(val)); \
|
||||||
} \
|
} \
|
||||||
|
d.release(); \
|
||||||
return ret.first; \
|
return ret.first; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
|
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
|
||||||
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||||
{ \
|
{ \
|
||||||
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type \
|
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
|
||||||
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n) \
|
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
|
||||||
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n); \
|
stored_allocator_type &a = this->get_stored_allocator(); \
|
||||||
value_type &val = vval; \
|
stored_allocator_traits::construct(a, &val \
|
||||||
|
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
|
||||||
|
scoped_destructor<stored_allocator_type> d(a, &val); \
|
||||||
iterator i = this->upper_bound(KeyOfValue()(val)); \
|
iterator i = this->upper_bound(KeyOfValue()(val)); \
|
||||||
i = this->m_data.m_vect.insert(i, boost::move(val)); \
|
i = this->m_data.m_vect.insert(i, boost::move(val)); \
|
||||||
|
d.release(); \
|
||||||
return i; \
|
return i; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -468,14 +504,19 @@ class flat_tree
|
|||||||
iterator emplace_hint_equal(const_iterator hint \
|
iterator emplace_hint_equal(const_iterator hint \
|
||||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||||
{ \
|
{ \
|
||||||
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type \
|
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
|
||||||
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n) \
|
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
|
||||||
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n); \
|
stored_allocator_type &a = this->get_stored_allocator(); \
|
||||||
value_type &val = vval; \
|
stored_allocator_traits::construct(a, &val \
|
||||||
|
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
|
||||||
|
scoped_destructor<stored_allocator_type> d(a, &val); \
|
||||||
insert_commit_data data; \
|
insert_commit_data data; \
|
||||||
this->priv_insert_equal_prepare(hint, val, data); \
|
this->priv_insert_equal_prepare(hint, val, data); \
|
||||||
return priv_insert_commit(data, boost::move(val)); \
|
iterator i = priv_insert_commit(data, boost::move(val)); \
|
||||||
|
d.release(); \
|
||||||
|
return i; \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
//!
|
//!
|
||||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||||
#include BOOST_PP_LOCAL_ITERATE()
|
#include BOOST_PP_LOCAL_ITERATE()
|
||||||
|
@@ -300,14 +300,6 @@ class flat_map
|
|||||||
const_iterator begin() const
|
const_iterator begin() const
|
||||||
{ return container_detail::force<const_iterator>(m_flat_tree.begin()); }
|
{ return container_detail::force<const_iterator>(m_flat_tree.begin()); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
//!
|
|
||||||
//! <b>Complexity</b>: Constant.
|
|
||||||
const_iterator cbegin() const
|
|
||||||
{ return container_detail::force<const_iterator>(m_flat_tree.cbegin()); }
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns an iterator to the end of the container.
|
//! <b>Effects</b>: Returns an iterator to the end of the container.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: Nothing.
|
//! <b>Throws</b>: Nothing.
|
||||||
@@ -324,14 +316,6 @@ class flat_map
|
|||||||
const_iterator end() const
|
const_iterator end() const
|
||||||
{ return container_detail::force<const_iterator>(m_flat_tree.end()); }
|
{ return container_detail::force<const_iterator>(m_flat_tree.end()); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
//!
|
|
||||||
//! <b>Complexity</b>: Constant.
|
|
||||||
const_iterator cend() const
|
|
||||||
{ return container_detail::force<const_iterator>(m_flat_tree.cend()); }
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
|
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
|
||||||
//! of the reversed container.
|
//! of the reversed container.
|
||||||
//!
|
//!
|
||||||
@@ -350,15 +334,6 @@ class flat_map
|
|||||||
const_reverse_iterator rbegin() const
|
const_reverse_iterator rbegin() const
|
||||||
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.rbegin()); }
|
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.rbegin()); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
|
|
||||||
//! of the reversed container.
|
|
||||||
//!
|
|
||||||
//! <b>Throws</b>: Nothing.
|
|
||||||
//!
|
|
||||||
//! <b>Complexity</b>: Constant.
|
|
||||||
const_reverse_iterator crbegin() const
|
|
||||||
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.crbegin()); }
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
|
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
|
||||||
//! of the reversed container.
|
//! of the reversed container.
|
||||||
//!
|
//!
|
||||||
@@ -377,6 +352,31 @@ class flat_map
|
|||||||
const_reverse_iterator rend() const
|
const_reverse_iterator rend() const
|
||||||
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.rend()); }
|
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.rend()); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_iterator cbegin() const
|
||||||
|
{ return container_detail::force<const_iterator>(m_flat_tree.cbegin()); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_iterator cend() const
|
||||||
|
{ return container_detail::force<const_iterator>(m_flat_tree.cend()); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
|
||||||
|
//! of the reversed container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_reverse_iterator crbegin() const
|
||||||
|
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.crbegin()); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
|
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
|
||||||
//! of the reversed container.
|
//! of the reversed container.
|
||||||
//!
|
//!
|
||||||
@@ -1119,6 +1119,40 @@ class flat_multimap
|
|||||||
const_reverse_iterator rend() const
|
const_reverse_iterator rend() const
|
||||||
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.rend()); }
|
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.rend()); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_iterator cbegin() const
|
||||||
|
{ return container_detail::force<const_iterator>(m_flat_tree.cbegin()); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_iterator cend() const
|
||||||
|
{ return container_detail::force<const_iterator>(m_flat_tree.cend()); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
|
||||||
|
//! of the reversed container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_reverse_iterator crbegin() const
|
||||||
|
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.crbegin()); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
|
||||||
|
//! of the reversed container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_reverse_iterator crend() const
|
||||||
|
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.crend()); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns true if the container contains no elements.
|
//! <b>Effects</b>: Returns true if the container contains no elements.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: Nothing.
|
//! <b>Throws</b>: Nothing.
|
||||||
|
@@ -65,6 +65,10 @@ template <class T, class VoidPointer>
|
|||||||
struct list_node
|
struct list_node
|
||||||
: public list_hook<VoidPointer>::type
|
: public list_hook<VoidPointer>::type
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
list_node();
|
||||||
|
|
||||||
|
public:
|
||||||
typedef typename list_hook<VoidPointer>::type hook_type;
|
typedef typename list_hook<VoidPointer>::type hook_type;
|
||||||
T m_data;
|
T m_data;
|
||||||
};
|
};
|
||||||
|
@@ -276,6 +276,14 @@ class map
|
|||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
const_iterator begin() const
|
const_iterator begin() const
|
||||||
|
{ return this->cbegin(); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_iterator cbegin() const
|
||||||
{ return m_tree.begin(); }
|
{ return m_tree.begin(); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns an iterator to the end of the container.
|
//! <b>Effects</b>: Returns an iterator to the end of the container.
|
||||||
@@ -292,6 +300,14 @@ class map
|
|||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
const_iterator end() const
|
const_iterator end() const
|
||||||
|
{ return this->cend(); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_iterator cend() const
|
||||||
{ return m_tree.end(); }
|
{ return m_tree.end(); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
|
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
|
||||||
@@ -310,6 +326,15 @@ class map
|
|||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
const_reverse_iterator rbegin() const
|
const_reverse_iterator rbegin() const
|
||||||
|
{ return this->crbegin(); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
|
||||||
|
//! of the reversed container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_reverse_iterator crbegin() const
|
||||||
{ return m_tree.rbegin(); }
|
{ return m_tree.rbegin(); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
|
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
|
||||||
@@ -328,6 +353,15 @@ class map
|
|||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
const_reverse_iterator rend() const
|
const_reverse_iterator rend() const
|
||||||
|
{ return this->crend(); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
|
||||||
|
//! of the reversed container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_reverse_iterator crend() const
|
||||||
{ return m_tree.rend(); }
|
{ return m_tree.rend(); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns true if the container contains no elements.
|
//! <b>Effects</b>: Returns true if the container contains no elements.
|
||||||
@@ -984,6 +1018,14 @@ class multimap
|
|||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
const_iterator begin() const
|
const_iterator begin() const
|
||||||
|
{ return this->cbegin(); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_iterator cbegin() const
|
||||||
{ return m_tree.begin(); }
|
{ return m_tree.begin(); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns an iterator to the end of the container.
|
//! <b>Effects</b>: Returns an iterator to the end of the container.
|
||||||
@@ -1000,6 +1042,14 @@ class multimap
|
|||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
const_iterator end() const
|
const_iterator end() const
|
||||||
|
{ return this->cend(); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_iterator cend() const
|
||||||
{ return m_tree.end(); }
|
{ return m_tree.end(); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
|
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
|
||||||
@@ -1018,6 +1068,15 @@ class multimap
|
|||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
const_reverse_iterator rbegin() const
|
const_reverse_iterator rbegin() const
|
||||||
|
{ return this->crbegin(); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
|
||||||
|
//! of the reversed container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_reverse_iterator crbegin() const
|
||||||
{ return m_tree.rbegin(); }
|
{ return m_tree.rbegin(); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
|
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
|
||||||
@@ -1036,6 +1095,15 @@ class multimap
|
|||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
const_reverse_iterator rend() const
|
const_reverse_iterator rend() const
|
||||||
|
{ return this->crend(); }
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
|
||||||
|
//! of the reversed container.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: Nothing.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
const_reverse_iterator crend() const
|
||||||
{ return m_tree.rend(); }
|
{ return m_tree.rend(); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns true if the container contains no elements.
|
//! <b>Effects</b>: Returns true if the container contains no elements.
|
||||||
|
@@ -674,6 +674,20 @@ class scoped_allocator_adaptor_base
|
|||||||
, inner(other.inner_allocator())
|
, inner(other.inner_allocator())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct internal_type_t{};
|
||||||
|
|
||||||
|
template <class OuterA2>
|
||||||
|
scoped_allocator_adaptor_base
|
||||||
|
( internal_type_t
|
||||||
|
, BOOST_FWD_REF(OuterA2) outerAlloc
|
||||||
|
, const inner_allocator_type &inner)
|
||||||
|
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
|
||||||
|
, m_inner(inner)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
scoped_allocator_adaptor_base &operator=
|
scoped_allocator_adaptor_base &operator=
|
||||||
(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
|
(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
|
||||||
{
|
{
|
||||||
@@ -772,17 +786,17 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
|
|||||||
scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc \
|
scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc \
|
||||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q, _)) \
|
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q, _)) \
|
||||||
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc)) \
|
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc)) \
|
||||||
, inner(BOOST_PP_ENUM_PARAMS(n, q)) \
|
, m_inner(BOOST_PP_ENUM_PARAMS(n, q)) \
|
||||||
{} \
|
{} \
|
||||||
\
|
\
|
||||||
scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) \
|
scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) \
|
||||||
: outer_allocator_type(other.outer_allocator()) \
|
: outer_allocator_type(other.outer_allocator()) \
|
||||||
, inner(other.inner_allocator()) \
|
, m_inner(other.inner_allocator()) \
|
||||||
{} \
|
{} \
|
||||||
\
|
\
|
||||||
scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) \
|
scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) \
|
||||||
: outer_allocator_type(::boost::move(other.outer_allocator())) \
|
: outer_allocator_type(::boost::move(other.outer_allocator())) \
|
||||||
, inner(::boost::move(other.inner_allocator())) \
|
, m_inner(::boost::move(other.inner_allocator())) \
|
||||||
{} \
|
{} \
|
||||||
\
|
\
|
||||||
template <class OuterA2> \
|
template <class OuterA2> \
|
||||||
@@ -793,7 +807,7 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
|
|||||||
, BOOST_CONTAINER_PP_IDENTITY, nat) \
|
, BOOST_CONTAINER_PP_IDENTITY, nat) \
|
||||||
>& other) \
|
>& other) \
|
||||||
: outer_allocator_type(other.outer_allocator()) \
|
: outer_allocator_type(other.outer_allocator()) \
|
||||||
, inner(other.inner_allocator()) \
|
, m_inner(other.inner_allocator()) \
|
||||||
{} \
|
{} \
|
||||||
\
|
\
|
||||||
template <class OuterA2> \
|
template <class OuterA2> \
|
||||||
@@ -805,29 +819,42 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
|
|||||||
, BOOST_CONTAINER_PP_IDENTITY, nat) \
|
, BOOST_CONTAINER_PP_IDENTITY, nat) \
|
||||||
> BOOST_RV_REF_END other) \
|
> BOOST_RV_REF_END other) \
|
||||||
: outer_allocator_type(other.outer_allocator()) \
|
: outer_allocator_type(other.outer_allocator()) \
|
||||||
, inner(other.inner_allocator()) \
|
, m_inner(other.inner_allocator()) \
|
||||||
{} \
|
{} \
|
||||||
\
|
\
|
||||||
|
protected: \
|
||||||
|
struct internal_type_t{}; \
|
||||||
|
\
|
||||||
|
template <class OuterA2> \
|
||||||
|
scoped_allocator_adaptor_base \
|
||||||
|
( internal_type_t \
|
||||||
|
, BOOST_FWD_REF(OuterA2) outerAlloc \
|
||||||
|
, const inner_allocator_type &inner) \
|
||||||
|
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc)) \
|
||||||
|
, m_inner(inner) \
|
||||||
|
{} \
|
||||||
|
\
|
||||||
|
public: \
|
||||||
scoped_allocator_adaptor_base &operator= \
|
scoped_allocator_adaptor_base &operator= \
|
||||||
(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) \
|
(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) \
|
||||||
{ \
|
{ \
|
||||||
outer_allocator_type::operator=(other.outer_allocator()); \
|
outer_allocator_type::operator=(other.outer_allocator()); \
|
||||||
inner = other.inner_allocator(); \
|
m_inner = other.inner_allocator(); \
|
||||||
return *this; \
|
return *this; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) \
|
scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) \
|
||||||
{ \
|
{ \
|
||||||
outer_allocator_type::operator=(boost::move(other.outer_allocator())); \
|
outer_allocator_type::operator=(boost::move(other.outer_allocator())); \
|
||||||
inner = ::boost::move(other.inner_allocator()); \
|
m_inner = ::boost::move(other.inner_allocator()); \
|
||||||
return *this; \
|
return *this; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
inner_allocator_type& inner_allocator() \
|
inner_allocator_type& inner_allocator() \
|
||||||
{ return inner; } \
|
{ return m_inner; } \
|
||||||
\
|
\
|
||||||
inner_allocator_type const& inner_allocator() const \
|
inner_allocator_type const& inner_allocator() const \
|
||||||
{ return inner; } \
|
{ return m_inner; } \
|
||||||
\
|
\
|
||||||
outer_allocator_type & outer_allocator() \
|
outer_allocator_type & outer_allocator() \
|
||||||
{ return static_cast<outer_allocator_type&>(*this); } \
|
{ return static_cast<outer_allocator_type&>(*this); } \
|
||||||
@@ -836,7 +863,7 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
|
|||||||
{ return static_cast<const outer_allocator_type&>(*this); } \
|
{ return static_cast<const outer_allocator_type&>(*this); } \
|
||||||
\
|
\
|
||||||
private: \
|
private: \
|
||||||
inner_allocator_type inner; \
|
inner_allocator_type m_inner; \
|
||||||
}; \
|
}; \
|
||||||
//!
|
//!
|
||||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||||
@@ -920,6 +947,15 @@ class scoped_allocator_adaptor_base
|
|||||||
: outer_allocator_type(other.outer_allocator())
|
: outer_allocator_type(other.outer_allocator())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct internal_type_t{};
|
||||||
|
|
||||||
|
template <class OuterA2>
|
||||||
|
scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &)
|
||||||
|
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
|
scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
|
||||||
{
|
{
|
||||||
outer_allocator_type::operator=(other.outer_allocator());
|
outer_allocator_type::operator=(other.outer_allocator());
|
||||||
@@ -1221,8 +1257,9 @@ class scoped_allocator_adaptor
|
|||||||
scoped_allocator_adaptor select_on_container_copy_construction() const
|
scoped_allocator_adaptor select_on_container_copy_construction() const
|
||||||
{
|
{
|
||||||
return scoped_allocator_adaptor
|
return scoped_allocator_adaptor
|
||||||
(outer_traits_type::select_on_container_copy_construction(this->outer_allocator()),
|
(internal_type_t()
|
||||||
outer_traits_type::select_on_container_copy_construction(this->inner_allocator())
|
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
|
||||||
|
,outer_traits_type::select_on_container_copy_construction(this->inner_allocator())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/// @cond
|
/// @cond
|
||||||
@@ -1309,11 +1346,11 @@ class scoped_allocator_adaptor
|
|||||||
|
|
||||||
template <class T1, class T2, class U, class V>
|
template <class T1, class T2, class U, class V>
|
||||||
void construct(std::pair<T1, T2>* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
|
void construct(std::pair<T1, T2>* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
|
||||||
{ this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<U>(y)); }
|
{ this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<V>(y)); }
|
||||||
|
|
||||||
template <class T1, class T2, class U, class V>
|
template <class T1, class T2, class U, class V>
|
||||||
void construct(container_detail::pair<T1, T2>* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
|
void construct(container_detail::pair<T1, T2>* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
|
||||||
{ this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<U>(y)); }
|
{ this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<V>(y)); }
|
||||||
|
|
||||||
template <class T1, class T2, class U, class V>
|
template <class T1, class T2, class U, class V>
|
||||||
void construct(std::pair<T1, T2>* p, const std::pair<U, V>& x)
|
void construct(std::pair<T1, T2>* p, const std::pair<U, V>& x)
|
||||||
@@ -1391,6 +1428,12 @@ class scoped_allocator_adaptor
|
|||||||
//template <class T1, class T2, class... Args1, class... Args2>
|
//template <class T1, class T2, class... Args1, class... Args2>
|
||||||
//void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
|
//void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <class OuterA2>
|
||||||
|
scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner)
|
||||||
|
: base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)
|
||||||
|
{}
|
||||||
|
|
||||||
/// @endcond
|
/// @endcond
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -65,6 +65,10 @@ template <class T, class VoidPointer>
|
|||||||
struct slist_node
|
struct slist_node
|
||||||
: public slist_hook<VoidPointer>::type
|
: public slist_hook<VoidPointer>::type
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
slist_node();
|
||||||
|
|
||||||
|
public:
|
||||||
typedef typename slist_hook<VoidPointer>::type hook_type;
|
typedef typename slist_hook<VoidPointer>::type hook_type;
|
||||||
T m_data;
|
T m_data;
|
||||||
};
|
};
|
||||||
|
@@ -119,6 +119,10 @@ template<typename VoidPointer, typename T>
|
|||||||
struct node_type
|
struct node_type
|
||||||
: public node_type_base<VoidPointer>
|
: public node_type_base<VoidPointer>
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
node_type();
|
||||||
|
|
||||||
|
public:
|
||||||
T value;
|
T value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,8 +1,18 @@
|
|||||||
|
#include <boost/container/detail/config_begin.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <boost/move/move.hpp>
|
#include <boost/move/move.hpp>
|
||||||
|
#include <boost/container/vector.hpp>
|
||||||
|
#include <boost/container/deque.hpp>
|
||||||
|
#include <boost/container/list.hpp>
|
||||||
|
#include <boost/container/slist.hpp>
|
||||||
|
#include <boost/container/stable_vector.hpp>
|
||||||
|
#include <boost/container/flat_map.hpp>
|
||||||
|
#include <boost/container/flat_set.hpp>
|
||||||
#include <boost/container/map.hpp>
|
#include <boost/container/map.hpp>
|
||||||
|
#include <boost/container/set.hpp>
|
||||||
|
#include <boost/container/detail/mpl.hpp>
|
||||||
|
|
||||||
#include <boost/container/scoped_allocator.hpp>
|
#include <boost/container/scoped_allocator.hpp>
|
||||||
|
|
||||||
template <typename Ty>
|
template <typename Ty>
|
||||||
@@ -14,82 +24,372 @@ public:
|
|||||||
typedef typename std::allocator<Ty>::size_type size_type;
|
typedef typename std::allocator<Ty>::size_type size_type;
|
||||||
|
|
||||||
SimpleAllocator(int value)
|
SimpleAllocator(int value)
|
||||||
: _value(value)
|
: m_state(value)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SimpleAllocator(const SimpleAllocator<T> &other)
|
SimpleAllocator(const SimpleAllocator<T> &other)
|
||||||
: _value(other._value)
|
: m_state(other.m_state)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
pointer allocate(size_type n)
|
pointer allocate(size_type n)
|
||||||
{
|
{
|
||||||
return _allocator.allocate(n);
|
return m_allocator.allocate(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(pointer p, size_type n)
|
void deallocate(pointer p, size_type n)
|
||||||
{
|
{
|
||||||
_allocator.deallocate(p, n);
|
m_allocator.deallocate(p, n);
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
int _value;
|
int get_value() const
|
||||||
std::allocator<Ty> _allocator;
|
{ return m_state; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_state;
|
||||||
|
std::allocator<Ty> m_allocator;
|
||||||
|
|
||||||
template <typename T> friend class SimpleAllocator;
|
template <typename T> friend class SimpleAllocator;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Ty>
|
class alloc_int
|
||||||
class ScopedAllocator : public boost::container::scoped_allocator_adaptor<SimpleAllocator<Ty> >
|
|
||||||
{
|
{
|
||||||
private:
|
private: // Not copyable
|
||||||
typedef boost::container::scoped_allocator_adaptor<SimpleAllocator<Ty> > Base;
|
|
||||||
|
|
||||||
public:
|
BOOST_MOVABLE_BUT_NOT_COPYABLE(alloc_int)
|
||||||
ScopedAllocator(int value)
|
|
||||||
: Base(SimpleAllocator<Ty>(value))
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Resource
|
public:
|
||||||
{
|
|
||||||
private: // Not copyable
|
|
||||||
Resource(const Resource &);
|
|
||||||
Resource &operator=(const Resource &);
|
|
||||||
public:
|
|
||||||
typedef SimpleAllocator<int> allocator_type;
|
typedef SimpleAllocator<int> allocator_type;
|
||||||
|
|
||||||
Resource(BOOST_RV_REF(Resource)other)
|
alloc_int(BOOST_RV_REF(alloc_int)other)
|
||||||
: _value(other._value), _allocator(boost::move(other._allocator))
|
: m_value(other.m_value), m_allocator(boost::move(other.m_allocator))
|
||||||
{
|
{
|
||||||
other._value = -1;
|
other.m_value = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Resource(BOOST_RV_REF(Resource)other, const allocator_type &allocator)
|
alloc_int(BOOST_RV_REF(alloc_int)other, const allocator_type &allocator)
|
||||||
: _value(other._value), _allocator(allocator)
|
: m_value(other.m_value), m_allocator(allocator)
|
||||||
{
|
{
|
||||||
other._value = -1;
|
other.m_value = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Resource(int value, const allocator_type &allocator)
|
alloc_int(int value, const allocator_type &allocator)
|
||||||
: _value(value), _allocator(allocator)
|
: m_value(value), m_allocator(allocator)
|
||||||
{}
|
{}
|
||||||
private:
|
|
||||||
int _value;
|
alloc_int & operator=(BOOST_RV_REF(alloc_int)other)
|
||||||
allocator_type _allocator;
|
{
|
||||||
|
other.m_value = other.m_value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_allocator_state() const
|
||||||
|
{ return m_allocator.get_value(); }
|
||||||
|
|
||||||
|
int get_value() const
|
||||||
|
{ return m_value; }
|
||||||
|
|
||||||
|
friend bool operator < (const alloc_int &l, const alloc_int &r)
|
||||||
|
{ return l.m_value < r.m_value; }
|
||||||
|
|
||||||
|
friend bool operator == (const alloc_int &l, const alloc_int &r)
|
||||||
|
{ return l.m_value == r.m_value; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_value;
|
||||||
|
allocator_type m_allocator;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::pair<const std::string, Resource> MapNode;
|
using namespace ::boost::container;
|
||||||
|
|
||||||
typedef boost::container::scoped_allocator_adaptor<SimpleAllocator<MapNode> > MapAllocator;
|
//general allocator
|
||||||
|
typedef scoped_allocator_adaptor<SimpleAllocator<alloc_int> > AllocIntAllocator;
|
||||||
|
|
||||||
typedef boost::container::map<std::string, Resource, std::less<std::string>, MapAllocator> Map;
|
//[multi]map/set
|
||||||
|
typedef std::pair<const alloc_int, alloc_int> MapNode;
|
||||||
|
typedef scoped_allocator_adaptor<SimpleAllocator<MapNode> > MapAllocator;
|
||||||
|
typedef map<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> Map;
|
||||||
|
typedef set<alloc_int, std::less<alloc_int>, AllocIntAllocator> Set;
|
||||||
|
typedef multimap<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> MultiMap;
|
||||||
|
typedef multiset<alloc_int, std::less<alloc_int>, AllocIntAllocator> MultiSet;
|
||||||
|
|
||||||
|
//[multi]flat_map/set
|
||||||
|
typedef std::pair<alloc_int, alloc_int> FlatMapNode;
|
||||||
|
typedef scoped_allocator_adaptor<SimpleAllocator<FlatMapNode> > FlatMapAllocator;
|
||||||
|
typedef flat_map<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> FlatMap;
|
||||||
|
typedef flat_set<alloc_int, std::less<alloc_int>, AllocIntAllocator> FlatSet;
|
||||||
|
typedef flat_multimap<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> FlatMultiMap;
|
||||||
|
typedef flat_multiset<alloc_int, std::less<alloc_int>, AllocIntAllocator> FlatMultiSet;
|
||||||
|
|
||||||
|
//vector, deque, list, slist, stable_vector.
|
||||||
|
typedef vector<alloc_int, AllocIntAllocator> Vector;
|
||||||
|
typedef deque<alloc_int, AllocIntAllocator> Deque;
|
||||||
|
typedef list<alloc_int, AllocIntAllocator> List;
|
||||||
|
typedef slist<alloc_int, AllocIntAllocator> Slist;
|
||||||
|
typedef stable_vector<alloc_int, AllocIntAllocator> StableVector;
|
||||||
|
|
||||||
|
/////////
|
||||||
|
//is_unique_assoc
|
||||||
|
/////////
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct is_unique_assoc
|
||||||
|
{
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class K, class V, class C, class A>
|
||||||
|
struct is_unique_assoc< map<K, V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class K, class V, class C, class A>
|
||||||
|
struct is_unique_assoc< flat_map<K, V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class V, class C, class A>
|
||||||
|
struct is_unique_assoc< set<V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class V, class C, class A>
|
||||||
|
struct is_unique_assoc< flat_set<V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/////////
|
||||||
|
//is_map
|
||||||
|
/////////
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct is_map
|
||||||
|
{
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class K, class V, class C, class A>
|
||||||
|
struct is_map< map<K, V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class K, class V, class C, class A>
|
||||||
|
struct is_map< flat_map<K, V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class K, class V, class C, class A>
|
||||||
|
struct is_map< multimap<K, V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class K, class V, class C, class A>
|
||||||
|
struct is_map< flat_multimap<K, V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct is_set
|
||||||
|
{
|
||||||
|
static const bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class V, class C, class A>
|
||||||
|
struct is_set< set<V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class V, class C, class A>
|
||||||
|
struct is_set< flat_set<V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class V, class C, class A>
|
||||||
|
struct is_set< multiset<V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class V, class C, class A>
|
||||||
|
struct is_set< flat_multiset<V, C, A> >
|
||||||
|
{
|
||||||
|
static const bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////
|
||||||
|
//container_wrapper
|
||||||
|
/////////
|
||||||
|
|
||||||
|
template< class Container
|
||||||
|
, bool Assoc = is_set<Container>::value || is_map<Container>::value
|
||||||
|
, bool UniqueAssoc = is_unique_assoc<Container>::value
|
||||||
|
, bool Map = is_map<Container>::value
|
||||||
|
>
|
||||||
|
struct container_wrapper
|
||||||
|
: public Container
|
||||||
|
{
|
||||||
|
typedef typename Container::allocator_type allocator_type;
|
||||||
|
|
||||||
|
container_wrapper(const allocator_type &a)
|
||||||
|
: Container(a)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Container> //map
|
||||||
|
struct container_wrapper<Container, true, true, true>
|
||||||
|
: public Container
|
||||||
|
{
|
||||||
|
typedef typename Container::allocator_type allocator_type;
|
||||||
|
typedef typename Container::key_compare key_compare;
|
||||||
|
typedef typename Container::value_type value_type;
|
||||||
|
typedef typename Container::const_iterator const_iterator;
|
||||||
|
typedef typename Container::iterator iterator;
|
||||||
|
|
||||||
|
container_wrapper(const allocator_type &a)
|
||||||
|
: Container(key_compare(), a)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<class Arg>
|
||||||
|
iterator emplace(const_iterator, const Arg &arg)
|
||||||
|
{
|
||||||
|
return this->Container::emplace(arg, arg).first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Container> //set
|
||||||
|
struct container_wrapper<Container, true, true, false>
|
||||||
|
: public Container
|
||||||
|
{
|
||||||
|
typedef typename Container::allocator_type allocator_type;
|
||||||
|
typedef typename Container::key_compare key_compare;
|
||||||
|
typedef typename Container::value_type value_type;
|
||||||
|
typedef typename Container::const_iterator const_iterator;
|
||||||
|
typedef typename Container::iterator iterator;
|
||||||
|
|
||||||
|
container_wrapper(const allocator_type &a)
|
||||||
|
: Container(key_compare(), a)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<class Arg>
|
||||||
|
iterator emplace(const_iterator, const Arg &arg)
|
||||||
|
{
|
||||||
|
return this->Container::emplace(arg).first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Container> //multimap
|
||||||
|
struct container_wrapper<Container, true, false, true>
|
||||||
|
: public Container
|
||||||
|
{
|
||||||
|
typedef typename Container::value_type value_type;
|
||||||
|
typedef typename Container::key_compare key_compare;
|
||||||
|
typedef typename Container::allocator_type allocator_type;
|
||||||
|
typedef typename Container::const_iterator const_iterator;
|
||||||
|
typedef typename Container::iterator iterator;
|
||||||
|
|
||||||
|
container_wrapper(const allocator_type &a)
|
||||||
|
: Container(key_compare(), a)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<class Arg>
|
||||||
|
iterator emplace(const_iterator, const Arg &arg)
|
||||||
|
{
|
||||||
|
return this->Container::emplace(arg, arg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//multiset
|
||||||
|
template<class Container> //multimap
|
||||||
|
struct container_wrapper<Container, true, false, false>
|
||||||
|
: public Container
|
||||||
|
{
|
||||||
|
typedef typename Container::value_type value_type;
|
||||||
|
typedef typename Container::key_compare key_compare;
|
||||||
|
typedef typename Container::allocator_type allocator_type;
|
||||||
|
typedef typename Container::const_iterator const_iterator;
|
||||||
|
typedef typename Container::iterator iterator;
|
||||||
|
|
||||||
|
container_wrapper(const allocator_type &a)
|
||||||
|
: Container(key_compare(), a)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<class Arg>
|
||||||
|
iterator emplace(const_iterator, const Arg &arg)
|
||||||
|
{
|
||||||
|
return this->Container::emplace(arg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool test_value_and_state_equals(const alloc_int &r, int value, int state)
|
||||||
|
{ return r.get_value() == value && r.get_allocator_state() == state; }
|
||||||
|
|
||||||
|
template<class F, class S>
|
||||||
|
bool test_value_and_state_equals(const container_detail::pair<F, S> &p, int value, int state)
|
||||||
|
{ return test_value_and_state_equals(p.first, value, state) && test_alloc_state_equals(p.second, value, state); }
|
||||||
|
|
||||||
|
template<class F, class S>
|
||||||
|
bool test_value_and_state_equals(const std::pair<F, S> &p, int value, int state)
|
||||||
|
{ return test_value_and_state_equals(p.first, value, state) && test_value_and_state_equals(p.second, value, state); }
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
bool one_level_allocator_propagation_test()
|
||||||
|
{
|
||||||
|
typedef container_wrapper<Container> ContainerWrapper;
|
||||||
|
typedef typename ContainerWrapper::iterator iterator;
|
||||||
|
ContainerWrapper c(SimpleAllocator<MapNode>(5));
|
||||||
|
|
||||||
|
c.clear();
|
||||||
|
iterator it = c.emplace(c.cbegin(), 42);
|
||||||
|
|
||||||
|
if(!test_value_and_state_equals(*it, 42, 5))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Map map1(std::less<std::string>(), SimpleAllocator<MapNode>(5));
|
//unique assoc
|
||||||
|
if(!one_level_allocator_propagation_test<FlatMap>())
|
||||||
map1.emplace("foo", 42);
|
return 1;
|
||||||
map1.emplace("bar", 11);
|
if(!one_level_allocator_propagation_test<Map>())
|
||||||
|
return 1;
|
||||||
//Map map2 = map1;
|
if(!one_level_allocator_propagation_test<FlatSet>())
|
||||||
|
return 1;
|
||||||
|
if(!one_level_allocator_propagation_test<Set>())
|
||||||
|
return 1;
|
||||||
|
//multi assoc
|
||||||
|
if(!one_level_allocator_propagation_test<FlatMultiMap>())
|
||||||
|
return 1;
|
||||||
|
if(!one_level_allocator_propagation_test<MultiMap>())
|
||||||
|
return 1;
|
||||||
|
if(!one_level_allocator_propagation_test<FlatMultiSet>())
|
||||||
|
return 1;
|
||||||
|
if(!one_level_allocator_propagation_test<MultiSet>())
|
||||||
|
return 1;
|
||||||
|
//sequence containers
|
||||||
|
if(!one_level_allocator_propagation_test<Vector>())
|
||||||
|
return 1;
|
||||||
|
if(!one_level_allocator_propagation_test<Deque>())
|
||||||
|
return 1;
|
||||||
|
if(!one_level_allocator_propagation_test<List>())
|
||||||
|
return 1;
|
||||||
|
if(!one_level_allocator_propagation_test<Slist>())
|
||||||
|
return 1;
|
||||||
|
if(!one_level_allocator_propagation_test<StableVector>())
|
||||||
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <boost/container/detail/config_end.hpp>
|
||||||
|
Reference in New Issue
Block a user