multi_index_container.hpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362
  1. /* Multiply indexed container.
  2. *
  3. * Copyright 2003-2014 Joaquin M Lopez Munoz.
  4. * Distributed under the Boost Software License, Version 1.0.
  5. * (See accompanying file LICENSE_1_0.txt or copy at
  6. * http://www.boost.org/LICENSE_1_0.txt)
  7. *
  8. * See http://www.boost.org/libs/multi_index for library home page.
  9. */
  10. #ifndef BOOST_MULTI_INDEX_HPP
  11. #define BOOST_MULTI_INDEX_HPP
  12. #if defined(_MSC_VER)
  13. #pragma once
  14. #endif
  15. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  16. #include <algorithm>
  17. #include <boost/detail/allocator_utilities.hpp>
  18. #include <boost/detail/no_exceptions_support.hpp>
  19. #include <boost/detail/workaround.hpp>
  20. #include <boost/move/core.hpp>
  21. #include <boost/mpl/at.hpp>
  22. #include <boost/mpl/contains.hpp>
  23. #include <boost/mpl/find_if.hpp>
  24. #include <boost/mpl/identity.hpp>
  25. #include <boost/mpl/int.hpp>
  26. #include <boost/mpl/size.hpp>
  27. #include <boost/mpl/deref.hpp>
  28. #include <boost/multi_index_container_fwd.hpp>
  29. #include <boost/multi_index/detail/access_specifier.hpp>
  30. #include <boost/multi_index/detail/adl_swap.hpp>
  31. #include <boost/multi_index/detail/base_type.hpp>
  32. #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
  33. #include <boost/multi_index/detail/converter.hpp>
  34. #include <boost/multi_index/detail/header_holder.hpp>
  35. #include <boost/multi_index/detail/has_tag.hpp>
  36. #include <boost/multi_index/detail/no_duplicate_tags.hpp>
  37. #include <boost/multi_index/detail/safe_mode.hpp>
  38. #include <boost/multi_index/detail/scope_guard.hpp>
  39. #include <boost/multi_index/detail/vartempl_support.hpp>
  40. #include <boost/static_assert.hpp>
  41. #include <boost/type_traits/is_same.hpp>
  42. #include <boost/utility/base_from_member.hpp>
  43. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  44. #include <initializer_list>
  45. #endif
  46. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  47. #include <boost/multi_index/detail/archive_constructed.hpp>
  48. #include <boost/multi_index/detail/serialization_version.hpp>
  49. #include <boost/serialization/collection_size_type.hpp>
  50. #include <boost/serialization/nvp.hpp>
  51. #include <boost/serialization/split_member.hpp>
  52. #include <boost/serialization/version.hpp>
  53. #include <boost/throw_exception.hpp>
  54. #endif
  55. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
  56. #include <boost/multi_index/detail/invariant_assert.hpp>
  57. #define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) \
  58. detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
  59. detail::make_obj_guard(x,&multi_index_container::check_invariant_); \
  60. BOOST_JOIN(check_invariant_,__LINE__).touch();
  61. #define BOOST_MULTI_INDEX_CHECK_INVARIANT \
  62. BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(*this)
  63. #else
  64. #define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x)
  65. #define BOOST_MULTI_INDEX_CHECK_INVARIANT
  66. #endif
  67. namespace boost{
  68. namespace multi_index{
  69. #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
  70. #pragma warning(push)
  71. #pragma warning(disable:4522) /* spurious warning on multiple operator=()'s */
  72. #endif
  73. template<typename Value,typename IndexSpecifierList,typename Allocator>
  74. class multi_index_container:
  75. private ::boost::base_from_member<
  76. typename boost::detail::allocator::rebind_to<
  77. Allocator,
  78. typename detail::multi_index_node_type<
  79. Value,IndexSpecifierList,Allocator>::type
  80. >::type>,
  81. BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder<
  82. typename boost::detail::allocator::rebind_to<
  83. Allocator,
  84. typename detail::multi_index_node_type<
  85. Value,IndexSpecifierList,Allocator>::type
  86. >::type::pointer,
  87. multi_index_container<Value,IndexSpecifierList,Allocator> >,
  88. public detail::multi_index_base_type<
  89. Value,IndexSpecifierList,Allocator>::type
  90. {
  91. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
  92. BOOST_WORKAROUND(__MWERKS__,<=0x3003)
  93. /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
  94. * lifetime of const references bound to temporaries --precisely what
  95. * scopeguards are.
  96. */
  97. #pragma parse_mfunc_templ off
  98. #endif
  99. private:
  100. BOOST_COPYABLE_AND_MOVABLE(multi_index_container)
  101. #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
  102. template <typename,typename,typename> friend class detail::index_base;
  103. template <typename,typename> friend struct detail::header_holder;
  104. template <typename,typename> friend struct detail::converter;
  105. #endif
  106. typedef typename detail::multi_index_base_type<
  107. Value,IndexSpecifierList,Allocator>::type super;
  108. typedef typename
  109. boost::detail::allocator::rebind_to<
  110. Allocator,
  111. typename super::node_type
  112. >::type node_allocator;
  113. typedef ::boost::base_from_member<
  114. node_allocator> bfm_allocator;
  115. typedef detail::header_holder<
  116. typename node_allocator::pointer,
  117. multi_index_container> bfm_header;
  118. public:
  119. /* All types are inherited from super, a few are explicitly
  120. * brought forward here to save us some typename's.
  121. */
  122. typedef typename super::ctor_args_list ctor_args_list;
  123. typedef IndexSpecifierList index_specifier_type_list;
  124. typedef typename super::index_type_list index_type_list;
  125. typedef typename super::iterator_type_list iterator_type_list;
  126. typedef typename super::const_iterator_type_list const_iterator_type_list;
  127. typedef typename super::value_type value_type;
  128. typedef typename super::final_allocator_type allocator_type;
  129. typedef typename super::iterator iterator;
  130. typedef typename super::const_iterator const_iterator;
  131. BOOST_STATIC_ASSERT(
  132. detail::no_duplicate_tags_in_index_list<index_type_list>::value);
  133. /* global project() needs to see this publicly */
  134. typedef typename super::node_type node_type;
  135. /* construct/copy/destroy */
  136. explicit multi_index_container(
  137. #if BOOST_WORKAROUND(__IBMCPP__,<=600)
  138. /* VisualAge seems to have an ETI issue with the default values
  139. * for arguments args_list and al.
  140. */
  141. const ctor_args_list& args_list=
  142. typename mpl::identity<multi_index_container>::type::
  143. ctor_args_list(),
  144. const allocator_type& al=
  145. typename mpl::identity<multi_index_container>::type::
  146. allocator_type()):
  147. #else
  148. const ctor_args_list& args_list=ctor_args_list(),
  149. const allocator_type& al=allocator_type()):
  150. #endif
  151. bfm_allocator(al),
  152. super(args_list,bfm_allocator::member),
  153. node_count(0)
  154. {
  155. BOOST_MULTI_INDEX_CHECK_INVARIANT;
  156. }
  157. explicit multi_index_container(const allocator_type& al):
  158. bfm_allocator(al),
  159. super(ctor_args_list(),bfm_allocator::member),
  160. node_count(0)
  161. {
  162. BOOST_MULTI_INDEX_CHECK_INVARIANT;
  163. }
  164. template<typename InputIterator>
  165. multi_index_container(
  166. InputIterator first,InputIterator last,
  167. #if BOOST_WORKAROUND(__IBMCPP__,<=600)
  168. /* VisualAge seems to have an ETI issue with the default values
  169. * for arguments args_list and al.
  170. */
  171. const ctor_args_list& args_list=
  172. typename mpl::identity<multi_index_container>::type::
  173. ctor_args_list(),
  174. const allocator_type& al=
  175. typename mpl::identity<multi_index_container>::type::
  176. allocator_type()):
  177. #else
  178. const ctor_args_list& args_list=ctor_args_list(),
  179. const allocator_type& al=allocator_type()):
  180. #endif
  181. bfm_allocator(al),
  182. super(args_list,bfm_allocator::member),
  183. node_count(0)
  184. {
  185. BOOST_MULTI_INDEX_CHECK_INVARIANT;
  186. BOOST_TRY{
  187. iterator hint=super::end();
  188. for(;first!=last;++first){
  189. hint=super::make_iterator(
  190. insert_ref_(*first,hint.get_node()).first);
  191. ++hint;
  192. }
  193. }
  194. BOOST_CATCH(...){
  195. clear_();
  196. BOOST_RETHROW;
  197. }
  198. BOOST_CATCH_END
  199. }
  200. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  201. multi_index_container(
  202. std::initializer_list<Value> list,
  203. const ctor_args_list& args_list=ctor_args_list(),
  204. const allocator_type& al=allocator_type()):
  205. bfm_allocator(al),
  206. super(args_list,bfm_allocator::member),
  207. node_count(0)
  208. {
  209. BOOST_MULTI_INDEX_CHECK_INVARIANT;
  210. BOOST_TRY{
  211. typedef const Value* init_iterator;
  212. iterator hint=super::end();
  213. for(init_iterator first=list.begin(),last=list.end();
  214. first!=last;++first){
  215. hint=super::make_iterator(insert_(*first,hint.get_node()).first);
  216. ++hint;
  217. }
  218. }
  219. BOOST_CATCH(...){
  220. clear_();
  221. BOOST_RETHROW;
  222. }
  223. BOOST_CATCH_END
  224. }
  225. #endif
  226. multi_index_container(
  227. const multi_index_container<Value,IndexSpecifierList,Allocator>& x):
  228. bfm_allocator(x.bfm_allocator::member),
  229. bfm_header(),
  230. super(x),
  231. node_count(0)
  232. {
  233. copy_map_type map(bfm_allocator::member,x.size(),x.header(),header());
  234. for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){
  235. map.clone(it.get_node());
  236. }
  237. super::copy_(x,map);
  238. map.release();
  239. node_count=x.size();
  240. /* Not until this point are the indices required to be consistent,
  241. * hence the position of the invariant checker.
  242. */
  243. BOOST_MULTI_INDEX_CHECK_INVARIANT;
  244. }
  245. multi_index_container(BOOST_RV_REF(multi_index_container) x):
  246. bfm_allocator(x.bfm_allocator::member),
  247. bfm_header(),
  248. super(x,detail::do_not_copy_elements_tag()),
  249. node_count(0)
  250. {
  251. BOOST_MULTI_INDEX_CHECK_INVARIANT;
  252. BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x);
  253. swap_elements_(x);
  254. }
  255. ~multi_index_container()
  256. {
  257. delete_all_nodes_();
  258. }
  259. #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  260. /* As per http://www.boost.org/doc/html/move/emulation_limitations.html
  261. * #move.emulation_limitations.assignment_operator
  262. */
  263. multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
  264. const multi_index_container<Value,IndexSpecifierList,Allocator>& x)
  265. {
  266. multi_index_container y(x);
  267. this->swap(y);
  268. return *this;
  269. }
  270. #endif
  271. multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
  272. BOOST_COPY_ASSIGN_REF(multi_index_container) x)
  273. {
  274. multi_index_container y(x);
  275. this->swap(y);
  276. return *this;
  277. }
  278. multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
  279. BOOST_RV_REF(multi_index_container) x)
  280. {
  281. this->swap(x);
  282. return *this;
  283. }
  284. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  285. multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
  286. std::initializer_list<Value> list)
  287. {
  288. BOOST_MULTI_INDEX_CHECK_INVARIANT;
  289. typedef const Value* init_iterator;
  290. multi_index_container x(*this,detail::do_not_copy_elements_tag());
  291. iterator hint=x.end();
  292. for(init_iterator first=list.begin(),last=list.end();
  293. first!=last;++first){
  294. hint=x.make_iterator(x.insert_(*first,hint.get_node()).first);
  295. ++hint;
  296. }
  297. x.swap_elements_(*this);
  298. return*this;
  299. }
  300. #endif
  301. allocator_type get_allocator()const BOOST_NOEXCEPT
  302. {
  303. return allocator_type(bfm_allocator::member);
  304. }
  305. /* retrieval of indices by number */
  306. #if !defined(BOOST_NO_MEMBER_TEMPLATES)
  307. template<int N>
  308. struct nth_index
  309. {
  310. BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
  311. typedef typename mpl::at_c<index_type_list,N>::type type;
  312. };
  313. template<int N>
  314. typename nth_index<N>::type& get()BOOST_NOEXCEPT
  315. {
  316. BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
  317. return *this;
  318. }
  319. template<int N>
  320. const typename nth_index<N>::type& get()const BOOST_NOEXCEPT
  321. {
  322. BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
  323. return *this;
  324. }
  325. #endif
  326. /* retrieval of indices by tag */
  327. #if !defined(BOOST_NO_MEMBER_TEMPLATES)
  328. template<typename Tag>
  329. struct index
  330. {
  331. typedef typename mpl::find_if<
  332. index_type_list,
  333. detail::has_tag<Tag>
  334. >::type iter;
  335. BOOST_STATIC_CONSTANT(
  336. bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
  337. BOOST_STATIC_ASSERT(index_found);
  338. typedef typename mpl::deref<iter>::type type;
  339. };
  340. template<typename Tag>
  341. typename index<Tag>::type& get()BOOST_NOEXCEPT
  342. {
  343. return *this;
  344. }
  345. template<typename Tag>
  346. const typename index<Tag>::type& get()const BOOST_NOEXCEPT
  347. {
  348. return *this;
  349. }
  350. #endif
  351. /* projection of iterators by number */
  352. #if !defined(BOOST_NO_MEMBER_TEMPLATES)
  353. template<int N>
  354. struct nth_index_iterator
  355. {
  356. typedef typename nth_index<N>::type::iterator type;
  357. };
  358. template<int N>
  359. struct nth_index_const_iterator
  360. {
  361. typedef typename nth_index<N>::type::const_iterator type;
  362. };
  363. template<int N,typename IteratorType>
  364. typename nth_index_iterator<N>::type project(IteratorType it)
  365. {
  366. typedef typename nth_index<N>::type index_type;
  367. #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
  368. BOOST_STATIC_ASSERT(
  369. (mpl::contains<iterator_type_list,IteratorType>::value));
  370. #endif
  371. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
  372. BOOST_MULTI_INDEX_CHECK_IS_OWNER(
  373. it,static_cast<typename IteratorType::container_type&>(*this));
  374. return index_type::make_iterator(static_cast<node_type*>(it.get_node()));
  375. }
  376. template<int N,typename IteratorType>
  377. typename nth_index_const_iterator<N>::type project(IteratorType it)const
  378. {
  379. typedef typename nth_index<N>::type index_type;
  380. #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
  381. BOOST_STATIC_ASSERT((
  382. mpl::contains<iterator_type_list,IteratorType>::value||
  383. mpl::contains<const_iterator_type_list,IteratorType>::value));
  384. #endif
  385. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
  386. BOOST_MULTI_INDEX_CHECK_IS_OWNER(
  387. it,static_cast<const typename IteratorType::container_type&>(*this));
  388. return index_type::make_iterator(static_cast<node_type*>(it.get_node()));
  389. }
  390. #endif
  391. /* projection of iterators by tag */
  392. #if !defined(BOOST_NO_MEMBER_TEMPLATES)
  393. template<typename Tag>
  394. struct index_iterator
  395. {
  396. typedef typename index<Tag>::type::iterator type;
  397. };
  398. template<typename Tag>
  399. struct index_const_iterator
  400. {
  401. typedef typename index<Tag>::type::const_iterator type;
  402. };
  403. template<typename Tag,typename IteratorType>
  404. typename index_iterator<Tag>::type project(IteratorType it)
  405. {
  406. typedef typename index<Tag>::type index_type;
  407. #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
  408. BOOST_STATIC_ASSERT(
  409. (mpl::contains<iterator_type_list,IteratorType>::value));
  410. #endif
  411. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
  412. BOOST_MULTI_INDEX_CHECK_IS_OWNER(
  413. it,static_cast<typename IteratorType::container_type&>(*this));
  414. return index_type::make_iterator(static_cast<node_type*>(it.get_node()));
  415. }
  416. template<typename Tag,typename IteratorType>
  417. typename index_const_iterator<Tag>::type project(IteratorType it)const
  418. {
  419. typedef typename index<Tag>::type index_type;
  420. #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
  421. BOOST_STATIC_ASSERT((
  422. mpl::contains<iterator_type_list,IteratorType>::value||
  423. mpl::contains<const_iterator_type_list,IteratorType>::value));
  424. #endif
  425. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
  426. BOOST_MULTI_INDEX_CHECK_IS_OWNER(
  427. it,static_cast<const typename IteratorType::container_type&>(*this));
  428. return index_type::make_iterator(static_cast<node_type*>(it.get_node()));
  429. }
  430. #endif
  431. BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
  432. typedef typename super::copy_map_type copy_map_type;
  433. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  434. multi_index_container(
  435. const multi_index_container<Value,IndexSpecifierList,Allocator>& x,
  436. detail::do_not_copy_elements_tag):
  437. bfm_allocator(x.bfm_allocator::member),
  438. bfm_header(),
  439. super(x,detail::do_not_copy_elements_tag()),
  440. node_count(0)
  441. {
  442. BOOST_MULTI_INDEX_CHECK_INVARIANT;
  443. }
  444. #endif
  445. node_type* header()const
  446. {
  447. return &*bfm_header::member;
  448. }
  449. node_type* allocate_node()
  450. {
  451. return &*bfm_allocator::member.allocate(1);
  452. }
  453. void deallocate_node(node_type* x)
  454. {
  455. typedef typename node_allocator::pointer node_pointer;
  456. bfm_allocator::member.deallocate(static_cast<node_pointer>(x),1);
  457. }
  458. bool empty_()const
  459. {
  460. return node_count==0;
  461. }
  462. std::size_t size_()const
  463. {
  464. return node_count;
  465. }
  466. std::size_t max_size_()const
  467. {
  468. return static_cast<std::size_t >(-1);
  469. }
  470. template<typename Variant>
  471. std::pair<node_type*,bool> insert_(const Value& v,Variant variant)
  472. {
  473. node_type* x=0;
  474. node_type* res=super::insert_(v,x,variant);
  475. if(res==x){
  476. ++node_count;
  477. return std::pair<node_type*,bool>(res,true);
  478. }
  479. else{
  480. return std::pair<node_type*,bool>(res,false);
  481. }
  482. }
  483. std::pair<node_type*,bool> insert_(const Value& v)
  484. {
  485. return insert_(v,detail::lvalue_tag());
  486. }
  487. std::pair<node_type*,bool> insert_rv_(const Value& v)
  488. {
  489. return insert_(v,detail::rvalue_tag());
  490. }
  491. template<typename T>
  492. std::pair<node_type*,bool> insert_ref_(T& t)
  493. {
  494. node_type* x=allocate_node();
  495. BOOST_TRY{
  496. new(&x->value()) value_type(t);
  497. BOOST_TRY{
  498. node_type* res=super::insert_(x->value(),x,detail::emplaced_tag());
  499. if(res==x){
  500. ++node_count;
  501. return std::pair<node_type*,bool>(res,true);
  502. }
  503. else{
  504. boost::detail::allocator::destroy(&x->value());
  505. deallocate_node(x);
  506. return std::pair<node_type*,bool>(res,false);
  507. }
  508. }
  509. BOOST_CATCH(...){
  510. boost::detail::allocator::destroy(&x->value());
  511. BOOST_RETHROW;
  512. }
  513. BOOST_CATCH_END
  514. }
  515. BOOST_CATCH(...){
  516. deallocate_node(x);
  517. BOOST_RETHROW;
  518. }
  519. BOOST_CATCH_END
  520. }
  521. std::pair<node_type*,bool> insert_ref_(const value_type& x)
  522. {
  523. return insert_(x);
  524. }
  525. std::pair<node_type*,bool> insert_ref_(value_type& x)
  526. {
  527. return insert_(x);
  528. }
  529. template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
  530. std::pair<node_type*,bool> emplace_(
  531. BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
  532. {
  533. node_type* x=allocate_node();
  534. BOOST_TRY{
  535. detail::vartempl_placement_new(
  536. &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
  537. BOOST_TRY{
  538. node_type* res=super::insert_(x->value(),x,detail::emplaced_tag());
  539. if(res==x){
  540. ++node_count;
  541. return std::pair<node_type*,bool>(res,true);
  542. }
  543. else{
  544. boost::detail::allocator::destroy(&x->value());
  545. deallocate_node(x);
  546. return std::pair<node_type*,bool>(res,false);
  547. }
  548. }
  549. BOOST_CATCH(...){
  550. boost::detail::allocator::destroy(&x->value());
  551. BOOST_RETHROW;
  552. }
  553. BOOST_CATCH_END
  554. }
  555. BOOST_CATCH(...){
  556. deallocate_node(x);
  557. BOOST_RETHROW;
  558. }
  559. BOOST_CATCH_END
  560. }
  561. template<typename Variant>
  562. std::pair<node_type*,bool> insert_(
  563. const Value& v,node_type* position,Variant variant)
  564. {
  565. node_type* x=0;
  566. node_type* res=super::insert_(v,position,x,variant);
  567. if(res==x){
  568. ++node_count;
  569. return std::pair<node_type*,bool>(res,true);
  570. }
  571. else{
  572. return std::pair<node_type*,bool>(res,false);
  573. }
  574. }
  575. std::pair<node_type*,bool> insert_(const Value& v,node_type* position)
  576. {
  577. return insert_(v,position,detail::lvalue_tag());
  578. }
  579. std::pair<node_type*,bool> insert_rv_(const Value& v,node_type* position)
  580. {
  581. return insert_(v,position,detail::rvalue_tag());
  582. }
  583. template<typename T>
  584. std::pair<node_type*,bool> insert_ref_(
  585. T& t,node_type* position)
  586. {
  587. node_type* x=allocate_node();
  588. BOOST_TRY{
  589. new(&x->value()) value_type(t);
  590. BOOST_TRY{
  591. node_type* res=super::insert_(
  592. x->value(),position,x,detail::emplaced_tag());
  593. if(res==x){
  594. ++node_count;
  595. return std::pair<node_type*,bool>(res,true);
  596. }
  597. else{
  598. boost::detail::allocator::destroy(&x->value());
  599. deallocate_node(x);
  600. return std::pair<node_type*,bool>(res,false);
  601. }
  602. }
  603. BOOST_CATCH(...){
  604. boost::detail::allocator::destroy(&x->value());
  605. BOOST_RETHROW;
  606. }
  607. BOOST_CATCH_END
  608. }
  609. BOOST_CATCH(...){
  610. deallocate_node(x);
  611. BOOST_RETHROW;
  612. }
  613. BOOST_CATCH_END
  614. }
  615. std::pair<node_type*,bool> insert_ref_(
  616. const value_type& x,node_type* position)
  617. {
  618. return insert_(x,position);
  619. }
  620. std::pair<node_type*,bool> insert_ref_(
  621. value_type& x,node_type* position)
  622. {
  623. return insert_(x,position);
  624. }
  625. template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
  626. std::pair<node_type*,bool> emplace_hint_(
  627. node_type* position,
  628. BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
  629. {
  630. node_type* x=allocate_node();
  631. BOOST_TRY{
  632. detail::vartempl_placement_new(
  633. &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
  634. BOOST_TRY{
  635. node_type* res=super::insert_(
  636. x->value(),position,x,detail::emplaced_tag());
  637. if(res==x){
  638. ++node_count;
  639. return std::pair<node_type*,bool>(res,true);
  640. }
  641. else{
  642. boost::detail::allocator::destroy(&x->value());
  643. deallocate_node(x);
  644. return std::pair<node_type*,bool>(res,false);
  645. }
  646. }
  647. BOOST_CATCH(...){
  648. boost::detail::allocator::destroy(&x->value());
  649. BOOST_RETHROW;
  650. }
  651. BOOST_CATCH_END
  652. }
  653. BOOST_CATCH(...){
  654. deallocate_node(x);
  655. BOOST_RETHROW;
  656. }
  657. BOOST_CATCH_END
  658. }
  659. void erase_(node_type* x)
  660. {
  661. --node_count;
  662. super::erase_(x);
  663. deallocate_node(x);
  664. }
  665. void delete_node_(node_type* x)
  666. {
  667. super::delete_node_(x);
  668. deallocate_node(x);
  669. }
  670. void delete_all_nodes_()
  671. {
  672. super::delete_all_nodes_();
  673. }
  674. void clear_()
  675. {
  676. delete_all_nodes_();
  677. super::clear_();
  678. node_count=0;
  679. }
  680. void swap_(multi_index_container<Value,IndexSpecifierList,Allocator>& x)
  681. {
  682. if(bfm_allocator::member!=x.bfm_allocator::member){
  683. detail::adl_swap(bfm_allocator::member,x.bfm_allocator::member);
  684. }
  685. std::swap(bfm_header::member,x.bfm_header::member);
  686. super::swap_(x);
  687. std::swap(node_count,x.node_count);
  688. }
  689. void swap_elements_(
  690. multi_index_container<Value,IndexSpecifierList,Allocator>& x)
  691. {
  692. std::swap(bfm_header::member,x.bfm_header::member);
  693. super::swap_elements_(x);
  694. std::swap(node_count,x.node_count);
  695. }
  696. bool replace_(const Value& k,node_type* x)
  697. {
  698. return super::replace_(k,x,detail::lvalue_tag());
  699. }
  700. bool replace_rv_(const Value& k,node_type* x)
  701. {
  702. return super::replace_(k,x,detail::rvalue_tag());
  703. }
  704. template<typename Modifier>
  705. bool modify_(Modifier& mod,node_type* x)
  706. {
  707. mod(const_cast<value_type&>(x->value()));
  708. BOOST_TRY{
  709. if(!super::modify_(x)){
  710. deallocate_node(x);
  711. --node_count;
  712. return false;
  713. }
  714. else return true;
  715. }
  716. BOOST_CATCH(...){
  717. deallocate_node(x);
  718. --node_count;
  719. BOOST_RETHROW;
  720. }
  721. BOOST_CATCH_END
  722. }
  723. template<typename Modifier,typename Rollback>
  724. bool modify_(Modifier& mod,Rollback& back_,node_type* x)
  725. {
  726. mod(const_cast<value_type&>(x->value()));
  727. bool b;
  728. BOOST_TRY{
  729. b=super::modify_rollback_(x);
  730. }
  731. BOOST_CATCH(...){
  732. BOOST_TRY{
  733. back_(const_cast<value_type&>(x->value()));
  734. BOOST_RETHROW;
  735. }
  736. BOOST_CATCH(...){
  737. this->erase_(x);
  738. BOOST_RETHROW;
  739. }
  740. BOOST_CATCH_END
  741. }
  742. BOOST_CATCH_END
  743. BOOST_TRY{
  744. if(!b){
  745. back_(const_cast<value_type&>(x->value()));
  746. return false;
  747. }
  748. else return true;
  749. }
  750. BOOST_CATCH(...){
  751. this->erase_(x);
  752. BOOST_RETHROW;
  753. }
  754. BOOST_CATCH_END
  755. }
  756. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  757. /* serialization */
  758. friend class boost::serialization::access;
  759. BOOST_SERIALIZATION_SPLIT_MEMBER()
  760. typedef typename super::index_saver_type index_saver_type;
  761. typedef typename super::index_loader_type index_loader_type;
  762. template<class Archive>
  763. void save(Archive& ar,const unsigned int version)const
  764. {
  765. const serialization::collection_size_type s(size_());
  766. const detail::serialization_version<value_type> value_version;
  767. ar<<serialization::make_nvp("count",s);
  768. ar<<serialization::make_nvp("value_version",value_version);
  769. index_saver_type sm(bfm_allocator::member,s);
  770. for(iterator it=super::begin(),it_end=super::end();it!=it_end;++it){
  771. serialization::save_construct_data_adl(ar,&*it,value_version);
  772. ar<<serialization::make_nvp("item",*it);
  773. sm.add(it.get_node(),ar,version);
  774. }
  775. sm.add_track(header(),ar,version);
  776. super::save_(ar,version,sm);
  777. }
  778. template<class Archive>
  779. void load(Archive& ar,const unsigned int version)
  780. {
  781. BOOST_MULTI_INDEX_CHECK_INVARIANT;
  782. clear_();
  783. serialization::collection_size_type s;
  784. detail::serialization_version<value_type> value_version;
  785. if(version<1){
  786. std::size_t sz;
  787. ar>>serialization::make_nvp("count",sz);
  788. s=static_cast<serialization::collection_size_type>(sz);
  789. }
  790. else{
  791. ar>>serialization::make_nvp("count",s);
  792. }
  793. if(version<2){
  794. value_version=0;
  795. }
  796. else{
  797. ar>>serialization::make_nvp("value_version",value_version);
  798. }
  799. index_loader_type lm(bfm_allocator::member,s);
  800. for(std::size_t n=0;n<s;++n){
  801. detail::archive_constructed<Value> value("item",ar,value_version);
  802. std::pair<node_type*,bool> p=insert_(
  803. value.get(),super::end().get_node());
  804. if(!p.second)throw_exception(
  805. archive::archive_exception(
  806. archive::archive_exception::other_exception));
  807. ar.reset_object_address(&p.first->value(),&value.get());
  808. lm.add(p.first,ar,version);
  809. }
  810. lm.add_track(header(),ar,version);
  811. super::load_(ar,version,lm);
  812. }
  813. #endif
  814. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
  815. /* invariant stuff */
  816. bool invariant_()const
  817. {
  818. return super::invariant_();
  819. }
  820. void check_invariant_()const
  821. {
  822. BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_());
  823. }
  824. #endif
  825. private:
  826. std::size_t node_count;
  827. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
  828. BOOST_WORKAROUND(__MWERKS__,<=0x3003)
  829. #pragma parse_mfunc_templ reset
  830. #endif
  831. };
  832. #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
  833. #pragma warning(pop) /* C4522 */
  834. #endif
  835. /* retrieval of indices by number */
  836. template<typename MultiIndexContainer,int N>
  837. struct nth_index
  838. {
  839. BOOST_STATIC_CONSTANT(
  840. int,
  841. M=mpl::size<typename MultiIndexContainer::index_type_list>::type::value);
  842. BOOST_STATIC_ASSERT(N>=0&&N<M);
  843. typedef typename mpl::at_c<
  844. typename MultiIndexContainer::index_type_list,N>::type type;
  845. };
  846. template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
  847. typename nth_index<
  848. multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
  849. get(
  850. multi_index_container<Value,IndexSpecifierList,Allocator>& m)BOOST_NOEXCEPT
  851. {
  852. typedef multi_index_container<
  853. Value,IndexSpecifierList,Allocator> multi_index_type;
  854. typedef typename nth_index<
  855. multi_index_container<
  856. Value,IndexSpecifierList,Allocator>,
  857. N
  858. >::type index_type;
  859. BOOST_STATIC_ASSERT(N>=0&&
  860. N<
  861. mpl::size<
  862. BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
  863. >::type::value);
  864. return detail::converter<multi_index_type,index_type>::index(m);
  865. }
  866. template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
  867. const typename nth_index<
  868. multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
  869. get(
  870. const multi_index_container<Value,IndexSpecifierList,Allocator>& m
  871. )BOOST_NOEXCEPT
  872. {
  873. typedef multi_index_container<
  874. Value,IndexSpecifierList,Allocator> multi_index_type;
  875. typedef typename nth_index<
  876. multi_index_container<
  877. Value,IndexSpecifierList,Allocator>,
  878. N
  879. >::type index_type;
  880. BOOST_STATIC_ASSERT(N>=0&&
  881. N<
  882. mpl::size<
  883. BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
  884. >::type::value);
  885. return detail::converter<multi_index_type,index_type>::index(m);
  886. }
  887. /* retrieval of indices by tag */
  888. template<typename MultiIndexContainer,typename Tag>
  889. struct index
  890. {
  891. typedef typename MultiIndexContainer::index_type_list index_type_list;
  892. typedef typename mpl::find_if<
  893. index_type_list,
  894. detail::has_tag<Tag>
  895. >::type iter;
  896. BOOST_STATIC_CONSTANT(
  897. bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
  898. BOOST_STATIC_ASSERT(index_found);
  899. typedef typename mpl::deref<iter>::type type;
  900. };
  901. template<
  902. typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
  903. >
  904. typename ::boost::multi_index::index<
  905. multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
  906. get(
  907. multi_index_container<Value,IndexSpecifierList,Allocator>& m)BOOST_NOEXCEPT
  908. {
  909. typedef multi_index_container<
  910. Value,IndexSpecifierList,Allocator> multi_index_type;
  911. typedef typename ::boost::multi_index::index<
  912. multi_index_container<
  913. Value,IndexSpecifierList,Allocator>,
  914. Tag
  915. >::type index_type;
  916. return detail::converter<multi_index_type,index_type>::index(m);
  917. }
  918. template<
  919. typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
  920. >
  921. const typename ::boost::multi_index::index<
  922. multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
  923. get(
  924. const multi_index_container<Value,IndexSpecifierList,Allocator>& m
  925. )BOOST_NOEXCEPT
  926. {
  927. typedef multi_index_container<
  928. Value,IndexSpecifierList,Allocator> multi_index_type;
  929. typedef typename ::boost::multi_index::index<
  930. multi_index_container<
  931. Value,IndexSpecifierList,Allocator>,
  932. Tag
  933. >::type index_type;
  934. return detail::converter<multi_index_type,index_type>::index(m);
  935. }
  936. /* projection of iterators by number */
  937. template<typename MultiIndexContainer,int N>
  938. struct nth_index_iterator
  939. {
  940. typedef typename nth_index<MultiIndexContainer,N>::type::iterator type;
  941. };
  942. template<typename MultiIndexContainer,int N>
  943. struct nth_index_const_iterator
  944. {
  945. typedef typename nth_index<MultiIndexContainer,N>::type::const_iterator type;
  946. };
  947. template<
  948. int N,typename IteratorType,
  949. typename Value,typename IndexSpecifierList,typename Allocator>
  950. typename nth_index_iterator<
  951. multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
  952. project(
  953. multi_index_container<Value,IndexSpecifierList,Allocator>& m,
  954. IteratorType it)
  955. {
  956. typedef multi_index_container<
  957. Value,IndexSpecifierList,Allocator> multi_index_type;
  958. typedef typename nth_index<multi_index_type,N>::type index_type;
  959. #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
  960. BOOST_STATIC_ASSERT((
  961. mpl::contains<
  962. BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
  963. IteratorType>::value));
  964. #endif
  965. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
  966. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  967. typedef detail::converter<
  968. multi_index_type,
  969. BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
  970. BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
  971. #endif
  972. return detail::converter<multi_index_type,index_type>::iterator(
  973. m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
  974. }
  975. template<
  976. int N,typename IteratorType,
  977. typename Value,typename IndexSpecifierList,typename Allocator>
  978. typename nth_index_const_iterator<
  979. multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
  980. project(
  981. const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
  982. IteratorType it)
  983. {
  984. typedef multi_index_container<
  985. Value,IndexSpecifierList,Allocator> multi_index_type;
  986. typedef typename nth_index<multi_index_type,N>::type index_type;
  987. #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
  988. BOOST_STATIC_ASSERT((
  989. mpl::contains<
  990. BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
  991. IteratorType>::value||
  992. mpl::contains<
  993. BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
  994. IteratorType>::value));
  995. #endif
  996. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
  997. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  998. typedef detail::converter<
  999. multi_index_type,
  1000. BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
  1001. BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
  1002. #endif
  1003. return detail::converter<multi_index_type,index_type>::const_iterator(
  1004. m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
  1005. }
  1006. /* projection of iterators by tag */
  1007. template<typename MultiIndexContainer,typename Tag>
  1008. struct index_iterator
  1009. {
  1010. typedef typename ::boost::multi_index::index<
  1011. MultiIndexContainer,Tag>::type::iterator type;
  1012. };
  1013. template<typename MultiIndexContainer,typename Tag>
  1014. struct index_const_iterator
  1015. {
  1016. typedef typename ::boost::multi_index::index<
  1017. MultiIndexContainer,Tag>::type::const_iterator type;
  1018. };
  1019. template<
  1020. typename Tag,typename IteratorType,
  1021. typename Value,typename IndexSpecifierList,typename Allocator>
  1022. typename index_iterator<
  1023. multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
  1024. project(
  1025. multi_index_container<Value,IndexSpecifierList,Allocator>& m,
  1026. IteratorType it)
  1027. {
  1028. typedef multi_index_container<
  1029. Value,IndexSpecifierList,Allocator> multi_index_type;
  1030. typedef typename ::boost::multi_index::index<
  1031. multi_index_type,Tag>::type index_type;
  1032. #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
  1033. BOOST_STATIC_ASSERT((
  1034. mpl::contains<
  1035. BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
  1036. IteratorType>::value));
  1037. #endif
  1038. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
  1039. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  1040. typedef detail::converter<
  1041. multi_index_type,
  1042. BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
  1043. BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
  1044. #endif
  1045. return detail::converter<multi_index_type,index_type>::iterator(
  1046. m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
  1047. }
  1048. template<
  1049. typename Tag,typename IteratorType,
  1050. typename Value,typename IndexSpecifierList,typename Allocator>
  1051. typename index_const_iterator<
  1052. multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
  1053. project(
  1054. const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
  1055. IteratorType it)
  1056. {
  1057. typedef multi_index_container<
  1058. Value,IndexSpecifierList,Allocator> multi_index_type;
  1059. typedef typename ::boost::multi_index::index<
  1060. multi_index_type,Tag>::type index_type;
  1061. #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
  1062. BOOST_STATIC_ASSERT((
  1063. mpl::contains<
  1064. BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
  1065. IteratorType>::value||
  1066. mpl::contains<
  1067. BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
  1068. IteratorType>::value));
  1069. #endif
  1070. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
  1071. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  1072. typedef detail::converter<
  1073. multi_index_type,
  1074. BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
  1075. BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
  1076. #endif
  1077. return detail::converter<multi_index_type,index_type>::const_iterator(
  1078. m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
  1079. }
  1080. /* Comparison. Simple forward to first index. */
  1081. template<
  1082. typename Value1,typename IndexSpecifierList1,typename Allocator1,
  1083. typename Value2,typename IndexSpecifierList2,typename Allocator2
  1084. >
  1085. bool operator==(
  1086. const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
  1087. const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
  1088. {
  1089. return get<0>(x)==get<0>(y);
  1090. }
  1091. template<
  1092. typename Value1,typename IndexSpecifierList1,typename Allocator1,
  1093. typename Value2,typename IndexSpecifierList2,typename Allocator2
  1094. >
  1095. bool operator<(
  1096. const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
  1097. const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
  1098. {
  1099. return get<0>(x)<get<0>(y);
  1100. }
  1101. template<
  1102. typename Value1,typename IndexSpecifierList1,typename Allocator1,
  1103. typename Value2,typename IndexSpecifierList2,typename Allocator2
  1104. >
  1105. bool operator!=(
  1106. const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
  1107. const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
  1108. {
  1109. return get<0>(x)!=get<0>(y);
  1110. }
  1111. template<
  1112. typename Value1,typename IndexSpecifierList1,typename Allocator1,
  1113. typename Value2,typename IndexSpecifierList2,typename Allocator2
  1114. >
  1115. bool operator>(
  1116. const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
  1117. const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
  1118. {
  1119. return get<0>(x)>get<0>(y);
  1120. }
  1121. template<
  1122. typename Value1,typename IndexSpecifierList1,typename Allocator1,
  1123. typename Value2,typename IndexSpecifierList2,typename Allocator2
  1124. >
  1125. bool operator>=(
  1126. const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
  1127. const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
  1128. {
  1129. return get<0>(x)>=get<0>(y);
  1130. }
  1131. template<
  1132. typename Value1,typename IndexSpecifierList1,typename Allocator1,
  1133. typename Value2,typename IndexSpecifierList2,typename Allocator2
  1134. >
  1135. bool operator<=(
  1136. const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
  1137. const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
  1138. {
  1139. return get<0>(x)<=get<0>(y);
  1140. }
  1141. /* specialized algorithms */
  1142. template<typename Value,typename IndexSpecifierList,typename Allocator>
  1143. void swap(
  1144. multi_index_container<Value,IndexSpecifierList,Allocator>& x,
  1145. multi_index_container<Value,IndexSpecifierList,Allocator>& y)
  1146. {
  1147. x.swap(y);
  1148. }
  1149. } /* namespace multi_index */
  1150. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  1151. /* class version = 1 : we now serialize the size through
  1152. * boost::serialization::collection_size_type.
  1153. * class version = 2 : proper use of {save|load}_construct_data.
  1154. */
  1155. namespace serialization {
  1156. template<typename Value,typename IndexSpecifierList,typename Allocator>
  1157. struct version<
  1158. boost::multi_index_container<Value,IndexSpecifierList,Allocator>
  1159. >
  1160. {
  1161. BOOST_STATIC_CONSTANT(int,value=2);
  1162. };
  1163. } /* namespace serialization */
  1164. #endif
  1165. /* Associated global functions are promoted to namespace boost, except
  1166. * comparison operators and swap, which are meant to be Koenig looked-up.
  1167. */
  1168. using multi_index::get;
  1169. using multi_index::project;
  1170. } /* namespace boost */
  1171. #undef BOOST_MULTI_INDEX_CHECK_INVARIANT
  1172. #undef BOOST_MULTI_INDEX_CHECK_INVARIANT_OF
  1173. #endif