ord_index_impl.hpp 46 KB

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