1 /* Copyright 2003-2020 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
6 * See http://www.boost.org/libs/multi_index for library home page.
8 * The internal implementation of red-black trees is based on that of SGI STL
11 * Copyright (c) 1996,1997
12 * Silicon Graphics Computer Systems, Inc.
14 * Permission to use, copy, modify, distribute and sell this software
15 * and its documentation for any purpose is hereby granted without fee,
16 * provided that the above copyright notice appear in all copies and
17 * that both that copyright notice and this permission notice appear
18 * in supporting documentation. Silicon Graphics makes no
19 * representations about the suitability of this software for any
20 * purpose. It is provided "as is" without express or implied warranty.
24 * Hewlett-Packard Company
26 * Permission to use, copy, modify, distribute and sell this software
27 * and its documentation for any purpose is hereby granted without fee,
28 * provided that the above copyright notice appear in all copies and
29 * that both that copyright notice and this permission notice appear
30 * in supporting documentation. Hewlett-Packard Company makes no
31 * representations about the suitability of this software for any
32 * purpose. It is provided "as is" without express or implied warranty.
36 #ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP
37 #define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP
43 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
45 #include <boost/call_traits.hpp>
46 #include <boost/core/addressof.hpp>
47 #include <boost/core/no_exceptions_support.hpp>
48 #include <boost/detail/workaround.hpp>
49 #include <boost/foreach_fwd.hpp>
50 #include <boost/iterator/reverse_iterator.hpp>
51 #include <boost/move/core.hpp>
52 #include <boost/move/utility_core.hpp>
53 #include <boost/mpl/bool.hpp>
54 #include <boost/mpl/if.hpp>
55 #include <boost/mpl/push_front.hpp>
56 #include <boost/multi_index/detail/access_specifier.hpp>
57 #include <boost/multi_index/detail/adl_swap.hpp>
58 #include <boost/multi_index/detail/allocator_traits.hpp>
59 #include <boost/multi_index/detail/bidir_node_iterator.hpp>
60 #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
61 #include <boost/multi_index/detail/index_node_base.hpp>
62 #include <boost/multi_index/detail/modify_key_adaptor.hpp>
63 #include <boost/multi_index/detail/node_handle.hpp>
64 #include <boost/multi_index/detail/ord_index_node.hpp>
65 #include <boost/multi_index/detail/ord_index_ops.hpp>
66 #include <boost/multi_index/detail/safe_mode.hpp>
67 #include <boost/multi_index/detail/scope_guard.hpp>
68 #include <boost/multi_index/detail/unbounded.hpp>
69 #include <boost/multi_index/detail/value_compare.hpp>
70 #include <boost/multi_index/detail/vartempl_support.hpp>
71 #include <boost/multi_index/detail/ord_index_impl_fwd.hpp>
72 #include <boost/ref.hpp>
73 #include <boost/tuple/tuple.hpp>
74 #include <boost/type_traits/is_same.hpp>
77 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
78 #include <initializer_list>
81 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
82 #include <boost/archive/archive_exception.hpp>
83 #include <boost/bind/bind.hpp>
84 #include <boost/multi_index/detail/duplicates_iterator.hpp>
85 #include <boost/throw_exception.hpp>
88 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
89 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \
90 detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
91 detail::make_obj_guard(x,&ordered_index_impl::check_invariant_); \
92 BOOST_JOIN(check_invariant_,__LINE__).touch();
93 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \
94 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this)
96 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x)
97 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
102 namespace multi_index{
106 /* ordered_index adds a layer of ordered indexing to a given Super and accepts
107 * an augmenting policy for optional addition of order statistics.
110 /* Most of the implementation of unique and non-unique indices is
111 * shared. We tell from one another on instantiation time by using
115 struct ordered_unique_tag{};
116 struct ordered_non_unique_tag{};
119 typename KeyFromValue,typename Compare,
120 typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
125 typename KeyFromValue,typename Compare,
126 typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
128 class ordered_index_impl:
129 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
131 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
132 ,public safe_mode::safe_container<
134 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy> >
138 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
139 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
140 /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
141 * lifetime of const references bound to temporaries --precisely what
145 #pragma parse_mfunc_templ off
148 typedef typename SuperMeta::type super;
151 typedef ordered_index_node<
152 AugmentPolicy,typename super::index_node_type> index_node_type;
154 protected: /* for the benefit of AugmentPolicy::augmented_interface */
155 typedef typename index_node_type::impl_type node_impl_type;
156 typedef typename node_impl_type::pointer node_impl_pointer;
161 typedef typename KeyFromValue::result_type key_type;
162 typedef typename index_node_type::value_type value_type;
163 typedef KeyFromValue key_from_value;
164 typedef Compare key_compare;
165 typedef value_comparison<
166 value_type,KeyFromValue,Compare> value_compare;
167 typedef tuple<key_from_value,key_compare> ctor_args;
168 typedef typename super::final_allocator_type allocator_type;
169 typedef value_type& reference;
170 typedef const value_type& const_reference;
172 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
173 typedef safe_mode::safe_iterator<
174 bidir_node_iterator<index_node_type>,
175 ordered_index_impl> iterator;
177 typedef bidir_node_iterator<index_node_type> iterator;
180 typedef iterator const_iterator;
183 typedef allocator_traits<allocator_type> alloc_traits;
186 typedef typename alloc_traits::size_type size_type;
187 typedef typename alloc_traits::difference_type difference_type;
188 typedef typename alloc_traits::pointer pointer;
189 typedef typename alloc_traits::const_pointer const_pointer;
191 boost::reverse_iterator<iterator> reverse_iterator;
193 boost::reverse_iterator<const_iterator> const_reverse_iterator;
194 typedef typename super::final_node_handle_type node_type;
195 typedef detail::insert_return_type<
196 iterator,node_type> insert_return_type;
197 typedef TagList tag_list;
200 typedef typename super::final_node_type final_node_type;
201 typedef tuples::cons<
203 typename super::ctor_args_list> ctor_args_list;
204 typedef typename mpl::push_front<
205 typename super::index_type_list,
207 KeyFromValue,Compare,
208 SuperMeta,TagList,Category,AugmentPolicy
209 > >::type index_type_list;
210 typedef typename mpl::push_front<
211 typename super::iterator_type_list,
212 iterator>::type iterator_type_list;
213 typedef typename mpl::push_front<
214 typename super::const_iterator_type_list,
215 const_iterator>::type const_iterator_type_list;
216 typedef typename super::copy_map_type copy_map_type;
218 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
219 typedef typename super::index_saver_type index_saver_type;
220 typedef typename super::index_loader_type index_loader_type;
224 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
225 typedef safe_mode::safe_container<
226 ordered_index_impl> safe_super;
229 typedef typename call_traits<
230 value_type>::param_type value_param_type;
231 typedef typename call_traits<
232 key_type>::param_type key_param_type;
234 /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
238 typedef std::pair<iterator,bool> emplace_return_type;
242 /* construct/copy/destroy
243 * Default and copy ctors are in the protected section as indices are
244 * not supposed to be created on their own. No range ctor either.
245 * Assignment operators defined at ordered_index rather than here.
248 allocator_type get_allocator()const BOOST_NOEXCEPT
250 return this->final().get_allocator();
256 begin()BOOST_NOEXCEPT{return make_iterator(leftmost());}
258 begin()const BOOST_NOEXCEPT{return make_iterator(leftmost());}
260 end()BOOST_NOEXCEPT{return make_iterator(header());}
262 end()const BOOST_NOEXCEPT{return make_iterator(header());}
264 rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
265 const_reverse_iterator
266 rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
268 rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
269 const_reverse_iterator
270 rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
272 cbegin()const BOOST_NOEXCEPT{return begin();}
274 cend()const BOOST_NOEXCEPT{return end();}
275 const_reverse_iterator
276 crbegin()const BOOST_NOEXCEPT{return rbegin();}
277 const_reverse_iterator
278 crend()const BOOST_NOEXCEPT{return rend();}
280 iterator iterator_to(const value_type& x)
282 return make_iterator(
283 node_from_value<index_node_type>(boost::addressof(x)));
286 const_iterator iterator_to(const value_type& x)const
288 return make_iterator(
289 node_from_value<index_node_type>(boost::addressof(x)));
294 bool empty()const BOOST_NOEXCEPT{return this->final_empty_();}
295 size_type size()const BOOST_NOEXCEPT{return this->final_size_();}
296 size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();}
300 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
301 emplace_return_type,emplace,emplace_impl)
303 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
304 iterator,emplace_hint,emplace_hint_impl,iterator,position)
306 std::pair<iterator,bool> insert(const value_type& x)
308 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
309 std::pair<final_node_type*,bool> p=this->final_insert_(x);
310 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
313 std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
315 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
316 std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
317 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
320 iterator insert(iterator position,const value_type& x)
322 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
323 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
324 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
325 std::pair<final_node_type*,bool> p=this->final_insert_(
326 x,static_cast<final_node_type*>(position.get_node()));
327 return make_iterator(p.first);
330 iterator insert(iterator position,BOOST_RV_REF(value_type) x)
332 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
333 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
334 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
335 std::pair<final_node_type*,bool> p=this->final_insert_rv_(
336 x,static_cast<final_node_type*>(position.get_node()));
337 return make_iterator(p.first);
340 template<typename InputIterator>
341 void insert(InputIterator first,InputIterator last)
343 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
344 index_node_type* hint=header(); /* end() */
345 for(;first!=last;++first){
346 hint=this->final_insert_ref_(
347 *first,static_cast<final_node_type*>(hint)).first;
348 index_node_type::increment(hint);
352 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
353 void insert(std::initializer_list<value_type> list)
355 insert(list.begin(),list.end());
359 insert_return_type insert(BOOST_RV_REF(node_type) nh)
361 if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
362 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
363 std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh);
364 return insert_return_type(make_iterator(p.first),p.second,boost::move(nh));
367 iterator insert(const_iterator position,BOOST_RV_REF(node_type) nh)
369 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
370 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
371 if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
372 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
373 std::pair<final_node_type*,bool> p=this->final_insert_nh_(
374 nh,static_cast<final_node_type*>(position.get_node()));
375 return make_iterator(p.first);
378 node_type extract(const_iterator position)
380 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
381 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
382 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
383 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
384 return this->final_extract_(
385 static_cast<final_node_type*>(position.get_node()));
388 node_type extract(key_param_type x)
390 iterator position=lower_bound(x);
391 if(position==end()||comp_(x,key(*position)))return node_type();
392 else return extract(position);
395 iterator erase(iterator position)
397 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
398 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
399 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
400 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
401 this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
405 size_type erase(key_param_type x)
407 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
408 std::pair<iterator,iterator> p=equal_range(x);
410 while(p.first!=p.second){
411 p.first=erase(p.first);
417 iterator erase(iterator first,iterator last)
419 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
420 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
421 BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
422 BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
423 BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
424 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
431 bool replace(iterator position,const value_type& x)
433 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
434 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
435 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
436 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
437 return this->final_replace_(
438 x,static_cast<final_node_type*>(position.get_node()));
441 bool replace(iterator position,BOOST_RV_REF(value_type) x)
443 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
444 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
445 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
446 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
447 return this->final_replace_rv_(
448 x,static_cast<final_node_type*>(position.get_node()));
451 template<typename Modifier>
452 bool modify(iterator position,Modifier mod)
454 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
455 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
456 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
457 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
459 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
460 /* MSVC++ 6.0 optimizer on safe mode code chokes if this
461 * this is not added. Left it for all compilers as it does no
468 return this->final_modify_(
469 mod,static_cast<final_node_type*>(position.get_node()));
472 template<typename Modifier,typename Rollback>
473 bool modify(iterator position,Modifier mod,Rollback back_)
475 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
476 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
477 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
478 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
480 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
481 /* MSVC++ 6.0 optimizer on safe mode code chokes if this
482 * this is not added. Left it for all compilers as it does no
489 return this->final_modify_(
490 mod,back_,static_cast<final_node_type*>(position.get_node()));
493 template<typename Modifier>
494 bool modify_key(iterator position,Modifier mod)
496 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
497 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
498 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
499 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
501 position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key));
504 template<typename Modifier,typename Rollback>
505 bool modify_key(iterator position,Modifier mod,Rollback back_)
507 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
508 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
509 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
510 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
513 modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key),
514 modify_key_adaptor<Rollback,value_type,KeyFromValue>(back_,key));
519 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
521 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
522 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x);
523 this->final_swap_(x.final());
526 void clear()BOOST_NOEXCEPT
528 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
529 this->final_clear_();
534 key_from_value key_extractor()const{return key;}
535 key_compare key_comp()const{return comp_;}
536 value_compare value_comp()const{return value_compare(key,comp_);}
540 /* Internally, these ops rely on const_iterator being the same
544 template<typename CompatibleKey>
545 iterator find(const CompatibleKey& x)const
547 return make_iterator(ordered_index_find(root(),header(),key,x,comp_));
550 template<typename CompatibleKey,typename CompatibleCompare>
552 const CompatibleKey& x,const CompatibleCompare& comp)const
554 return make_iterator(ordered_index_find(root(),header(),key,x,comp));
557 template<typename CompatibleKey>
558 size_type count(const CompatibleKey& x)const
560 return count(x,comp_);
563 template<typename CompatibleKey,typename CompatibleCompare>
564 size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const
566 std::pair<iterator,iterator> p=equal_range(x,comp);
567 size_type n=static_cast<size_type>(std::distance(p.first,p.second));
571 template<typename CompatibleKey>
572 iterator lower_bound(const CompatibleKey& x)const
574 return make_iterator(
575 ordered_index_lower_bound(root(),header(),key,x,comp_));
578 template<typename CompatibleKey,typename CompatibleCompare>
579 iterator lower_bound(
580 const CompatibleKey& x,const CompatibleCompare& comp)const
582 return make_iterator(
583 ordered_index_lower_bound(root(),header(),key,x,comp));
586 template<typename CompatibleKey>
587 iterator upper_bound(const CompatibleKey& x)const
589 return make_iterator(
590 ordered_index_upper_bound(root(),header(),key,x,comp_));
593 template<typename CompatibleKey,typename CompatibleCompare>
594 iterator upper_bound(
595 const CompatibleKey& x,const CompatibleCompare& comp)const
597 return make_iterator(
598 ordered_index_upper_bound(root(),header(),key,x,comp));
601 template<typename CompatibleKey>
602 std::pair<iterator,iterator> equal_range(
603 const CompatibleKey& x)const
605 std::pair<index_node_type*,index_node_type*> p=
606 ordered_index_equal_range(root(),header(),key,x,comp_);
607 return std::pair<iterator,iterator>(
608 make_iterator(p.first),make_iterator(p.second));
611 template<typename CompatibleKey,typename CompatibleCompare>
612 std::pair<iterator,iterator> equal_range(
613 const CompatibleKey& x,const CompatibleCompare& comp)const
615 std::pair<index_node_type*,index_node_type*> p=
616 ordered_index_equal_range(root(),header(),key,x,comp);
617 return std::pair<iterator,iterator>(
618 make_iterator(p.first),make_iterator(p.second));
623 template<typename LowerBounder,typename UpperBounder>
624 std::pair<iterator,iterator>
625 range(LowerBounder lower,UpperBounder upper)const
627 typedef typename mpl::if_<
628 is_same<LowerBounder,unbounded_type>,
629 BOOST_DEDUCED_TYPENAME mpl::if_<
630 is_same<UpperBounder,unbounded_type>,
634 BOOST_DEDUCED_TYPENAME mpl::if_<
635 is_same<UpperBounder,unbounded_type>,
641 return range(lower,upper,dispatch());
644 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
645 ordered_index_impl(const ctor_args_list& args_list,const allocator_type& al):
646 super(args_list.get_tail(),al),
647 key(tuples::get<0>(args_list.get_head())),
648 comp_(tuples::get<1>(args_list.get_head()))
654 const ordered_index_impl<
655 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x):
658 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
665 /* Copy ctor just takes the key and compare objects from x. The rest is
666 * done in a subsequent call to copy_().
671 const ordered_index_impl<
672 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
673 do_not_copy_elements_tag):
674 super(x,do_not_copy_elements_tag()),
676 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
686 ~ordered_index_impl()
688 /* the container is guaranteed to be empty by now */
691 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
692 iterator make_iterator(index_node_type* node)
693 {return iterator(node,this);}
694 const_iterator make_iterator(index_node_type* node)const
695 {return const_iterator(node,const_cast<ordered_index_impl*>(this));}
697 iterator make_iterator(index_node_type* node){return iterator(node);}
698 const_iterator make_iterator(index_node_type* node)const
699 {return const_iterator(node);}
703 const ordered_index_impl<
704 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
705 const copy_map_type& map)
711 header()->color()=x.header()->color();
712 AugmentPolicy::copy(x.header()->impl(),header()->impl());
714 index_node_type* root_cpy=map.find(
715 static_cast<final_node_type*>(x.root()));
716 header()->parent()=root_cpy->impl();
718 index_node_type* leftmost_cpy=map.find(
719 static_cast<final_node_type*>(x.leftmost()));
720 header()->left()=leftmost_cpy->impl();
722 index_node_type* rightmost_cpy=map.find(
723 static_cast<final_node_type*>(x.rightmost()));
724 header()->right()=rightmost_cpy->impl();
726 typedef typename copy_map_type::const_iterator copy_map_iterator;
727 for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){
728 index_node_type* org=it->first;
729 index_node_type* cpy=it->second;
731 cpy->color()=org->color();
732 AugmentPolicy::copy(org->impl(),cpy->impl());
734 node_impl_pointer parent_org=org->parent();
735 if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0);
737 index_node_type* parent_cpy=map.find(
738 static_cast<final_node_type*>(
739 index_node_type::from_impl(parent_org)));
740 cpy->parent()=parent_cpy->impl();
741 if(parent_org->left()==org->impl()){
742 parent_cpy->left()=cpy->impl();
744 else if(parent_org->right()==org->impl()){
745 /* header() does not satisfy this nor the previous check */
746 parent_cpy->right()=cpy->impl();
750 if(org->left()==node_impl_pointer(0))
751 cpy->left()=node_impl_pointer(0);
752 if(org->right()==node_impl_pointer(0))
753 cpy->right()=node_impl_pointer(0);
760 template<typename Variant>
761 final_node_type* insert_(
762 value_param_type v,final_node_type*& x,Variant variant)
765 if(!link_point(key(v),inf,Category())){
766 return static_cast<final_node_type*>(
767 index_node_type::from_impl(inf.pos));
770 final_node_type* res=super::insert_(v,x,variant);
772 node_impl_type::link(
773 static_cast<index_node_type*>(x)->impl(),
774 inf.side,inf.pos,header()->impl());
779 template<typename Variant>
780 final_node_type* insert_(
781 value_param_type v,index_node_type* position,
782 final_node_type*& x,Variant variant)
785 if(!hinted_link_point(key(v),position,inf,Category())){
786 return static_cast<final_node_type*>(
787 index_node_type::from_impl(inf.pos));
790 final_node_type* res=super::insert_(v,position,x,variant);
792 node_impl_type::link(
793 static_cast<index_node_type*>(x)->impl(),
794 inf.side,inf.pos,header()->impl());
799 void extract_(index_node_type* x)
801 node_impl_type::rebalance_for_extract(
802 x->impl(),header()->parent(),header()->left(),header()->right());
805 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
810 void delete_all_nodes_()
812 delete_all_nodes(root());
820 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
821 safe_super::detach_dereferenceable_iterators();
825 template<typename BoolConstant>
828 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
829 BoolConstant swap_allocators)
832 adl_swap(comp_,x.comp_);
834 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
838 super::swap_(x,swap_allocators);
843 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
845 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
849 super::swap_elements_(x);
852 template<typename Variant>
853 bool replace_(value_param_type v,index_node_type* x,Variant variant)
855 if(in_place(v,x,Category())){
856 return super::replace_(v,x,variant);
859 index_node_type* next=x;
860 index_node_type::increment(next);
862 node_impl_type::rebalance_for_extract(
863 x->impl(),header()->parent(),header()->left(),header()->right());
867 if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){
868 node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
871 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
875 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
881 bool modify_(index_node_type* x)
885 b=in_place(x->value(),x,Category());
893 node_impl_type::rebalance_for_extract(
894 x->impl(),header()->parent(),header()->left(),header()->right());
897 if(!link_point(key(x->value()),inf,Category())){
900 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
905 node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
910 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
920 if(!super::modify_(x)){
921 node_impl_type::rebalance_for_extract(
922 x->impl(),header()->parent(),header()->left(),header()->right());
924 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
933 node_impl_type::rebalance_for_extract(
934 x->impl(),header()->parent(),header()->left(),header()->right());
936 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
945 bool modify_rollback_(index_node_type* x)
947 if(in_place(x->value(),x,Category())){
948 return super::modify_rollback_(x);
951 index_node_type* next=x;
952 index_node_type::increment(next);
954 node_impl_type::rebalance_for_extract(
955 x->impl(),header()->parent(),header()->left(),header()->right());
959 if(link_point(key(x->value()),inf,Category())&&
960 super::modify_rollback_(x)){
961 node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
964 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
968 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
974 bool check_rollback_(index_node_type* x)const
976 return in_place(x->value(),x,Category())&&super::check_rollback_(x);
979 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
982 template<typename Archive>
984 Archive& ar,const unsigned int version,const index_saver_type& sm)const
986 save_(ar,version,sm,Category());
989 template<typename Archive>
990 void load_(Archive& ar,const unsigned int version,const index_loader_type& lm)
992 load_(ar,version,lm,Category());
996 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
997 /* invariant stuff */
999 bool invariant_()const
1001 if(size()==0||begin()==end()){
1002 if(size()!=0||begin()!=end()||
1003 header()->left()!=header()->impl()||
1004 header()->right()!=header()->impl())return false;
1007 if((size_type)std::distance(begin(),end())!=size())return false;
1009 std::size_t len=node_impl_type::black_count(
1010 leftmost()->impl(),root()->impl());
1011 for(const_iterator it=begin(),it_end=end();it!=it_end;++it){
1012 index_node_type* x=it.get_node();
1013 index_node_type* left_x=index_node_type::from_impl(x->left());
1014 index_node_type* right_x=index_node_type::from_impl(x->right());
1016 if(x->color()==red){
1017 if((left_x&&left_x->color()==red)||
1018 (right_x&&right_x->color()==red))return false;
1020 if(left_x&&comp_(key(x->value()),key(left_x->value())))return false;
1021 if(right_x&&comp_(key(right_x->value()),key(x->value())))return false;
1022 if(!left_x&&!right_x&&
1023 node_impl_type::black_count(x->impl(),root()->impl())!=len)
1025 if(!AugmentPolicy::invariant(x->impl()))return false;
1028 if(leftmost()->impl()!=node_impl_type::minimum(root()->impl()))
1030 if(rightmost()->impl()!=node_impl_type::maximum(root()->impl()))
1034 return super::invariant_();
1038 /* This forwarding function eases things for the boost::mem_fn construct
1039 * in BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT. Actually,
1040 * final_check_invariant is already an inherited member function of
1041 * ordered_index_impl.
1043 void check_invariant_()const{this->final_check_invariant_();}
1046 protected: /* for the benefit of AugmentPolicy::augmented_interface */
1047 index_node_type* header()const
1048 {return this->final_header();}
1049 index_node_type* root()const
1050 {return index_node_type::from_impl(header()->parent());}
1051 index_node_type* leftmost()const
1052 {return index_node_type::from_impl(header()->left());}
1053 index_node_type* rightmost()const
1054 {return index_node_type::from_impl(header()->right());}
1057 void empty_initialize()
1059 header()->color()=red;
1060 /* used to distinguish header() from root, in iterator.operator++ */
1062 header()->parent()=node_impl_pointer(0);
1063 header()->left()=header()->impl();
1064 header()->right()=header()->impl();
1069 /* coverity[uninit_ctor]: suppress warning */
1070 link_info():side(to_left){}
1072 ordered_index_side side;
1073 node_impl_pointer pos;
1076 bool link_point(key_param_type k,link_info& inf,ordered_unique_tag)
1078 index_node_type* y=header();
1079 index_node_type* x=root();
1083 c=comp_(k,key(x->value()));
1084 x=index_node_type::from_impl(c?x->left():x->right());
1086 index_node_type* yy=y;
1093 else index_node_type::decrement(yy);
1096 if(comp_(key(yy->value()),k)){
1097 inf.side=c?to_left:to_right;
1107 bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
1109 index_node_type* y=header();
1110 index_node_type* x=root();
1114 c=comp_(k,key(x->value()));
1115 x=index_node_type::from_impl(c?x->left():x->right());
1117 inf.side=c?to_left:to_right;
1122 bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
1124 index_node_type* y=header();
1125 index_node_type* x=root();
1129 c=comp_(key(x->value()),k);
1130 x=index_node_type::from_impl(c?x->right():x->left());
1132 inf.side=c?to_right:to_left;
1137 bool hinted_link_point(
1138 key_param_type k,index_node_type* position,
1139 link_info& inf,ordered_unique_tag)
1141 if(position->impl()==header()->left()){
1142 if(size()>0&&comp_(k,key(position->value()))){
1144 inf.pos=position->impl();
1147 else return link_point(k,inf,ordered_unique_tag());
1149 else if(position==header()){
1150 if(comp_(key(rightmost()->value()),k)){
1152 inf.pos=rightmost()->impl();
1155 else return link_point(k,inf,ordered_unique_tag());
1158 index_node_type* before=position;
1159 index_node_type::decrement(before);
1160 if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){
1161 if(before->right()==node_impl_pointer(0)){
1163 inf.pos=before->impl();
1168 inf.pos=position->impl();
1172 else return link_point(k,inf,ordered_unique_tag());
1176 bool hinted_link_point(
1177 key_param_type k,index_node_type* position,
1178 link_info& inf,ordered_non_unique_tag)
1180 if(position->impl()==header()->left()){
1181 if(size()>0&&!comp_(key(position->value()),k)){
1183 inf.pos=position->impl();
1186 else return lower_link_point(k,inf,ordered_non_unique_tag());
1188 else if(position==header()){
1189 if(!comp_(k,key(rightmost()->value()))){
1191 inf.pos=rightmost()->impl();
1194 else return link_point(k,inf,ordered_non_unique_tag());
1197 index_node_type* before=position;
1198 index_node_type::decrement(before);
1199 if(!comp_(k,key(before->value()))){
1200 if(!comp_(key(position->value()),k)){
1201 if(before->right()==node_impl_pointer(0)){
1203 inf.pos=before->impl();
1208 inf.pos=position->impl();
1212 else return lower_link_point(k,inf,ordered_non_unique_tag());
1214 else return link_point(k,inf,ordered_non_unique_tag());
1218 void delete_all_nodes(index_node_type* x)
1222 delete_all_nodes(index_node_type::from_impl(x->left()));
1223 delete_all_nodes(index_node_type::from_impl(x->right()));
1224 this->final_delete_node_(static_cast<final_node_type*>(x));
1227 bool in_place(value_param_type v,index_node_type* x,ordered_unique_tag)const
1232 index_node_type::decrement(y);
1233 if(!comp_(key(y->value()),key(v)))return false;
1237 index_node_type::increment(y);
1238 return y==header()||comp_(key(v),key(y->value()));
1242 value_param_type v,index_node_type* x,ordered_non_unique_tag)const
1247 index_node_type::decrement(y);
1248 if(comp_(key(v),key(y->value())))return false;
1252 index_node_type::increment(y);
1253 return y==header()||!comp_(key(y->value()),key(v));
1256 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
1257 void detach_iterators(index_node_type* x)
1259 iterator it=make_iterator(x);
1260 safe_mode::detach_equivalent_iterators(it);
1264 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
1265 std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
1267 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
1268 std::pair<final_node_type*,bool>p=
1269 this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
1270 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
1273 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
1274 iterator emplace_hint_impl(
1275 iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
1277 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
1278 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
1279 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
1280 std::pair<final_node_type*,bool>p=
1281 this->final_emplace_hint_(
1282 static_cast<final_node_type*>(position.get_node()),
1283 BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
1284 return make_iterator(p.first);
1287 template<typename LowerBounder,typename UpperBounder>
1288 std::pair<iterator,iterator>
1289 range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
1291 index_node_type* y=header();
1292 index_node_type* z=root();
1295 if(!lower(key(z->value()))){
1296 z=index_node_type::from_impl(z->right());
1298 else if(!upper(key(z->value()))){
1300 z=index_node_type::from_impl(z->left());
1303 return std::pair<iterator,iterator>(
1305 lower_range(index_node_type::from_impl(z->left()),z,lower)),
1307 upper_range(index_node_type::from_impl(z->right()),y,upper)));
1311 return std::pair<iterator,iterator>(make_iterator(y),make_iterator(y));
1314 template<typename LowerBounder,typename UpperBounder>
1315 std::pair<iterator,iterator>
1316 range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
1318 return std::pair<iterator,iterator>(
1320 make_iterator(upper_range(root(),header(),upper)));
1323 template<typename LowerBounder,typename UpperBounder>
1324 std::pair<iterator,iterator>
1325 range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
1327 return std::pair<iterator,iterator>(
1328 make_iterator(lower_range(root(),header(),lower)),
1332 template<typename LowerBounder,typename UpperBounder>
1333 std::pair<iterator,iterator>
1334 range(LowerBounder,UpperBounder,both_unbounded_tag)const
1336 return std::pair<iterator,iterator>(begin(),end());
1339 template<typename LowerBounder>
1340 index_node_type * lower_range(
1341 index_node_type* top,index_node_type* y,LowerBounder lower)const
1344 if(lower(key(top->value()))){
1346 top=index_node_type::from_impl(top->left());
1348 else top=index_node_type::from_impl(top->right());
1354 template<typename UpperBounder>
1355 index_node_type * upper_range(
1356 index_node_type* top,index_node_type* y,UpperBounder upper)const
1359 if(!upper(key(top->value()))){
1361 top=index_node_type::from_impl(top->left());
1363 else top=index_node_type::from_impl(top->right());
1369 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
1370 template<typename Archive>
1372 Archive& ar,const unsigned int version,const index_saver_type& sm,
1373 ordered_unique_tag)const
1375 super::save_(ar,version,sm);
1378 template<typename Archive>
1380 Archive& ar,const unsigned int version,const index_loader_type& lm,
1383 super::load_(ar,version,lm);
1386 template<typename Archive>
1388 Archive& ar,const unsigned int version,const index_saver_type& sm,
1389 ordered_non_unique_tag)const
1391 typedef duplicates_iterator<index_node_type,value_compare> dup_iterator;
1394 dup_iterator(begin().get_node(),end().get_node(),value_comp()),
1395 dup_iterator(end().get_node(),value_comp()),
1397 super::save_(ar,version,sm);
1400 template<typename Archive>
1402 Archive& ar,const unsigned int version,const index_loader_type& lm,
1403 ordered_non_unique_tag)
1407 &ordered_index_impl::rearranger,this,
1408 ::boost::arg<1>(),::boost::arg<2>()),
1410 super::load_(ar,version,lm);
1413 void rearranger(index_node_type* position,index_node_type *x)
1415 if(!position||comp_(key(position->value()),key(x->value()))){
1416 position=lower_bound(key(x->value())).get_node();
1418 else if(comp_(key(x->value()),key(position->value()))){
1419 /* inconsistent rearrangement */
1421 archive::archive_exception(
1422 archive::archive_exception::other_exception));
1424 else index_node_type::increment(position);
1427 node_impl_type::rebalance_for_extract(
1428 x->impl(),header()->parent(),header()->left(),header()->right());
1429 node_impl_type::restore(
1430 x->impl(),position->impl(),header()->impl());
1433 #endif /* serialization */
1435 protected: /* for the benefit of AugmentPolicy::augmented_interface */
1439 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
1440 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
1441 #pragma parse_mfunc_templ reset
1446 typename KeyFromValue,typename Compare,
1447 typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
1449 class ordered_index:
1450 public AugmentPolicy::template augmented_interface<
1452 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy
1456 typedef typename AugmentPolicy::template
1457 augmented_interface<
1459 KeyFromValue,Compare,
1460 SuperMeta,TagList,Category,AugmentPolicy
1464 typedef typename super::ctor_args_list ctor_args_list;
1465 typedef typename super::allocator_type allocator_type;
1466 typedef typename super::iterator iterator;
1468 /* construct/copy/destroy
1469 * Default and copy ctors are in the protected section as indices are
1470 * not supposed to be created on their own. No range ctor either.
1473 ordered_index& operator=(const ordered_index& x)
1475 this->final()=x.final();
1479 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1480 ordered_index& operator=(
1481 std::initializer_list<BOOST_DEDUCED_TYPENAME super::value_type> list)
1490 const ctor_args_list& args_list,const allocator_type& al):
1491 super(args_list,al){}
1493 ordered_index(const ordered_index& x):super(x){}
1495 ordered_index(const ordered_index& x,do_not_copy_elements_tag):
1496 super(x,do_not_copy_elements_tag()){}
1502 typename KeyFromValue1,typename Compare1,
1503 typename SuperMeta1,typename TagList1,typename Category1,
1504 typename AugmentPolicy1,
1505 typename KeyFromValue2,typename Compare2,
1506 typename SuperMeta2,typename TagList2,typename Category2,
1507 typename AugmentPolicy2
1510 const ordered_index<
1511 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1512 const ordered_index<
1513 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1515 return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
1519 typename KeyFromValue1,typename Compare1,
1520 typename SuperMeta1,typename TagList1,typename Category1,
1521 typename AugmentPolicy1,
1522 typename KeyFromValue2,typename Compare2,
1523 typename SuperMeta2,typename TagList2,typename Category2,
1524 typename AugmentPolicy2
1527 const ordered_index<
1528 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1529 const ordered_index<
1530 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1532 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
1536 typename KeyFromValue1,typename Compare1,
1537 typename SuperMeta1,typename TagList1,typename Category1,
1538 typename AugmentPolicy1,
1539 typename KeyFromValue2,typename Compare2,
1540 typename SuperMeta2,typename TagList2,typename Category2,
1541 typename AugmentPolicy2
1544 const ordered_index<
1545 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1546 const ordered_index<
1547 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1553 typename KeyFromValue1,typename Compare1,
1554 typename SuperMeta1,typename TagList1,typename Category1,
1555 typename AugmentPolicy1,
1556 typename KeyFromValue2,typename Compare2,
1557 typename SuperMeta2,typename TagList2,typename Category2,
1558 typename AugmentPolicy2
1561 const ordered_index<
1562 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1563 const ordered_index<
1564 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1570 typename KeyFromValue1,typename Compare1,
1571 typename SuperMeta1,typename TagList1,typename Category1,
1572 typename AugmentPolicy1,
1573 typename KeyFromValue2,typename Compare2,
1574 typename SuperMeta2,typename TagList2,typename Category2,
1575 typename AugmentPolicy2
1578 const ordered_index<
1579 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1580 const ordered_index<
1581 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1587 typename KeyFromValue1,typename Compare1,
1588 typename SuperMeta1,typename TagList1,typename Category1,
1589 typename AugmentPolicy1,
1590 typename KeyFromValue2,typename Compare2,
1591 typename SuperMeta2,typename TagList2,typename Category2,
1592 typename AugmentPolicy2
1595 const ordered_index<
1596 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1597 const ordered_index<
1598 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1603 /* specialized algorithms */
1606 typename KeyFromValue,typename Compare,
1607 typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
1611 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
1613 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y)
1618 } /* namespace multi_index::detail */
1620 } /* namespace multi_index */
1622 } /* namespace boost */
1624 /* Boost.Foreach compatibility */
1627 typename KeyFromValue,typename Compare,
1628 typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
1630 inline boost::mpl::true_* boost_foreach_is_noncopyable(
1631 boost::multi_index::detail::ordered_index<
1632 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>*&,
1633 boost_foreach_argument_dependent_lookup_hack)
1638 #undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
1639 #undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF