Merged from trunk

[SVN r79555]
This commit is contained in:
Ion Gaztañaga
2012-07-16 08:29:51 +00:00
parent c5de943676
commit bd7e6c3fd9
8 changed files with 238 additions and 117 deletions

View File

@@ -213,8 +213,8 @@ struct allocator_traits
static void deallocate(Alloc &a, pointer p, size_type n) static void deallocate(Alloc &a, pointer p, size_type n)
{ return a.deallocate(p, n); } { return a.deallocate(p, n); }
//! <b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed; //! <b>Effects</b>: calls `a.allocate(n, p)` if that call is well-formed;
//! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)` //! otherwise, invokes `a.allocate(n)`
static pointer allocate(Alloc &a, size_type n, const_void_pointer p) static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
{ {
const bool value = boost::container::container_detail:: const bool value = boost::container::container_detail::

View File

@@ -65,6 +65,44 @@ struct null_scoped_array_deallocator
{} {}
}; };
template <class Allocator>
struct scoped_destroy_deallocator
{
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::size_type size_type;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<Allocator>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
scoped_destroy_deallocator(pointer p, Allocator& a)
: m_ptr(p), m_alloc(a) {}
~scoped_destroy_deallocator()
{
if(m_ptr){
AllocTraits::destroy(m_alloc, container_detail::to_raw_pointer(m_ptr));
priv_deallocate(m_ptr, alloc_version());
}
}
void release()
{ m_ptr = 0; }
private:
void priv_deallocate(const pointer &p, allocator_v1)
{ AllocTraits::deallocate(m_alloc, p, 1); }
void priv_deallocate(const pointer &p, allocator_v2)
{ m_alloc.deallocate_one(p); }
pointer m_ptr;
Allocator& m_alloc;
};
//!A deleter for scoped_ptr that destroys //!A deleter for scoped_ptr that destroys
//!an object using a STL allocator. //!an object using a STL allocator.
@@ -150,6 +188,27 @@ class scoped_destructor
A &a_; A &a_;
}; };
template<class A>
class value_destructor
{
typedef boost::container::allocator_traits<A> AllocTraits;
public:
typedef typename A::value_type value_type;
value_destructor(A &a, value_type &rv)
: rv_(rv), a_(a)
{}
~value_destructor()
{
AllocTraits::destroy(a_, &rv_);
}
private:
value_type &rv_;
A &a_;
};
template <class Allocator> template <class Allocator>
class allocator_destroyer class allocator_destroyer
{ {

View File

@@ -395,14 +395,13 @@ class flat_tree
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... ); stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
scoped_destructor<stored_allocator_type> d(a, &val); value_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;
} }
@@ -413,13 +412,12 @@ class flat_tree
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... ); stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
scoped_destructor<stored_allocator_type> d(a, &val); value_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;
} }
@@ -430,10 +428,9 @@ class flat_tree
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... ); stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
scoped_destructor<stored_allocator_type> d(a, &val); value_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;
} }
@@ -444,11 +441,10 @@ class flat_tree
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... ); stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
scoped_destructor<stored_allocator_type> d(a, &val); value_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);
iterator i = priv_insert_commit(data, boost::move(val)); iterator i = priv_insert_commit(data, boost::move(val));
d.release();
return i; return i;
} }
@@ -464,13 +460,12 @@ class flat_tree
stored_allocator_type &a = this->get_stored_allocator(); \ stored_allocator_type &a = this->get_stored_allocator(); \
stored_allocator_traits::construct(a, &val \ stored_allocator_traits::construct(a, &val \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
scoped_destructor<stored_allocator_type> d(a, &val); \ value_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; \
} \ } \
\ \
@@ -483,13 +478,12 @@ class flat_tree
stored_allocator_type &a = this->get_stored_allocator(); \ stored_allocator_type &a = this->get_stored_allocator(); \
stored_allocator_traits::construct(a, &val \ stored_allocator_traits::construct(a, &val \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
scoped_destructor<stored_allocator_type> d(a, &val); \ value_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; \
} \ } \
\ \
@@ -501,10 +495,9 @@ class flat_tree
stored_allocator_type &a = this->get_stored_allocator(); \ stored_allocator_type &a = this->get_stored_allocator(); \
stored_allocator_traits::construct(a, &val \ stored_allocator_traits::construct(a, &val \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
scoped_destructor<stored_allocator_type> d(a, &val); \ value_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; \
} \ } \
\ \
@@ -517,11 +510,10 @@ class flat_tree
stored_allocator_type &a = this->get_stored_allocator(); \ stored_allocator_type &a = this->get_stored_allocator(); \
stored_allocator_traits::construct(a, &val \ stored_allocator_traits::construct(a, &val \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
scoped_destructor<stored_allocator_type> d(a, &val); \ value_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); \
iterator i = priv_insert_commit(data, boost::move(val)); \ iterator i = priv_insert_commit(data, boost::move(val)); \
d.release(); \
return i; \ return i; \
} \ } \

View File

@@ -745,12 +745,14 @@ class rbtree
{ {
value_type &v = p->get_data(); value_type &v = p->get_data();
insert_commit_data data; insert_commit_data data;
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(p, this->node_alloc());
std::pair<iterator,bool> ret = std::pair<iterator,bool> ret =
this->insert_unique_check(KeyOfValue()(v), data); this->insert_unique_check(KeyOfValue()(v), data);
if(!ret.second){ if(!ret.second){
Destroyer(this->node_alloc())(p);
return ret; return ret;
} }
//No throw insertion part, release rollback
destroy_deallocator.release();
return std::pair<iterator,bool> return std::pair<iterator,bool>
( iterator(iiterator(this->icont().insert_unique_commit(*p, data))) ( iterator(iiterator(this->icont().insert_unique_commit(*p, data)))
, true ); , true );

View File

@@ -264,21 +264,21 @@ class flat_map
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
key_compare key_comp() const key_compare key_comp() const
{ return container_detail::force<key_compare>(m_flat_tree.key_comp()); } { return container_detail::force_copy<key_compare>(m_flat_tree.key_comp()); }
//! <b>Effects</b>: Returns an object of value_compare constructed out //! <b>Effects</b>: Returns an object of value_compare constructed out
//! of the comparison object. //! of the comparison object.
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
value_compare value_comp() const value_compare value_comp() const
{ return value_compare(container_detail::force<key_compare>(m_flat_tree.key_comp())); } { return value_compare(container_detail::force_copy<key_compare>(m_flat_tree.key_comp())); }
//! <b>Effects</b>: Returns a copy of the Allocator that //! <b>Effects</b>: Returns a copy of the Allocator that
//! was passed to the object's constructor. //! was passed to the object's constructor.
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
allocator_type get_allocator() const allocator_type get_allocator() const
{ return container_detail::force<allocator_type>(m_flat_tree.get_allocator()); } { return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
const stored_allocator_type &get_stored_allocator() const const stored_allocator_type &get_stored_allocator() const
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); } { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
@@ -300,7 +300,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator begin() const const_iterator begin() const
{ return container_detail::force<const_iterator>(m_flat_tree.begin()); } { return container_detail::force_copy<const_iterator>(m_flat_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.
//! //!
@@ -316,7 +316,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator end() const const_iterator end() const
{ return container_detail::force<const_iterator>(m_flat_tree.end()); } { return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
//! <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.
@@ -325,7 +325,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reverse_iterator rbegin() reverse_iterator rbegin()
{ return container_detail::force<reverse_iterator>(m_flat_tree.rbegin()); } { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed container. //! of the reversed container.
@@ -334,7 +334,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
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_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
//! <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.
@@ -343,7 +343,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reverse_iterator rend() reverse_iterator rend()
{ return container_detail::force<reverse_iterator>(m_flat_tree.rend()); } { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
//! <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.
@@ -352,7 +352,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
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_copy<const_reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
//! //!
@@ -360,7 +360,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator cbegin() const const_iterator cbegin() const
{ return container_detail::force<const_iterator>(m_flat_tree.cbegin()); } { return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container. //! <b>Effects</b>: Returns a const_iterator to the end of the container.
//! //!
@@ -368,7 +368,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator cend() const const_iterator cend() const
{ return container_detail::force<const_iterator>(m_flat_tree.cend()); } { return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed container. //! of the reversed container.
@@ -377,7 +377,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reverse_iterator crbegin() const const_reverse_iterator crbegin() const
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.crbegin()); } { return container_detail::force_copy<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.
@@ -386,7 +386,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reverse_iterator crend() const const_reverse_iterator crend() const
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.crend()); } { return container_detail::force_copy<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.
//! //!
@@ -477,7 +477,7 @@ class flat_map
//! //!
//! <b>Note</b>: If an element is inserted it might invalidate elements. //! <b>Note</b>: If an element is inserted it might invalidate elements.
std::pair<iterator,bool> insert(const value_type& x) std::pair<iterator,bool> insert(const value_type& x)
{ return container_detail::force<std::pair<iterator,bool> >( { return container_detail::force_copy<std::pair<iterator,bool> >(
m_flat_tree.insert_unique(container_detail::force<impl_value_type>(x))); } m_flat_tree.insert_unique(container_detail::force<impl_value_type>(x))); }
//! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
@@ -492,7 +492,7 @@ class flat_map
//! //!
//! <b>Note</b>: If an element is inserted it might invalidate elements. //! <b>Note</b>: If an element is inserted it might invalidate elements.
std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x) std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
{ return container_detail::force<std::pair<iterator,bool> >( { return container_detail::force_copy<std::pair<iterator,bool> >(
m_flat_tree.insert_unique(boost::move(container_detail::force<impl_value_type>(x)))); } m_flat_tree.insert_unique(boost::move(container_detail::force<impl_value_type>(x)))); }
//! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
@@ -508,7 +508,7 @@ class flat_map
//! <b>Note</b>: If an element is inserted it might invalidate elements. //! <b>Note</b>: If an element is inserted it might invalidate elements.
std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x) std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x)
{ {
return container_detail::force<std::pair<iterator,bool> > return container_detail::force_copy<std::pair<iterator,bool> >
(m_flat_tree.insert_unique(boost::move(x))); (m_flat_tree.insert_unique(boost::move(x)));
} }
@@ -524,8 +524,11 @@ class flat_map
//! //!
//! <b>Note</b>: If an element is inserted it might invalidate elements. //! <b>Note</b>: If an element is inserted it might invalidate elements.
iterator insert(const_iterator position, const value_type& x) iterator insert(const_iterator position, const value_type& x)
{ return container_detail::force_copy<iterator>( {
m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), container_detail::force<impl_value_type>(x))); } return container_detail::force_copy<iterator>(
m_flat_tree.insert_unique( container_detail::force_copy<impl_const_iterator>(position)
, container_detail::force<impl_value_type>(x)));
}
//! <b>Effects</b>: Inserts an element move constructed from x in the container. //! <b>Effects</b>: Inserts an element move constructed from x in the container.
//! p is a hint pointing to where the insert should start to search. //! p is a hint pointing to where the insert should start to search.
@@ -539,7 +542,7 @@ class flat_map
iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
{ {
return container_detail::force_copy<iterator> return container_detail::force_copy<iterator>
(m_flat_tree.insert_unique( container_detail::force<impl_const_iterator>(position) (m_flat_tree.insert_unique( container_detail::force_copy<impl_const_iterator>(position)
, boost::move(container_detail::force<impl_value_type>(x)))); , boost::move(container_detail::force<impl_value_type>(x))));
} }
@@ -555,7 +558,7 @@ class flat_map
iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x) iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x)
{ {
return container_detail::force_copy<iterator>( return container_detail::force_copy<iterator>(
m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), boost::move(x))); m_flat_tree.insert_unique(container_detail::force_copy<impl_const_iterator>(position), boost::move(x)));
} }
//! <b>Requires</b>: first, last are not iterators into *this. //! <b>Requires</b>: first, last are not iterators into *this.
@@ -620,8 +623,11 @@ class flat_map
//! <b>Note</b>: If an element is inserted it might invalidate elements. //! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args> template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args) iterator emplace_hint(const_iterator hint, Args&&... args)
{ return container_detail::force_copy<iterator> {
(m_flat_tree.emplace_hint_unique(container_detail::force<impl_const_iterator>(hint), boost::forward<Args>(args)...)); } return container_detail::force_copy<iterator>
(m_flat_tree.emplace_hint_unique( container_detail::force_copy<impl_const_iterator>(hint)
, boost::forward<Args>(args)...));
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -635,7 +641,7 @@ class flat_map
iterator emplace_hint(const_iterator hint \ iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique \ { return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique \
(container_detail::force<impl_const_iterator>(hint) \ (container_detail::force_copy<impl_const_iterator>(hint) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
//! //!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
@@ -654,7 +660,10 @@ class flat_map
//! <b>Note</b>: Invalidates elements with keys //! <b>Note</b>: Invalidates elements with keys
//! not less than the erased element. //! not less than the erased element.
iterator erase(const_iterator position) iterator erase(const_iterator position)
{ return container_detail::force_copy<iterator>(m_flat_tree.erase(container_detail::force<impl_const_iterator>(position))); } {
return container_detail::force_copy<iterator>
(m_flat_tree.erase(container_detail::force_copy<impl_const_iterator>(position)));
}
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x. //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
//! //!
@@ -674,8 +683,11 @@ class flat_map
//! <b>Complexity</b>: Logarithmic search time plus erasure time //! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys. //! linear to the elements with bigger keys.
iterator erase(const_iterator first, const_iterator last) iterator erase(const_iterator first, const_iterator last)
{ return container_detail::force_copy<iterator> {
(m_flat_tree.erase(container_detail::force<impl_const_iterator>(first), container_detail::force<impl_const_iterator>(last))); } return container_detail::force_copy<iterator>(
m_flat_tree.erase( container_detail::force_copy<impl_const_iterator>(first)
, container_detail::force_copy<impl_const_iterator>(last)));
}
//! <b>Effects</b>: erase(a.begin(),a.end()). //! <b>Effects</b>: erase(a.begin(),a.end()).
//! //!
@@ -706,7 +718,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Logarithmic.s //! <b>Complexity</b>: Logarithmic.s
const_iterator find(const key_type& x) const const_iterator find(const key_type& x) const
{ return container_detail::force<const_iterator>(m_flat_tree.find(x)); } { return container_detail::force_copy<const_iterator>(m_flat_tree.find(x)); }
//! <b>Returns</b>: The number of elements with key equivalent to x. //! <b>Returns</b>: The number of elements with key equivalent to x.
//! //!
@@ -726,7 +738,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Logarithmic //! <b>Complexity</b>: Logarithmic
const_iterator lower_bound(const key_type& x) const const_iterator lower_bound(const key_type& x) const
{ return container_detail::force<const_iterator>(m_flat_tree.lower_bound(x)); } { return container_detail::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less //! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than x, or end() if such an element is not found. //! than x, or end() if such an element is not found.
@@ -740,7 +752,7 @@ class flat_map
//! //!
//! <b>Complexity</b>: Logarithmic //! <b>Complexity</b>: Logarithmic
const_iterator upper_bound(const key_type& x) const const_iterator upper_bound(const key_type& x) const
{ return container_detail::force<const_iterator>(m_flat_tree.upper_bound(x)); } { return container_detail::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//! //!
@@ -1050,21 +1062,21 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
key_compare key_comp() const key_compare key_comp() const
{ return container_detail::force<key_compare>(m_flat_tree.key_comp()); } { return container_detail::force_copy<key_compare>(m_flat_tree.key_comp()); }
//! <b>Effects</b>: Returns an object of value_compare constructed out //! <b>Effects</b>: Returns an object of value_compare constructed out
//! of the comparison object. //! of the comparison object.
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
value_compare value_comp() const value_compare value_comp() const
{ return value_compare(container_detail::force<key_compare>(m_flat_tree.key_comp())); } { return value_compare(container_detail::force_copy<key_compare>(m_flat_tree.key_comp())); }
//! <b>Effects</b>: Returns a copy of the Allocator that //! <b>Effects</b>: Returns a copy of the Allocator that
//! was passed to the object's constructor. //! was passed to the object's constructor.
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
allocator_type get_allocator() const allocator_type get_allocator() const
{ return container_detail::force<allocator_type>(m_flat_tree.get_allocator()); } { return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
const stored_allocator_type &get_stored_allocator() const const stored_allocator_type &get_stored_allocator() const
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); } { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
@@ -1086,7 +1098,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator begin() const const_iterator begin() const
{ return container_detail::force<const_iterator>(m_flat_tree.begin()); } { return container_detail::force_copy<const_iterator>(m_flat_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.
//! //!
@@ -1102,7 +1114,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator end() const const_iterator end() const
{ return container_detail::force<const_iterator>(m_flat_tree.end()); } { return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
//! <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.
@@ -1111,7 +1123,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reverse_iterator rbegin() reverse_iterator rbegin()
{ return container_detail::force<reverse_iterator>(m_flat_tree.rbegin()); } { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed container. //! of the reversed container.
@@ -1120,7 +1132,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
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_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
//! <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.
@@ -1129,7 +1141,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reverse_iterator rend() reverse_iterator rend()
{ return container_detail::force<reverse_iterator>(m_flat_tree.rend()); } { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
//! <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.
@@ -1138,7 +1150,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
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_copy<const_reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
//! //!
@@ -1146,7 +1158,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator cbegin() const const_iterator cbegin() const
{ return container_detail::force<const_iterator>(m_flat_tree.cbegin()); } { return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container. //! <b>Effects</b>: Returns a const_iterator to the end of the container.
//! //!
@@ -1154,7 +1166,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator cend() const const_iterator cend() const
{ return container_detail::force<const_iterator>(m_flat_tree.cend()); } { return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed container. //! of the reversed container.
@@ -1163,7 +1175,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reverse_iterator crbegin() const const_reverse_iterator crbegin() const
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.crbegin()); } { return container_detail::force_copy<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.
@@ -1172,7 +1184,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reverse_iterator crend() const const_reverse_iterator crend() const
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.crend()); } { return container_detail::force_copy<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.
//! //!
@@ -1214,7 +1226,10 @@ class flat_multimap
//! //!
//! <b>Note</b>: If an element is inserted it might invalidate elements. //! <b>Note</b>: If an element is inserted it might invalidate elements.
iterator insert(const value_type& x) iterator insert(const value_type& x)
{ return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(container_detail::force<impl_value_type>(x))); } {
return container_detail::force_copy<iterator>(
m_flat_tree.insert_equal(container_detail::force<impl_value_type>(x)));
}
//! <b>Effects</b>: Inserts a new value move-constructed from x and returns //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
//! the iterator pointing to the newly inserted element. //! the iterator pointing to the newly inserted element.
@@ -1248,8 +1263,11 @@ class flat_multimap
//! //!
//! <b>Note</b>: If an element is inserted it might invalidate elements. //! <b>Note</b>: If an element is inserted it might invalidate elements.
iterator insert(const_iterator position, const value_type& x) iterator insert(const_iterator position, const value_type& x)
{ return container_detail::force_copy<iterator> {
(m_flat_tree.insert_equal(container_detail::force<impl_const_iterator>(position), container_detail::force<impl_value_type>(x))); } return container_detail::force_copy<iterator>
(m_flat_tree.insert_equal( container_detail::force_copy<impl_const_iterator>(position)
, container_detail::force<impl_value_type>(x)));
}
//! <b>Effects</b>: Inserts a value move constructed from x in the container. //! <b>Effects</b>: Inserts a value move constructed from x in the container.
//! p is a hint pointing to where the insert should start to search. //! p is a hint pointing to where the insert should start to search.
@@ -1265,7 +1283,7 @@ class flat_multimap
iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
{ {
return container_detail::force_copy<iterator> return container_detail::force_copy<iterator>
(m_flat_tree.insert_equal(container_detail::force<impl_const_iterator>(position) (m_flat_tree.insert_equal(container_detail::force_copy<impl_const_iterator>(position)
, boost::move(x))); , boost::move(x)));
} }
@@ -1283,7 +1301,7 @@ class flat_multimap
iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x) iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x)
{ {
return container_detail::force_copy<iterator>( return container_detail::force_copy<iterator>(
m_flat_tree.insert_equal(container_detail::force<impl_const_iterator>(position), boost::move(x))); m_flat_tree.insert_equal(container_detail::force_copy<impl_const_iterator>(position), boost::move(x)));
} }
//! <b>Requires</b>: first, last are not iterators into *this. //! <b>Requires</b>: first, last are not iterators into *this.
@@ -1344,7 +1362,7 @@ class flat_multimap
iterator emplace_hint(const_iterator hint, Args&&... args) iterator emplace_hint(const_iterator hint, Args&&... args)
{ {
return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal
(container_detail::force<impl_const_iterator>(hint), boost::forward<Args>(args)...)); (container_detail::force_copy<impl_const_iterator>(hint), boost::forward<Args>(args)...));
} }
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -1359,7 +1377,7 @@ class flat_multimap
iterator emplace_hint(const_iterator hint \ iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal \ { return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal \
(container_detail::force<impl_const_iterator>(hint) \ (container_detail::force_copy<impl_const_iterator>(hint) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
//! //!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
@@ -1378,7 +1396,10 @@ class flat_multimap
//! <b>Note</b>: Invalidates elements with keys //! <b>Note</b>: Invalidates elements with keys
//! not less than the erased element. //! not less than the erased element.
iterator erase(const_iterator position) iterator erase(const_iterator position)
{ return container_detail::force_copy<iterator>(m_flat_tree.erase(container_detail::force<impl_const_iterator>(position))); } {
return container_detail::force_copy<iterator>(
m_flat_tree.erase(container_detail::force_copy<impl_const_iterator>(position)));
}
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x. //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
//! //!
@@ -1398,8 +1419,11 @@ class flat_multimap
//! <b>Complexity</b>: Logarithmic search time plus erasure time //! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys. //! linear to the elements with bigger keys.
iterator erase(const_iterator first, const_iterator last) iterator erase(const_iterator first, const_iterator last)
{ return container_detail::force_copy<iterator> {
(m_flat_tree.erase(container_detail::force<impl_const_iterator>(first), container_detail::force<impl_const_iterator>(last))); } return container_detail::force_copy<iterator>
(m_flat_tree.erase( container_detail::force_copy<impl_const_iterator>(first)
, container_detail::force_copy<impl_const_iterator>(last)));
}
//! <b>Effects</b>: erase(a.begin(),a.end()). //! <b>Effects</b>: erase(a.begin(),a.end()).
//! //!
@@ -1430,7 +1454,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Logarithmic. //! <b>Complexity</b>: Logarithmic.
const_iterator find(const key_type& x) const const_iterator find(const key_type& x) const
{ return container_detail::force<const_iterator>(m_flat_tree.find(x)); } { return container_detail::force_copy<const_iterator>(m_flat_tree.find(x)); }
//! <b>Returns</b>: The number of elements with key equivalent to x. //! <b>Returns</b>: The number of elements with key equivalent to x.
//! //!
@@ -1450,7 +1474,7 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Logarithmic //! <b>Complexity</b>: Logarithmic
const_iterator lower_bound(const key_type& x) const const_iterator lower_bound(const key_type& x) const
{ return container_detail::force<const_iterator>(m_flat_tree.lower_bound(x)); } { return container_detail::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less //! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than x, or end() if such an element is not found. //! than x, or end() if such an element is not found.
@@ -1464,20 +1488,20 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Logarithmic //! <b>Complexity</b>: Logarithmic
const_iterator upper_bound(const key_type& x) const const_iterator upper_bound(const key_type& x) const
{ return container_detail::force<const_iterator>(m_flat_tree.upper_bound(x)); } { return container_detail::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//! //!
//! <b>Complexity</b>: Logarithmic //! <b>Complexity</b>: Logarithmic
std::pair<iterator,iterator> equal_range(const key_type& x) std::pair<iterator,iterator> equal_range(const key_type& x)
{ return container_detail::force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); } { return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//! //!
//! <b>Complexity</b>: Logarithmic //! <b>Complexity</b>: Logarithmic
std::pair<const_iterator,const_iterator> std::pair<const_iterator,const_iterator>
equal_range(const key_type& x) const equal_range(const key_type& x) const
{ return container_detail::force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); } { return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Number of elements for which memory has been allocated. //! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size(). //! capacity() is always greater than or equal to size().

View File

@@ -23,6 +23,7 @@
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
#include <boost/container/scoped_allocator_fwd.hpp>
#include <boost/type_traits/integral_constant.hpp> #include <boost/type_traits/integral_constant.hpp>
#include <boost/container/allocator_traits.hpp> #include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
@@ -31,50 +32,9 @@
#include <boost/container/detail/pair.hpp> #include <boost/container/detail/pair.hpp>
#include <boost/move/move.hpp> #include <boost/move/move.hpp>
#if defined(BOOST_NO_VARIADIC_TEMPLATES)
#include <boost/container/detail/preprocessor.hpp>
#endif
namespace boost { namespace container { namespace boost { namespace container {
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING)
#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
template <typename OuterAlloc, typename ...InnerAllocs>
class scoped_allocator_adaptor;
#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
template <typename ...InnerAllocs>
class scoped_allocator_adaptor;
template <typename OuterAlloc, typename ...InnerAllocs>
class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
#else // #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <typename OuterAlloc
BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
, BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT, container_detail::nat)
>
class scoped_allocator_adaptor;
#endif
//! The allocator_arg_t struct is an empty structure type used as a unique type to
//! disambiguate constructor and function overloading. Specifically, several types
//! have constructors with allocator_arg_t as the first argument, immediately followed
//! by an argument of a type that satisfies the Allocator requirements
struct allocator_arg_t{};
//! A instance of type allocator_arg_t
//!
static const allocator_arg_t allocator_arg = allocator_arg_t();
//! <b>Remark</b>: if a specialization is derived from true_type, indicates that T may be constructed //! <b>Remark</b>: if a specialization is derived from true_type, indicates that T may be constructed
//! with an allocator as its last constructor argument. Ideally, all constructors of T (including the //! with an allocator as its last constructor argument. Ideally, all constructors of T (including the
//! copy and move constructors) should have a variant that accepts a final argument of //! copy and move constructors) should have a variant that accepts a final argument of

View File

@@ -0,0 +1,83 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2012. 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_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
#if (defined MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#if defined(BOOST_NO_VARIADIC_TEMPLATES)
#include <boost/container/detail/preprocessor.hpp>
#include <boost/container/detail/type_traits.hpp>
#endif
namespace boost { namespace container {
///@cond
#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
template <typename OuterAlloc, typename ...InnerAllocs>
class scoped_allocator_adaptor;
#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
template <typename ...InnerAllocs>
class scoped_allocator_adaptor;
template <typename OuterAlloc, typename ...InnerAllocs>
class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
#else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
template <typename OuterAlloc
BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
, BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT, container_detail::nat)
>
class scoped_allocator_adaptor;
#endif
///@endcond
//! The allocator_arg_t struct is an empty structure type used as a unique type to
//! disambiguate constructor and function overloading. Specifically, several types
//! have constructors with allocator_arg_t as the first argument, immediately followed
//! by an argument of a type that satisfies the Allocator requirements
struct allocator_arg_t{};
//! A instance of type allocator_arg_t
//!
static const allocator_arg_t allocator_arg = allocator_arg_t();
template <class T>
struct constructible_with_allocator_suffix;
template <class T>
struct constructible_with_allocator_prefix;
template <typename T, typename Alloc>
struct uses_allocator;
}} // namespace boost { namespace container {
#include <boost/container/detail/config_end.hpp>
#endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP

View File

@@ -47,6 +47,7 @@
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/move/move.hpp> #include <boost/move/move.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/functional/hash.hpp>
#include <functional> #include <functional>
#include <string> #include <string>