Merging into release branch for 1.49

[SVN r76247]
This commit is contained in:
Ion Gaztañaga
2011-12-31 16:19:15 +00:00
parent 43a784a1f9
commit 0aafb2f9be
13 changed files with 186 additions and 163 deletions

View File

@@ -590,7 +590,9 @@ use [*Boost.Container]? There are several reasons for that:
* Fixed bugs * Fixed bugs
[@https://svn.boost.org/trac/boost/ticket/6205 #6205], [@https://svn.boost.org/trac/boost/ticket/6205 #6205],
[@https://svn.boost.org/trac/boost/ticket/6287 #6287], [@https://svn.boost.org/trac/boost/ticket/6287 #6287],
[@https://svn.boost.org/trac/boost/ticket/4383 #4383]. [@https://svn.boost.org/trac/boost/ticket/4383 #4383],
[@https://svn.boost.org/trac/boost/ticket/6336 #6336],
[@https://svn.boost.org/trac/boost/ticket/6335 #6335].
* Added `allocator_traits` support for both C++11 and C++03 * Added `allocator_traits` support for both C++11 and C++03
compilers through an internal `allocator_traits` clone. compilers through an internal `allocator_traits` clone.

View File

@@ -26,6 +26,7 @@
#include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/allocator/memory_util.hpp> #include <boost/container/allocator/memory_util.hpp>
#include <boost/type_traits/integral_constant.hpp> #include <boost/type_traits/integral_constant.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/move/move.hpp> #include <boost/move/move.hpp>
#include <limits> //numeric_limits<>::max() #include <limits> //numeric_limits<>::max()
#include <new> //placement new #include <new> //placement new
@@ -118,27 +119,27 @@ struct allocator_traits
pointer, value_type*) pointer, value_type*)
pointer; pointer;
//const_pointer //const_pointer
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
const_pointer, typename boost::intrusive::pointer_traits<pointer>::template const_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<const value_type>::type) rebind_pointer<const value_type>)
const_pointer; const_pointer;
//reference //reference
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
reference, value_type&) reference, typename container_detail::unvoid<value_type>::type&)
reference; reference;
//const_reference //const_reference
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
const_reference, const value_type&) const_reference, const typename container_detail::unvoid<value_type>::type&)
const_reference; const_reference;
//void_pointer //void_pointer
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
void_pointer, typename boost::intrusive::pointer_traits<pointer>::template void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<void>::type) rebind_pointer<void>)
void_pointer; void_pointer;
//const_void_pointer //const_void_pointer
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<const void>::type) rebind_pointer<const void>)
const_void_pointer; const_void_pointer;
//difference_type //difference_type
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,

View File

@@ -352,7 +352,7 @@ class flat_tree
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
template <class... Args> template <class... Args>
iterator emplace_unique(Args&&... args) std::pair<iterator, bool> emplace_unique(Args&&... args)
{ {
value_type && val = value_type(boost::forward<Args>(args)...); value_type && val = value_type(boost::forward<Args>(args)...);
insert_commit_data data; insert_commit_data data;
@@ -361,7 +361,7 @@ class flat_tree
if(ret.second){ if(ret.second){
ret.first = priv_insert_commit(data, boost::move(val)); ret.first = priv_insert_commit(data, boost::move(val));
} }
return ret.first; return ret;
} }
template <class... Args> template <class... Args>
@@ -398,7 +398,8 @@ class flat_tree
#define BOOST_PP_LOCAL_MACRO(n) \ #define BOOST_PP_LOCAL_MACRO(n) \
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_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ std::pair<iterator, bool> \
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 \ BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type \
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n) \ BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n) \
@@ -409,7 +410,7 @@ class flat_tree
if(ret.second){ \ if(ret.second){ \
ret.first = priv_insert_commit(data, boost::move(val)); \ ret.first = priv_insert_commit(data, boost::move(val)); \
} \ } \
return ret.first; \ return ret; \
} \ } \
\ \
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, >) \
@@ -743,23 +744,6 @@ class flat_tree
for ( ; first != last; ++first) for ( ; first != last; ++first)
this->insert_equal(*first); this->insert_equal(*first);
} }
/*
template <class FwdIt>
void priv_insert_unique(FwdIt first, FwdIt last, std::forward_iterator_tag)
{
size_type len = static_cast<size_type>(std::distance(first, last));
this->reserve(this->size()+len);
priv_insert_unique(first, last, std::input_iterator_tag());
}
template <class InIt>
void priv_insert_unique(InIt first, InIt last, std::input_iterator_tag)
{
for ( ; first != last; ++first)
this->insert_unique(*first);
}
*/
}; };
template <class Key, class Value, class KeyOfValue, template <class Key, class Value, class KeyOfValue,

