summaryrefslogtreecommitdiff
path: root/boost/container/detail
diff options
context:
space:
mode:
Diffstat (limited to 'boost/container/detail')
-rw-r--r--boost/container/detail/copy_move_algo.hpp71
-rw-r--r--boost/container/detail/flat_tree.hpp98
-rw-r--r--boost/container/detail/iterator.hpp1
-rw-r--r--boost/container/detail/iterators.hpp12
-rw-r--r--boost/container/detail/mpl.hpp175
-rw-r--r--boost/container/detail/node_alloc_holder.hpp108
-rw-r--r--boost/container/detail/pair.hpp79
-rw-r--r--boost/container/detail/std_fwd.hpp6
-rw-r--r--boost/container/detail/tree.hpp91
-rw-r--r--boost/container/detail/type_traits.hpp1
10 files changed, 222 insertions, 420 deletions
diff --git a/boost/container/detail/copy_move_algo.hpp b/boost/container/detail/copy_move_algo.hpp
index 79cbde80a9..23fa730838 100644
--- a/boost/container/detail/copy_move_algo.hpp
+++ b/boost/container/detail/copy_move_algo.hpp
@@ -123,48 +123,49 @@ struct are_elements_contiguous< ::boost::interprocess::offset_ptr<PointedType, D
template <typename I, typename O>
struct are_contiguous_and_same
-{
- static const bool is_same_io =
- is_same< typename remove_const< typename ::boost::container::iterator_traits<I>::value_type >::type
- , typename ::boost::container::iterator_traits<O>::value_type
- >::value;
- static const bool value = is_same_io &&
- are_elements_contiguous<I>::value &&
- are_elements_contiguous<O>::value;
-};
+ : boost::move_detail::and_
+ < are_elements_contiguous<I>
+ , are_elements_contiguous<O>
+ , is_same< typename remove_const< typename ::boost::container::iterator_traits<I>::value_type >::type
+ , typename ::boost::container::iterator_traits<O>::value_type
+ >
+ >
+{};
template <typename I, typename O>
struct is_memtransfer_copy_assignable
-{
- static const bool value = are_contiguous_and_same<I, O>::value &&
- container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits<I>::value_type >::value;
-};
+ : boost::move_detail::and_
+ < are_contiguous_and_same<I, O>
+ , container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits<I>::value_type >
+ >
+{};
template <typename I, typename O>
struct is_memtransfer_copy_constructible
-{
- static const bool value = are_contiguous_and_same<I, O>::value &&
- container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits<I>::value_type >::value;
-};
+ : boost::move_detail::and_
+ < are_contiguous_and_same<I, O>
+ , container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits<I>::value_type >
+ >
+{};
template <typename I, typename O, typename R>
struct enable_if_memtransfer_copy_constructible
- : enable_if_c<container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
+ : enable_if<container_detail::is_memtransfer_copy_constructible<I, O>, R>
{};
template <typename I, typename O, typename R>
struct disable_if_memtransfer_copy_constructible
- : enable_if_c<!container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
+ : disable_if<container_detail::is_memtransfer_copy_constructible<I, O>, R>
{};
template <typename I, typename O, typename R>
struct enable_if_memtransfer_copy_assignable
- : enable_if_c<container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
+ : enable_if<container_detail::is_memtransfer_copy_assignable<I, O>, R>
{};
template <typename I, typename O, typename R>
struct disable_if_memtransfer_copy_assignable
- : enable_if_c<!container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
+ : disable_if<container_detail::is_memtransfer_copy_assignable<I, O>, R>
{};
template
@@ -174,8 +175,10 @@ inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef typename boost::container::iterator_traits<I>::value_type value_type;
typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
- std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- boost::container::iterator_advance(r, n);
+ if(n){
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(r, n);
+ }
return r;
}
@@ -185,8 +188,10 @@ template
F memmove_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef typename boost::container::iterator_traits<I>::value_type value_type;
- std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- boost::container::iterator_advance(r, n);
+ if(n){
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(r, n);
+ }
return r;
}
@@ -195,9 +200,11 @@ template
typename F> // F models ForwardIterator
I memmove_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
- typedef typename boost::container::iterator_traits<I>::value_type value_type;
- std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- boost::container::iterator_advance(f, n);
+ if(n){
+ typedef typename boost::container::iterator_traits<I>::value_type value_type;
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(f, n);
+ }
return f;
}
@@ -207,9 +214,11 @@ template
I memmove_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef typename boost::container::iterator_traits<I>::value_type value_type;
- std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- boost::container::iterator_advance(f, n);
- boost::container::iterator_advance(r, n);
+ if(n){
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(f, n);
+ boost::container::iterator_advance(r, n);
+ }
return f;
}
diff --git a/boost/container/detail/flat_tree.hpp b/boost/container/detail/flat_tree.hpp
index a94043c6bd..f27421125f 100644
--- a/boost/container/detail/flat_tree.hpp
+++ b/boost/container/detail/flat_tree.hpp
@@ -470,20 +470,22 @@ class flat_tree
template <class BidirIt>
void insert_equal(ordered_range_t, BidirIt first, BidirIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_input_iterator<BidirIt>::value &&
- !container_detail::is_forward_iterator<BidirIt>::value
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_input_iterator<BidirIt>
+ , container_detail::is_forward_iterator<BidirIt>
>::type * = 0
#endif
)
- { this->priv_insert_ordered_range(false, first, last); }
+ { this->m_data.m_vect.merge(first, last); }
template <class InIt>
void insert_unique(ordered_unique_range_t, InIt first, InIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < container_detail::is_input_iterator<InIt>::value ||
- container_detail::is_forward_iterator<InIt>::value
+ , typename container_detail::enable_if_or
+ < void
+ , container_detail::is_input_iterator<InIt>
+ , container_detail::is_forward_iterator<InIt>
>::type * = 0
#endif
)
@@ -504,7 +506,7 @@ class flat_tree
>::type * = 0
#endif
)
- { this->priv_insert_ordered_range(true, first, last); }
+ { this->m_data.m_vect.merge_unique(first, last, value_compare()); }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -855,8 +857,8 @@ class flat_tree
}
template <class RanIt>
- RanIt priv_upper_bound(RanIt first, const RanIt last,
- const key_type & key) const
+ RanIt priv_upper_bound
+ (RanIt first, const RanIt last,const key_type & key) const
{
const Compare &key_cmp = this->m_data.get_comp();
KeyOfValue key_extract;
@@ -904,9 +906,9 @@ class flat_tree
//Middle is equal to key
last = first;
last += len;
+ RanIt const first_ret = this->priv_lower_bound(first, middle, key);
return std::pair<RanIt, RanIt>
- ( this->priv_lower_bound(first, middle, key)
- , this->priv_upper_bound(++middle, last, key));
+ ( first_ret, this->priv_upper_bound(++middle, last, key));
}
}
return std::pair<RanIt, RanIt>(first, first);
@@ -939,81 +941,11 @@ class flat_tree
for ( ; first != last; ++first){
//If ordered, then try hint version
//to achieve constant-time complexity per insertion
+ //in some cases
pos = this->insert_equal(pos, *first);
++pos;
}
}
-
- template <class BidirIt>
- void priv_insert_ordered_range(const bool unique_values, BidirIt first, BidirIt last)
- {
- size_type len = static_cast<size_type>(boost::container::iterator_distance(first, last));
- //Prereserve all memory so that iterators are not invalidated
- this->reserve(this->size()+len);
- //Auxiliary data for insertion positions.
- const size_type BurstSize = len;
- const ::boost::movelib::unique_ptr<size_type[]> positions =
- ::boost::movelib::make_unique_definit<size_type[]>(BurstSize);
-
- const const_iterator b(this->cbegin());
- const const_iterator ce(this->cend());
- const_iterator pos(b);
- const value_compare &val_cmp = this->m_data;
- //Loop in burst sizes
- bool back_insert = false;
- while(len && !back_insert){
- const size_type burst = len < BurstSize ? len : BurstSize;
- size_type unique_burst = 0u;
- size_type checked = 0;
- for(; checked != burst; ++checked){
- //Get the insertion position for each key, use iterator_traits<BidirIt>::value_type
- //because it can be different from container::value_type
- //(e.g. conversion between std::pair<T1, T2> -> boost::container::pair<T1, T2>
- const typename boost::container::iterator_traits<BidirIt>::value_type & val = *first;
- pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
- //Check if already present
- if (pos != ce){
- ++first;
- --len;
- positions[checked] = (unique_values && !val_cmp(val, *pos)) ?
- size_type(-1) : (++unique_burst, static_cast<size_type>(pos - b));
- }
- else{ //this element and the remaining should be back inserted
- back_insert = true;
- break;
- }
- }
- if(unique_burst){
- //Insert all in a single step in the precalculated positions
- this->m_data.m_vect.insert_ordered_at(unique_burst, positions.get() + checked, first);
- //Next search position updated, iterator still valid because we've preserved the vector
- pos += unique_burst;
- }
- }
- //The remaining range should be back inserted
- if(unique_values){
- while(len--){
- BidirIt next(first);
- ++next;
- //Use iterator_traits<BidirIt>::value_type
- //because it can be different from container::value_type
- //(e.g. conversion between std::pair<T1, T2> -> boost::container::pair<T1, T2>
- const typename boost::container::iterator_traits<BidirIt>::value_type & val = *first;
- if (next == last || val_cmp(val, *next)){
- const bool room = this->m_data.m_vect.stable_emplace_back(*first);
- (void)room;
- BOOST_ASSERT(room);
- }
- first = next;
- }
- BOOST_ASSERT(first == last);
- }
- else{
- BOOST_ASSERT(size_type(boost::container::iterator_distance(first, last)) == len);
- if(len)
- this->m_data.m_vect.insert(this->m_data.m_vect.cend(), len, first, last);
- }
- }
};
} //namespace container_detail {
diff --git a/boost/container/detail/iterator.hpp b/boost/container/detail/iterator.hpp
index ceb224f3ad..8538acc161 100644
--- a/boost/container/detail/iterator.hpp
+++ b/boost/container/detail/iterator.hpp
@@ -32,6 +32,7 @@ using ::boost::intrusive::iterator_advance;
using ::boost::intrusive::iterator;
using ::boost::intrusive::iterator_enable_if_tag;
using ::boost::intrusive::iterator_disable_if_tag;
+using ::boost::intrusive::iterator_arrow_result;
} //namespace container {
} //namespace boost {
diff --git a/boost/container/detail/iterators.hpp b/boost/container/detail/iterators.hpp
index 1f80d3e122..e8cfcf97a4 100644
--- a/boost/container/detail/iterators.hpp
+++ b/boost/container/detail/iterators.hpp
@@ -651,11 +651,13 @@ namespace container_detail {
template<class T>
struct has_iterator_category
{
+ struct two { char _[2]; };
+
template <typename X>
static char test(int, typename X::iterator_category*);
template <typename X>
- static int test(int, ...);
+ static two test(int, ...);
static const bool value = (1 == sizeof(test<T>(0, 0)));
};
@@ -673,6 +675,12 @@ struct is_input_iterator<T, false>
static const bool value = false;
};
+template<class T>
+struct is_not_input_iterator
+{
+ static const bool value = !is_input_iterator<T>::value;
+};
+
template<class T, bool = has_iterator_category<T>::value >
struct is_forward_iterator
{
@@ -796,7 +804,7 @@ class iterator_from_iiterator
{ return !(l == r); }
reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
- { return (*this->m_iit).get_data(); }
+ { return this->m_iit->get_data(); }
pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
{ return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); }
diff --git a/boost/container/detail/mpl.hpp b/boost/container/detail/mpl.hpp
index 74b618f8c6..e1684ea0b1 100644
--- a/boost/container/detail/mpl.hpp
+++ b/boost/container/detail/mpl.hpp
@@ -23,6 +23,8 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+#include <boost/move/detail/type_traits.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
#include <cstddef>
@@ -30,110 +32,35 @@ namespace boost {
namespace container {
namespace container_detail {
-template <class T, T val>
-struct integral_constant
-{
- static const T value = val;
- typedef integral_constant<T,val> type;
-};
-
-template< bool C_ >
-struct bool_ : integral_constant<bool, C_>
-{
- static const bool value = C_;
- operator bool() const { return bool_::value; }
-};
-
-template< unsigned V_ >
-struct unsigned_ : integral_constant<unsigned, V_>
-{
- static const unsigned value = V_;
- operator unsigned() const { return unsigned_::value; }
-};
-
-typedef bool_<true> true_;
-typedef bool_<false> false_;
-
-typedef true_ true_type;
-typedef false_ false_type;
-
-typedef char yes_type;
-struct no_type
-{
- char padding[8];
-};
-
-template <bool B, class T = void>
-struct enable_if_c {
- typedef T type;
-};
-
-template <class T>
-struct enable_if_c<false, T> {};
-
-template <class Cond, class T = void>
-struct enable_if : public enable_if_c<Cond::value, T> {};
-
-template <class Cond, class T = void>
-struct disable_if : public enable_if_c<!Cond::value, T> {};
-
-template <bool B, class T = void>
-struct disable_if_c : public enable_if_c<!B, T> {};
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-
-template <class T, class U>
-struct is_convertible
-{
- static const bool value = __is_convertible_to(T, U);
-};
-
-#else
-
-template <class T, class U>
-class is_convertible
-{
- typedef char true_t;
- class false_t { char dummy[2]; };
- //use any_conversion as first parameter since in MSVC
- //overaligned types can't go through ellipsis
- static false_t dispatch(...);
- static true_t dispatch(U);
- static T &trigger();
- public:
- static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
-};
-
-#endif
-
-template<
- bool C
- , typename T1
- , typename T2
- >
-struct if_c
-{
- typedef T1 type;
-};
-
-template<
- typename T1
- , typename T2
- >
-struct if_c<false,T1,T2>
-{
- typedef T2 type;
-};
-
-template<
- typename T1
- , typename T2
- , typename T3
- >
-struct if_
-{
- typedef typename if_c<0 != T1::value, T2, T3>::type type;
-};
+using boost::move_detail::integral_constant;
+using boost::move_detail::true_type;
+using boost::move_detail::false_type;
+using boost::move_detail::enable_if_c;
+using boost::move_detail::enable_if;
+using boost::move_detail::enable_if_convertible;
+using boost::move_detail::disable_if_c;
+using boost::move_detail::disable_if;
+using boost::move_detail::disable_if_convertible;
+using boost::move_detail::is_convertible;
+using boost::move_detail::if_c;
+using boost::move_detail::if_;
+using boost::move_detail::identity;
+using boost::move_detail::bool_;
+using boost::move_detail::true_;
+using boost::move_detail::false_;
+using boost::move_detail::yes_type;
+using boost::move_detail::no_type;
+using boost::move_detail::bool_;
+using boost::move_detail::true_;
+using boost::move_detail::false_;
+using boost::move_detail::unvoid_ref;
+using boost::move_detail::and_;
+using boost::move_detail::or_;
+using boost::move_detail::not_;
+using boost::move_detail::enable_if_and;
+using boost::move_detail::disable_if_and;
+using boost::move_detail::enable_if_or;
+using boost::move_detail::disable_if_or;
template <class Pair>
@@ -150,46 +77,6 @@ struct select1st
{ return x; }
};
-// identity is an extension: it is not part of the standard.
-template <class T>
-struct identity
-{
- typedef T argument_type;
- typedef T result_type;
-
- typedef T type;
- const T& operator()(const T& x) const
- { return x; }
-};
-
-template<std::size_t S>
-struct ls_zeros
-{
- static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + ls_zeros<(S >> 1u)>::value);
-};
-
-template<>
-struct ls_zeros<0>
-{
- static const std::size_t value = 0;
-};
-
-template<>
-struct ls_zeros<1>
-{
- static const std::size_t value = 0;
-};
-
-template <std::size_t OrigSize, std::size_t RoundTo>
-struct ct_rounded_size
-{
- static const std::size_t value = ((OrigSize-1)/RoundTo+1)*RoundTo;
-};
-
-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 {
} //namespace boost {
diff --git a/boost/container/detail/node_alloc_holder.hpp b/boost/container/detail/node_alloc_holder.hpp
index 98c8e62baa..3b632a677d 100644
--- a/boost/container/detail/node_alloc_holder.hpp
+++ b/boost/container/detail/node_alloc_holder.hpp
@@ -173,87 +173,25 @@ struct node_alloc_holder
}
#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- NodePtr create_node()
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data));
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
-
- template<BOOST_MOVE_CLASS1>
- NodePtr create_node(BOOST_MOVE_UREF1)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data)
- , BOOST_MOVE_FWD1);
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
- template<BOOST_MOVE_CLASS2>
- NodePtr create_node(BOOST_MOVE_UREF2)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data)
- , BOOST_MOVE_FWD2);
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
-
- template<BOOST_MOVE_CLASS3>
- NodePtr create_node(BOOST_MOVE_UREF3)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data)
- , BOOST_MOVE_FWD3);
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
-
- template<BOOST_MOVE_CLASS4>
- NodePtr create_node(BOOST_MOVE_UREF4)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data)
- , BOOST_MOVE_FWD4);
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
-
- template<BOOST_MOVE_CLASS5>
- NodePtr create_node(BOOST_MOVE_UREF5)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::addressof(p->m_data)
- , BOOST_MOVE_FWD5);
- node_deallocator.release();
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
- return (p);
- }
+ #define BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ NodePtr create_node(BOOST_MOVE_UREF##N)\
+ {\
+ NodePtr p = this->allocate_one();\
+ Deallocator node_deallocator(p, this->node_alloc());\
+ allocator_traits<NodeAlloc>::construct\
+ ( this->node_alloc()\
+ , container_detail::addressof(p->m_data)\
+ BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ node_deallocator.release();\
+ typedef typename Node::hook_type hook_type;\
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;\
+ return (p);\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL)
+ #undef BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -375,7 +313,7 @@ struct node_alloc_holder
{}
NodePtr operator()(const Node &other) const
- { return m_holder.create_node(other.get_data()); }
+ { return m_holder.create_node(other.m_data); }
node_alloc_holder &m_holder;
};
@@ -387,7 +325,9 @@ struct node_alloc_holder
{}
NodePtr operator()(Node &other)
- { return m_holder.create_node(::boost::move(other.get_data())); }
+ { //Use m_data instead of get_data to allow moving const key in [multi]map
+ return m_holder.create_node(::boost::move(other.m_data));
+ }
node_alloc_holder &m_holder;
};
@@ -413,12 +353,12 @@ struct node_alloc_holder
template<class ConvertibleToAlloc>
members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const value_compare &c)
: NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
- , m_icont(typename ICont::value_compare(c))
+ , m_icont(typename ICont::key_compare(c))
{}
explicit members_holder(const value_compare &c)
: NodeAlloc()
- , m_icont(typename ICont::value_compare(c))
+ , m_icont(typename ICont::key_compare(c))
{}
//The intrusive container
diff --git a/boost/container/detail/pair.hpp b/boost/container/detail/pair.hpp
index 6d31d3b796..35e8846caa 100644
--- a/boost/container/detail/pair.hpp
+++ b/boost/container/detail/pair.hpp
@@ -33,6 +33,46 @@
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <boost/move/utility_core.hpp>
+/*
+namespace boost{
+
+template<class T1, class T2>
+inline rv< std::pair<T1, T2> > &move(std::pair<T1, T2> &r)
+{
+ return reinterpret_cast< rv< std::pair<T1, T2> > &>(r);
+}
+
+template<class T1, class T2>
+inline rv< std::pair<T1, T2> > &move(rv< std::pair<T1, T2> > &r)
+{
+ return r;
+}
+
+template <class T>
+inline typename ::boost::move_detail::enable_if_and
+ < T &
+ , boost::container::container_detail::is_std_pair<T>
+ , ::boost::move_detail::is_rv<T>
+ >::type
+ forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
+{
+ return const_cast<T&>(x);
+}
+
+template <class T>
+inline typename ::boost::move_detail::enable_if_and
+ < const T &
+ , boost::container::container_detail::is_std_pair<T>
+ , ::boost::move_detail::is_not_rv<T>
+ >::type
+ forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
+{
+ return x;
+}
+
+} //namespace boost {
+*/
+
namespace boost {
namespace container {
namespace container_detail {
@@ -58,6 +98,24 @@ struct is_pair< std::pair<T1, T2> >
static const bool value = true;
};
+template <class T>
+struct is_not_pair
+{
+ static const bool value = !is_pair<T>::value;
+};
+
+template <class T>
+struct is_std_pair
+{
+ static const bool value = false;
+};
+
+template <class T1, class T2>
+struct is_std_pair< std::pair<T1, T2> >
+{
+ static const bool value = true;
+};
+
struct pair_nat;
struct piecewise_construct_t { };
@@ -182,10 +240,11 @@ struct pair
}
template <class D, class S>
- typename ::boost::container::container_detail::enable_if_c
- < !(::boost::container::container_detail::is_same<T1, D>::value &&
- ::boost::container::container_detail::is_same<T2, S>::value)
- , pair &>::type
+ typename ::boost::container::container_detail::disable_if_or
+ < pair &
+ , ::boost::container::container_detail::is_same<T1, D>
+ , ::boost::container::container_detail::is_same<T2, S>
+ >::type
operator=(const pair<D, S>&p)
{
first = p.first;
@@ -194,18 +253,18 @@ struct pair
}
template <class D, class S>
- typename ::boost::container::container_detail::enable_if_c
- < !(::boost::container::container_detail::is_same<T1, D>::value &&
- ::boost::container::container_detail::is_same<T2, S>::value)
- , pair &>::type
+ typename ::boost::container::container_detail::disable_if_or
+ < pair &
+ , ::boost::container::container_detail::is_same<T1, D>
+ , ::boost::container::container_detail::is_same<T2, S>
+ >::type
operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
{
first = ::boost::move(p.first);
second = ::boost::move(p.second);
return *this;
}
-
- //std::pair copy assignment
+//std::pair copy assignment
pair& operator=(const std::pair<T1, T2> &p)
{
first = p.first;
diff --git a/boost/container/detail/std_fwd.hpp b/boost/container/detail/std_fwd.hpp
index a2931c134b..1277df071f 100644
--- a/boost/container/detail/std_fwd.hpp
+++ b/boost/container/detail/std_fwd.hpp
@@ -23,10 +23,12 @@
// Standard predeclarations
//////////////////////////////////////////////////////////////////////////////
-#if defined(__clang__) && defined(_LIBCPP_VERSION)
+#if defined(_LIBCPP_VERSION)
#define BOOST_CONTAINER_CLANG_INLINE_STD_NS
#pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wc++11-extensions"
+ #if defined(__clang__)
+ #pragma GCC diagnostic ignored "-Wc++11-extensions"
+ #endif
#define BOOST_CONTAINER_STD_NS_BEG _LIBCPP_BEGIN_NAMESPACE_STD
#define BOOST_CONTAINER_STD_NS_END _LIBCPP_END_NAMESPACE_STD
#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE_VERSION) //GCC >= 4.6
diff --git a/boost/container/detail/tree.hpp b/boost/container/detail/tree.hpp
index 0f90b5a4e2..c90202973a 100644
--- a/boost/container/detail/tree.hpp
+++ b/boost/container/detail/tree.hpp
@@ -43,6 +43,7 @@
#include <boost/intrusive/sgtree.hpp>
// intrusive/detail
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
+#include <boost/intrusive/detail/tree_value_compare.hpp> //tree_value_compare
// move
#include <boost/move/utility_core.hpp>
// move/detail
@@ -52,57 +53,15 @@
// other
#include <boost/core/no_exceptions_support.hpp>
-namespace boost {
-namespace container {
-namespace container_detail {
-template<class Key, class T, class Compare, class KeyOfValue>
-struct tree_value_compare
- : public Compare
-{
- typedef T value_type;
- typedef Compare key_compare;
- typedef KeyOfValue key_of_value;
- typedef Key key_type;
- explicit tree_value_compare(const key_compare &kcomp)
- : Compare(kcomp)
- {}
-
- tree_value_compare()
- : Compare()
- {}
+#include <boost/container/detail/std_fwd.hpp>
- const key_compare &key_comp() const
- { return static_cast<const key_compare &>(*this); }
-
- key_compare &key_comp()
- { return static_cast<key_compare &>(*this); }
-
- template<class U>
- struct is_key
- {
- static const bool value = is_same<const U, const key_type>::value;
- };
-
- template<class U>
- typename enable_if_c<is_key<U>::value, const key_type &>::type
- key_forward(const U &key) const
- { return key; }
-
- template<class U>
- typename enable_if_c<!is_key<U>::value, const key_type &>::type
- key_forward(const U &key) const
- { return KeyOfValue()(key); }
-
- template<class KeyType, class KeyType2>
- bool operator()(const KeyType &key1, const KeyType2 &key2) const
- { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
+namespace boost {
+namespace container {
+namespace container_detail {
- template<class KeyType, class KeyType2>
- bool operator()(const KeyType &key1, const KeyType2 &key2)
- { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
-};
+using boost::intrusive::tree_value_compare;
template<class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
struct intrusive_tree_hook;
@@ -156,7 +115,7 @@ struct tree_internal_data_type
template<class T1, class T2>
struct tree_internal_data_type< std::pair<T1, T2> >
{
- typedef pair<T1, T2> type;
+ typedef pair<typename boost::move_detail::remove_const<T1>::type, T2> type;
};
//The node to be store in the tree
@@ -549,9 +508,10 @@ class tree
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
const allocator_type& a
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, version_1>::value
+ , typename container_detail::enable_if_or
+ < void
+ , container_detail::is_same<alloc_version, version_1>
+ , container_detail::is_input_iterator<InputIterator>
>::type * = 0
#endif
)
@@ -577,9 +537,10 @@ class tree
tree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
const allocator_type& a
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !(container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, version_1>::value)
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_same<alloc_version, version_1>
+ , container_detail::is_input_iterator<InputIterator>
>::type * = 0
#endif
)
@@ -606,10 +567,11 @@ class tree
tree( ordered_range_t, InputIterator first, InputIterator last
, const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, version_1>::value
- >::type * = 0
+ , typename container_detail::enable_if_or
+ < void
+ , container_detail::is_same<alloc_version, version_1>
+ , container_detail::is_input_iterator<InputIterator>
+ >::type * = 0
#endif
)
: AllocHolder(value_compare(comp), a)
@@ -623,10 +585,11 @@ class tree
tree( ordered_range_t, InputIterator first, InputIterator last
, const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !(container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, version_1>::value)
- >::type * = 0
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_same<alloc_version, version_1>
+ , container_detail::is_input_iterator<InputIterator>
+ >::type * = 0
#endif
)
: AllocHolder(value_compare(comp), a)
@@ -663,7 +626,7 @@ class tree
}
else{
this->icont().clone_from
- (x.icont(), typename AllocHolder::move_cloner(*this), Destroyer(this->node_alloc()));
+ (boost::move(x.icont()), typename AllocHolder::move_cloner(*this), Destroyer(this->node_alloc()));
}
}
@@ -730,7 +693,7 @@ class tree
//Now recreate the source tree reusing nodes stored by other_tree
this->icont().clone_from
- (x.icont()
+ (::boost::move(x.icont())
, RecyclingCloner<AllocHolder, true>(*this, other_tree)
, Destroyer(this->node_alloc()));
diff --git a/boost/container/detail/type_traits.hpp b/boost/container/detail/type_traits.hpp
index 1ae2426863..e02709ac6e 100644
--- a/boost/container/detail/type_traits.hpp
+++ b/boost/container/detail/type_traits.hpp
@@ -31,6 +31,7 @@ namespace container {
namespace container_detail {
using ::boost::move_detail::is_same;
+using ::boost::move_detail::is_different;
using ::boost::move_detail::is_pointer;
using ::boost::move_detail::add_reference;
using ::boost::move_detail::add_const;