File indexing completed on 2025-01-18 09:42:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP
0037 #define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP
0038
0039 #if defined(_MSC_VER)
0040 #pragma once
0041 #endif
0042
0043 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
0044 #include <algorithm>
0045 #include <boost/call_traits.hpp>
0046 #include <boost/core/addressof.hpp>
0047 #include <boost/core/no_exceptions_support.hpp>
0048 #include <boost/core/ref.hpp>
0049 #include <boost/detail/workaround.hpp>
0050 #include <boost/iterator/reverse_iterator.hpp>
0051 #include <boost/move/core.hpp>
0052 #include <boost/move/utility_core.hpp>
0053 #include <boost/mpl/bool.hpp>
0054 #include <boost/mpl/if.hpp>
0055 #include <boost/mpl/push_front.hpp>
0056 #include <boost/multi_index/detail/access_specifier.hpp>
0057 #include <boost/multi_index/detail/adl_swap.hpp>
0058 #include <boost/multi_index/detail/allocator_traits.hpp>
0059 #include <boost/multi_index/detail/bidir_node_iterator.hpp>
0060 #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
0061 #include <boost/multi_index/detail/index_node_base.hpp>
0062 #include <boost/multi_index/detail/invalidate_iterators.hpp>
0063 #include <boost/multi_index/detail/modify_key_adaptor.hpp>
0064 #include <boost/multi_index/detail/node_handle.hpp>
0065 #include <boost/multi_index/detail/ord_index_node.hpp>
0066 #include <boost/multi_index/detail/ord_index_ops.hpp>
0067 #include <boost/multi_index/detail/safe_mode.hpp>
0068 #include <boost/multi_index/detail/scope_guard.hpp>
0069 #include <boost/multi_index/detail/unbounded.hpp>
0070 #include <boost/multi_index/detail/value_compare.hpp>
0071 #include <boost/multi_index/detail/vartempl_support.hpp>
0072 #include <boost/multi_index/detail/ord_index_impl_fwd.hpp>
0073 #include <boost/tuple/tuple.hpp>
0074 #include <boost/type_traits/is_same.hpp>
0075 #include <utility>
0076
0077 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0078 #include <initializer_list>
0079 #endif
0080
0081 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
0082 #include <boost/bind/bind.hpp>
0083 #include <boost/multi_index/detail/bad_archive_exception.hpp>
0084 #include <boost/multi_index/detail/duplicates_iterator.hpp>
0085 #include <boost/throw_exception.hpp>
0086 #endif
0087
0088 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
0089 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \
0090 detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
0091 detail::make_obj_guard(x,&ordered_index_impl::check_invariant_); \
0092 BOOST_JOIN(check_invariant_,__LINE__).touch();
0093 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \
0094 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this)
0095 #else
0096 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x)
0097 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
0098 #endif
0099
0100 namespace boost{
0101
0102 namespace multi_index{
0103
0104 namespace detail{
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115 struct ordered_unique_tag{};
0116 struct ordered_non_unique_tag{};
0117
0118 #if defined(BOOST_MSVC)
0119 #pragma warning(push)
0120 #pragma warning(disable:4355)
0121 #endif
0122
0123 template<
0124 typename KeyFromValue,typename Compare,
0125 typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
0126 >
0127 class ordered_index;
0128
0129 template<
0130 typename KeyFromValue,typename Compare,
0131 typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
0132 >
0133 class ordered_index_impl:
0134 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
0135 {
0136 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
0137 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
0138
0139
0140
0141
0142
0143 #pragma parse_mfunc_templ off
0144 #endif
0145
0146 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
0147
0148
0149 template <typename,typename,typename> friend class index_base;
0150 #endif
0151
0152 typedef typename SuperMeta::type super;
0153
0154 protected:
0155 typedef ordered_index_node<
0156 AugmentPolicy,typename super::index_node_type> index_node_type;
0157
0158 protected:
0159 typedef typename index_node_type::impl_type node_impl_type;
0160 typedef typename node_impl_type::pointer node_impl_pointer;
0161
0162 public:
0163
0164
0165 typedef typename KeyFromValue::result_type key_type;
0166 typedef typename index_node_type::value_type value_type;
0167 typedef KeyFromValue key_from_value;
0168 typedef Compare key_compare;
0169 typedef value_comparison<
0170 value_type,KeyFromValue,Compare> value_compare;
0171 typedef tuple<key_from_value,key_compare> ctor_args;
0172 typedef typename super::final_allocator_type allocator_type;
0173 typedef value_type& reference;
0174 typedef const value_type& const_reference;
0175
0176 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0177 typedef safe_mode::safe_iterator<
0178 bidir_node_iterator<index_node_type> > iterator;
0179 #else
0180 typedef bidir_node_iterator<index_node_type> iterator;
0181 #endif
0182
0183 typedef iterator const_iterator;
0184
0185 private:
0186 typedef allocator_traits<allocator_type> alloc_traits;
0187
0188 public:
0189 typedef typename alloc_traits::size_type size_type;
0190 typedef typename alloc_traits::difference_type difference_type;
0191 typedef typename alloc_traits::pointer pointer;
0192 typedef typename alloc_traits::const_pointer const_pointer;
0193 typedef typename
0194 boost::reverse_iterator<iterator> reverse_iterator;
0195 typedef typename
0196 boost::reverse_iterator<const_iterator> const_reverse_iterator;
0197 typedef typename super::final_node_handle_type node_type;
0198 typedef detail::insert_return_type<
0199 iterator,node_type> insert_return_type;
0200 typedef TagList tag_list;
0201
0202 protected:
0203 typedef typename super::final_node_type final_node_type;
0204 typedef tuples::cons<
0205 ctor_args,
0206 typename super::ctor_args_list> ctor_args_list;
0207 typedef typename mpl::push_front<
0208 typename super::index_type_list,
0209 ordered_index<
0210 KeyFromValue,Compare,
0211 SuperMeta,TagList,Category,AugmentPolicy
0212 > >::type index_type_list;
0213 typedef typename mpl::push_front<
0214 typename super::iterator_type_list,
0215 iterator>::type iterator_type_list;
0216 typedef typename mpl::push_front<
0217 typename super::const_iterator_type_list,
0218 const_iterator>::type const_iterator_type_list;
0219 typedef typename super::copy_map_type copy_map_type;
0220
0221 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
0222 typedef typename super::index_saver_type index_saver_type;
0223 typedef typename super::index_loader_type index_loader_type;
0224 #endif
0225
0226 protected:
0227 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0228 typedef safe_mode::safe_container<iterator> safe_container;
0229 #endif
0230
0231 typedef typename call_traits<
0232 value_type>::param_type value_param_type;
0233 typedef typename call_traits<
0234 key_type>::param_type key_param_type;
0235
0236
0237
0238 typedef std::pair<iterator,bool> pair_return_type;
0239
0240 public:
0241
0242
0243
0244
0245
0246
0247
0248 allocator_type get_allocator()const BOOST_NOEXCEPT
0249 {
0250 return this->final().get_allocator();
0251 }
0252
0253
0254
0255 iterator
0256 begin()BOOST_NOEXCEPT{return make_iterator(leftmost());}
0257 const_iterator
0258 begin()const BOOST_NOEXCEPT{return make_iterator(leftmost());}
0259 iterator
0260 end()BOOST_NOEXCEPT{return make_iterator(header());}
0261 const_iterator
0262 end()const BOOST_NOEXCEPT{return make_iterator(header());}
0263 reverse_iterator
0264 rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
0265 const_reverse_iterator
0266 rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
0267 reverse_iterator
0268 rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
0269 const_reverse_iterator
0270 rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
0271 const_iterator
0272 cbegin()const BOOST_NOEXCEPT{return begin();}
0273 const_iterator
0274 cend()const BOOST_NOEXCEPT{return end();}
0275 const_reverse_iterator
0276 crbegin()const BOOST_NOEXCEPT{return rbegin();}
0277 const_reverse_iterator
0278 crend()const BOOST_NOEXCEPT{return rend();}
0279
0280 iterator iterator_to(const value_type& x)
0281 {
0282 return make_iterator(
0283 node_from_value<index_node_type>(boost::addressof(x)));
0284 }
0285
0286 const_iterator iterator_to(const value_type& x)const
0287 {
0288 return make_iterator(
0289 node_from_value<index_node_type>(boost::addressof(x)));
0290 }
0291
0292
0293
0294 bool empty()const BOOST_NOEXCEPT{return this->final_empty_();}
0295 size_type size()const BOOST_NOEXCEPT{return this->final_size_();}
0296 size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();}
0297
0298
0299
0300 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
0301 pair_return_type,emplace,emplace_impl)
0302
0303 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
0304 iterator,emplace_hint,emplace_hint_impl,iterator,position)
0305
0306 std::pair<iterator,bool> insert(const value_type& x)
0307 {
0308 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0309 std::pair<final_node_type*,bool> p=this->final_insert_(x);
0310 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
0311 }
0312
0313 std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
0314 {
0315 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0316 std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
0317 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
0318 }
0319
0320 iterator insert(iterator position,const value_type& x)
0321 {
0322 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
0323 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
0324 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0325 std::pair<final_node_type*,bool> p=this->final_insert_(
0326 x,static_cast<final_node_type*>(position.get_node()));
0327 return make_iterator(p.first);
0328 }
0329
0330 iterator insert(iterator position,BOOST_RV_REF(value_type) x)
0331 {
0332 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
0333 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
0334 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0335 std::pair<final_node_type*,bool> p=this->final_insert_rv_(
0336 x,static_cast<final_node_type*>(position.get_node()));
0337 return make_iterator(p.first);
0338 }
0339
0340 template<typename InputIterator>
0341 void insert(InputIterator first,InputIterator last)
0342 {
0343 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0344 for(;first!=last;++first)this->final_insert_ref_(*first);
0345 }
0346
0347 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0348 void insert(std::initializer_list<value_type> list)
0349 {
0350 insert(list.begin(),list.end());
0351 }
0352 #endif
0353
0354 insert_return_type insert(BOOST_RV_REF(node_type) nh)
0355 {
0356 if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
0357 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0358 std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh);
0359 return insert_return_type(make_iterator(p.first),p.second,boost::move(nh));
0360 }
0361
0362 iterator insert(const_iterator position,BOOST_RV_REF(node_type) nh)
0363 {
0364 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
0365 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
0366 if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
0367 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0368 std::pair<final_node_type*,bool> p=this->final_insert_nh_(
0369 nh,static_cast<final_node_type*>(position.get_node()));
0370 return make_iterator(p.first);
0371 }
0372
0373 node_type extract(const_iterator position)
0374 {
0375 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
0376 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
0377 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
0378 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0379 return this->final_extract_(
0380 static_cast<final_node_type*>(position.get_node()));
0381 }
0382
0383 node_type extract(key_param_type x)
0384 {
0385 iterator position=lower_bound(x);
0386 if(position==end()||comp_(x,key(*position)))return node_type();
0387 else return extract(position);
0388 }
0389
0390 iterator erase(iterator position)
0391 {
0392 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
0393 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
0394 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
0395 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0396 this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
0397 return position;
0398 }
0399
0400 size_type erase(key_param_type x)
0401 {
0402 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0403 std::pair<iterator,iterator> p=equal_range(x);
0404 size_type s=0;
0405 while(p.first!=p.second){
0406 p.first=erase(p.first);
0407 ++s;
0408 }
0409 return s;
0410 }
0411
0412 iterator erase(iterator first,iterator last)
0413 {
0414 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
0415 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
0416 BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
0417 BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
0418 BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
0419 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0420 while(first!=last){
0421 first=erase(first);
0422 }
0423 return first;
0424 }
0425
0426 bool replace(iterator position,const value_type& x)
0427 {
0428 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
0429 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
0430 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
0431 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0432 return this->final_replace_(
0433 x,static_cast<final_node_type*>(position.get_node()));
0434 }
0435
0436 bool replace(iterator position,BOOST_RV_REF(value_type) x)
0437 {
0438 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
0439 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
0440 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
0441 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0442 return this->final_replace_rv_(
0443 x,static_cast<final_node_type*>(position.get_node()));
0444 }
0445
0446 template<typename Modifier>
0447 bool modify(iterator position,Modifier mod)
0448 {
0449 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
0450 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
0451 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
0452 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0453
0454 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0455
0456
0457
0458
0459
0460 position.detach();
0461 #endif
0462
0463 return this->final_modify_(
0464 mod,static_cast<final_node_type*>(position.get_node()));
0465 }
0466
0467 template<typename Modifier,typename Rollback>
0468 bool modify(iterator position,Modifier mod,Rollback back_)
0469 {
0470 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
0471 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
0472 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
0473 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0474
0475 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0476
0477
0478
0479
0480
0481 position.detach();
0482 #endif
0483
0484 return this->final_modify_(
0485 mod,back_,static_cast<final_node_type*>(position.get_node()));
0486 }
0487
0488 template<typename Modifier>
0489 bool modify_key(iterator position,Modifier mod)
0490 {
0491 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
0492 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
0493 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
0494 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0495 return modify(
0496 position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key));
0497 }
0498
0499 template<typename Modifier,typename Rollback>
0500 bool modify_key(iterator position,Modifier mod,Rollback back_)
0501 {
0502 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
0503 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
0504 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
0505 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0506 return modify(
0507 position,
0508 modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key),
0509 modify_key_adaptor<Rollback,value_type,KeyFromValue>(back_,key));
0510 }
0511
0512 void swap(
0513 ordered_index<
0514 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
0515 {
0516 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0517 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x);
0518 this->final_swap_(x.final());
0519 }
0520
0521 void clear()BOOST_NOEXCEPT
0522 {
0523 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0524 this->final_clear_();
0525 }
0526
0527 template<typename Index>
0528 BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
0529 merge(Index& x)
0530 {
0531 merge(x,x.begin(),x.end());
0532 }
0533
0534 template<typename Index>
0535 BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
0536 merge(BOOST_RV_REF(Index) x){merge(static_cast<Index&>(x));}
0537
0538 template<typename Index>
0539 BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
0540 ordered_index_impl,Index,pair_return_type)
0541 merge(Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
0542 {
0543 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
0544 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
0545 BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
0546 BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
0547 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0548 if(x.end().get_node()==this->header()){
0549 return std::pair<iterator,bool>(
0550 make_iterator(static_cast<final_node_type*>(i.get_node())),true);
0551 }
0552 else{
0553 std::pair<final_node_type*,bool> p=this->final_transfer_(
0554 x,static_cast<final_node_type*>(i.get_node()));
0555 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
0556 }
0557 }
0558
0559 template<typename Index>
0560 BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
0561 ordered_index_impl,Index,pair_return_type)
0562 merge(BOOST_RV_REF(Index) x,BOOST_DEDUCED_TYPENAME Index::iterator i)
0563 {
0564 return merge(static_cast<Index&>(x),i);
0565 }
0566
0567 template<typename Index>
0568 BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
0569 merge(
0570 Index& x,
0571 BOOST_DEDUCED_TYPENAME Index::iterator first,
0572 BOOST_DEDUCED_TYPENAME Index::iterator last)
0573 {
0574 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
0575 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
0576 BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x);
0577 BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
0578 BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
0579 BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
0580 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
0581 if(x.end().get_node()!=this->header()){
0582 this->final_transfer_range_(x,first,last);
0583 }
0584 }
0585
0586 template<typename Index>
0587 BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
0588 merge(
0589 BOOST_RV_REF(Index) x,
0590 BOOST_DEDUCED_TYPENAME Index::iterator first,
0591 BOOST_DEDUCED_TYPENAME Index::iterator last)
0592 {
0593 merge(static_cast<Index&>(x),first,last);
0594 }
0595
0596
0597
0598 key_from_value key_extractor()const{return key;}
0599 key_compare key_comp()const{return comp_;}
0600 value_compare value_comp()const{return value_compare(key,comp_);}
0601
0602
0603
0604
0605
0606
0607
0608 template<typename CompatibleKey>
0609 iterator find(const CompatibleKey& x)const
0610 {
0611 return make_iterator(ordered_index_find(root(),header(),key,x,comp_));
0612 }
0613
0614 template<typename CompatibleKey,typename CompatibleCompare>
0615 iterator find(
0616 const CompatibleKey& x,const CompatibleCompare& comp)const
0617 {
0618 return make_iterator(ordered_index_find(root(),header(),key,x,comp));
0619 }
0620
0621 template<typename CompatibleKey>
0622 size_type count(const CompatibleKey& x)const
0623 {
0624 return count(x,comp_);
0625 }
0626
0627 template<typename CompatibleKey,typename CompatibleCompare>
0628 size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const
0629 {
0630 std::pair<iterator,iterator> p=equal_range(x,comp);
0631 size_type n=static_cast<size_type>(std::distance(p.first,p.second));
0632 return n;
0633 }
0634
0635 template<typename CompatibleKey>
0636 bool contains(const CompatibleKey& x)const
0637 {
0638 return contains(x,comp_);
0639 }
0640
0641 template<typename CompatibleKey,typename CompatibleCompare>
0642 bool contains(
0643 const CompatibleKey& x,const CompatibleCompare& comp)const
0644 {
0645 return find(x,comp)!=end();
0646 }
0647
0648 template<typename CompatibleKey>
0649 iterator lower_bound(const CompatibleKey& x)const
0650 {
0651 return make_iterator(
0652 ordered_index_lower_bound(root(),header(),key,x,comp_));
0653 }
0654
0655 template<typename CompatibleKey,typename CompatibleCompare>
0656 iterator lower_bound(
0657 const CompatibleKey& x,const CompatibleCompare& comp)const
0658 {
0659 return make_iterator(
0660 ordered_index_lower_bound(root(),header(),key,x,comp));
0661 }
0662
0663 template<typename CompatibleKey>
0664 iterator upper_bound(const CompatibleKey& x)const
0665 {
0666 return make_iterator(
0667 ordered_index_upper_bound(root(),header(),key,x,comp_));
0668 }
0669
0670 template<typename CompatibleKey,typename CompatibleCompare>
0671 iterator upper_bound(
0672 const CompatibleKey& x,const CompatibleCompare& comp)const
0673 {
0674 return make_iterator(
0675 ordered_index_upper_bound(root(),header(),key,x,comp));
0676 }
0677
0678 template<typename CompatibleKey>
0679 std::pair<iterator,iterator> equal_range(
0680 const CompatibleKey& x)const
0681 {
0682 std::pair<index_node_type*,index_node_type*> p=
0683 ordered_index_equal_range(root(),header(),key,x,comp_);
0684 return std::pair<iterator,iterator>(
0685 make_iterator(p.first),make_iterator(p.second));
0686 }
0687
0688 template<typename CompatibleKey,typename CompatibleCompare>
0689 std::pair<iterator,iterator> equal_range(
0690 const CompatibleKey& x,const CompatibleCompare& comp)const
0691 {
0692 std::pair<index_node_type*,index_node_type*> p=
0693 ordered_index_equal_range(root(),header(),key,x,comp);
0694 return std::pair<iterator,iterator>(
0695 make_iterator(p.first),make_iterator(p.second));
0696 }
0697
0698
0699
0700 template<typename LowerBounder,typename UpperBounder>
0701 std::pair<iterator,iterator>
0702 range(LowerBounder lower,UpperBounder upper)const
0703 {
0704 typedef typename mpl::if_<
0705 is_same<LowerBounder,unbounded_type>,
0706 BOOST_DEDUCED_TYPENAME mpl::if_<
0707 is_same<UpperBounder,unbounded_type>,
0708 both_unbounded_tag,
0709 lower_unbounded_tag
0710 >::type,
0711 BOOST_DEDUCED_TYPENAME mpl::if_<
0712 is_same<UpperBounder,unbounded_type>,
0713 upper_unbounded_tag,
0714 none_unbounded_tag
0715 >::type
0716 >::type dispatch;
0717
0718 return range(lower,upper,dispatch());
0719 }
0720
0721 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
0722 ordered_index_impl(const ctor_args_list& args_list,const allocator_type& al):
0723 super(args_list.get_tail(),al),
0724 key(tuples::get<0>(args_list.get_head())),
0725 comp_(tuples::get<1>(args_list.get_head()))
0726
0727 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0728 ,safe(*this)
0729 #endif
0730
0731 {
0732 empty_initialize();
0733 }
0734
0735 ordered_index_impl(
0736 const ordered_index_impl<
0737 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x):
0738 super(x),
0739 key(x.key),
0740 comp_(x.comp_)
0741
0742 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0743 ,safe(*this)
0744 #endif
0745
0746 {
0747
0748
0749
0750 }
0751
0752 ordered_index_impl(
0753 const ordered_index_impl<
0754 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
0755 do_not_copy_elements_tag):
0756 super(x,do_not_copy_elements_tag()),
0757 key(x.key),
0758 comp_(x.comp_)
0759
0760 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0761 ,safe(*this)
0762 #endif
0763
0764 {
0765 empty_initialize();
0766 }
0767
0768 ~ordered_index_impl()
0769 {
0770
0771 }
0772
0773 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0774 iterator make_iterator(index_node_type* node)
0775 {return iterator(node,&safe);}
0776 const_iterator make_iterator(index_node_type* node)const
0777 {return const_iterator(node,const_cast<safe_container*>(&safe));}
0778 #else
0779 iterator make_iterator(index_node_type* node){return iterator(node);}
0780 const_iterator make_iterator(index_node_type* node)const
0781 {return const_iterator(node);}
0782 #endif
0783
0784 void copy_(
0785 const ordered_index_impl<
0786 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
0787 const copy_map_type& map)
0788 {
0789 if(!x.root()){
0790 empty_initialize();
0791 }
0792 else{
0793 header()->color()=x.header()->color();
0794 AugmentPolicy::copy(x.header()->impl(),header()->impl());
0795
0796 index_node_type* root_cpy=map.find(
0797 static_cast<final_node_type*>(x.root()));
0798 header()->parent()=root_cpy->impl();
0799
0800 index_node_type* leftmost_cpy=map.find(
0801 static_cast<final_node_type*>(x.leftmost()));
0802 header()->left()=leftmost_cpy->impl();
0803
0804 index_node_type* rightmost_cpy=map.find(
0805 static_cast<final_node_type*>(x.rightmost()));
0806 header()->right()=rightmost_cpy->impl();
0807
0808 typedef typename copy_map_type::const_iterator copy_map_iterator;
0809 for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){
0810 index_node_type* org=it->first;
0811 index_node_type* cpy=it->second;
0812
0813 cpy->color()=org->color();
0814 AugmentPolicy::copy(org->impl(),cpy->impl());
0815
0816 node_impl_pointer parent_org=org->parent();
0817 if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0);
0818 else{
0819 index_node_type* parent_cpy=map.find(
0820 static_cast<final_node_type*>(
0821 index_node_type::from_impl(parent_org)));
0822 cpy->parent()=parent_cpy->impl();
0823 if(parent_org->left()==org->impl()){
0824 parent_cpy->left()=cpy->impl();
0825 }
0826 else if(parent_org->right()==org->impl()){
0827
0828 parent_cpy->right()=cpy->impl();
0829 }
0830 }
0831
0832 if(org->left()==node_impl_pointer(0))
0833 cpy->left()=node_impl_pointer(0);
0834 if(org->right()==node_impl_pointer(0))
0835 cpy->right()=node_impl_pointer(0);
0836 }
0837 }
0838
0839 super::copy_(x,map);
0840 }
0841
0842 template<typename Variant>
0843 final_node_type* insert_(
0844 value_param_type v,final_node_type*& x,Variant variant)
0845 {
0846 link_info inf;
0847 if(!link_point(key(v),inf,Category())){
0848 return static_cast<final_node_type*>(
0849 index_node_type::from_impl(inf.pos));
0850 }
0851
0852 final_node_type* res=super::insert_(v,x,variant);
0853 if(res==x){
0854 node_impl_type::link(
0855 static_cast<index_node_type*>(x)->impl(),
0856 inf.side,inf.pos,header()->impl());
0857 }
0858 return res;
0859 }
0860
0861 template<typename Variant>
0862 final_node_type* insert_(
0863 value_param_type v,index_node_type* position,
0864 final_node_type*& x,Variant variant)
0865 {
0866 link_info inf;
0867 if(!hinted_link_point(key(v),position,inf,Category())){
0868 return static_cast<final_node_type*>(
0869 index_node_type::from_impl(inf.pos));
0870 }
0871
0872 final_node_type* res=super::insert_(v,position,x,variant);
0873 if(res==x){
0874 node_impl_type::link(
0875 static_cast<index_node_type*>(x)->impl(),
0876 inf.side,inf.pos,header()->impl());
0877 }
0878 return res;
0879 }
0880
0881 template<typename Dst>
0882 void extract_(index_node_type* x,Dst dst)
0883 {
0884 node_impl_type::rebalance_for_extract(
0885 x->impl(),header()->parent(),header()->left(),header()->right());
0886 super::extract_(x,dst.next());
0887
0888 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0889 transfer_iterators(dst.get(),x);
0890 #endif
0891 }
0892
0893 void delete_all_nodes_()
0894 {
0895 delete_all_nodes(root());
0896 }
0897
0898 void clear_()
0899 {
0900 super::clear_();
0901 empty_initialize();
0902
0903 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0904 safe.detach_dereferenceable_iterators();
0905 #endif
0906 }
0907
0908 template<typename BoolConstant>
0909 void swap_(
0910 ordered_index_impl<
0911 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
0912 BoolConstant swap_allocators)
0913 {
0914 adl_swap(key,x.key);
0915 adl_swap(comp_,x.comp_);
0916
0917 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0918 safe.swap(x.safe);
0919 #endif
0920
0921 super::swap_(x,swap_allocators);
0922 }
0923
0924 void swap_elements_(
0925 ordered_index_impl<
0926 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
0927 {
0928 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0929 safe.swap(x.safe);
0930 #endif
0931
0932 super::swap_elements_(x);
0933 }
0934
0935 template<typename Variant>
0936 bool replace_(value_param_type v,index_node_type* x,Variant variant)
0937 {
0938 if(in_place(v,x,Category())){
0939 return super::replace_(v,x,variant);
0940 }
0941
0942 index_node_type* next=x;
0943 index_node_type::increment(next);
0944
0945 node_impl_type::rebalance_for_extract(
0946 x->impl(),header()->parent(),header()->left(),header()->right());
0947
0948 BOOST_TRY{
0949 link_info inf;
0950 if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){
0951 node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
0952 return true;
0953 }
0954 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
0955 return false;
0956 }
0957 BOOST_CATCH(...){
0958 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
0959 BOOST_RETHROW;
0960 }
0961 BOOST_CATCH_END
0962 }
0963
0964 bool modify_(index_node_type* x)
0965 {
0966 bool b;
0967 BOOST_TRY{
0968 b=in_place(x->value(),x,Category());
0969 }
0970 BOOST_CATCH(...){
0971 extract_(x,invalidate_iterators());
0972 BOOST_RETHROW;
0973 }
0974 BOOST_CATCH_END
0975 if(!b){
0976 node_impl_type::rebalance_for_extract(
0977 x->impl(),header()->parent(),header()->left(),header()->right());
0978 BOOST_TRY{
0979 link_info inf;
0980 if(!link_point(key(x->value()),inf,Category())){
0981 super::extract_(x,invalidate_iterators());
0982
0983 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0984 detach_iterators(x);
0985 #endif
0986 return false;
0987 }
0988 node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
0989 }
0990 BOOST_CATCH(...){
0991 super::extract_(x,invalidate_iterators());
0992
0993 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
0994 detach_iterators(x);
0995 #endif
0996
0997 BOOST_RETHROW;
0998 }
0999 BOOST_CATCH_END
1000 }
1001
1002 BOOST_TRY{
1003 if(!super::modify_(x)){
1004 node_impl_type::rebalance_for_extract(
1005 x->impl(),header()->parent(),header()->left(),header()->right());
1006
1007 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
1008 detach_iterators(x);
1009 #endif
1010
1011 return false;
1012 }
1013 else return true;
1014 }
1015 BOOST_CATCH(...){
1016 node_impl_type::rebalance_for_extract(
1017 x->impl(),header()->parent(),header()->left(),header()->right());
1018
1019 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
1020 detach_iterators(x);
1021 #endif
1022
1023 BOOST_RETHROW;
1024 }
1025 BOOST_CATCH_END
1026 }
1027
1028 bool modify_rollback_(index_node_type* x)
1029 {
1030 if(in_place(x->value(),x,Category())){
1031 return super::modify_rollback_(x);
1032 }
1033
1034 index_node_type* next=x;
1035 index_node_type::increment(next);
1036
1037 node_impl_type::rebalance_for_extract(
1038 x->impl(),header()->parent(),header()->left(),header()->right());
1039
1040 BOOST_TRY{
1041 link_info inf;
1042 if(link_point(key(x->value()),inf,Category())&&
1043 super::modify_rollback_(x)){
1044 node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
1045 return true;
1046 }
1047 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
1048 return false;
1049 }
1050 BOOST_CATCH(...){
1051 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
1052 BOOST_RETHROW;
1053 }
1054 BOOST_CATCH_END
1055 }
1056
1057 bool check_rollback_(index_node_type* x)const
1058 {
1059 return in_place(x->value(),x,Category())&&super::check_rollback_(x);
1060 }
1061
1062 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
1063
1064
1065 template<typename Archive>
1066 void save_(
1067 Archive& ar,const unsigned int version,const index_saver_type& sm)const
1068 {
1069 save_(ar,version,sm,Category());
1070 }
1071
1072 template<typename Archive>
1073 void load_(Archive& ar,const unsigned int version,const index_loader_type& lm)
1074 {
1075 load_(ar,version,lm,Category());
1076 }
1077 #endif
1078
1079 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
1080
1081
1082 bool invariant_()const
1083 {
1084 if(size()==0||begin()==end()){
1085 if(size()!=0||begin()!=end()||
1086 header()->left()!=header()->impl()||
1087 header()->right()!=header()->impl())return false;
1088 }
1089 else{
1090 if((size_type)std::distance(begin(),end())!=size())return false;
1091
1092 std::size_t len=node_impl_type::black_count(
1093 leftmost()->impl(),root()->impl());
1094 for(const_iterator it=begin(),it_end=end();it!=it_end;++it){
1095 index_node_type* x=it.get_node();
1096 index_node_type* left_x=index_node_type::from_impl(x->left());
1097 index_node_type* right_x=index_node_type::from_impl(x->right());
1098
1099 if(x->color()==red){
1100 if((left_x&&left_x->color()==red)||
1101 (right_x&&right_x->color()==red))return false;
1102 }
1103 if(left_x&&comp_(key(x->value()),key(left_x->value())))return false;
1104 if(right_x&&comp_(key(right_x->value()),key(x->value())))return false;
1105 if(!left_x&&!right_x&&
1106 node_impl_type::black_count(x->impl(),root()->impl())!=len)
1107 return false;
1108 if(!AugmentPolicy::invariant(x->impl()))return false;
1109 }
1110
1111 if(leftmost()->impl()!=node_impl_type::minimum(root()->impl()))
1112 return false;
1113 if(rightmost()->impl()!=node_impl_type::maximum(root()->impl()))
1114 return false;
1115 }
1116
1117 return super::invariant_();
1118 }
1119
1120
1121
1122
1123
1124
1125
1126 void check_invariant_()const{this->final_check_invariant_();}
1127 #endif
1128
1129 protected:
1130 index_node_type* header()const
1131 {return this->final_header();}
1132 index_node_type* root()const
1133 {return index_node_type::from_impl(header()->parent());}
1134 index_node_type* leftmost()const
1135 {return index_node_type::from_impl(header()->left());}
1136 index_node_type* rightmost()const
1137 {return index_node_type::from_impl(header()->right());}
1138
1139 private:
1140 void empty_initialize()
1141 {
1142 header()->color()=red;
1143
1144
1145 header()->parent()=node_impl_pointer(0);
1146 header()->left()=header()->impl();
1147 header()->right()=header()->impl();
1148 }
1149
1150 struct link_info
1151 {
1152
1153 link_info():side(to_left){}
1154
1155 ordered_index_side side;
1156 node_impl_pointer pos;
1157 };
1158
1159 bool link_point(key_param_type k,link_info& inf,ordered_unique_tag)
1160 {
1161 index_node_type* y=header();
1162 index_node_type* x=root();
1163 bool c=true;
1164 while(x){
1165 y=x;
1166 c=comp_(k,key(x->value()));
1167 x=index_node_type::from_impl(c?x->left():x->right());
1168 }
1169 index_node_type* yy=y;
1170 if(c){
1171 if(yy==leftmost()){
1172 inf.side=to_left;
1173 inf.pos=y->impl();
1174 return true;
1175 }
1176 else index_node_type::decrement(yy);
1177 }
1178
1179 if(comp_(key(yy->value()),k)){
1180 inf.side=c?to_left:to_right;
1181 inf.pos=y->impl();
1182 return true;
1183 }
1184 else{
1185 inf.pos=yy->impl();
1186 return false;
1187 }
1188 }
1189
1190 bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
1191 {
1192 index_node_type* y=header();
1193 index_node_type* x=root();
1194 bool c=true;
1195 while (x){
1196 y=x;
1197 c=comp_(k,key(x->value()));
1198 x=index_node_type::from_impl(c?x->left():x->right());
1199 }
1200 inf.side=c?to_left:to_right;
1201 inf.pos=y->impl();
1202 return true;
1203 }
1204
1205 bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
1206 {
1207 index_node_type* y=header();
1208 index_node_type* x=root();
1209 bool c=false;
1210 while (x){
1211 y=x;
1212 c=comp_(key(x->value()),k);
1213 x=index_node_type::from_impl(c?x->right():x->left());
1214 }
1215 inf.side=c?to_right:to_left;
1216 inf.pos=y->impl();
1217 return true;
1218 }
1219
1220 bool hinted_link_point(
1221 key_param_type k,index_node_type* position,
1222 link_info& inf,ordered_unique_tag)
1223 {
1224 if(position->impl()==header()->left()){
1225 if(size()>0&&comp_(k,key(position->value()))){
1226 inf.side=to_left;
1227 inf.pos=position->impl();
1228 return true;
1229 }
1230 else return link_point(k,inf,ordered_unique_tag());
1231 }
1232 else if(position==header()){
1233 if(comp_(key(rightmost()->value()),k)){
1234 inf.side=to_right;
1235 inf.pos=rightmost()->impl();
1236 return true;
1237 }
1238 else return link_point(k,inf,ordered_unique_tag());
1239 }
1240 else{
1241 index_node_type* before=position;
1242 index_node_type::decrement(before);
1243 if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){
1244 if(before->right()==node_impl_pointer(0)){
1245 inf.side=to_right;
1246 inf.pos=before->impl();
1247 return true;
1248 }
1249 else{
1250 inf.side=to_left;
1251 inf.pos=position->impl();
1252 return true;
1253 }
1254 }
1255 else return link_point(k,inf,ordered_unique_tag());
1256 }
1257 }
1258
1259 bool hinted_link_point(
1260 key_param_type k,index_node_type* position,
1261 link_info& inf,ordered_non_unique_tag)
1262 {
1263 if(position->impl()==header()->left()){
1264 if(size()>0&&!comp_(key(position->value()),k)){
1265 inf.side=to_left;
1266 inf.pos=position->impl();
1267 return true;
1268 }
1269 else return lower_link_point(k,inf,ordered_non_unique_tag());
1270 }
1271 else if(position==header()){
1272 if(!comp_(k,key(rightmost()->value()))){
1273 inf.side=to_right;
1274 inf.pos=rightmost()->impl();
1275 return true;
1276 }
1277 else return link_point(k,inf,ordered_non_unique_tag());
1278 }
1279 else{
1280 index_node_type* before=position;
1281 index_node_type::decrement(before);
1282 if(!comp_(k,key(before->value()))){
1283 if(!comp_(key(position->value()),k)){
1284 if(before->right()==node_impl_pointer(0)){
1285 inf.side=to_right;
1286 inf.pos=before->impl();
1287 return true;
1288 }
1289 else{
1290 inf.side=to_left;
1291 inf.pos=position->impl();
1292 return true;
1293 }
1294 }
1295 else return lower_link_point(k,inf,ordered_non_unique_tag());
1296 }
1297 else return link_point(k,inf,ordered_non_unique_tag());
1298 }
1299 }
1300
1301 void delete_all_nodes(index_node_type* x)
1302 {
1303 if(!x)return;
1304
1305 delete_all_nodes(index_node_type::from_impl(x->left()));
1306 delete_all_nodes(index_node_type::from_impl(x->right()));
1307 this->final_delete_node_(static_cast<final_node_type*>(x));
1308 }
1309
1310 bool in_place(value_param_type v,index_node_type* x,ordered_unique_tag)const
1311 {
1312 index_node_type* y;
1313 if(x!=leftmost()){
1314 y=x;
1315 index_node_type::decrement(y);
1316 if(!comp_(key(y->value()),key(v)))return false;
1317 }
1318
1319 y=x;
1320 index_node_type::increment(y);
1321 return y==header()||comp_(key(v),key(y->value()));
1322 }
1323
1324 bool in_place(
1325 value_param_type v,index_node_type* x,ordered_non_unique_tag)const
1326 {
1327 index_node_type* y;
1328 if(x!=leftmost()){
1329 y=x;
1330 index_node_type::decrement(y);
1331 if(comp_(key(v),key(y->value())))return false;
1332 }
1333
1334 y=x;
1335 index_node_type::increment(y);
1336 return y==header()||!comp_(key(y->value()),key(v));
1337 }
1338
1339 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
1340 void detach_iterators(index_node_type* x)
1341 {
1342 iterator it=make_iterator(x);
1343 safe_mode::detach_equivalent_iterators(it);
1344 }
1345
1346 template<typename Dst>
1347 void transfer_iterators(Dst& dst,index_node_type* x)
1348 {
1349 iterator it=make_iterator(x);
1350 safe_mode::transfer_equivalent_iterators(dst,it);
1351 }
1352 #endif
1353
1354 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
1355 std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
1356 {
1357 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
1358 std::pair<final_node_type*,bool>p=
1359 this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
1360 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
1361 }
1362
1363 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
1364 iterator emplace_hint_impl(
1365 iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
1366 {
1367 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
1368 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
1369 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
1370 std::pair<final_node_type*,bool>p=
1371 this->final_emplace_hint_(
1372 static_cast<final_node_type*>(position.get_node()),
1373 BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
1374 return make_iterator(p.first);
1375 }
1376
1377 template<typename LowerBounder,typename UpperBounder>
1378 std::pair<iterator,iterator>
1379 range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
1380 {
1381 index_node_type* y=header();
1382 index_node_type* z=root();
1383
1384 while(z){
1385 if(!lower(key(z->value()))){
1386 z=index_node_type::from_impl(z->right());
1387 }
1388 else if(!upper(key(z->value()))){
1389 y=z;
1390 z=index_node_type::from_impl(z->left());
1391 }
1392 else{
1393 return std::pair<iterator,iterator>(
1394 make_iterator(
1395 lower_range(index_node_type::from_impl(z->left()),z,lower)),
1396 make_iterator(
1397 upper_range(index_node_type::from_impl(z->right()),y,upper)));
1398 }
1399 }
1400
1401 return std::pair<iterator,iterator>(make_iterator(y),make_iterator(y));
1402 }
1403
1404 template<typename LowerBounder,typename UpperBounder>
1405 std::pair<iterator,iterator>
1406 range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
1407 {
1408 return std::pair<iterator,iterator>(
1409 begin(),
1410 make_iterator(upper_range(root(),header(),upper)));
1411 }
1412
1413 template<typename LowerBounder,typename UpperBounder>
1414 std::pair<iterator,iterator>
1415 range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
1416 {
1417 return std::pair<iterator,iterator>(
1418 make_iterator(lower_range(root(),header(),lower)),
1419 end());
1420 }
1421
1422 template<typename LowerBounder,typename UpperBounder>
1423 std::pair<iterator,iterator>
1424 range(LowerBounder,UpperBounder,both_unbounded_tag)const
1425 {
1426 return std::pair<iterator,iterator>(begin(),end());
1427 }
1428
1429 template<typename LowerBounder>
1430 index_node_type * lower_range(
1431 index_node_type* top,index_node_type* y,LowerBounder lower)const
1432 {
1433 while(top){
1434 if(lower(key(top->value()))){
1435 y=top;
1436 top=index_node_type::from_impl(top->left());
1437 }
1438 else top=index_node_type::from_impl(top->right());
1439 }
1440
1441 return y;
1442 }
1443
1444 template<typename UpperBounder>
1445 index_node_type * upper_range(
1446 index_node_type* top,index_node_type* y,UpperBounder upper)const
1447 {
1448 while(top){
1449 if(!upper(key(top->value()))){
1450 y=top;
1451 top=index_node_type::from_impl(top->left());
1452 }
1453 else top=index_node_type::from_impl(top->right());
1454 }
1455
1456 return y;
1457 }
1458
1459 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
1460 template<typename Archive>
1461 void save_(
1462 Archive& ar,const unsigned int version,const index_saver_type& sm,
1463 ordered_unique_tag)const
1464 {
1465 super::save_(ar,version,sm);
1466 }
1467
1468 template<typename Archive>
1469 void load_(
1470 Archive& ar,const unsigned int version,const index_loader_type& lm,
1471 ordered_unique_tag)
1472 {
1473 super::load_(ar,version,lm);
1474 }
1475
1476 template<typename Archive>
1477 void save_(
1478 Archive& ar,const unsigned int version,const index_saver_type& sm,
1479 ordered_non_unique_tag)const
1480 {
1481 typedef duplicates_iterator<index_node_type,value_compare> dup_iterator;
1482
1483 sm.save(
1484 dup_iterator(begin().get_node(),end().get_node(),value_comp()),
1485 dup_iterator(end().get_node(),value_comp()),
1486 ar,version);
1487 super::save_(ar,version,sm);
1488 }
1489
1490 template<typename Archive>
1491 void load_(
1492 Archive& ar,const unsigned int version,const index_loader_type& lm,
1493 ordered_non_unique_tag)
1494 {
1495 lm.load(
1496 ::boost::bind(
1497 &ordered_index_impl::rearranger,this,
1498 ::boost::arg<1>(),::boost::arg<2>()),
1499 ar,version);
1500 super::load_(ar,version,lm);
1501 }
1502
1503 void rearranger(index_node_type* position,index_node_type *x)
1504 {
1505 if(!position||comp_(key(position->value()),key(x->value()))){
1506 position=lower_bound(key(x->value())).get_node();
1507 }
1508 else if(comp_(key(x->value()),key(position->value()))){
1509
1510 throw_exception(bad_archive_exception());
1511 }
1512 else index_node_type::increment(position);
1513
1514 if(position!=x){
1515 node_impl_type::rebalance_for_extract(
1516 x->impl(),header()->parent(),header()->left(),header()->right());
1517 node_impl_type::restore(
1518 x->impl(),position->impl(),header()->impl());
1519 }
1520 }
1521 #endif
1522
1523 protected:
1524 key_from_value key;
1525 key_compare comp_;
1526
1527 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
1528 safe_container safe;
1529 #endif
1530
1531 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
1532 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
1533 #pragma parse_mfunc_templ reset
1534 #endif
1535 };
1536
1537 template<
1538 typename KeyFromValue,typename Compare,
1539 typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
1540 >
1541 class ordered_index:
1542 public AugmentPolicy::template augmented_interface<
1543 ordered_index_impl<
1544 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy
1545 >
1546 >::type
1547 {
1548 typedef typename AugmentPolicy::template
1549 augmented_interface<
1550 ordered_index_impl<
1551 KeyFromValue,Compare,
1552 SuperMeta,TagList,Category,AugmentPolicy
1553 >
1554 >::type super;
1555 public:
1556 typedef typename super::ctor_args_list ctor_args_list;
1557 typedef typename super::allocator_type allocator_type;
1558 typedef typename super::iterator iterator;
1559
1560
1561
1562
1563
1564
1565 ordered_index& operator=(const ordered_index& x)
1566 {
1567 this->final()=x.final();
1568 return *this;
1569 }
1570
1571 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1572 ordered_index& operator=(
1573 std::initializer_list<BOOST_DEDUCED_TYPENAME super::value_type> list)
1574 {
1575 this->final()=list;
1576 return *this;
1577 }
1578 #endif
1579
1580 protected:
1581 ordered_index(
1582 const ctor_args_list& args_list,const allocator_type& al):
1583 super(args_list,al){}
1584
1585 ordered_index(const ordered_index& x):super(x){}
1586
1587 ordered_index(const ordered_index& x,do_not_copy_elements_tag):
1588 super(x,do_not_copy_elements_tag()){}
1589 };
1590
1591 #if defined(BOOST_MSVC)
1592 #pragma warning(pop)
1593 #endif
1594
1595
1596
1597 template<
1598 typename KeyFromValue1,typename Compare1,
1599 typename SuperMeta1,typename TagList1,typename Category1,
1600 typename AugmentPolicy1,
1601 typename KeyFromValue2,typename Compare2,
1602 typename SuperMeta2,typename TagList2,typename Category2,
1603 typename AugmentPolicy2
1604 >
1605 bool operator==(
1606 const ordered_index<
1607 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1608 const ordered_index<
1609 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1610 {
1611 return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
1612 }
1613
1614 template<
1615 typename KeyFromValue1,typename Compare1,
1616 typename SuperMeta1,typename TagList1,typename Category1,
1617 typename AugmentPolicy1,
1618 typename KeyFromValue2,typename Compare2,
1619 typename SuperMeta2,typename TagList2,typename Category2,
1620 typename AugmentPolicy2
1621 >
1622 bool operator<(
1623 const ordered_index<
1624 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1625 const ordered_index<
1626 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1627 {
1628 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
1629 }
1630
1631 template<
1632 typename KeyFromValue1,typename Compare1,
1633 typename SuperMeta1,typename TagList1,typename Category1,
1634 typename AugmentPolicy1,
1635 typename KeyFromValue2,typename Compare2,
1636 typename SuperMeta2,typename TagList2,typename Category2,
1637 typename AugmentPolicy2
1638 >
1639 bool operator!=(
1640 const ordered_index<
1641 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1642 const ordered_index<
1643 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1644 {
1645 return !(x==y);
1646 }
1647
1648 template<
1649 typename KeyFromValue1,typename Compare1,
1650 typename SuperMeta1,typename TagList1,typename Category1,
1651 typename AugmentPolicy1,
1652 typename KeyFromValue2,typename Compare2,
1653 typename SuperMeta2,typename TagList2,typename Category2,
1654 typename AugmentPolicy2
1655 >
1656 bool operator>(
1657 const ordered_index<
1658 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1659 const ordered_index<
1660 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1661 {
1662 return y<x;
1663 }
1664
1665 template<
1666 typename KeyFromValue1,typename Compare1,
1667 typename SuperMeta1,typename TagList1,typename Category1,
1668 typename AugmentPolicy1,
1669 typename KeyFromValue2,typename Compare2,
1670 typename SuperMeta2,typename TagList2,typename Category2,
1671 typename AugmentPolicy2
1672 >
1673 bool operator>=(
1674 const ordered_index<
1675 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1676 const ordered_index<
1677 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1678 {
1679 return !(x<y);
1680 }
1681
1682 template<
1683 typename KeyFromValue1,typename Compare1,
1684 typename SuperMeta1,typename TagList1,typename Category1,
1685 typename AugmentPolicy1,
1686 typename KeyFromValue2,typename Compare2,
1687 typename SuperMeta2,typename TagList2,typename Category2,
1688 typename AugmentPolicy2
1689 >
1690 bool operator<=(
1691 const ordered_index<
1692 KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
1693 const ordered_index<
1694 KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
1695 {
1696 return !(x>y);
1697 }
1698
1699
1700
1701 template<
1702 typename KeyFromValue,typename Compare,
1703 typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
1704 >
1705 void swap(
1706 ordered_index<
1707 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
1708 ordered_index<
1709 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y)
1710 {
1711 x.swap(y);
1712 }
1713
1714 }
1715
1716 }
1717
1718 }
1719
1720
1721
1722 namespace boost{
1723 namespace foreach{
1724
1725 template<typename>
1726 struct is_noncopyable;
1727
1728 template<
1729 typename KeyFromValue,typename Compare,
1730 typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
1731 >
1732 struct is_noncopyable<
1733 boost::multi_index::detail::ordered_index<
1734 KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>
1735 >:boost::mpl::true_{};
1736
1737 }
1738 }
1739
1740 #undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
1741 #undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF
1742
1743 #endif