View File

@@ -148,6 +148,10 @@ struct ls_zeros<1>
static const std::size_t value = 0; static const std::size_t value = 0;
}; };
template <typename T> struct unvoid { typedef T type; };
template <> struct unvoid<void> { struct type { }; };
template <> struct unvoid<const void> { struct type { }; };
} //namespace container_detail { } //namespace container_detail {
} //namespace container { } //namespace container {
} //namespace boost { } //namespace boost {

View File

@@ -753,7 +753,7 @@ class rbtree
} }
private: private:
iterator emplace_unique_impl(NodePtr p) std::pair<iterator, bool> emplace_unique_impl(NodePtr p)
{ {
value_type &v = p->get_data(); value_type &v = p->get_data();
insert_commit_data data; insert_commit_data data;
@@ -761,9 +761,11 @@ class rbtree
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); Destroyer(this->node_alloc())(p);
return ret.first; return ret;
} }
return iterator(iiterator(this->icont().insert_unique_commit(*p, data))); return std::pair<iterator,bool>
( iterator(iiterator(this->icont().insert_unique_commit(*p, data)))
, true );
} }
iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p) iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
@@ -784,7 +786,7 @@ class rbtree
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
template <class... Args> template <class... Args>
iterator emplace_unique(Args&&... args) std::pair<iterator, bool> emplace_unique(Args&&... args)
{ return this->emplace_unique_impl(AllocHolder::create_node(boost::forward<Args>(args)...)); } { return this->emplace_unique_impl(AllocHolder::create_node(boost::forward<Args>(args)...)); }
template <class... Args> template <class... Args>
@@ -809,7 +811,7 @@ class rbtree
#define BOOST_PP_LOCAL_MACRO(n) \ #define BOOST_PP_LOCAL_MACRO(n) \
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_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ std::pair<iterator, bool> emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \ { \
return this->emplace_unique_impl \ return this->emplace_unique_impl \
(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ (AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \

View File

@@ -515,8 +515,8 @@ 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, 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), boost::move(container_detail::force<impl_value_type>(x)))); } (m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), boost::move(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.
@@ -548,7 +548,7 @@ class flat_map
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with //! <b>Effects</b>: Inserts an object x of type T constructed with
//! std::forward<Args>(args)... if and only if there is no element in the container //! std::forward<Args>(args)... if and only if there is no element in the container
//! with key equivalent to the key of x. //! with key equivalent to the key of x.
//! //!
@@ -561,8 +561,8 @@ 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(Args&&... args) std::pair<iterator,bool> emplace(Args&&... args)
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); } { return container_detail::force_copy< std::pair<iterator, bool> >(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); }
//! <b>Effects</b>: Inserts an object of type T constructed with //! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the container if and only if there is //! std::forward<Args>(args)... in the container if and only if there is
@@ -578,15 +578,16 @@ 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<impl_const_iterator>(hint), boost::forward<Args>(args)...)); }
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \ #define BOOST_PP_LOCAL_MACRO(n) \
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(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_unique \ { return container_detail::force_copy< std::pair<iterator, bool> > \
(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \ (m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
\ \
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_hint(const_iterator hint \ iterator emplace_hint(const_iterator hint \
@@ -631,7 +632,8 @@ 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<impl_const_iterator>(first), container_detail::force<impl_const_iterator>(last))); }
//! <b>Effects</b>: erase(a.begin(),a.end()). //! <b>Effects</b>: erase(a.begin(),a.end()).
//! //!
@@ -1151,7 +1153,8 @@ 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<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.
@@ -1284,7 +1287,8 @@ 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<impl_const_iterator>(first), container_detail::force<impl_const_iterator>(last))); }
//! <b>Effects</b>: erase(a.begin(),a.end()). //! <b>Effects</b>: erase(a.begin(),a.end()).
//! //!

