diff options
Diffstat (limited to 'boost/container/detail')
-rw-r--r-- | boost/container/detail/copy_move_algo.hpp | 71 | ||||
-rw-r--r-- | boost/container/detail/flat_tree.hpp | 98 | ||||
-rw-r--r-- | boost/container/detail/iterator.hpp | 1 | ||||
-rw-r--r-- | boost/container/detail/iterators.hpp | 12 | ||||
-rw-r--r-- | boost/container/detail/mpl.hpp | 175 | ||||
-rw-r--r-- | boost/container/detail/node_alloc_holder.hpp | 108 | ||||
-rw-r--r-- | boost/container/detail/pair.hpp | 79 | ||||
-rw-r--r-- | boost/container/detail/std_fwd.hpp | 6 | ||||
-rw-r--r-- | boost/container/detail/tree.hpp | 91 | ||||
-rw-r--r-- | boost/container/detail/type_traits.hpp | 1 |
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; |