summaryrefslogtreecommitdiff
path: root/boost/multi_index/detail
diff options
context:
space:
mode:
Diffstat (limited to 'boost/multi_index/detail')
-rw-r--r--boost/multi_index/detail/archive_constructed.hpp4
-rw-r--r--boost/multi_index/detail/bucket_array.hpp5
-rw-r--r--boost/multi_index/detail/copy_map.hpp15
-rw-r--r--boost/multi_index/detail/hash_index_node.hpp22
-rw-r--r--boost/multi_index/detail/index_loader.hpp5
-rw-r--r--boost/multi_index/detail/index_matcher.hpp5
-rw-r--r--boost/multi_index/detail/index_node_base.hpp8
-rw-r--r--boost/multi_index/detail/ord_index_impl.hpp1567
-rw-r--r--boost/multi_index/detail/ord_index_impl_fwd.hpp128
-rw-r--r--boost/multi_index/detail/ord_index_node.hpp104
-rw-r--r--boost/multi_index/detail/raw_ptr.hpp52
-rw-r--r--boost/multi_index/detail/rnd_index_node.hpp13
-rw-r--r--boost/multi_index/detail/rnd_index_ops.hpp10
-rw-r--r--boost/multi_index/detail/rnk_index_ops.hpp300
-rw-r--r--boost/multi_index/detail/seq_index_node.hpp15
-rw-r--r--boost/multi_index/detail/seq_index_ops.hpp6
-rw-r--r--boost/multi_index/detail/value_compare.hpp9
17 files changed, 2182 insertions, 86 deletions
diff --git a/boost/multi_index/detail/archive_constructed.hpp b/boost/multi_index/detail/archive_constructed.hpp
index 0cf7991e86..c3891bb32a 100644
--- a/boost/multi_index/detail/archive_constructed.hpp
+++ b/boost/multi_index/detail/archive_constructed.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -64,7 +64,7 @@ struct archive_constructed:private noncopyable
(&get())->~T();
}
- T& get(){return *static_cast<T*>(static_cast<void*>(&space));}
+ T& get(){return *reinterpret_cast<T*>(&space);}
private:
typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space;
diff --git a/boost/multi_index/detail/bucket_array.hpp b/boost/multi_index/detail/bucket_array.hpp
index f688ba1621..d9fa434d9a 100644
--- a/boost/multi_index/detail/bucket_array.hpp
+++ b/boost/multi_index/detail/bucket_array.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2014 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -77,7 +77,8 @@ template<bool _=true> /* templatized to have in-header static var defs */
class bucket_array_base:private noncopyable
{
protected:
- static const std::size_t sizes[];
+ static const std::size_t sizes[
+ BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES)];
static std::size_t size_index(std::size_t n)
{
diff --git a/boost/multi_index/detail/copy_map.hpp b/boost/multi_index/detail/copy_map.hpp
index a0b6cad590..9a34b259cf 100644
--- a/boost/multi_index/detail/copy_map.hpp
+++ b/boost/multi_index/detail/copy_map.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -17,6 +17,7 @@
#include <algorithm>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <cstddef>
#include <functional>
@@ -75,13 +76,13 @@ public:
}
}
- const_iterator begin()const{return &*spc.data();}
- const_iterator end()const{return &*(spc.data()+n);}
+ const_iterator begin()const{return raw_ptr<const_iterator>(spc.data());}
+ const_iterator end()const{return raw_ptr<const_iterator>(spc.data()+n);}
void clone(Node* node)
{
(spc.data()+n)->first=node;
- (spc.data()+n)->second=&*al_.allocate(1);
+ (spc.data()+n)->second=raw_ptr<Node*>(al_.allocate(1));
BOOST_TRY{
boost::detail::allocator::construct(
&(spc.data()+n)->second->value(),node->value());
@@ -93,7 +94,11 @@ public:
BOOST_CATCH_END
++n;
- if(n==size_)std::sort(&*spc.data(),&*spc.data()+size_);
+ if(n==size_){
+ std::sort(
+ raw_ptr<copy_map_entry<Node>*>(spc.data()),
+ raw_ptr<copy_map_entry<Node>*>(spc.data())+size_);
+ }
}
Node* find(Node* node)const
diff --git a/boost/multi_index/detail/hash_index_node.hpp b/boost/multi_index/detail/hash_index_node.hpp
index cfc60f6488..7788e810ac 100644
--- a/boost/multi_index/detail/hash_index_node.hpp
+++ b/boost/multi_index/detail/hash_index_node.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2014 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -15,6 +15,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/allocator_utilities.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#include <utility>
namespace boost{
@@ -143,12 +144,15 @@ public:
static pointer pointer_from(base_pointer x)
{
- return static_cast<pointer>(static_cast<hashed_index_node_impl*>(&*x));
+ return static_cast<pointer>(
+ static_cast<hashed_index_node_impl*>(
+ raw_ptr<super*>(x)));
}
static base_pointer base_pointer_from(pointer x)
{
- return static_cast<base_pointer>(&*x);
+ return static_cast<base_pointer>(
+ raw_ptr<hashed_index_node_impl*>(x));
}
private:
@@ -738,14 +742,18 @@ public:
static hashed_index_node* from_impl(impl_pointer x)
{
- return static_cast<hashed_index_node*>(
- static_cast<trampoline*>(&*x));
+ return
+ static_cast<hashed_index_node*>(
+ static_cast<trampoline*>(
+ raw_ptr<impl_type*>(x)));
}
static const hashed_index_node* from_impl(const_impl_pointer x)
{
- return static_cast<const hashed_index_node*>(
- static_cast<const trampoline*>(&*x));
+ return
+ static_cast<const hashed_index_node*>(
+ static_cast<const trampoline*>(
+ raw_ptr<const impl_type*>(x)));
}
/* interoperability with hashed_index_iterator */
diff --git a/boost/multi_index/detail/index_loader.hpp b/boost/multi_index/detail/index_loader.hpp
index 3f0428c595..71418a10e1 100644
--- a/boost/multi_index/detail/index_loader.hpp
+++ b/boost/multi_index/detail/index_loader.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -18,6 +18,7 @@
#include <boost/archive/archive_exception.hpp>
#include <boost/noncopyable.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/throw_exception.hpp>
#include <cstddef>
@@ -91,7 +92,7 @@ public:
}
private:
- Node** entries()const{return &*spc.data();}
+ Node** entries()const{return raw_ptr<Node**>(spc.data());}
/* We try to delay sorting as much as possible just in case it
* is not necessary, hence this version of load_node.
diff --git a/boost/multi_index/detail/index_matcher.hpp b/boost/multi_index/detail/index_matcher.hpp
index f3675acd40..34d1f9d5a8 100644
--- a/boost/multi_index/detail/index_matcher.hpp
+++ b/boost/multi_index/detail/index_matcher.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -17,6 +17,7 @@
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#include <cstddef>
#include <functional>
@@ -179,7 +180,7 @@ protected:
}
private:
- entry* entries()const{return &*spc.data();}
+ entry* entries()const{return raw_ptr<entry*>(spc.data());}
auto_space<entry,Allocator> spc;
std::size_t size_;
diff --git a/boost/multi_index/detail/index_node_base.hpp b/boost/multi_index/detail/index_node_base.hpp
index 150eb75e79..e6fabe62bb 100644
--- a/boost/multi_index/detail/index_node_base.hpp
+++ b/boost/multi_index/detail/index_node_base.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -51,14 +51,12 @@ struct index_node_base:private pod_value_holder<Value>
value_type& value()
{
- return *static_cast<value_type*>(
- static_cast<void*>(&this->space));
+ return *reinterpret_cast<value_type*>(&this->space);
}
const value_type& value()const
{
- return *static_cast<const value_type*>(
- static_cast<const void*>(&this->space));
+ return *reinterpret_cast<const value_type*>(&this->space);
}
static index_node_base* from_value(const value_type* p)
diff --git a/boost/multi_index/detail/ord_index_impl.hpp b/boost/multi_index/detail/ord_index_impl.hpp
new file mode 100644
index 0000000000..8ebaccb2cf
--- /dev/null
+++ b/boost/multi_index/detail/ord_index_impl.hpp
@@ -0,0 +1,1567 @@
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ *
+ * The internal implementation of red-black trees is based on that of SGI STL
+ * stl_tree.h file:
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP
+#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <boost/call_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/foreach_fwd.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+#include <boost/move/core.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/push_front.hpp>
+#include <boost/multi_index/detail/access_specifier.hpp>
+#include <boost/multi_index/detail/bidir_node_iterator.hpp>
+#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
+#include <boost/multi_index/detail/index_node_base.hpp>
+#include <boost/multi_index/detail/modify_key_adaptor.hpp>
+#include <boost/multi_index/detail/ord_index_node.hpp>
+#include <boost/multi_index/detail/ord_index_ops.hpp>
+#include <boost/multi_index/detail/safe_mode.hpp>
+#include <boost/multi_index/detail/scope_guard.hpp>
+#include <boost/multi_index/detail/unbounded.hpp>
+#include <boost/multi_index/detail/value_compare.hpp>
+#include <boost/multi_index/detail/vartempl_support.hpp>
+#include <boost/multi_index/detail/ord_index_impl_fwd.hpp>
+#include <boost/ref.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <utility>
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+#include <boost/archive/archive_exception.hpp>
+#include <boost/bind.hpp>
+#include <boost/multi_index/detail/duplicates_iterator.hpp>
+#include <boost/throw_exception.hpp>
+#endif
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \
+ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
+ detail::make_obj_guard(x,&ordered_index_impl::check_invariant_); \
+ BOOST_JOIN(check_invariant_,__LINE__).touch();
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this)
+#else
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x)
+#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
+#endif
+
+namespace boost{
+
+namespace multi_index{
+
+namespace detail{
+
+/* ordered_index adds a layer of ordered indexing to a given Super and accepts
+ * an augmenting policy for optional addition of order statistics.
+ */
+
+/* Most of the implementation of unique and non-unique indices is
+ * shared. We tell from one another on instantiation time by using
+ * these tags.
+ */
+
+struct ordered_unique_tag{};
+struct ordered_non_unique_tag{};
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+class ordered_index;
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+class ordered_index_impl:
+ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ ,public safe_mode::safe_container<
+ ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy> >
+#endif
+
+{
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
+ BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
+ * lifetime of const references bound to temporaries --precisely what
+ * scopeguards are.
+ */
+
+#pragma parse_mfunc_templ off
+#endif
+
+ typedef typename SuperMeta::type super;
+
+protected:
+ typedef ordered_index_node<
+ AugmentPolicy,typename super::node_type> node_type;
+
+protected: /* for the benefit of AugmentPolicy::augmented_interface */
+ typedef typename node_type::impl_type node_impl_type;
+ typedef typename node_impl_type::pointer node_impl_pointer;
+
+public:
+ /* types */
+
+ typedef typename KeyFromValue::result_type key_type;
+ typedef typename node_type::value_type value_type;
+ typedef KeyFromValue key_from_value;
+ typedef Compare key_compare;
+ typedef value_comparison<
+ value_type,KeyFromValue,Compare> value_compare;
+ typedef tuple<key_from_value,key_compare> ctor_args;
+ typedef typename super::final_allocator_type allocator_type;
+ typedef typename allocator_type::reference reference;
+ typedef typename allocator_type::const_reference const_reference;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ typedef safe_mode::safe_iterator<
+ bidir_node_iterator<node_type>,
+ ordered_index_impl> iterator;
+#else
+ typedef bidir_node_iterator<node_type> iterator;
+#endif
+
+ typedef iterator const_iterator;
+
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef typename allocator_type::pointer pointer;
+ typedef typename allocator_type::const_pointer const_pointer;
+ typedef typename
+ boost::reverse_iterator<iterator> reverse_iterator;
+ typedef typename
+ boost::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef TagList tag_list;
+
+protected:
+ typedef typename super::final_node_type final_node_type;
+ typedef tuples::cons<
+ ctor_args,
+ typename super::ctor_args_list> ctor_args_list;
+ typedef typename mpl::push_front<
+ typename super::index_type_list,
+ ordered_index<
+ KeyFromValue,Compare,
+ SuperMeta,TagList,Category,AugmentPolicy
+ > >::type index_type_list;
+ typedef typename mpl::push_front<
+ typename super::iterator_type_list,
+ iterator>::type iterator_type_list;
+ typedef typename mpl::push_front<
+ typename super::const_iterator_type_list,
+ const_iterator>::type const_iterator_type_list;
+ typedef typename super::copy_map_type copy_map_type;
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+ typedef typename super::index_saver_type index_saver_type;
+ typedef typename super::index_loader_type index_loader_type;
+#endif
+
+protected:
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ typedef safe_mode::safe_container<
+ ordered_index_impl> safe_super;
+#endif
+
+ typedef typename call_traits<
+ value_type>::param_type value_param_type;
+ typedef typename call_traits<
+ key_type>::param_type key_param_type;
+
+ /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
+ * expansion.
+ */
+
+ typedef std::pair<iterator,bool> emplace_return_type;
+
+public:
+
+ /* construct/copy/destroy
+ * Default and copy ctors are in the protected section as indices are
+ * not supposed to be created on their own. No range ctor either.
+ * Assignment operators defined at ordered_index rather than here.
+ */
+
+ allocator_type get_allocator()const BOOST_NOEXCEPT
+ {
+ return this->final().get_allocator();
+ }
+
+ /* iterators */
+
+ iterator
+ begin()BOOST_NOEXCEPT{return make_iterator(leftmost());}
+ const_iterator
+ begin()const BOOST_NOEXCEPT{return make_iterator(leftmost());}
+ iterator
+ end()BOOST_NOEXCEPT{return make_iterator(header());}
+ const_iterator
+ end()const BOOST_NOEXCEPT{return make_iterator(header());}
+ reverse_iterator
+ rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
+ const_reverse_iterator
+ rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
+ reverse_iterator
+ rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
+ const_reverse_iterator
+ rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
+ const_iterator
+ cbegin()const BOOST_NOEXCEPT{return begin();}
+ const_iterator
+ cend()const BOOST_NOEXCEPT{return end();}
+ const_reverse_iterator
+ crbegin()const BOOST_NOEXCEPT{return rbegin();}
+ const_reverse_iterator
+ crend()const BOOST_NOEXCEPT{return rend();}
+
+ iterator iterator_to(const value_type& x)
+ {
+ return make_iterator(node_from_value<node_type>(&x));
+ }
+
+ const_iterator iterator_to(const value_type& x)const
+ {
+ return make_iterator(node_from_value<node_type>(&x));
+ }
+
+ /* capacity */
+
+ bool empty()const BOOST_NOEXCEPT{return this->final_empty_();}
+ size_type size()const BOOST_NOEXCEPT{return this->final_size_();}
+ size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();}
+
+ /* modifiers */
+
+ BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
+ emplace_return_type,emplace,emplace_impl)
+
+ BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
+ iterator,emplace_hint,emplace_hint_impl,iterator,position)
+
+ std::pair<iterator,bool> insert(const value_type& x)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool> p=this->final_insert_(x);
+ return std::pair<iterator,bool>(make_iterator(p.first),p.second);
+ }
+
+ std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
+ return std::pair<iterator,bool>(make_iterator(p.first),p.second);
+ }
+
+ iterator insert(iterator position,const value_type& x)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool> p=this->final_insert_(
+ x,static_cast<final_node_type*>(position.get_node()));
+ return make_iterator(p.first);
+ }
+
+ iterator insert(iterator position,BOOST_RV_REF(value_type) x)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool> p=this->final_insert_rv_(
+ x,static_cast<final_node_type*>(position.get_node()));
+ return make_iterator(p.first);
+ }
+
+ template<typename InputIterator>
+ void insert(InputIterator first,InputIterator last)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ node_type* hint=header(); /* end() */
+ for(;first!=last;++first){
+ hint=this->final_insert_ref_(
+ *first,static_cast<final_node_type*>(hint)).first;
+ node_type::increment(hint);
+ }
+ }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ void insert(std::initializer_list<value_type> list)
+ {
+ insert(list.begin(),list.end());
+ }
+#endif
+
+ iterator erase(iterator position)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
+ return position;
+ }
+
+ size_type erase(key_param_type x)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<iterator,iterator> p=equal_range(x);
+ size_type s=0;
+ while(p.first!=p.second){
+ p.first=erase(p.first);
+ ++s;
+ }
+ return s;
+ }
+
+ iterator erase(iterator first,iterator last)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
+ BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ while(first!=last){
+ first=erase(first);
+ }
+ return first;
+ }
+
+ bool replace(iterator position,const value_type& x)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ return this->final_replace_(
+ x,static_cast<final_node_type*>(position.get_node()));
+ }
+
+ bool replace(iterator position,BOOST_RV_REF(value_type) x)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ return this->final_replace_rv_(
+ x,static_cast<final_node_type*>(position.get_node()));
+ }
+
+ template<typename Modifier>
+ bool modify(iterator position,Modifier mod)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ /* MSVC++ 6.0 optimizer on safe mode code chokes if this
+ * this is not added. Left it for all compilers as it does no
+ * harm.
+ */
+
+ position.detach();
+#endif
+
+ return this->final_modify_(
+ mod,static_cast<final_node_type*>(position.get_node()));
+ }
+
+ template<typename Modifier,typename Rollback>
+ bool modify(iterator position,Modifier mod,Rollback back_)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ /* MSVC++ 6.0 optimizer on safe mode code chokes if this
+ * this is not added. Left it for all compilers as it does no
+ * harm.
+ */
+
+ position.detach();
+#endif
+
+ return this->final_modify_(
+ mod,back_,static_cast<final_node_type*>(position.get_node()));
+ }
+
+ template<typename Modifier>
+ bool modify_key(iterator position,Modifier mod)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ return modify(
+ position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key));
+ }
+
+ template<typename Modifier,typename Rollback>
+ bool modify_key(iterator position,Modifier mod,Rollback back_)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ return modify(
+ position,
+ modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key),
+ modify_key_adaptor<Rollback,value_type,KeyFromValue>(back_,key));
+ }
+
+ void swap(
+ ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x);
+ this->final_swap_(x.final());
+ }
+
+ void clear()BOOST_NOEXCEPT
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ this->final_clear_();
+ }
+
+ /* observers */
+
+ key_from_value key_extractor()const{return key;}
+ key_compare key_comp()const{return comp_;}
+ value_compare value_comp()const{return value_compare(key,comp_);}
+
+ /* set operations */
+
+ /* Internally, these ops rely on const_iterator being the same
+ * type as iterator.
+ */
+
+ template<typename CompatibleKey>
+ iterator find(const CompatibleKey& x)const
+ {
+ return make_iterator(ordered_index_find(root(),header(),key,x,comp_));
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ iterator find(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ return make_iterator(ordered_index_find(root(),header(),key,x,comp));
+ }
+
+ template<typename CompatibleKey>
+ size_type count(const CompatibleKey& x)const
+ {
+ return count(x,comp_);
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ std::pair<iterator,iterator> p=equal_range(x,comp);
+ size_type n=std::distance(p.first,p.second);
+ return n;
+ }
+
+ template<typename CompatibleKey>
+ iterator lower_bound(const CompatibleKey& x)const
+ {
+ return make_iterator(
+ ordered_index_lower_bound(root(),header(),key,x,comp_));
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ iterator lower_bound(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ return make_iterator(
+ ordered_index_lower_bound(root(),header(),key,x,comp));
+ }
+
+ template<typename CompatibleKey>
+ iterator upper_bound(const CompatibleKey& x)const
+ {
+ return make_iterator(
+ ordered_index_upper_bound(root(),header(),key,x,comp_));
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ iterator upper_bound(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ return make_iterator(
+ ordered_index_upper_bound(root(),header(),key,x,comp));
+ }
+
+ template<typename CompatibleKey>
+ std::pair<iterator,iterator> equal_range(
+ const CompatibleKey& x)const
+ {
+ std::pair<node_type*,node_type*> p=
+ ordered_index_equal_range(root(),header(),key,x,comp_);
+ return std::pair<iterator,iterator>(
+ make_iterator(p.first),make_iterator(p.second));
+ }
+
+ template<typename CompatibleKey,typename CompatibleCompare>
+ std::pair<iterator,iterator> equal_range(
+ const CompatibleKey& x,const CompatibleCompare& comp)const
+ {
+ std::pair<node_type*,node_type*> p=
+ ordered_index_equal_range(root(),header(),key,x,comp);
+ return std::pair<iterator,iterator>(
+ make_iterator(p.first),make_iterator(p.second));
+ }
+
+ /* range */
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<iterator,iterator>
+ range(LowerBounder lower,UpperBounder upper)const
+ {
+ typedef typename mpl::if_<
+ is_same<LowerBounder,unbounded_type>,
+ BOOST_DEDUCED_TYPENAME mpl::if_<
+ is_same<UpperBounder,unbounded_type>,
+ both_unbounded_tag,
+ lower_unbounded_tag
+ >::type,
+ BOOST_DEDUCED_TYPENAME mpl::if_<
+ is_same<UpperBounder,unbounded_type>,
+ upper_unbounded_tag,
+ none_unbounded_tag
+ >::type
+ >::type dispatch;
+
+ return range(lower,upper,dispatch());
+ }
+
+BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
+ ordered_index_impl(const ctor_args_list& args_list,const allocator_type& al):
+ super(args_list.get_tail(),al),
+ key(tuples::get<0>(args_list.get_head())),
+ comp_(tuples::get<1>(args_list.get_head()))
+ {
+ empty_initialize();
+ }
+
+ ordered_index_impl(
+ const ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x):
+ super(x),
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ safe_super(),
+#endif
+
+ key(x.key),
+ comp_(x.comp_)
+ {
+ /* Copy ctor just takes the key and compare objects from x. The rest is
+ * done in a subsequent call to copy_().
+ */
+ }
+
+ ordered_index_impl(
+ const ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
+ do_not_copy_elements_tag):
+ super(x,do_not_copy_elements_tag()),
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ safe_super(),
+#endif
+
+ key(x.key),
+ comp_(x.comp_)
+ {
+ empty_initialize();
+ }
+
+ ~ordered_index_impl()
+ {
+ /* the container is guaranteed to be empty by now */
+ }
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ iterator make_iterator(node_type* node){return iterator(node,this);}
+ const_iterator make_iterator(node_type* node)const
+ {return const_iterator(node,const_cast<ordered_index_impl*>(this));}
+#else
+ iterator make_iterator(node_type* node){return iterator(node);}
+ const_iterator make_iterator(node_type* node)const
+ {return const_iterator(node);}
+#endif
+
+ void copy_(
+ const ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
+ const copy_map_type& map)
+ {
+ if(!x.root()){
+ empty_initialize();
+ }
+ else{
+ header()->color()=x.header()->color();
+ AugmentPolicy::copy(x.header()->impl(),header()->impl());
+
+ node_type* root_cpy=map.find(static_cast<final_node_type*>(x.root()));
+ header()->parent()=root_cpy->impl();
+
+ node_type* leftmost_cpy=map.find(
+ static_cast<final_node_type*>(x.leftmost()));
+ header()->left()=leftmost_cpy->impl();
+
+ node_type* rightmost_cpy=map.find(
+ static_cast<final_node_type*>(x.rightmost()));
+ header()->right()=rightmost_cpy->impl();
+
+ typedef typename copy_map_type::const_iterator copy_map_iterator;
+ for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){
+ node_type* org=it->first;
+ node_type* cpy=it->second;
+
+ cpy->color()=org->color();
+ AugmentPolicy::copy(org->impl(),cpy->impl());
+
+ node_impl_pointer parent_org=org->parent();
+ if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0);
+ else{
+ node_type* parent_cpy=map.find(
+ static_cast<final_node_type*>(node_type::from_impl(parent_org)));
+ cpy->parent()=parent_cpy->impl();
+ if(parent_org->left()==org->impl()){
+ parent_cpy->left()=cpy->impl();
+ }
+ else if(parent_org->right()==org->impl()){
+ /* header() does not satisfy this nor the previous check */
+ parent_cpy->right()=cpy->impl();
+ }
+ }
+
+ if(org->left()==node_impl_pointer(0))
+ cpy->left()=node_impl_pointer(0);
+ if(org->right()==node_impl_pointer(0))
+ cpy->right()=node_impl_pointer(0);
+ }
+ }
+
+ super::copy_(x,map);
+ }
+
+ template<typename Variant>
+ final_node_type* insert_(
+ value_param_type v,final_node_type*& x,Variant variant)
+ {
+ link_info inf;
+ if(!link_point(key(v),inf,Category())){
+ return static_cast<final_node_type*>(node_type::from_impl(inf.pos));
+ }
+
+ final_node_type* res=super::insert_(v,x,variant);
+ if(res==x){
+ node_impl_type::link(
+ static_cast<node_type*>(x)->impl(),inf.side,inf.pos,header()->impl());
+ }
+ return res;
+ }
+
+ template<typename Variant>
+ final_node_type* insert_(
+ value_param_type v,node_type* position,final_node_type*& x,Variant variant)
+ {
+ link_info inf;
+ if(!hinted_link_point(key(v),position,inf,Category())){
+ return static_cast<final_node_type*>(node_type::from_impl(inf.pos));
+ }
+
+ final_node_type* res=super::insert_(v,position,x,variant);
+ if(res==x){
+ node_impl_type::link(
+ static_cast<node_type*>(x)->impl(),inf.side,inf.pos,header()->impl());
+ }
+ return res;
+ }
+
+ void erase_(node_type* x)
+ {
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+ super::erase_(x);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ detach_iterators(x);
+#endif
+ }
+
+ void delete_all_nodes_()
+ {
+ delete_all_nodes(root());
+ }
+
+ void clear_()
+ {
+ super::clear_();
+ empty_initialize();
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ safe_super::detach_dereferenceable_iterators();
+#endif
+ }
+
+ void swap_(
+ ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
+ {
+ std::swap(key,x.key);
+ std::swap(comp_,x.comp_);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ safe_super::swap(x);
+#endif
+
+ super::swap_(x);
+ }
+
+ void swap_elements_(
+ ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
+ {
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ safe_super::swap(x);
+#endif
+
+ super::swap_elements_(x);
+ }
+
+ template<typename Variant>
+ bool replace_(value_param_type v,node_type* x,Variant variant)
+ {
+ if(in_place(v,x,Category())){
+ return super::replace_(v,x,variant);
+ }
+
+ node_type* next=x;
+ node_type::increment(next);
+
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+
+ BOOST_TRY{
+ link_info inf;
+ if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){
+ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
+ return true;
+ }
+ node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+ return false;
+ }
+ BOOST_CATCH(...){
+ node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ }
+
+ bool modify_(node_type* x)
+ {
+ bool b;
+ BOOST_TRY{
+ b=in_place(x->value(),x,Category());
+ }
+ BOOST_CATCH(...){
+ erase_(x);
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ if(!b){
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+ BOOST_TRY{
+ link_info inf;
+ if(!link_point(key(x->value()),inf,Category())){
+ super::erase_(x);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ detach_iterators(x);
+#endif
+ return false;
+ }
+ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
+ }
+ BOOST_CATCH(...){
+ super::erase_(x);
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ detach_iterators(x);
+#endif
+
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ }
+
+ BOOST_TRY{
+ if(!super::modify_(x)){
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ detach_iterators(x);
+#endif
+
+ return false;
+ }
+ else return true;
+ }
+ BOOST_CATCH(...){
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ detach_iterators(x);
+#endif
+
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ }
+
+ bool modify_rollback_(node_type* x)
+ {
+ if(in_place(x->value(),x,Category())){
+ return super::modify_rollback_(x);
+ }
+
+ node_type* next=x;
+ node_type::increment(next);
+
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+
+ BOOST_TRY{
+ link_info inf;
+ if(link_point(key(x->value()),inf,Category())&&
+ super::modify_rollback_(x)){
+ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
+ return true;
+ }
+ node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+ return false;
+ }
+ BOOST_CATCH(...){
+ node_impl_type::restore(x->impl(),next->impl(),header()->impl());
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ }
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+ /* serialization */
+
+ template<typename Archive>
+ void save_(
+ Archive& ar,const unsigned int version,const index_saver_type& sm)const
+ {
+ save_(ar,version,sm,Category());
+ }
+
+ template<typename Archive>
+ void load_(Archive& ar,const unsigned int version,const index_loader_type& lm)
+ {
+ load_(ar,version,lm,Category());
+ }
+#endif
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
+ /* invariant stuff */
+
+ bool invariant_()const
+ {
+ if(size()==0||begin()==end()){
+ if(size()!=0||begin()!=end()||
+ header()->left()!=header()->impl()||
+ header()->right()!=header()->impl())return false;
+ }
+ else{
+ if((size_type)std::distance(begin(),end())!=size())return false;
+
+ std::size_t len=node_impl_type::black_count(
+ leftmost()->impl(),root()->impl());
+ for(const_iterator it=begin(),it_end=end();it!=it_end;++it){
+ node_type* x=it.get_node();
+ node_type* left_x=node_type::from_impl(x->left());
+ node_type* right_x=node_type::from_impl(x->right());
+
+ if(x->color()==red){
+ if((left_x&&left_x->color()==red)||
+ (right_x&&right_x->color()==red))return false;
+ }
+ if(left_x&&comp_(key(x->value()),key(left_x->value())))return false;
+ if(right_x&&comp_(key(right_x->value()),key(x->value())))return false;
+ if(!left_x&&!right_x&&
+ node_impl_type::black_count(x->impl(),root()->impl())!=len)
+ return false;
+ if(!AugmentPolicy::invariant(x->impl()))return false;
+ }
+
+ if(leftmost()->impl()!=node_impl_type::minimum(root()->impl()))
+ return false;
+ if(rightmost()->impl()!=node_impl_type::maximum(root()->impl()))
+ return false;
+ }
+
+ return super::invariant_();
+ }
+
+
+ /* This forwarding function eases things for the boost::mem_fn construct
+ * in BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT. Actually,
+ * final_check_invariant is already an inherited member function of
+ * ordered_index_impl.
+ */
+ void check_invariant_()const{this->final_check_invariant_();}
+#endif
+
+protected: /* for the benefit of AugmentPolicy::augmented_interface */
+ node_type* header()const{return this->final_header();}
+ node_type* root()const{return node_type::from_impl(header()->parent());}
+ node_type* leftmost()const{return node_type::from_impl(header()->left());}
+ node_type* rightmost()const{return node_type::from_impl(header()->right());}
+
+private:
+ void empty_initialize()
+ {
+ header()->color()=red;
+ /* used to distinguish header() from root, in iterator.operator++ */
+
+ header()->parent()=node_impl_pointer(0);
+ header()->left()=header()->impl();
+ header()->right()=header()->impl();
+ }
+
+ struct link_info
+ {
+ /* coverity[uninit_ctor]: suppress warning */
+ link_info():side(to_left){}
+
+ ordered_index_side side;
+ node_impl_pointer pos;
+ };
+
+ bool link_point(key_param_type k,link_info& inf,ordered_unique_tag)
+ {
+ node_type* y=header();
+ node_type* x=root();
+ bool c=true;
+ while(x){
+ y=x;
+ c=comp_(k,key(x->value()));
+ x=node_type::from_impl(c?x->left():x->right());
+ }
+ node_type* yy=y;
+ if(c){
+ if(yy==leftmost()){
+ inf.side=to_left;
+ inf.pos=y->impl();
+ return true;
+ }
+ else node_type::decrement(yy);
+ }
+
+ if(comp_(key(yy->value()),k)){
+ inf.side=c?to_left:to_right;
+ inf.pos=y->impl();
+ return true;
+ }
+ else{
+ inf.pos=yy->impl();
+ return false;
+ }
+ }
+
+ bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
+ {
+ node_type* y=header();
+ node_type* x=root();
+ bool c=true;
+ while (x){
+ y=x;
+ c=comp_(k,key(x->value()));
+ x=node_type::from_impl(c?x->left():x->right());
+ }
+ inf.side=c?to_left:to_right;
+ inf.pos=y->impl();
+ return true;
+ }
+
+ bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
+ {
+ node_type* y=header();
+ node_type* x=root();
+ bool c=false;
+ while (x){
+ y=x;
+ c=comp_(key(x->value()),k);
+ x=node_type::from_impl(c?x->right():x->left());
+ }
+ inf.side=c?to_right:to_left;
+ inf.pos=y->impl();
+ return true;
+ }
+
+ bool hinted_link_point(
+ key_param_type k,node_type* position,link_info& inf,ordered_unique_tag)
+ {
+ if(position->impl()==header()->left()){
+ if(size()>0&&comp_(k,key(position->value()))){
+ inf.side=to_left;
+ inf.pos=position->impl();
+ return true;
+ }
+ else return link_point(k,inf,ordered_unique_tag());
+ }
+ else if(position==header()){
+ if(comp_(key(rightmost()->value()),k)){
+ inf.side=to_right;
+ inf.pos=rightmost()->impl();
+ return true;
+ }
+ else return link_point(k,inf,ordered_unique_tag());
+ }
+ else{
+ node_type* before=position;
+ node_type::decrement(before);
+ if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){
+ if(before->right()==node_impl_pointer(0)){
+ inf.side=to_right;
+ inf.pos=before->impl();
+ return true;
+ }
+ else{
+ inf.side=to_left;
+ inf.pos=position->impl();
+ return true;
+ }
+ }
+ else return link_point(k,inf,ordered_unique_tag());
+ }
+ }
+
+ bool hinted_link_point(
+ key_param_type k,node_type* position,link_info& inf,ordered_non_unique_tag)
+ {
+ if(position->impl()==header()->left()){
+ if(size()>0&&!comp_(key(position->value()),k)){
+ inf.side=to_left;
+ inf.pos=position->impl();
+ return true;
+ }
+ else return lower_link_point(k,inf,ordered_non_unique_tag());
+ }
+ else if(position==header()){
+ if(!comp_(k,key(rightmost()->value()))){
+ inf.side=to_right;
+ inf.pos=rightmost()->impl();
+ return true;
+ }
+ else return link_point(k,inf,ordered_non_unique_tag());
+ }
+ else{
+ node_type* before=position;
+ node_type::decrement(before);
+ if(!comp_(k,key(before->value()))){
+ if(!comp_(key(position->value()),k)){
+ if(before->right()==node_impl_pointer(0)){
+ inf.side=to_right;
+ inf.pos=before->impl();
+ return true;
+ }
+ else{
+ inf.side=to_left;
+ inf.pos=position->impl();
+ return true;
+ }
+ }
+ else return lower_link_point(k,inf,ordered_non_unique_tag());
+ }
+ else return link_point(k,inf,ordered_non_unique_tag());
+ }
+ }
+
+ void delete_all_nodes(node_type* x)
+ {
+ if(!x)return;
+
+ delete_all_nodes(node_type::from_impl(x->left()));
+ delete_all_nodes(node_type::from_impl(x->right()));
+ this->final_delete_node_(static_cast<final_node_type*>(x));
+ }
+
+ bool in_place(value_param_type v,node_type* x,ordered_unique_tag)
+ {
+ node_type* y;
+ if(x!=leftmost()){
+ y=x;
+ node_type::decrement(y);
+ if(!comp_(key(y->value()),key(v)))return false;
+ }
+
+ y=x;
+ node_type::increment(y);
+ return y==header()||comp_(key(v),key(y->value()));
+ }
+
+ bool in_place(value_param_type v,node_type* x,ordered_non_unique_tag)
+ {
+ node_type* y;
+ if(x!=leftmost()){
+ y=x;
+ node_type::decrement(y);
+ if(comp_(key(v),key(y->value())))return false;
+ }
+
+ y=x;
+ node_type::increment(y);
+ return y==header()||!comp_(key(y->value()),key(v));
+ }
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
+ void detach_iterators(node_type* x)
+ {
+ iterator it=make_iterator(x);
+ safe_mode::detach_equivalent_iterators(it);
+ }
+#endif
+
+ template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
+ std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
+ {
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool>p=
+ this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
+ return std::pair<iterator,bool>(make_iterator(p.first),p.second);
+ }
+
+ template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
+ iterator emplace_hint_impl(
+ iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
+ {
+ BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
+ BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
+ BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
+ std::pair<final_node_type*,bool>p=
+ this->final_emplace_hint_(
+ static_cast<final_node_type*>(position.get_node()),
+ BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
+ return make_iterator(p.first);
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<iterator,iterator>
+ range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
+ {
+ node_type* y=header();
+ node_type* z=root();
+
+ while(z){
+ if(!lower(key(z->value()))){
+ z=node_type::from_impl(z->right());
+ }
+ else if(!upper(key(z->value()))){
+ y=z;
+ z=node_type::from_impl(z->left());
+ }
+ else{
+ return std::pair<iterator,iterator>(
+ make_iterator(
+ lower_range(node_type::from_impl(z->left()),z,lower)),
+ make_iterator(
+ upper_range(node_type::from_impl(z->right()),y,upper)));
+ }
+ }
+
+ return std::pair<iterator,iterator>(make_iterator(y),make_iterator(y));
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<iterator,iterator>
+ range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
+ {
+ return std::pair<iterator,iterator>(
+ begin(),
+ make_iterator(upper_range(root(),header(),upper)));
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<iterator,iterator>
+ range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
+ {
+ return std::pair<iterator,iterator>(
+ make_iterator(lower_range(root(),header(),lower)),
+ end());
+ }
+
+ template<typename LowerBounder,typename UpperBounder>
+ std::pair<iterator,iterator>
+ range(LowerBounder,UpperBounder,both_unbounded_tag)const
+ {
+ return std::pair<iterator,iterator>(begin(),end());
+ }
+
+ template<typename LowerBounder>
+ node_type * lower_range(node_type* top,node_type* y,LowerBounder lower)const
+ {
+ while(top){
+ if(lower(key(top->value()))){
+ y=top;
+ top=node_type::from_impl(top->left());
+ }
+ else top=node_type::from_impl(top->right());
+ }
+
+ return y;
+ }
+
+ template<typename UpperBounder>
+ node_type * upper_range(node_type* top,node_type* y,UpperBounder upper)const
+ {
+ while(top){
+ if(!upper(key(top->value()))){
+ y=top;
+ top=node_type::from_impl(top->left());
+ }
+ else top=node_type::from_impl(top->right());
+ }
+
+ return y;
+ }
+
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+ template<typename Archive>
+ void save_(
+ Archive& ar,const unsigned int version,const index_saver_type& sm,
+ ordered_unique_tag)const
+ {
+ super::save_(ar,version,sm);
+ }
+
+ template<typename Archive>
+ void load_(
+ Archive& ar,const unsigned int version,const index_loader_type& lm,
+ ordered_unique_tag)
+ {
+ super::load_(ar,version,lm);
+ }
+
+ template<typename Archive>
+ void save_(
+ Archive& ar,const unsigned int version,const index_saver_type& sm,
+ ordered_non_unique_tag)const
+ {
+ typedef duplicates_iterator<node_type,value_compare> dup_iterator;
+
+ sm.save(
+ dup_iterator(begin().get_node(),end().get_node(),value_comp()),
+ dup_iterator(end().get_node(),value_comp()),
+ ar,version);
+ super::save_(ar,version,sm);
+ }
+
+ template<typename Archive>
+ void load_(
+ Archive& ar,const unsigned int version,const index_loader_type& lm,
+ ordered_non_unique_tag)
+ {
+ lm.load(
+ ::boost::bind(
+ &ordered_index_impl::rearranger,this,
+ ::boost::arg<1>(),::boost::arg<2>()),
+ ar,version);
+ super::load_(ar,version,lm);
+ }
+
+ void rearranger(node_type* position,node_type *x)
+ {
+ if(!position||comp_(key(position->value()),key(x->value()))){
+ position=lower_bound(key(x->value())).get_node();
+ }
+ else if(comp_(key(x->value()),key(position->value()))){
+ /* inconsistent rearrangement */
+ throw_exception(
+ archive::archive_exception(
+ archive::archive_exception::other_exception));
+ }
+ else node_type::increment(position);
+
+ if(position!=x){
+ node_impl_type::rebalance_for_erase(
+ x->impl(),header()->parent(),header()->left(),header()->right());
+ node_impl_type::restore(
+ x->impl(),position->impl(),header()->impl());
+ }
+ }
+#endif /* serialization */
+
+protected: /* for the benefit of AugmentPolicy::augmented_interface */
+ key_from_value key;
+ key_compare comp_;
+
+#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
+ BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+#pragma parse_mfunc_templ reset
+#endif
+};
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+class ordered_index:
+ public AugmentPolicy::template augmented_interface<
+ ordered_index_impl<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy
+ >
+ >::type
+{
+ typedef typename AugmentPolicy::template
+ augmented_interface<
+ ordered_index_impl<
+ KeyFromValue,Compare,
+ SuperMeta,TagList,Category,AugmentPolicy
+ >
+ >::type super;
+public:
+ typedef typename super::ctor_args_list ctor_args_list;
+ typedef typename super::allocator_type allocator_type;
+ typedef typename super::iterator iterator;
+
+ /* construct/copy/destroy
+ * Default and copy ctors are in the protected section as indices are
+ * not supposed to be created on their own. No range ctor either.
+ */
+
+ ordered_index& operator=(const ordered_index& x)
+ {
+ this->final()=x.final();
+ return *this;
+ }
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ ordered_index& operator=(
+ std::initializer_list<BOOST_DEDUCED_TYPENAME super::value_type> list)
+ {
+ this->final()=list;
+ return *this;
+ }
+#endif
+
+protected:
+ ordered_index(
+ const ctor_args_list& args_list,const allocator_type& al):
+ super(args_list,al){}
+
+ ordered_index(const ordered_index& x):super(x){};
+
+ ordered_index(const ordered_index& x,do_not_copy_elements_tag):
+ super(x,do_not_copy_elements_tag()){};
+};
+
+/* comparison */
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator==(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
+}
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator<(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
+}
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator!=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return !(x==y);
+}
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator>(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return y<x;
+}
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator>=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return !(x<y);
+}
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator<=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
+{
+ return !(x>y);
+}
+
+/* specialized algorithms */
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+void swap(
+ ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
+ ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y)
+{
+ x.swap(y);
+}
+
+} /* namespace multi_index::detail */
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+/* Boost.Foreach compatibility */
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+inline boost::mpl::true_* boost_foreach_is_noncopyable(
+ boost::multi_index::detail::ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>*&,
+ boost::foreach::tag)
+{
+ return 0;
+}
+
+#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
+#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF
+
+#endif
diff --git a/boost/multi_index/detail/ord_index_impl_fwd.hpp b/boost/multi_index/detail/ord_index_impl_fwd.hpp
new file mode 100644
index 0000000000..6590ef05fd
--- /dev/null
+++ b/boost/multi_index/detail/ord_index_impl_fwd.hpp
@@ -0,0 +1,128 @@
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP
+#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+namespace boost{
+
+namespace multi_index{
+
+namespace detail{
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+class ordered_index;
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator==(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator<(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator!=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator>(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator>=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue1,typename Compare1,
+ typename SuperMeta1,typename TagList1,typename Category1,
+ typename AugmentPolicy1,
+ typename KeyFromValue2,typename Compare2,
+ typename SuperMeta2,typename TagList2,typename Category2,
+ typename AugmentPolicy2
+>
+bool operator<=(
+ const ordered_index<
+ KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
+ const ordered_index<
+ KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y);
+
+template<
+ typename KeyFromValue,typename Compare,
+ typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
+>
+void swap(
+ ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
+ ordered_index<
+ KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y);
+
+} /* namespace multi_index::detail */
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+#endif
diff --git a/boost/multi_index/detail/ord_index_node.hpp b/boost/multi_index/detail/ord_index_node.hpp
index 60727e04ed..e7af0377fb 100644
--- a/boost/multi_index/detail/ord_index_node.hpp
+++ b/boost/multi_index/detail/ord_index_node.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -43,6 +43,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <cstddef>
#include <boost/detail/allocator_utilities.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
#include <boost/mpl/and.hpp>
@@ -63,24 +64,24 @@ namespace detail{
enum ordered_index_color{red=false,black=true};
enum ordered_index_side{to_left=false,to_right=true};
-template<typename Allocator>
+template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_impl; /* fwd decl. */
-template<typename Allocator>
+template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_std_base
{
typedef typename
boost::detail::allocator::rebind_to<
Allocator,
- ordered_index_node_impl<Allocator>
- >::type::pointer pointer;
+ ordered_index_node_impl<AugmentPolicy,Allocator>
+ >::type::pointer pointer;
typedef typename
boost::detail::allocator::rebind_to<
Allocator,
- ordered_index_node_impl<Allocator>
- >::type::const_pointer const_pointer;
- typedef ordered_index_color& color_ref;
- typedef pointer& parent_ref;
+ ordered_index_node_impl<AugmentPolicy,Allocator>
+ >::type::const_pointer const_pointer;
+ typedef ordered_index_color& color_ref;
+ typedef pointer& parent_ref;
ordered_index_color& color(){return color_;}
ordered_index_color color()const{return color_;}
@@ -116,11 +117,13 @@ private:
#pragma warning(disable:4312 4311)
#endif
-template<typename Allocator>
+template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_compressed_base
{
- typedef ordered_index_node_impl<Allocator>* pointer;
- typedef const ordered_index_node_impl<Allocator>* const_pointer;
+ typedef ordered_index_node_impl<
+ AugmentPolicy,Allocator>* pointer;
+ typedef const ordered_index_node_impl<
+ AugmentPolicy,Allocator>* const_pointer;
struct color_ref
{
@@ -179,7 +182,7 @@ struct ordered_index_node_compressed_base
color_ref color(){return color_ref(&parentcolor_);}
ordered_index_color color()const
{
- return ordered_index_color(parentcolor_&std::size_t(1ul));
+ return ordered_index_color(parentcolor_&uintptr_type(1));
}
parent_ref parent(){return parent_ref(&parentcolor_);}
@@ -203,39 +206,46 @@ private:
#endif
#endif
-template<typename Allocator>
+template<typename AugmentPolicy,typename Allocator>
struct ordered_index_node_impl_base:
#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
- mpl::if_c<
- !(has_uintptr_type::value)||
- (alignment_of<ordered_index_node_compressed_base<Allocator> >::value%2)||
- !(is_same<
- typename boost::detail::allocator::rebind_to<
- Allocator,
- ordered_index_node_impl<Allocator>
- >::type::pointer,
- ordered_index_node_impl<Allocator>*>::value),
- ordered_index_node_std_base<Allocator>,
- ordered_index_node_compressed_base<Allocator>
+ AugmentPolicy::template augmented_node<
+ typename mpl::if_c<
+ !(has_uintptr_type::value)||
+ (alignment_of<
+ ordered_index_node_compressed_base<AugmentPolicy,Allocator>
+ >::value%2)||
+ !(is_same<
+ typename boost::detail::allocator::rebind_to<
+ Allocator,
+ ordered_index_node_impl<AugmentPolicy,Allocator>
+ >::type::pointer,
+ ordered_index_node_impl<AugmentPolicy,Allocator>*>::value),
+ ordered_index_node_std_base<AugmentPolicy,Allocator>,
+ ordered_index_node_compressed_base<AugmentPolicy,Allocator>
+ >::type
>::type
#else
- ordered_index_node_std_base<Allocator>
+ AugmentPolicy::template augmented_node<
+ ordered_index_node_std_base<AugmentPolicy,Allocator>
+ >::type
#endif
{};
-template<typename Allocator>
-struct ordered_index_node_impl:ordered_index_node_impl_base<Allocator>
+template<typename AugmentPolicy,typename Allocator>
+struct ordered_index_node_impl:
+ ordered_index_node_impl_base<AugmentPolicy,Allocator>
{
private:
- typedef ordered_index_node_impl_base<Allocator> super;
+ typedef ordered_index_node_impl_base<AugmentPolicy,Allocator> super;
public:
- typedef typename super::color_ref color_ref;
- typedef typename super::parent_ref parent_ref;
- typedef typename super::pointer pointer;
- typedef typename super::const_pointer const_pointer;
+ typedef typename super::color_ref color_ref;
+ typedef typename super::parent_ref parent_ref;
+ typedef typename super::pointer pointer;
+ typedef typename super::const_pointer const_pointer;
/* interoperability with bidir_node_iterator */
@@ -288,6 +298,7 @@ public:
else x->parent()->right()=y;
y->left()=x;
x->parent()=y;
+ AugmentPolicy::rotate_left(x,y);
}
static pointer minimum(pointer x)
@@ -314,6 +325,7 @@ public:
else x->parent()->left()=y;
y->right()=x;
x->parent()=y;
+ AugmentPolicy::rotate_right(x,y);
}
static void rebalance(pointer x,parent_ref root)
@@ -382,6 +394,7 @@ public:
x->parent()=position;
x->left()=pointer(0);
x->right()=pointer(0);
+ AugmentPolicy::add(x,pointer(header->parent()));
ordered_index_node_impl::rebalance(x,header->parent());
}
@@ -404,7 +417,9 @@ public:
x=y->right();
}
}
+ AugmentPolicy::remove(y,pointer(root));
if(y!=z){
+ AugmentPolicy::copy(z,y);
z->left()->parent()=y; /* relink y in place of z. y is z's successor */
y->left()=z->left();
if(y!=z->right()){
@@ -547,9 +562,10 @@ public:
#endif
};
-template<typename Super>
+template<typename AugmentPolicy,typename Super>
struct ordered_index_node_trampoline:
ordered_index_node_impl<
+ AugmentPolicy,
typename boost::detail::allocator::rebind_to<
typename Super::allocator_type,
char
@@ -557,6 +573,7 @@ struct ordered_index_node_trampoline:
>
{
typedef ordered_index_node_impl<
+ AugmentPolicy,
typename boost::detail::allocator::rebind_to<
typename Super::allocator_type,
char
@@ -564,11 +581,12 @@ struct ordered_index_node_trampoline:
> impl_type;
};
-template<typename Super>
-struct ordered_index_node:Super,ordered_index_node_trampoline<Super>
+template<typename AugmentPolicy,typename Super>
+struct ordered_index_node:
+ Super,ordered_index_node_trampoline<AugmentPolicy,Super>
{
private:
- typedef ordered_index_node_trampoline<Super> trampoline;
+ typedef ordered_index_node_trampoline<AugmentPolicy,Super> trampoline;
public:
typedef typename trampoline::impl_type impl_type;
@@ -600,14 +618,18 @@ public:
static ordered_index_node* from_impl(impl_pointer x)
{
- return static_cast<ordered_index_node*>(
- static_cast<trampoline*>(&*x));
+ return
+ static_cast<ordered_index_node*>(
+ static_cast<trampoline*>(
+ raw_ptr<impl_type*>(x)));
}
static const ordered_index_node* from_impl(const_impl_pointer x)
{
- return static_cast<const ordered_index_node*>(
- static_cast<const trampoline*>(&*x));
+ return
+ static_cast<const ordered_index_node*>(
+ static_cast<const trampoline*>(
+ raw_ptr<const impl_type*>(x)));
}
/* interoperability with bidir_node_iterator */
diff --git a/boost/multi_index/detail/raw_ptr.hpp b/boost/multi_index/detail/raw_ptr.hpp
new file mode 100644
index 0000000000..c32007435c
--- /dev/null
+++ b/boost/multi_index/detail/raw_ptr.hpp
@@ -0,0 +1,52 @@
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP
+#define BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/mpl/bool.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost{
+
+namespace multi_index{
+
+namespace detail{
+
+/* gets the underlying pointer of a pointer-like value */
+
+template<typename RawPointer>
+inline RawPointer raw_ptr(RawPointer const& p,mpl::true_)
+{
+ return p;
+}
+
+template<typename RawPointer,typename Pointer>
+inline RawPointer raw_ptr(Pointer const& p,mpl::false_)
+{
+ return p==Pointer(0)?0:&*p;
+}
+
+template<typename RawPointer,typename Pointer>
+inline RawPointer raw_ptr(Pointer const& p)
+{
+ return raw_ptr<RawPointer>(p,is_same<RawPointer,Pointer>());
+}
+
+} /* namespace multi_index::detail */
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+#endif
diff --git a/boost/multi_index/detail/rnd_index_node.hpp b/boost/multi_index/detail/rnd_index_node.hpp
index def057583a..ad61ea25dd 100644
--- a/boost/multi_index/detail/rnd_index_node.hpp
+++ b/boost/multi_index/detail/rnd_index_node.hpp
@@ -17,6 +17,7 @@
#include <algorithm>
#include <boost/detail/allocator_utilities.hpp>
#include <boost/integer/common_factor_rt.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
#include <cstddef>
#include <functional>
@@ -219,14 +220,18 @@ public:
static random_access_index_node* from_impl(impl_pointer x)
{
- return static_cast<random_access_index_node*>(
- static_cast<trampoline*>(&*x));
+ return
+ static_cast<random_access_index_node*>(
+ static_cast<trampoline*>(
+ raw_ptr<impl_type*>(x)));
}
static const random_access_index_node* from_impl(const_impl_pointer x)
{
- return static_cast<const random_access_index_node*>(
- static_cast<const trampoline*>(&*x));
+ return
+ static_cast<const random_access_index_node*>(
+ static_cast<const trampoline*>(
+ raw_ptr<const impl_type*>(x)));
}
/* interoperability with rnd_node_iterator */
diff --git a/boost/multi_index/detail/rnd_index_ops.hpp b/boost/multi_index/detail/rnd_index_ops.hpp
index d05386d747..f5e76e4441 100644
--- a/boost/multi_index/detail/rnd_index_ops.hpp
+++ b/boost/multi_index/detail/rnd_index_ops.hpp
@@ -16,7 +16,6 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/multi_index/detail/rnd_index_ptr_array.hpp>
-#include <functional>
namespace boost{
@@ -123,11 +122,12 @@ void random_access_index_inplace_merge(
/* auxiliary stuff */
template<typename Node,typename Compare>
-struct random_access_index_sort_compare:
- std::binary_function<
- typename Node::impl_pointer,
- typename Node::impl_pointer,bool>
+struct random_access_index_sort_compare
{
+ typedef typename Node::impl_pointer first_argument_type;
+ typedef typename Node::impl_pointer second_argument_type;
+ typedef bool result_type;
+
random_access_index_sort_compare(Compare comp_=Compare()):comp(comp_){}
bool operator()(
diff --git a/boost/multi_index/detail/rnk_index_ops.hpp b/boost/multi_index/detail/rnk_index_ops.hpp
new file mode 100644
index 0000000000..275642236b
--- /dev/null
+++ b/boost/multi_index/detail/rnk_index_ops.hpp
@@ -0,0 +1,300 @@
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP
+#define BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/mpl/and.hpp>
+#include <boost/multi_index/detail/promotes_arg.hpp>
+#include <cstddef>
+#include <utility>
+
+namespace boost{
+
+namespace multi_index{
+
+namespace detail{
+
+/* Common code for ranked_index memfuns having templatized and
+ * non-templatized versions.
+ */
+
+template<typename Pointer>
+inline std::size_t ranked_node_size(Pointer x)
+{
+ return x!=Pointer(0)?x->size:0;
+}
+
+template<typename Pointer>
+inline Pointer ranked_index_nth(std::size_t n,Pointer end_)
+{
+ Pointer top=end_->parent();
+ if(top==Pointer(0)||n>=top->size)return end_;
+
+ for(;;){
+ std::size_t s=ranked_node_size(top->left());
+ if(n==s)return top;
+ if(n<s)top=top->left();
+ else{
+ top=top->right();
+ n-=s+1;
+ }
+ }
+}
+
+template<typename Pointer>
+inline std::size_t ranked_index_rank(Pointer x,Pointer end_)
+{
+ Pointer top=end_->parent();
+ if(top==Pointer(0))return 0;
+ if(x==end_)return top->size;
+
+ std::size_t s=ranked_node_size(x->left());
+ while(x!=top){
+ Pointer z=x->parent();
+ if(x==z->right()){
+ s+=ranked_node_size(z->left())+1;
+ }
+ x=z;
+ }
+ return s;
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_find_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp)
+{
+ typedef typename KeyFromValue::result_type key_type;
+
+ return ranked_index_find_rank(
+ top,y,key,x,comp,
+ mpl::and_<
+ promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
+ promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleCompare
+>
+inline std::size_t ranked_index_find_rank(
+ Node* top,Node* y,const KeyFromValue& key,
+ const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
+ const CompatibleCompare& comp,mpl::true_)
+{
+ return ranked_index_find_rank(top,y,key,x,comp,mpl::false_());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_find_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp,mpl::false_)
+{
+ if(!top)return 0;
+
+ std::size_t s=top->size,
+ s0=s;
+ Node* y0=y;
+
+ do{
+ if(!comp(key(top->value()),x)){
+ y=top;
+ s-=ranked_node_size(y->right())+1;
+ top=Node::from_impl(top->left());
+ }
+ else top=Node::from_impl(top->right());
+ }while(top);
+
+ return (y==y0||comp(x,key(y->value())))?s0:s;
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_lower_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp)
+{
+ typedef typename KeyFromValue::result_type key_type;
+
+ return ranked_index_lower_bound_rank(
+ top,y,key,x,comp,
+ promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey>());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleCompare
+>
+inline std::size_t ranked_index_lower_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,
+ const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
+ const CompatibleCompare& comp,mpl::true_)
+{
+ return ranked_index_lower_bound_rank(top,y,key,x,comp,mpl::false_());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_lower_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp,mpl::false_)
+{
+ if(!top)return 0;
+
+ std::size_t s=top->size;
+
+ do{
+ if(!comp(key(top->value()),x)){
+ y=top;
+ s-=ranked_node_size(y->right())+1;
+ top=Node::from_impl(top->left());
+ }
+ else top=Node::from_impl(top->right());
+ }while(top);
+
+ return s;
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_upper_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp)
+{
+ typedef typename KeyFromValue::result_type key_type;
+
+ return ranked_index_upper_bound_rank(
+ top,y,key,x,comp,
+ promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleCompare
+>
+inline std::size_t ranked_index_upper_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,
+ const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
+ const CompatibleCompare& comp,mpl::true_)
+{
+ return ranked_index_upper_bound_rank(top,y,key,x,comp,mpl::false_());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::size_t ranked_index_upper_bound_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp,mpl::false_)
+{
+ if(!top)return 0;
+
+ std::size_t s=top->size;
+
+ do{
+ if(comp(x,key(top->value()))){
+ y=top;
+ s-=ranked_node_size(y->right())+1;
+ top=Node::from_impl(top->left());
+ }
+ else top=Node::from_impl(top->right());
+ }while(top);
+
+ return s;
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp)
+{
+ typedef typename KeyFromValue::result_type key_type;
+
+ return ranked_index_equal_range_rank(
+ top,y,key,x,comp,
+ mpl::and_<
+ promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>,
+ promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleCompare
+>
+inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
+ Node* top,Node* y,const KeyFromValue& key,
+ const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x,
+ const CompatibleCompare& comp,mpl::true_)
+{
+ return ranked_index_equal_range_rank(top,y,key,x,comp,mpl::false_());
+}
+
+template<
+ typename Node,typename KeyFromValue,
+ typename CompatibleKey,typename CompatibleCompare
+>
+inline std::pair<std::size_t,std::size_t> ranked_index_equal_range_rank(
+ Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x,
+ const CompatibleCompare& comp,mpl::false_)
+{
+ if(!top)return std::pair<std::size_t,std::size_t>(0,0);
+
+ std::size_t s=top->size;
+
+ do{
+ if(comp(key(top->value()),x)){
+ top=Node::from_impl(top->right());
+ }
+ else if(comp(x,key(top->value()))){
+ y=top;
+ s-=ranked_node_size(y->right())+1;
+ top=Node::from_impl(top->left());
+ }
+ else{
+ return std::pair<std::size_t,std::size_t>(
+ s-top->size+
+ ranked_index_lower_bound_rank(
+ Node::from_impl(top->left()),top,key,x,comp,mpl::false_()),
+ s-ranked_node_size(top->right())+
+ ranked_index_upper_bound_rank(
+ Node::from_impl(top->right()),y,key,x,comp,mpl::false_()));
+ }
+ }while(top);
+
+ return std::pair<std::size_t,std::size_t>(s,s);
+}
+
+} /* namespace multi_index::detail */
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+#endif
diff --git a/boost/multi_index/detail/seq_index_node.hpp b/boost/multi_index/detail/seq_index_node.hpp
index 5cb467650f..85b345af93 100644
--- a/boost/multi_index/detail/seq_index_node.hpp
+++ b/boost/multi_index/detail/seq_index_node.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -16,6 +16,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/detail/allocator_utilities.hpp>
+#include <boost/multi_index/detail/raw_ptr.hpp>
namespace boost{
@@ -176,14 +177,18 @@ public:
static sequenced_index_node* from_impl(impl_pointer x)
{
- return static_cast<sequenced_index_node*>(
- static_cast<trampoline*>(&*x));
+ return
+ static_cast<sequenced_index_node*>(
+ static_cast<trampoline*>(
+ raw_ptr<impl_type*>(x)));
}
static const sequenced_index_node* from_impl(const_impl_pointer x)
{
- return static_cast<const sequenced_index_node*>(
- static_cast<const trampoline*>(&*x));
+ return
+ static_cast<const sequenced_index_node*>(
+ static_cast<const trampoline*>(
+ raw_ptr<const impl_type*>(x)));
}
/* interoperability with bidir_node_iterator */
diff --git a/boost/multi_index/detail/seq_index_ops.hpp b/boost/multi_index/detail/seq_index_ops.hpp
index 56da408342..a3c2bc1f04 100644
--- a/boost/multi_index/detail/seq_index_ops.hpp
+++ b/boost/multi_index/detail/seq_index_ops.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -135,7 +135,7 @@ void sequenced_index_sort(Node* header,Compare comp)
>::type carry_spc_type;
carry_spc_type carry_spc;
impl_type& carry=
- *static_cast<impl_type*>(static_cast<void*>(&carry_spc));
+ *reinterpret_cast<impl_type*>(&carry_spc);
typedef typename aligned_storage<
sizeof(
impl_type
@@ -147,7 +147,7 @@ void sequenced_index_sort(Node* header,Compare comp)
>::type counter_spc_type;
counter_spc_type counter_spc;
impl_type* counter=
- static_cast<impl_type*>(static_cast<void*>(&counter_spc));
+ reinterpret_cast<impl_type*>(&counter_spc);
std::size_t fill=0;
carry.prior()=carry.next()=static_cast<impl_pointer>(&carry);
diff --git a/boost/multi_index/detail/value_compare.hpp b/boost/multi_index/detail/value_compare.hpp
index 1fde20549f..ac42e8779a 100644
--- a/boost/multi_index/detail/value_compare.hpp
+++ b/boost/multi_index/detail/value_compare.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+/* Copyright 2003-2015 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@@ -15,7 +15,6 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/call_traits.hpp>
-#include <functional>
namespace boost{
@@ -24,8 +23,12 @@ namespace multi_index{
namespace detail{
template<typename Value,typename KeyFromValue,typename Compare>
-struct value_comparison:std::binary_function<Value,Value,bool>
+struct value_comparison
{
+ typedef Value first_argument_type;
+ typedef Value second_argument_type;
+ typedef bool result_type;
+
value_comparison(
const KeyFromValue& key_=KeyFromValue(),const Compare& comp_=Compare()):
key(key_),comp(comp_)