View File

@@ -418,7 +418,7 @@ class flat_set
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with //! <b>Effects</b>: Inserts an object x of type T constructed with
//! std::forward<Args>(args)... if and only if there is no element in the container //! std::forward<Args>(args)... if and only if there is no element in the container
//! with key equivalent to the key of x. //! with key equivalent to the key of x.
//! //!
@@ -431,7 +431,7 @@ class flat_set
//! //!
//! <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(Args&&... args) std::pair<iterator,bool> emplace(Args&&... args)
{ return m_flat_tree.emplace_unique(boost::forward<Args>(args)...); } { return m_flat_tree.emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with //! <b>Effects</b>: Inserts an object of type T constructed with
@@ -454,7 +454,7 @@ class flat_set
#define BOOST_PP_LOCAL_MACRO(n) \ #define BOOST_PP_LOCAL_MACRO(n) \
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(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ { return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\ \
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, >) \
@@ -982,7 +982,8 @@ class flat_multiset
{ return this->insert(position, const_cast<const T &>(x)); } { return this->insert(position, const_cast<const T &>(x)); }
template<class U> template<class U>
iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0) iterator insert( const_iterator position, const U &u
, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(position, u); } { return priv_insert(position, u); }
#endif #endif

View File

@@ -504,18 +504,19 @@ class map
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with //! <b>Effects</b>: Inserts an object x of type T constructed with
//! std::forward<Args>(args)... in the container if and only if there is //! std::forward<Args>(args)... in the container if and only if there is
//! no element in the container with an equivalent key. //! no element in the container with an equivalent key.
//! 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.
//! //!
//! <b>Returns</b>: An iterator pointing to the element with key equivalent //! <b>Returns</b>: The bool component of the returned pair is true if and only
//! to the key of x. //! if the insertion takes place, and the iterator component of the pair
//! points to the element with key equivalent to the key of x.
//! //!
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p. //! is inserted right before p.
template <class... Args> template <class... Args>
iterator emplace(Args&&... args) std::pair<iterator,bool> emplace(Args&&... args)
{ return m_tree.emplace_unique(boost::forward<Args>(args)...); } { return m_tree.emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with //! <b>Effects</b>: Inserts an object of type T constructed with
@@ -536,7 +537,7 @@ class map
#define BOOST_PP_LOCAL_MACRO(n) \ #define BOOST_PP_LOCAL_MACRO(n) \
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(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\ \
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, >) \

View File

@@ -340,7 +340,8 @@ class set
{ return this->insert(const_cast<const T &>(x)); } { return this->insert(const_cast<const T &>(x)); }
template<class U> template<class U>
std::pair<iterator,bool> insert(const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0) std::pair<iterator,bool> insert(const U &u
, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(u); } { return priv_insert(u); }
#endif #endif
@@ -372,7 +373,8 @@ class set
{ return this->insert(position, const_cast<const T &>(x)); } { return this->insert(position, const_cast<const T &>(x)); }
template<class U> template<class U>
iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0) iterator insert( const_iterator position, const U &u
, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(position, u); } { return priv_insert(position, u); }
#endif #endif
@@ -397,18 +399,22 @@ class set
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with //! <b>Effects</b>: Inserts an object x of type T constructed with
//! std::forward<Args>(args)... if and only if there is //! std::forward<Args>(args)... if and only if there is
//! no element in the container with equivalent value. //! no element in the container with equivalent value.
//! and returns the iterator pointing to the //! and returns the iterator pointing to the
//! newly inserted element. //! newly inserted element.
//! //!
//! <b>Returns</b>: The bool component of the returned pair is true if and only
//! if the insertion takes place, and the iterator component of the pair
//! points to the element with key equivalent to the key of x.
//!
//! <b>Throws</b>: If memory allocation throws or //! <b>Throws</b>: If memory allocation throws or
//! T's in-place constructor throws. //! T's in-place constructor throws.
//! //!
//! <b>Complexity</b>: Logarithmic. //! <b>Complexity</b>: Logarithmic.
template <class... Args> template <class... Args>
iterator emplace(Args&&... args) std::pair<iterator,bool> emplace(Args&&... args)
{ return m_tree.emplace_unique(boost::forward<Args>(args)...); } { return m_tree.emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with //! <b>Effects</b>: Inserts an object of type T constructed with
@@ -428,7 +434,7 @@ class set
#define BOOST_PP_LOCAL_MACRO(n) \ #define BOOST_PP_LOCAL_MACRO(n) \
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(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\ \
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, >) \
@@ -902,7 +908,8 @@ class multiset
{ return this->insert(const_cast<const T &>(x)); } { return this->insert(const_cast<const T &>(x)); }
template<class U> template<class U>
iterator insert(const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0) iterator insert(const U &u
, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(u); } { return priv_insert(u); }
#endif #endif
@@ -932,7 +939,8 @@ class multiset
{ return this->insert(position, const_cast<const T &>(x)); } { return this->insert(position, const_cast<const T &>(x)); }
template<class U> template<class U>
iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0) iterator insert( const_iterator position, const U &u
, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(position, u); } { return priv_insert(position, u); }
#endif #endif

View File

@@ -638,7 +638,8 @@ class slist
void push_front(T &x) { push_front(const_cast<const T &>(x)); } void push_front(T &x) { push_front(const_cast<const T &>(x)); }
template<class U> template<class U>
void push_front(const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0) void push_front(const U &u
, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_push_front(u); } { return priv_push_front(u); }
#endif #endif
@@ -700,7 +701,8 @@ class slist
{ return this->insert_after(position, const_cast<const T &>(x)); } { return this->insert_after(position, const_cast<const T &>(x)); }
template<class U> template<class U>
iterator insert_after(const_iterator position, const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0) iterator insert_after( const_iterator position, const U &u
, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return this->priv_insert_after(position, u); } { return this->priv_insert_after(position, u); }
#endif #endif
@@ -768,7 +770,8 @@ class slist
{ return this->insert(position, const_cast<const T &>(x)); } { return this->insert(position, const_cast<const T &>(x)); }
template<class U> template<class U>
iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0) iterator insert( const_iterator position, const U &u
, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return this->priv_insert(position, u); } { return this->priv_insert(position, u); }
#endif #endif

