ord_index_impl.hpp 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743
  1. /* Copyright 2003-2023 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)
  5. *
  6. * See http://www.boost.org/libs/multi_index for library home page.
  7. *
  8. * The internal implementation of red-black trees is based on that of SGI STL
  9. * stl_tree.h file:
  10. *
  11. * Copyright (c) 1996,1997
  12. * Silicon Graphics Computer Systems, Inc.
  13. *
  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.
  21. *
  22. *
  23. * Copyright (c) 1994
  24. * Hewlett-Packard Company
  25. *
  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.
  33. *
  34. */
  35. #ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP
  36. #define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP
  37. #if defined(_MSC_VER)
  38. #pragma once
  39. #endif
  40. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  41. #include <algorithm>
  42. #include <boost/call_traits.hpp>
  43. #include <boost/core/addressof.hpp>
  44. #include <boost/core/no_exceptions_support.hpp>
  45. #include <boost/core/ref.hpp>
  46. #include <boost/detail/workaround.hpp>
  47. #include <boost/iterator/reverse_iterator.hpp>
  48. #include <boost/move/core.hpp>
  49. #include <boost/move/utility_core.hpp>
  50. #include <boost/mpl/bool.hpp>
  51. #include <boost/mpl/if.hpp>
  52. #include <boost/mpl/push_front.hpp>
  53. #include <boost/multi_index/detail/access_specifier.hpp>
  54. #include <boost/multi_index/detail/adl_swap.hpp>
  55. #include <boost/multi_index/detail/allocator_traits.hpp>
  56. #include <boost/multi_index/detail/bidir_node_iterator.hpp>
  57. #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
  58. #include <boost/multi_index/detail/index_node_base.hpp>
  59. #include <boost/multi_index/detail/invalidate_iterators.hpp>
  60. #include <boost/multi_index/detail/modify_key_adaptor.hpp>
  61. #include <boost/multi_index/detail/node_handle.hpp>
  62. #include <boost/multi_index/detail/ord_index_node.hpp>
  63. #include <boost/multi_index/detail/ord_index_ops.hpp>
  64. #include <boost/multi_index/detail/safe_mode.hpp>
  65. #include <boost/multi_index/detail/scope_guard.hpp>
  66. #include <boost/multi_index/detail/unbounded.hpp>
  67. #include <boost/multi_index/detail/value_compare.hpp>
  68. #include <boost/multi_index/detail/vartempl_support.hpp>
  69. #include <boost/multi_index/detail/ord_index_impl_fwd.hpp>
  70. #include <boost/tuple/tuple.hpp>
  71. #include <boost/type_traits/is_same.hpp>
  72. #include <utility>
  73. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  74. #include <initializer_list>
  75. #endif
  76. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  77. #include <boost/bind/bind.hpp>
  78. #include <boost/multi_index/detail/bad_archive_exception.hpp>
  79. #include <boost/multi_index/detail/duplicates_iterator.hpp>
  80. #include <boost/throw_exception.hpp>
  81. #endif
  82. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
  83. #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \
  84. detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
  85. detail::make_obj_guard(x,&ordered_index_impl::check_invariant_); \
  86. BOOST_JOIN(check_invariant_,__LINE__).touch();
  87. #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \
  88. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this)
  89. #else
  90. #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x)
  91. #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
  92. #endif
  93. namespace boost{
  94. namespace multi_index{
  95. namespace detail{
  96. /* ordered_index adds a layer of ordered indexing to a given Super and accepts
  97. * an augmenting policy for optional addition of order statistics.
  98. */
  99. /* Most of the implementation of unique and non-unique indices is
  100. * shared. We tell from one another on instantiation time by using
  101. * these tags.
  102. */
  103. struct ordered_unique_tag{};
  104. struct ordered_non_unique_tag{};
  105. #if defined(BOOST_MSVC)
  106. #pragma warning(push)
  107. #pragma warning(disable:4355) /* this used in base member initializer list */
  108. #endif
  109. template<
  110. typename KeyFromValue,typename Compare,
  111. typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
  112. >
  113. class ordered_index;
  114. template<
  115. typename KeyFromValue,typename Compare,
  116. typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
  117. >
  118. class ordered_index_impl:
  119. BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
  120. {
  121. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
  122. BOOST_WORKAROUND(__MWERKS__,<=0x3003)
  123. /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
  124. * lifetime of const references bound to temporaries --precisely what
  125. * scopeguards are.
  126. */
  127. #pragma parse_mfunc_templ off
  128. #endif
  129. #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
  130. /* cross-index access */
  131. template <typename,typename,typename> friend class index_base;
  132. #endif
  133. typedef typename SuperMeta::type super;
  134. protected:
  135. typedef ordered_index_node<
  136. AugmentPolicy,typename super::index_node_type> index_node_type;
  137. protected: /* for the benefit of AugmentPolicy::augmented_interface */
  138. typedef typename index_node_type::impl_type node_impl_type;
  139. typedef typename node_impl_type::pointer node_impl_pointer;
  140. public:
  141. /* types */
  142. typedef typename KeyFromValue::result_type key_type;
  143. typedef typename index_node_type::value_type value_type;
  144. typedef KeyFromValue key_from_value;
  145. typedef Compare key_compare;
  146. typedef value_comparison<
  147. value_type,KeyFromValue,Compare> value_compare;
  148. typedef tuple<key_from_value,key_compare> ctor_args;
  149. typedef typename super::final_allocator_type allocator_type;
  150. typedef value_type& reference;
  151. typedef const value_type& const_reference;
  152. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  153. typedef safe_mode::safe_iterator<
  154. bidir_node_iterator<index_node_type> > iterator;
  155. #else
  156. typedef bidir_node_iterator<index_node_type> iterator;
  157. #endif
  158. typedef iterator const_iterator;
  159. private:
  160. typedef allocator_traits<allocator_type> alloc_traits;
  161. public:
  162. typedef typename alloc_traits::size_type size_type;
  163. typedef typename alloc_traits::difference_type difference_type;
  164. typedef typename alloc_traits::pointer pointer;
  165. typedef typename alloc_traits::const_pointer const_pointer;
  166. typedef typename
  167. boost::reverse_iterator<iterator> reverse_iterator;
  168. typedef typename
  169. boost::reverse_iterator<const_iterator> const_reverse_iterator;
  170. typedef typename super::final_node_handle_type node_type;
  171. typedef detail::insert_return_type<
  172. iterator,node_type> insert_return_type;
  173. typedef TagList tag_list;
  174. protected:
  175. typedef typename super::final_node_type final_node_type;
  176. typedef tuples::cons<
  177. ctor_args,
  178. typename super::ctor_args_list> ctor_args_list;
  179. typedef typename mpl::push_front<
  180. typename super::index_type_list,
  181. ordered_index<
  182. KeyFromValue,Compare,
  183. SuperMeta,TagList,Category,AugmentPolicy
  184. > >::type index_type_list;
  185. typedef typename mpl::push_front<
  186. typename super::iterator_type_list,
  187. iterator>::type iterator_type_list;
  188. typedef typename mpl::push_front<
  189. typename super::const_iterator_type_list,
  190. const_iterator>::type const_iterator_type_list;
  191. typedef typename super::copy_map_type copy_map_type;
  192. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  193. typedef typename super::index_saver_type index_saver_type;
  194. typedef typename super::index_loader_type index_loader_type;
  195. #endif
  196. protected:
  197. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  198. typedef safe_mode::safe_container<iterator> safe_container;
  199. #endif
  200. typedef typename call_traits<
  201. value_type>::param_type value_param_type;
  202. typedef typename call_traits<
  203. key_type>::param_type key_param_type;
  204. /* needed to avoid commas in some macros */
  205. typedef std::pair<iterator,bool> pair_return_type;
  206. public:
  207. /* construct/copy/destroy
  208. * Default and copy ctors are in the protected section as indices are
  209. * not supposed to be created on their own. No range ctor either.
  210. * Assignment operators defined at ordered_index rather than here.
  211. */
  212. allocator_type get_allocator()const BOOST_NOEXCEPT
  213. {
  214. return this->final().get_allocator();
  215. }
  216. /* iterators */
  217. iterator
  218. begin()BOOST_NOEXCEPT{return make_iterator(leftmost());}
  219. const_iterator
  220. begin()const BOOST_NOEXCEPT{return make_iterator(leftmost());}
  221. iterator
  222. end()BOOST_NOEXCEPT{return make_iterator(header());}
  223. const_iterator
  224. end()const BOOST_NOEXCEPT{return make_iterator(header());}
  225. reverse_iterator
  226. rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
  227. const_reverse_iterator
  228. rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
  229. reverse_iterator
  230. rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
  231. const_reverse_iterator
  232. rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
  233. const_iterator
  234. cbegin()const BOOST_NOEXCEPT{return begin();}
  235. const_iterator
  236. cend()const BOOST_NOEXCEPT{return end();}
  237. const_reverse_iterator
  238. crbegin()const BOOST_NOEXCEPT{return rbegin();}
  239. const_reverse_iterator
  240. crend()const BOOST_NOEXCEPT{return rend();}
  241. iterator iterator_to(const value_type& x)
  242. {
  243. return make_iterator(
  244. node_from_value<index_node_type>(boost::addressof(x)));
  245. }
  246. const_iterator iterator_to(const value_type& x)const
  247. {
  248. return make_iterator(
  249. node_from_value<index_node_type>(boost::addressof(x)));
  250. }
  251. /* capacity */
  252. bool empty()const BOOST_NOEXCEPT{return this->final_empty_();}
  253. size_type size()const BOOST_NOEXCEPT{return this->final_size_();}
  254. size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();}
  255. /* modifiers */
  256. BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
  257. pair_return_type,emplace,emplace_impl)
  258. BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
  259. iterator,emplace_hint,emplace_hint_impl,iterator,position)
  260. std::pair<iterator,bool> insert(const value_type& x)
  261. {
  262. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  263. std::pair<final_node_type*,bool> p=this->final_insert_(x);
  264. return std::pair<iterator,bool>(make_iterator(p.first),p.second);
  265. }
  266. std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
  267. {
  268. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  269. std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
  270. return std::pair<iterator,bool>(make_iterator(p.first),p.second);
  271. }
  272. iterator insert(iterator position,const value_type& x)
  273. {
  274. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  275. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  276. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  277. std::pair<final_node_type*,bool> p=this->final_insert_(
  278. x,static_cast<final_node_type*>(position.get_node()));
  279. return make_iterator(p.first);
  280. }
  281. iterator insert(iterator position,BOOST_RV_REF(value_type) x)
  282. {
  283. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  284. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  285. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  286. std::pair<final_node_type*,bool> p=this->final_insert_rv_(
  287. x,static_cast<final_node_type*>(position.get_node()));
  288. return make_iterator(p.first);
  289. }
  290. template<typename InputIterator>
  291. void insert(InputIterator first,InputIterator last)
  292. {
  293. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  294. for(;first!=last;++first)this->final_insert_ref_(*first);
  295. }
  296. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  297. void insert(std::initializer_list<value_type> list)
  298. {
  299. insert(list.begin(),list.end());
  300. }
  301. #endif
  302. insert_return_type insert(BOOST_RV_REF(node_type) nh)
  303. {
  304. if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
  305. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  306. std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh);
  307. return insert_return_type(make_iterator(p.first),p.second,boost::move(nh));
  308. }
  309. iterator insert(const_iterator position,BOOST_RV_REF(node_type) nh)
  310. {
  311. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  312. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  313. if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
  314. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  315. std::pair<final_node_type*,bool> p=this->final_insert_nh_(
  316. nh,static_cast<final_node_type*>(position.get_node()));
  317. return make_iterator(p.first);
  318. }
  319. node_type extract(const_iterator position)
  320. {
  321. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  322. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  323. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  324. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  325. return this->final_extract_(
  326. static_cast<final_node_type*>(position.get_node()));
  327. }
  328. node_type extract(key_param_type x)
  329. {
  330. iterator position=lower_bound(x);
  331. if(position==end()||comp_(x,key(*position)))return node_type();
  332. else return extract(position);
  333. }
  334. iterator erase(iterator position)
  335. {
  336. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  337. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  338. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  339. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  340. this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
  341. return position;
  342. }
  343. size_type erase(key_param_type x)
  344. {
  345. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  346. std::pair<iterator,iterator> p=equal_range(x);
  347. size_type s=0;
  348. while(p.first!=p.second){
  349. p.first=erase(p.first);
  350. ++s;
  351. }
  352. return s;
  353. }
  354. iterator erase(iterator first,iterator last)
  355. {
  356. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
  357. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
  358. BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
  359. BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
  360. BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
  361. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  362. while(first!=last){
  363. first=erase(first);
  364. }
  365. return first;
  366. }
  367. bool replace(iterator position,const value_type& x)
  368. {
  369. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  370. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  371. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  372. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  373. return this->final_replace_(
  374. x,static_cast<final_node_type*>(position.get_node()));
  375. }
  376. bool replace(iterator position,BOOST_RV_REF(value_type) x)
  377. {
  378. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  379. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  380. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  381. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  382. return this->final_replace_rv_(
  383. x,static_cast<final_node_type*>(position.get_node()));
  384. }
  385. template<typename Modifier>
  386. bool modify(iterator position,Modifier mod)
  387. {
  388. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  389. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  390. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  391. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  392. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  393. /* MSVC++ 6.0 optimizer on safe mode code chokes if this
  394. * this is not added. Left it for all compilers as it does no
  395. * harm.
  396. */
  397. position.detach();
  398. #endif
  399. return this->final_modify_(
  400. mod,static_cast<final_node_type*>(position.get_node()));
  401. }
  402. template<typename Modifier,typename Rollback>
  403. bool modify(iterator position,Modifier mod,Rollback back_)
  404. {
  405. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  406. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  407. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  408. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  409. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  410. /* MSVC++ 6.0 optimizer on safe mode code chokes if this
  411. * this is not added. Left it for all compilers as it does no
  412. * harm.
  413. */
  414. position.detach();
  415. #endif
  416. return this->final_modify_(
  417. mod,back_,static_cast<final_node_type*>(position.get_node()));
  418. }
  419. template<typename Modifier>
  420. bool modify_key(iterator position,Modifier mod)
  421. {
  422. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  423. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  424. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  425. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  426. return modify(
  427. position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key));
  428. }
  429. template<typename Modifier,typename Rollback>
  430. bool modify_key(iterator position,Modifier mod,Rollback back_)
  431. {
  432. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  433. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  434. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  435. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  436. return modify(
  437. position,
  438. modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key),
  439. modify_key_adaptor<Rollback,value_type,KeyFromValue>(back_,key));
  440. }
  441. void swap(
  442. ordered_index<
  443. KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
  444. {
  445. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  446. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x);
  447. this->final_swap_(x.final());
  448. }
  449. void clear()BOOST_NOEXCEPT
  450. {
  451. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  452. this->final_clear_();
  453. }
  454. template<typename Index>
  455. BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
  456. merge(Index& x)
  457. {
  458. merge(x,x.begin(),x.end());
  459. }
  460. template<typename Index>
  461. BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
  462. merge(BOOST_RV_REF(Index) x){merge(static_cast<Index&>(x));}
  463. template<typename Index>
  464. BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
  465. ordered_index_impl,Index,pair_return_type)
  466. merge(Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
  467. {
  468. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
  469. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
  470. BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
  471. BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
  472. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  473. if(x.end().get_node()==this->header()){ /* same container */
  474. return std::pair<iterator,bool>(
  475. make_iterator(static_cast<final_node_type*>(i.get_node())),true);
  476. }
  477. else{
  478. std::pair<final_node_type*,bool> p=this->final_transfer_(
  479. x,static_cast<final_node_type*>(i.get_node()));
  480. return std::pair<iterator,bool>(make_iterator(p.first),p.second);
  481. }
  482. }
  483. template<typename Index>
  484. BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
  485. ordered_index_impl,Index,pair_return_type)
  486. merge(BOOST_RV_REF(Index) x,BOOST_DEDUCED_TYPENAME Index::iterator i)
  487. {
  488. return merge(static_cast<Index&>(x),i);
  489. }
  490. template<typename Index>
  491. BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
  492. merge(
  493. Index& x,
  494. BOOST_DEDUCED_TYPENAME Index::iterator first,
  495. BOOST_DEDUCED_TYPENAME Index::iterator last)
  496. {
  497. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
  498. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
  499. BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x);
  500. BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
  501. BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
  502. BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
  503. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  504. if(x.end().get_node()!=this->header()){ /* different containers */
  505. this->final_transfer_range_(x,first,last);
  506. }
  507. }
  508. template<typename Index>
  509. BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
  510. merge(
  511. BOOST_RV_REF(Index) x,
  512. BOOST_DEDUCED_TYPENAME Index::iterator first,
  513. BOOST_DEDUCED_TYPENAME Index::iterator last)
  514. {
  515. merge(static_cast<Index&>(x),first,last);
  516. }
  517. /* observers */
  518. key_from_value key_extractor()const{return key;}
  519. key_compare key_comp()const{return comp_;}
  520. value_compare value_comp()const{return value_compare(key,comp_);}
  521. /* set operations */
  522. /* Internally, these ops rely on const_iterator being the same
  523. * type as iterator.
  524. */
  525. template<typename CompatibleKey>
  526. iterator find(const CompatibleKey& x)const
  527. {
  528. return make_iterator(ordered_index_find(root(),header(),key,x,comp_));
  529. }
  530. template<typename CompatibleKey,typename CompatibleCompare>
  531. iterator find(
  532. const CompatibleKey& x,const CompatibleCompare& comp)const
  533. {
  534. return make_iterator(ordered_index_find(root(),header(),key,x,comp));
  535. }
  536. template<typename CompatibleKey>
  537. size_type count(const CompatibleKey& x)const
  538. {
  539. return count(x,comp_);
  540. }
  541. template<typename CompatibleKey,typename CompatibleCompare>
  542. size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const
  543. {
  544. std::pair<iterator,iterator> p=equal_range(x,comp);
  545. size_type n=static_cast<size_type>(std::distance(p.first,p.second));
  546. return n;
  547. }
  548. template<typename CompatibleKey>
  549. bool contains(const CompatibleKey& x)const
  550. {
  551. return contains(x,comp_);
  552. }
  553. template<typename CompatibleKey,typename CompatibleCompare>
  554. bool contains(
  555. const CompatibleKey& x,const CompatibleCompare& comp)const
  556. {
  557. return find(x,comp)!=end();
  558. }
  559. template<typename CompatibleKey>
  560. iterator lower_bound(const CompatibleKey& x)const
  561. {
  562. return make_iterator(
  563. ordered_index_lower_bound(root(),header(),key,x,comp_));
  564. }
  565. template<typename CompatibleKey,typename CompatibleCompare>
  566. iterator lower_bound(
  567. const CompatibleKey& x,const CompatibleCompare& comp)const
  568. {
  569. return make_iterator(
  570. ordered_index_lower_bound(root(),header(),key,x,comp));
  571. }
  572. template<typename CompatibleKey>
  573. iterator upper_bound(const CompatibleKey& x)const
  574. {
  575. return make_iterator(
  576. ordered_index_upper_bound(root(),header(),key,x,comp_));
  577. }
  578. template<typename CompatibleKey,typename CompatibleCompare>
  579. iterator upper_bound(
  580. const CompatibleKey& x,const CompatibleCompare& comp)const
  581. {
  582. return make_iterator(
  583. ordered_index_upper_bound(root(),header(),key,x,comp));
  584. }
  585. template<typename CompatibleKey>
  586. std::pair<iterator,iterator> equal_range(
  587. const CompatibleKey& x)const
  588. {
  589. std::pair<index_node_type*,index_node_type*> p=
  590. ordered_index_equal_range(root(),header(),key,x,comp_);
  591. return std::pair<iterator,iterator>(
  592. make_iterator(p.first),make_iterator(p.second));
  593. }
  594. template<typename CompatibleKey,typename CompatibleCompare>
  595. std::pair<iterator,iterator> equal_range(
  596. const CompatibleKey& x,const CompatibleCompare& comp)const
  597. {
  598. std::pair<index_node_type*,index_node_type*> p=
  599. ordered_index_equal_range(root(),header(),key,x,comp);
  600. return std::pair<iterator,iterator>(
  601. make_iterator(p.first),make_iterator(p.second));
  602. }
  603. /* range */
  604. template<typename LowerBounder,typename UpperBounder>
  605. std::pair<iterator,iterator>
  606. range(LowerBounder lower,UpperBounder upper)const
  607. {
  608. typedef typename mpl::if_<
  609. is_same<LowerBounder,unbounded_type>,
  610. BOOST_DEDUCED_TYPENAME mpl::if_<
  611. is_same<UpperBounder,unbounded_type>,
  612. both_unbounded_tag,
  613. lower_unbounded_tag
  614. >::type,
  615. BOOST_DEDUCED_TYPENAME mpl::if_<
  616. is_same<UpperBounder,unbounded_type>,
  617. upper_unbounded_tag,
  618. none_unbounded_tag
  619. >::type
  620. >::type dispatch;
  621. return range(lower,upper,dispatch());
  622. }
  623. BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
  624. ordered_index_impl(const ctor_args_list& args_list,const allocator_type& al):
  625. super(args_list.get_tail(),al),
  626. key(tuples::get<0>(args_list.get_head())),
  627. comp_(tuples::get<1>(args_list.get_head()))
  628. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  629. ,safe(*this)
  630. #endif
  631. {
  632. empty_initialize();
  633. }
  634. ordered_index_impl(
  635. const ordered_index_impl<
  636. KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x):
  637. super(x),
  638. key(x.key),
  639. comp_(x.comp_)
  640. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  641. ,safe(*this)
  642. #endif
  643. {
  644. /* Copy ctor just takes the key and compare objects from x. The rest is
  645. * done in a subsequent call to copy_().
  646. */
  647. }
  648. ordered_index_impl(
  649. const ordered_index_impl<
  650. KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
  651. do_not_copy_elements_tag):
  652. super(x,do_not_copy_elements_tag()),
  653. key(x.key),
  654. comp_(x.comp_)
  655. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  656. ,safe(*this)
  657. #endif
  658. {
  659. empty_initialize();
  660. }
  661. ~ordered_index_impl()
  662. {
  663. /* the container is guaranteed to be empty by now */
  664. }
  665. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  666. iterator make_iterator(index_node_type* node)
  667. {return iterator(node,&safe);}
  668. const_iterator make_iterator(index_node_type* node)const
  669. {return const_iterator(node,const_cast<safe_container*>(&safe));}
  670. #else
  671. iterator make_iterator(index_node_type* node){return iterator(node);}
  672. const_iterator make_iterator(index_node_type* node)const
  673. {return const_iterator(node);}
  674. #endif
  675. void copy_(
  676. const ordered_index_impl<
  677. KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
  678. const copy_map_type& map)
  679. {
  680. if(!x.root()){
  681. empty_initialize();
  682. }
  683. else{
  684. header()->color()=x.header()->color();
  685. AugmentPolicy::copy(x.header()->impl(),header()->impl());
  686. index_node_type* root_cpy=map.find(
  687. static_cast<final_node_type*>(x.root()));
  688. header()->parent()=root_cpy->impl();
  689. index_node_type* leftmost_cpy=map.find(
  690. static_cast<final_node_type*>(x.leftmost()));
  691. header()->left()=leftmost_cpy->impl();
  692. index_node_type* rightmost_cpy=map.find(
  693. static_cast<final_node_type*>(x.rightmost()));
  694. header()->right()=rightmost_cpy->impl();
  695. typedef typename copy_map_type::const_iterator copy_map_iterator;
  696. for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){
  697. index_node_type* org=it->first;
  698. index_node_type* cpy=it->second;
  699. cpy->color()=org->color();
  700. AugmentPolicy::copy(org->impl(),cpy->impl());
  701. node_impl_pointer parent_org=org->parent();
  702. if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0);
  703. else{
  704. index_node_type* parent_cpy=map.find(
  705. static_cast<final_node_type*>(
  706. index_node_type::from_impl(parent_org)));
  707. cpy->parent()=parent_cpy->impl();
  708. if(parent_org->left()==org->impl()){
  709. parent_cpy->left()=cpy->impl();
  710. }
  711. else if(parent_org->right()==org->impl()){
  712. /* header() does not satisfy this nor the previous check */
  713. parent_cpy->right()=cpy->impl();
  714. }
  715. }
  716. if(org->left()==node_impl_pointer(0))
  717. cpy->left()=node_impl_pointer(0);
  718. if(org->right()==node_impl_pointer(0))
  719. cpy->right()=node_impl_pointer(0);
  720. }
  721. }
  722. super::copy_(x,map);
  723. }
  724. template<typename Variant>
  725. final_node_type* insert_(
  726. value_param_type v,final_node_type*& x,Variant variant)
  727. {
  728. link_info inf;
  729. if(!link_point(key(v),inf,Category())){
  730. return static_cast<final_node_type*>(
  731. index_node_type::from_impl(inf.pos));
  732. }
  733. final_node_type* res=super::insert_(v,x,variant);
  734. if(res==x){
  735. node_impl_type::link(
  736. static_cast<index_node_type*>(x)->impl(),
  737. inf.side,inf.pos,header()->impl());
  738. }
  739. return res;
  740. }
  741. template<typename Variant>
  742. final_node_type* insert_(
  743. value_param_type v,index_node_type* position,
  744. final_node_type*& x,Variant variant)
  745. {
  746. link_info inf;
  747. if(!hinted_link_point(key(v),position,inf,Category())){
  748. return static_cast<final_node_type*>(
  749. index_node_type::from_impl(inf.pos));
  750. }
  751. final_node_type* res=super::insert_(v,position,x,variant);
  752. if(res==x){
  753. node_impl_type::link(
  754. static_cast<index_node_type*>(x)->impl(),
  755. inf.side,inf.pos,header()->impl());
  756. }
  757. return res;
  758. }
  759. template<typename Dst>
  760. void extract_(index_node_type* x,Dst dst)
  761. {
  762. node_impl_type::rebalance_for_extract(
  763. x->impl(),header()->parent(),header()->left(),header()->right());
  764. super::extract_(x,dst.next());
  765. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  766. transfer_iterators(dst.get(),x);
  767. #endif
  768. }
  769. void delete_all_nodes_()
  770. {
  771. delete_all_nodes(root());
  772. }
  773. void clear_()
  774. {
  775. super::clear_();
  776. empty_initialize();
  777. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  778. safe.detach_dereferenceable_iterators();
  779. #endif
  780. }
  781. template<typename BoolConstant>
  782. void swap_(
  783. ordered_index_impl<
  784. KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
  785. BoolConstant swap_allocators)
  786. {
  787. adl_swap(key,x.key);
  788. adl_swap(comp_,x.comp_);
  789. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  790. safe.swap(x.safe);
  791. #endif
  792. super::swap_(x,swap_allocators);
  793. }
  794. void swap_elements_(
  795. ordered_index_impl<
  796. KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x)
  797. {
  798. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  799. safe.swap(x.safe);
  800. #endif
  801. super::swap_elements_(x);
  802. }
  803. template<typename Variant>
  804. bool replace_(value_param_type v,index_node_type* x,Variant variant)
  805. {
  806. if(in_place(v,x,Category())){
  807. return super::replace_(v,x,variant);
  808. }
  809. index_node_type* next=x;
  810. index_node_type::increment(next);
  811. node_impl_type::rebalance_for_extract(
  812. x->impl(),header()->parent(),header()->left(),header()->right());
  813. BOOST_TRY{
  814. link_info inf;
  815. if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){
  816. node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
  817. return true;
  818. }
  819. node_impl_type::restore(x->impl(),next->impl(),header()->impl());
  820. return false;
  821. }
  822. BOOST_CATCH(...){
  823. node_impl_type::restore(x->impl(),next->impl(),header()->impl());
  824. BOOST_RETHROW;
  825. }
  826. BOOST_CATCH_END
  827. }
  828. bool modify_(index_node_type* x)
  829. {
  830. bool b;
  831. BOOST_TRY{
  832. b=in_place(x->value(),x,Category());
  833. }
  834. BOOST_CATCH(...){
  835. extract_(x,invalidate_iterators());
  836. BOOST_RETHROW;
  837. }
  838. BOOST_CATCH_END
  839. if(!b){
  840. node_impl_type::rebalance_for_extract(
  841. x->impl(),header()->parent(),header()->left(),header()->right());
  842. BOOST_TRY{
  843. link_info inf;
  844. if(!link_point(key(x->value()),inf,Category())){
  845. super::extract_(x,invalidate_iterators());
  846. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  847. detach_iterators(x);
  848. #endif
  849. return false;
  850. }
  851. node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
  852. }
  853. BOOST_CATCH(...){
  854. super::extract_(x,invalidate_iterators());
  855. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  856. detach_iterators(x);
  857. #endif
  858. BOOST_RETHROW;
  859. }
  860. BOOST_CATCH_END
  861. }
  862. BOOST_TRY{
  863. if(!super::modify_(x)){
  864. node_impl_type::rebalance_for_extract(
  865. x->impl(),header()->parent(),header()->left(),header()->right());
  866. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  867. detach_iterators(x);
  868. #endif
  869. return false;
  870. }
  871. else return true;
  872. }
  873. BOOST_CATCH(...){
  874. node_impl_type::rebalance_for_extract(
  875. x->impl(),header()->parent(),header()->left(),header()->right());
  876. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  877. detach_iterators(x);
  878. #endif
  879. BOOST_RETHROW;
  880. }
  881. BOOST_CATCH_END
  882. }
  883. bool modify_rollback_(index_node_type* x)
  884. {
  885. if(in_place(x->value(),x,Category())){
  886. return super::modify_rollback_(x);
  887. }
  888. index_node_type* next=x;
  889. index_node_type::increment(next);
  890. node_impl_type::rebalance_for_extract(
  891. x->impl(),header()->parent(),header()->left(),header()->right());
  892. BOOST_TRY{
  893. link_info inf;
  894. if(link_point(key(x->value()),inf,Category())&&
  895. super::modify_rollback_(x)){
  896. node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
  897. return true;
  898. }
  899. node_impl_type::restore(x->impl(),next->impl(),header()->impl());
  900. return false;
  901. }
  902. BOOST_CATCH(...){
  903. node_impl_type::restore(x->impl(),next->impl(),header()->impl());
  904. BOOST_RETHROW;
  905. }
  906. BOOST_CATCH_END
  907. }
  908. bool check_rollback_(index_node_type* x)const
  909. {
  910. return in_place(x->value(),x,Category())&&super::check_rollback_(x);
  911. }
  912. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  913. /* serialization */
  914. template<typename Archive>
  915. void save_(
  916. Archive& ar,const unsigned int version,const index_saver_type& sm)const
  917. {
  918. save_(ar,version,sm,Category());
  919. }
  920. template<typename Archive>
  921. void load_(Archive& ar,const unsigned int version,const index_loader_type& lm)
  922. {
  923. load_(ar,version,lm,Category());
  924. }
  925. #endif
  926. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
  927. /* invariant stuff */
  928. bool invariant_()const
  929. {
  930. if(size()==0||begin()==end()){
  931. if(size()!=0||begin()!=end()||
  932. header()->left()!=header()->impl()||
  933. header()->right()!=header()->impl())return false;
  934. }
  935. else{
  936. if((size_type)std::distance(begin(),end())!=size())return false;
  937. std::size_t len=node_impl_type::black_count(
  938. leftmost()->impl(),root()->impl());
  939. for(const_iterator it=begin(),it_end=end();it!=it_end;++it){
  940. index_node_type* x=it.get_node();
  941. index_node_type* left_x=index_node_type::from_impl(x->left());
  942. index_node_type* right_x=index_node_type::from_impl(x->right());
  943. if(x->color()==red){
  944. if((left_x&&left_x->color()==red)||
  945. (right_x&&right_x->color()==red))return false;
  946. }
  947. if(left_x&&comp_(key(x->value()),key(left_x->value())))return false;
  948. if(right_x&&comp_(key(right_x->value()),key(x->value())))return false;
  949. if(!left_x&&!right_x&&
  950. node_impl_type::black_count(x->impl(),root()->impl())!=len)
  951. return false;
  952. if(!AugmentPolicy::invariant(x->impl()))return false;
  953. }
  954. if(leftmost()->impl()!=node_impl_type::minimum(root()->impl()))
  955. return false;
  956. if(rightmost()->impl()!=node_impl_type::maximum(root()->impl()))
  957. return false;
  958. }
  959. return super::invariant_();
  960. }
  961. /* This forwarding function eases things for the boost::mem_fn construct
  962. * in BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT. Actually,
  963. * final_check_invariant is already an inherited member function of
  964. * ordered_index_impl.
  965. */
  966. void check_invariant_()const{this->final_check_invariant_();}
  967. #endif
  968. protected: /* for the benefit of AugmentPolicy::augmented_interface */
  969. index_node_type* header()const
  970. {return this->final_header();}
  971. index_node_type* root()const
  972. {return index_node_type::from_impl(header()->parent());}
  973. index_node_type* leftmost()const
  974. {return index_node_type::from_impl(header()->left());}
  975. index_node_type* rightmost()const
  976. {return index_node_type::from_impl(header()->right());}
  977. private:
  978. void empty_initialize()
  979. {
  980. header()->color()=red;
  981. /* used to distinguish header() from root, in iterator.operator++ */
  982. header()->parent()=node_impl_pointer(0);
  983. header()->left()=header()->impl();
  984. header()->right()=header()->impl();
  985. }
  986. struct link_info
  987. {
  988. /* coverity[uninit_ctor]: suppress warning */
  989. link_info():side(to_left){}
  990. ordered_index_side side;
  991. node_impl_pointer pos;
  992. };
  993. bool link_point(key_param_type k,link_info& inf,ordered_unique_tag)
  994. {
  995. index_node_type* y=header();
  996. index_node_type* x=root();
  997. bool c=true;
  998. while(x){
  999. y=x;
  1000. c=comp_(k,key(x->value()));
  1001. x=index_node_type::from_impl(c?x->left():x->right());
  1002. }
  1003. index_node_type* yy=y;
  1004. if(c){
  1005. if(yy==leftmost()){
  1006. inf.side=to_left;
  1007. inf.pos=y->impl();
  1008. return true;
  1009. }
  1010. else index_node_type::decrement(yy);
  1011. }
  1012. if(comp_(key(yy->value()),k)){
  1013. inf.side=c?to_left:to_right;
  1014. inf.pos=y->impl();
  1015. return true;
  1016. }
  1017. else{
  1018. inf.pos=yy->impl();
  1019. return false;
  1020. }
  1021. }
  1022. bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
  1023. {
  1024. index_node_type* y=header();
  1025. index_node_type* x=root();
  1026. bool c=true;
  1027. while (x){
  1028. y=x;
  1029. c=comp_(k,key(x->value()));
  1030. x=index_node_type::from_impl(c?x->left():x->right());
  1031. }
  1032. inf.side=c?to_left:to_right;
  1033. inf.pos=y->impl();
  1034. return true;
  1035. }
  1036. bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
  1037. {
  1038. index_node_type* y=header();
  1039. index_node_type* x=root();
  1040. bool c=false;
  1041. while (x){
  1042. y=x;
  1043. c=comp_(key(x->value()),k);
  1044. x=index_node_type::from_impl(c?x->right():x->left());
  1045. }
  1046. inf.side=c?to_right:to_left;
  1047. inf.pos=y->impl();
  1048. return true;
  1049. }
  1050. bool hinted_link_point(
  1051. key_param_type k,index_node_type* position,
  1052. link_info& inf,ordered_unique_tag)
  1053. {
  1054. if(position->impl()==header()->left()){
  1055. if(size()>0&&comp_(k,key(position->value()))){
  1056. inf.side=to_left;
  1057. inf.pos=position->impl();
  1058. return true;
  1059. }
  1060. else return link_point(k,inf,ordered_unique_tag());
  1061. }
  1062. else if(position==header()){
  1063. if(comp_(key(rightmost()->value()),k)){
  1064. inf.side=to_right;
  1065. inf.pos=rightmost()->impl();
  1066. return true;
  1067. }
  1068. else return link_point(k,inf,ordered_unique_tag());
  1069. }
  1070. else{
  1071. index_node_type* before=position;
  1072. index_node_type::decrement(before);
  1073. if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){
  1074. if(before->right()==node_impl_pointer(0)){
  1075. inf.side=to_right;
  1076. inf.pos=before->impl();
  1077. return true;
  1078. }
  1079. else{
  1080. inf.side=to_left;
  1081. inf.pos=position->impl();
  1082. return true;
  1083. }
  1084. }
  1085. else return link_point(k,inf,ordered_unique_tag());
  1086. }
  1087. }
  1088. bool hinted_link_point(
  1089. key_param_type k,index_node_type* position,
  1090. link_info& inf,ordered_non_unique_tag)
  1091. {
  1092. if(position->impl()==header()->left()){
  1093. if(size()>0&&!comp_(key(position->value()),k)){
  1094. inf.side=to_left;
  1095. inf.pos=position->impl();
  1096. return true;
  1097. }
  1098. else return lower_link_point(k,inf,ordered_non_unique_tag());
  1099. }
  1100. else if(position==header()){
  1101. if(!comp_(k,key(rightmost()->value()))){
  1102. inf.side=to_right;
  1103. inf.pos=rightmost()->impl();
  1104. return true;
  1105. }
  1106. else return link_point(k,inf,ordered_non_unique_tag());
  1107. }
  1108. else{
  1109. index_node_type* before=position;
  1110. index_node_type::decrement(before);
  1111. if(!comp_(k,key(before->value()))){
  1112. if(!comp_(key(position->value()),k)){
  1113. if(before->right()==node_impl_pointer(0)){
  1114. inf.side=to_right;
  1115. inf.pos=before->impl();
  1116. return true;
  1117. }
  1118. else{
  1119. inf.side=to_left;
  1120. inf.pos=position->impl();
  1121. return true;
  1122. }
  1123. }
  1124. else return lower_link_point(k,inf,ordered_non_unique_tag());
  1125. }
  1126. else return link_point(k,inf,ordered_non_unique_tag());
  1127. }
  1128. }
  1129. void delete_all_nodes(index_node_type* x)
  1130. {
  1131. if(!x)return;
  1132. delete_all_nodes(index_node_type::from_impl(x->left()));
  1133. delete_all_nodes(index_node_type::from_impl(x->right()));
  1134. this->final_delete_node_(static_cast<final_node_type*>(x));
  1135. }
  1136. bool in_place(value_param_type v,index_node_type* x,ordered_unique_tag)const
  1137. {
  1138. index_node_type* y;
  1139. if(x!=leftmost()){
  1140. y=x;
  1141. index_node_type::decrement(y);
  1142. if(!comp_(key(y->value()),key(v)))return false;
  1143. }
  1144. y=x;
  1145. index_node_type::increment(y);
  1146. return y==header()||comp_(key(v),key(y->value()));
  1147. }
  1148. bool in_place(
  1149. value_param_type v,index_node_type* x,ordered_non_unique_tag)const
  1150. {
  1151. index_node_type* y;
  1152. if(x!=leftmost()){
  1153. y=x;
  1154. index_node_type::decrement(y);
  1155. if(comp_(key(v),key(y->value())))return false;
  1156. }
  1157. y=x;
  1158. index_node_type::increment(y);
  1159. return y==header()||!comp_(key(y->value()),key(v));
  1160. }
  1161. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  1162. void detach_iterators(index_node_type* x)
  1163. {
  1164. iterator it=make_iterator(x);
  1165. safe_mode::detach_equivalent_iterators(it);
  1166. }
  1167. template<typename Dst>
  1168. void transfer_iterators(Dst& dst,index_node_type* x)
  1169. {
  1170. iterator it=make_iterator(x);
  1171. safe_mode::transfer_equivalent_iterators(dst,it);
  1172. }
  1173. #endif
  1174. template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
  1175. std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
  1176. {
  1177. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  1178. std::pair<final_node_type*,bool>p=
  1179. this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
  1180. return std::pair<iterator,bool>(make_iterator(p.first),p.second);
  1181. }
  1182. template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
  1183. iterator emplace_hint_impl(
  1184. iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
  1185. {
  1186. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  1187. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  1188. BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
  1189. std::pair<final_node_type*,bool>p=
  1190. this->final_emplace_hint_(
  1191. static_cast<final_node_type*>(position.get_node()),
  1192. BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
  1193. return make_iterator(p.first);
  1194. }
  1195. template<typename LowerBounder,typename UpperBounder>
  1196. std::pair<iterator,iterator>
  1197. range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
  1198. {
  1199. index_node_type* y=header();
  1200. index_node_type* z=root();
  1201. while(z){
  1202. if(!lower(key(z->value()))){
  1203. z=index_node_type::from_impl(z->right());
  1204. }
  1205. else if(!upper(key(z->value()))){
  1206. y=z;
  1207. z=index_node_type::from_impl(z->left());
  1208. }
  1209. else{
  1210. return std::pair<iterator,iterator>(
  1211. make_iterator(
  1212. lower_range(index_node_type::from_impl(z->left()),z,lower)),
  1213. make_iterator(
  1214. upper_range(index_node_type::from_impl(z->right()),y,upper)));
  1215. }
  1216. }
  1217. return std::pair<iterator,iterator>(make_iterator(y),make_iterator(y));
  1218. }
  1219. template<typename LowerBounder,typename UpperBounder>
  1220. std::pair<iterator,iterator>
  1221. range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
  1222. {
  1223. return std::pair<iterator,iterator>(
  1224. begin(),
  1225. make_iterator(upper_range(root(),header(),upper)));
  1226. }
  1227. template<typename LowerBounder,typename UpperBounder>
  1228. std::pair<iterator,iterator>
  1229. range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
  1230. {
  1231. return std::pair<iterator,iterator>(
  1232. make_iterator(lower_range(root(),header(),lower)),
  1233. end());
  1234. }
  1235. template<typename LowerBounder,typename UpperBounder>
  1236. std::pair<iterator,iterator>
  1237. range(LowerBounder,UpperBounder,both_unbounded_tag)const
  1238. {
  1239. return std::pair<iterator,iterator>(begin(),end());
  1240. }
  1241. template<typename LowerBounder>
  1242. index_node_type * lower_range(
  1243. index_node_type* top,index_node_type* y,LowerBounder lower)const
  1244. {
  1245. while(top){
  1246. if(lower(key(top->value()))){
  1247. y=top;
  1248. top=index_node_type::from_impl(top->left());
  1249. }
  1250. else top=index_node_type::from_impl(top->right());
  1251. }
  1252. return y;
  1253. }
  1254. template<typename UpperBounder>
  1255. index_node_type * upper_range(
  1256. index_node_type* top,index_node_type* y,UpperBounder upper)const
  1257. {
  1258. while(top){
  1259. if(!upper(key(top->value()))){
  1260. y=top;
  1261. top=index_node_type::from_impl(top->left());
  1262. }
  1263. else top=index_node_type::from_impl(top->right());
  1264. }
  1265. return y;
  1266. }
  1267. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  1268. template<typename Archive>
  1269. void save_(
  1270. Archive& ar,const unsigned int version,const index_saver_type& sm,
  1271. ordered_unique_tag)const
  1272. {
  1273. super::save_(ar,version,sm);
  1274. }
  1275. template<typename Archive>
  1276. void load_(
  1277. Archive& ar,const unsigned int version,const index_loader_type& lm,
  1278. ordered_unique_tag)
  1279. {
  1280. super::load_(ar,version,lm);
  1281. }
  1282. template<typename Archive>
  1283. void save_(
  1284. Archive& ar,const unsigned int version,const index_saver_type& sm,
  1285. ordered_non_unique_tag)const
  1286. {
  1287. typedef duplicates_iterator<index_node_type,value_compare> dup_iterator;
  1288. sm.save(
  1289. dup_iterator(begin().get_node(),end().get_node(),value_comp()),
  1290. dup_iterator(end().get_node(),value_comp()),
  1291. ar,version);
  1292. super::save_(ar,version,sm);
  1293. }
  1294. template<typename Archive>
  1295. void load_(
  1296. Archive& ar,const unsigned int version,const index_loader_type& lm,
  1297. ordered_non_unique_tag)
  1298. {
  1299. lm.load(
  1300. ::boost::bind(
  1301. &ordered_index_impl::rearranger,this,
  1302. ::boost::arg<1>(),::boost::arg<2>()),
  1303. ar,version);
  1304. super::load_(ar,version,lm);
  1305. }
  1306. void rearranger(index_node_type* position,index_node_type *x)
  1307. {
  1308. if(!position||comp_(key(position->value()),key(x->value()))){
  1309. position=lower_bound(key(x->value())).get_node();
  1310. }
  1311. else if(comp_(key(x->value()),key(position->value()))){
  1312. /* inconsistent rearrangement */
  1313. throw_exception(bad_archive_exception());
  1314. }
  1315. else index_node_type::increment(position);
  1316. if(position!=x){
  1317. node_impl_type::rebalance_for_extract(
  1318. x->impl(),header()->parent(),header()->left(),header()->right());
  1319. node_impl_type::restore(
  1320. x->impl(),position->impl(),header()->impl());
  1321. }
  1322. }
  1323. #endif /* serialization */
  1324. protected: /* for the benefit of AugmentPolicy::augmented_interface */
  1325. key_from_value key;
  1326. key_compare comp_;
  1327. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  1328. safe_container safe;
  1329. #endif
  1330. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
  1331. BOOST_WORKAROUND(__MWERKS__,<=0x3003)
  1332. #pragma parse_mfunc_templ reset
  1333. #endif
  1334. };
  1335. template<
  1336. typename KeyFromValue,typename Compare,
  1337. typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
  1338. >
  1339. class ordered_index:
  1340. public AugmentPolicy::template augmented_interface<
  1341. ordered_index_impl<
  1342. KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy
  1343. >
  1344. >::type
  1345. {
  1346. typedef typename AugmentPolicy::template
  1347. augmented_interface<
  1348. ordered_index_impl<
  1349. KeyFromValue,Compare,
  1350. SuperMeta,TagList,Category,AugmentPolicy
  1351. >
  1352. >::type super;
  1353. public:
  1354. typedef typename super::ctor_args_list ctor_args_list;
  1355. typedef typename super::allocator_type allocator_type;
  1356. typedef typename super::iterator iterator;
  1357. /* construct/copy/destroy
  1358. * Default and copy ctors are in the protected section as indices are
  1359. * not supposed to be created on their own. No range ctor either.
  1360. */
  1361. ordered_index& operator=(const ordered_index& x)
  1362. {
  1363. this->final()=x.final();
  1364. return *this;
  1365. }
  1366. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  1367. ordered_index& operator=(
  1368. std::initializer_list<BOOST_DEDUCED_TYPENAME super::value_type> list)
  1369. {
  1370. this->final()=list;
  1371. return *this;
  1372. }
  1373. #endif
  1374. protected:
  1375. ordered_index(
  1376. const ctor_args_list& args_list,const allocator_type& al):
  1377. super(args_list,al){}
  1378. ordered_index(const ordered_index& x):super(x){}
  1379. ordered_index(const ordered_index& x,do_not_copy_elements_tag):
  1380. super(x,do_not_copy_elements_tag()){}
  1381. };
  1382. #if defined(BOOST_MSVC)
  1383. #pragma warning(pop) /* C4355 */
  1384. #endif
  1385. /* comparison */
  1386. template<
  1387. typename KeyFromValue1,typename Compare1,
  1388. typename SuperMeta1,typename TagList1,typename Category1,
  1389. typename AugmentPolicy1,
  1390. typename KeyFromValue2,typename Compare2,
  1391. typename SuperMeta2,typename TagList2,typename Category2,
  1392. typename AugmentPolicy2
  1393. >
  1394. bool operator==(
  1395. const ordered_index<
  1396. KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
  1397. const ordered_index<
  1398. KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
  1399. {
  1400. return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
  1401. }
  1402. template<
  1403. typename KeyFromValue1,typename Compare1,
  1404. typename SuperMeta1,typename TagList1,typename Category1,
  1405. typename AugmentPolicy1,
  1406. typename KeyFromValue2,typename Compare2,
  1407. typename SuperMeta2,typename TagList2,typename Category2,
  1408. typename AugmentPolicy2
  1409. >
  1410. bool operator<(
  1411. const ordered_index<
  1412. KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
  1413. const ordered_index<
  1414. KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
  1415. {
  1416. return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
  1417. }
  1418. template<
  1419. typename KeyFromValue1,typename Compare1,
  1420. typename SuperMeta1,typename TagList1,typename Category1,
  1421. typename AugmentPolicy1,
  1422. typename KeyFromValue2,typename Compare2,
  1423. typename SuperMeta2,typename TagList2,typename Category2,
  1424. typename AugmentPolicy2
  1425. >
  1426. bool operator!=(
  1427. const ordered_index<
  1428. KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
  1429. const ordered_index<
  1430. KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
  1431. {
  1432. return !(x==y);
  1433. }
  1434. template<
  1435. typename KeyFromValue1,typename Compare1,
  1436. typename SuperMeta1,typename TagList1,typename Category1,
  1437. typename AugmentPolicy1,
  1438. typename KeyFromValue2,typename Compare2,
  1439. typename SuperMeta2,typename TagList2,typename Category2,
  1440. typename AugmentPolicy2
  1441. >
  1442. bool operator>(
  1443. const ordered_index<
  1444. KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
  1445. const ordered_index<
  1446. KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
  1447. {
  1448. return y<x;
  1449. }
  1450. template<
  1451. typename KeyFromValue1,typename Compare1,
  1452. typename SuperMeta1,typename TagList1,typename Category1,
  1453. typename AugmentPolicy1,
  1454. typename KeyFromValue2,typename Compare2,
  1455. typename SuperMeta2,typename TagList2,typename Category2,
  1456. typename AugmentPolicy2
  1457. >
  1458. bool operator>=(
  1459. const ordered_index<
  1460. KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
  1461. const ordered_index<
  1462. KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
  1463. {
  1464. return !(x<y);
  1465. }
  1466. template<
  1467. typename KeyFromValue1,typename Compare1,
  1468. typename SuperMeta1,typename TagList1,typename Category1,
  1469. typename AugmentPolicy1,
  1470. typename KeyFromValue2,typename Compare2,
  1471. typename SuperMeta2,typename TagList2,typename Category2,
  1472. typename AugmentPolicy2
  1473. >
  1474. bool operator<=(
  1475. const ordered_index<
  1476. KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x,
  1477. const ordered_index<
  1478. KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y)
  1479. {
  1480. return !(x>y);
  1481. }
  1482. /* specialized algorithms */
  1483. template<
  1484. typename KeyFromValue,typename Compare,
  1485. typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
  1486. >
  1487. void swap(
  1488. ordered_index<
  1489. KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x,
  1490. ordered_index<
  1491. KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y)
  1492. {
  1493. x.swap(y);
  1494. }
  1495. } /* namespace multi_index::detail */
  1496. } /* namespace multi_index */
  1497. } /* namespace boost */
  1498. /* Boost.Foreach compatibility */
  1499. namespace boost{
  1500. namespace foreach{
  1501. template<typename>
  1502. struct is_noncopyable;
  1503. template<
  1504. typename KeyFromValue,typename Compare,
  1505. typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy
  1506. >
  1507. struct is_noncopyable<
  1508. boost::multi_index::detail::ordered_index<
  1509. KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>
  1510. >:boost::mpl::true_{};
  1511. }
  1512. }
  1513. #undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
  1514. #undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF
  1515. #endif