View File

@@ -7,13 +7,14 @@
// See http://www.boost.org/libs/container for documentation. // See http://www.boost.org/libs/container for documentation.
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/* Stable vector. // Stable vector.
* //
* Copyright 2008 Joaquin M Lopez Munoz. // Copyright 2008 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0. // Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
*/ //
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP #ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP
#define BOOST_CONTAINER_STABLE_VECTOR_HPP #define BOOST_CONTAINER_STABLE_VECTOR_HPP

View File

@@ -15,6 +15,7 @@
#include <boost/type_traits/integral_constant.hpp> #include <boost/type_traits/integral_constant.hpp>
#include <boost/container/detail/function_detector.hpp> #include <boost/container/detail/function_detector.hpp>
#include <boost/move/move.hpp> #include <boost/move/move.hpp>
#include <memory>
template<class T> template<class T>
class SimpleAllocator class SimpleAllocator
@@ -63,7 +64,7 @@ class SimpleSmartPtr
T *ptr_; T *ptr_;
}; };
template<class T, class Arg> template<class T>
class ComplexAllocator class ComplexAllocator
{ {
bool allocate_called_; bool allocate_called_;
@@ -78,8 +79,10 @@ class ComplexAllocator
typedef T value_type; typedef T value_type;
typedef SimpleSmartPtr<T> pointer; typedef SimpleSmartPtr<T> pointer;
typedef SimpleSmartPtr<const T> const_pointer; typedef SimpleSmartPtr<const T> const_pointer;
typedef T & reference; typedef typename boost::container::
typedef const T & const_reference; container_detail::unvoid<T>::type & reference;
typedef const typename boost::container::
container_detail::unvoid<T>::type & const_reference;
typedef SimpleSmartPtr<void> void_pointer; typedef SimpleSmartPtr<void> void_pointer;
typedef SimpleSmartPtr<const void> const_void_pointer; typedef SimpleSmartPtr<const void> const_void_pointer;
typedef signed short difference_type; typedef signed short difference_type;
@@ -187,8 +190,17 @@ class copymovable
{ return moved_; } { return moved_; }
}; };
void test_void_allocator()
{
boost::container::allocator_traits<std::allocator<void> > stdtraits; (void)stdtraits;
boost::container::allocator_traits<SimpleAllocator<void> > simtraits; (void)simtraits;
boost::container::allocator_traits<ComplexAllocator<void> > comtraits; (void)comtraits;
}
int main() int main()
{ {
test_void_allocator();
//SimpleAllocator //SimpleAllocator
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::value_type, int>::value )); < SimpleAllocator<int> >::value_type, int>::value ));
@@ -219,33 +231,33 @@ int main()
//ComplexAllocator //ComplexAllocator
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::value_type, int>::value )); < ComplexAllocator<int> >::value_type, int>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::pointer, SimpleSmartPtr<int> >::value )); < ComplexAllocator<int> >::pointer, SimpleSmartPtr<int> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::const_pointer, SimpleSmartPtr<const int> >::value )); < ComplexAllocator<int> >::const_pointer, SimpleSmartPtr<const int> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::void_pointer, SimpleSmartPtr<void> >::value )); < ComplexAllocator<int> >::void_pointer, SimpleSmartPtr<void> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::const_void_pointer, SimpleSmartPtr<const void> >::value )); < ComplexAllocator<int> >::const_void_pointer, SimpleSmartPtr<const void> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::difference_type, signed short>::value )); < ComplexAllocator<int> >::difference_type, signed short>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::size_type, unsigned short>::value )); < ComplexAllocator<int> >::size_type, unsigned short>::value ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< ComplexAllocator<int, void> >::propagate_on_container_copy_assignment::value == true )); < ComplexAllocator<int> >::propagate_on_container_copy_assignment::value == true ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< ComplexAllocator<int, void> >::propagate_on_container_move_assignment::value == true )); < ComplexAllocator<int> >::propagate_on_container_move_assignment::value == true ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< ComplexAllocator<int, void> >::propagate_on_container_swap::value == true )); < ComplexAllocator<int> >::propagate_on_container_swap::value == true ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::rebind_traits<double>::allocator_type < ComplexAllocator<int> >::rebind_traits<double>::allocator_type
, ComplexAllocator<double, void> >::value )); , ComplexAllocator<double> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::rebind_alloc<double>::value_type < ComplexAllocator<int> >::rebind_alloc<double>::value_type
, double >::value )); , double >::value ));
typedef ComplexAllocator<int, void> CAlloc; typedef ComplexAllocator<int> CAlloc;
typedef SimpleAllocator<int> SAlloc; typedef SimpleAllocator<int> SAlloc;
typedef boost::container::allocator_traits<CAlloc> CAllocTraits; typedef boost::container::allocator_traits<CAlloc> CAllocTraits;
typedef boost::container::allocator_traits<SAlloc> SAllocTraits; typedef boost::container::allocator_traits<SAlloc> SAllocTraits;