random_access_index.hpp 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  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. #ifndef BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP
  9. #define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #include <algorithm>
  15. #include <boost/bind/bind.hpp>
  16. #include <boost/call_traits.hpp>
  17. #include <boost/core/addressof.hpp>
  18. #include <boost/core/no_exceptions_support.hpp>
  19. #include <boost/detail/workaround.hpp>
  20. #include <boost/foreach_fwd.hpp>
  21. #include <boost/iterator/reverse_iterator.hpp>
  22. #include <boost/move/core.hpp>
  23. #include <boost/move/utility_core.hpp>
  24. #include <boost/mpl/bool.hpp>
  25. #include <boost/mpl/not.hpp>
  26. #include <boost/mpl/push_front.hpp>
  27. #include <boost/multi_index/detail/access_specifier.hpp>
  28. #include <boost/multi_index/detail/allocator_traits.hpp>
  29. #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
  30. #include <boost/multi_index/detail/index_node_base.hpp>
  31. #include <boost/multi_index/detail/node_handle.hpp>
  32. #include <boost/multi_index/detail/rnd_node_iterator.hpp>
  33. #include <boost/multi_index/detail/rnd_index_node.hpp>
  34. #include <boost/multi_index/detail/rnd_index_ops.hpp>
  35. #include <boost/multi_index/detail/rnd_index_ptr_array.hpp>
  36. #include <boost/multi_index/detail/safe_mode.hpp>
  37. #include <boost/multi_index/detail/scope_guard.hpp>
  38. #include <boost/multi_index/detail/vartempl_support.hpp>
  39. #include <boost/multi_index/random_access_index_fwd.hpp>
  40. #include <boost/throw_exception.hpp>
  41. #include <boost/tuple/tuple.hpp>
  42. #include <boost/type_traits/is_integral.hpp>
  43. #include <functional>
  44. #include <stdexcept>
  45. #include <utility>
  46. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  47. #include<initializer_list>
  48. #endif
  49. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  50. #include <boost/multi_index/detail/rnd_index_loader.hpp>
  51. #endif
  52. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
  53. #define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) \
  54. detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
  55. detail::make_obj_guard(x,&random_access_index::check_invariant_); \
  56. BOOST_JOIN(check_invariant_,__LINE__).touch();
  57. #define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \
  58. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(*this)
  59. #else
  60. #define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x)
  61. #define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT
  62. #endif
  63. namespace boost{
  64. namespace multi_index{
  65. namespace detail{
  66. /* random_access_index adds a layer of random access indexing
  67. * to a given Super
  68. */
  69. template<typename SuperMeta,typename TagList>
  70. class random_access_index:
  71. BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
  72. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  73. ,public safe_mode::safe_container<
  74. random_access_index<SuperMeta,TagList> >
  75. #endif
  76. {
  77. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
  78. BOOST_WORKAROUND(__MWERKS__,<=0x3003)
  79. /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
  80. * lifetime of const references bound to temporaries --precisely what
  81. * scopeguards are.
  82. */
  83. #pragma parse_mfunc_templ off
  84. #endif
  85. typedef typename SuperMeta::type super;
  86. protected:
  87. typedef random_access_index_node<
  88. typename super::index_node_type> index_node_type;
  89. private:
  90. typedef typename index_node_type::impl_type node_impl_type;
  91. typedef random_access_index_ptr_array<
  92. typename super::final_allocator_type> ptr_array;
  93. typedef typename ptr_array::pointer node_impl_ptr_pointer;
  94. public:
  95. /* types */
  96. typedef typename index_node_type::value_type value_type;
  97. typedef tuples::null_type ctor_args;
  98. typedef typename super::final_allocator_type allocator_type;
  99. typedef value_type& reference;
  100. typedef const value_type& const_reference;
  101. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  102. typedef safe_mode::safe_iterator<
  103. rnd_node_iterator<index_node_type>,
  104. random_access_index> iterator;
  105. #else
  106. typedef rnd_node_iterator<index_node_type> iterator;
  107. #endif
  108. typedef iterator const_iterator;
  109. private:
  110. typedef allocator_traits<allocator_type> alloc_traits;
  111. public:
  112. typedef typename alloc_traits::pointer pointer;
  113. typedef typename alloc_traits::const_pointer const_pointer;
  114. typedef typename alloc_traits::size_type size_type;
  115. typedef typename alloc_traits::difference_type difference_type;
  116. typedef typename
  117. boost::reverse_iterator<iterator> reverse_iterator;
  118. typedef typename
  119. boost::reverse_iterator<const_iterator> const_reverse_iterator;
  120. typedef typename super::final_node_handle_type node_type;
  121. typedef detail::insert_return_type<
  122. iterator,node_type> insert_return_type;
  123. typedef TagList tag_list;
  124. protected:
  125. typedef typename super::final_node_type final_node_type;
  126. typedef tuples::cons<
  127. ctor_args,
  128. typename super::ctor_args_list> ctor_args_list;
  129. typedef typename mpl::push_front<
  130. typename super::index_type_list,
  131. random_access_index>::type index_type_list;
  132. typedef typename mpl::push_front<
  133. typename super::iterator_type_list,
  134. iterator>::type iterator_type_list;
  135. typedef typename mpl::push_front<
  136. typename super::const_iterator_type_list,
  137. const_iterator>::type const_iterator_type_list;
  138. typedef typename super::copy_map_type copy_map_type;
  139. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  140. typedef typename super::index_saver_type index_saver_type;
  141. typedef typename super::index_loader_type index_loader_type;
  142. #endif
  143. private:
  144. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  145. typedef safe_mode::safe_container<
  146. random_access_index> safe_super;
  147. #endif
  148. typedef typename call_traits<
  149. value_type>::param_type value_param_type;
  150. /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
  151. * expansion.
  152. */
  153. typedef std::pair<iterator,bool> emplace_return_type;
  154. public:
  155. /* construct/copy/destroy
  156. * Default and copy ctors are in the protected section as indices are
  157. * not supposed to be created on their own. No range ctor either.
  158. */
  159. random_access_index<SuperMeta,TagList>& operator=(
  160. const random_access_index<SuperMeta,TagList>& x)
  161. {
  162. this->final()=x.final();
  163. return *this;
  164. }
  165. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  166. random_access_index<SuperMeta,TagList>& operator=(
  167. std::initializer_list<value_type> list)
  168. {
  169. this->final()=list;
  170. return *this;
  171. }
  172. #endif
  173. template <class InputIterator>
  174. void assign(InputIterator first,InputIterator last)
  175. {
  176. assign_iter(first,last,mpl::not_<is_integral<InputIterator> >());
  177. }
  178. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  179. void assign(std::initializer_list<value_type> list)
  180. {
  181. assign(list.begin(),list.end());
  182. }
  183. #endif
  184. void assign(size_type n,value_param_type value)
  185. {
  186. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  187. clear();
  188. for(size_type i=0;i<n;++i)push_back(value);
  189. }
  190. allocator_type get_allocator()const BOOST_NOEXCEPT
  191. {
  192. return this->final().get_allocator();
  193. }
  194. /* iterators */
  195. iterator begin()BOOST_NOEXCEPT
  196. {return make_iterator(index_node_type::from_impl(*ptrs.begin()));}
  197. const_iterator begin()const BOOST_NOEXCEPT
  198. {return make_iterator(index_node_type::from_impl(*ptrs.begin()));}
  199. iterator
  200. end()BOOST_NOEXCEPT{return make_iterator(header());}
  201. const_iterator
  202. end()const BOOST_NOEXCEPT{return make_iterator(header());}
  203. reverse_iterator
  204. rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
  205. const_reverse_iterator
  206. rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
  207. reverse_iterator
  208. rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
  209. const_reverse_iterator
  210. rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
  211. const_iterator
  212. cbegin()const BOOST_NOEXCEPT{return begin();}
  213. const_iterator
  214. cend()const BOOST_NOEXCEPT{return end();}
  215. const_reverse_iterator
  216. crbegin()const BOOST_NOEXCEPT{return rbegin();}
  217. const_reverse_iterator
  218. crend()const BOOST_NOEXCEPT{return rend();}
  219. iterator iterator_to(const value_type& x)
  220. {
  221. return make_iterator(
  222. node_from_value<index_node_type>(boost::addressof(x)));
  223. }
  224. const_iterator iterator_to(const value_type& x)const
  225. {
  226. return make_iterator(
  227. node_from_value<index_node_type>(boost::addressof(x)));
  228. }
  229. /* capacity */
  230. bool empty()const BOOST_NOEXCEPT{return this->final_empty_();}
  231. size_type size()const BOOST_NOEXCEPT{return this->final_size_();}
  232. size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();}
  233. size_type capacity()const BOOST_NOEXCEPT{return ptrs.capacity();}
  234. void reserve(size_type n)
  235. {
  236. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  237. ptrs.reserve(n);
  238. }
  239. void shrink_to_fit()
  240. {
  241. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  242. ptrs.shrink_to_fit();
  243. }
  244. void resize(size_type n)
  245. {
  246. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  247. if(n>size())
  248. for(size_type m=n-size();m--;)
  249. this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK);
  250. else if(n<size())erase(begin()+n,end());
  251. }
  252. void resize(size_type n,value_param_type x)
  253. {
  254. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  255. if(n>size())for(size_type m=n-size();m--;)this->final_insert_(x);
  256. else if(n<size())erase(begin()+n,end());
  257. }
  258. /* access: no non-const versions provided as random_access_index
  259. * handles const elements.
  260. */
  261. const_reference operator[](size_type n)const
  262. {
  263. BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(n<size(),safe_mode::out_of_bounds);
  264. return index_node_type::from_impl(*ptrs.at(n))->value();
  265. }
  266. const_reference at(size_type n)const
  267. {
  268. if(n>=size())throw_exception(std::out_of_range("random access index"));
  269. return index_node_type::from_impl(*ptrs.at(n))->value();
  270. }
  271. const_reference front()const{return operator[](0);}
  272. const_reference back()const{return operator[](size()-1);}
  273. /* modifiers */
  274. BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
  275. emplace_return_type,emplace_front,emplace_front_impl)
  276. std::pair<iterator,bool> push_front(const value_type& x)
  277. {return insert(begin(),x);}
  278. std::pair<iterator,bool> push_front(BOOST_RV_REF(value_type) x)
  279. {return insert(begin(),boost::move(x));}
  280. void pop_front(){erase(begin());}
  281. BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
  282. emplace_return_type,emplace_back,emplace_back_impl)
  283. std::pair<iterator,bool> push_back(const value_type& x)
  284. {return insert(end(),x);}
  285. std::pair<iterator,bool> push_back(BOOST_RV_REF(value_type) x)
  286. {return insert(end(),boost::move(x));}
  287. void pop_back(){erase(--end());}
  288. BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
  289. emplace_return_type,emplace,emplace_impl,iterator,position)
  290. std::pair<iterator,bool> insert(iterator position,const value_type& x)
  291. {
  292. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  293. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  294. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  295. std::pair<final_node_type*,bool> p=this->final_insert_(x);
  296. if(p.second&&position.get_node()!=header()){
  297. relocate(position.get_node(),p.first);
  298. }
  299. return std::pair<iterator,bool>(make_iterator(p.first),p.second);
  300. }
  301. std::pair<iterator,bool> insert(iterator position,BOOST_RV_REF(value_type) x)
  302. {
  303. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  304. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  305. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  306. std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
  307. if(p.second&&position.get_node()!=header()){
  308. relocate(position.get_node(),p.first);
  309. }
  310. return std::pair<iterator,bool>(make_iterator(p.first),p.second);
  311. }
  312. void insert(iterator position,size_type n,value_param_type x)
  313. {
  314. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  315. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  316. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  317. size_type s=0;
  318. BOOST_TRY{
  319. while(n--){
  320. if(push_back(x).second)++s;
  321. }
  322. }
  323. BOOST_CATCH(...){
  324. relocate(position,end()-s,end());
  325. BOOST_RETHROW;
  326. }
  327. BOOST_CATCH_END
  328. relocate(position,end()-s,end());
  329. }
  330. template<typename InputIterator>
  331. void insert(iterator position,InputIterator first,InputIterator last)
  332. {
  333. insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >());
  334. }
  335. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  336. void insert(iterator position,std::initializer_list<value_type> list)
  337. {
  338. insert(position,list.begin(),list.end());
  339. }
  340. #endif
  341. insert_return_type insert(const_iterator position,BOOST_RV_REF(node_type) nh)
  342. {
  343. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  344. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  345. if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh);
  346. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  347. std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh);
  348. if(p.second&&position.get_node()!=header()){
  349. relocate(position.get_node(),p.first);
  350. }
  351. return insert_return_type(make_iterator(p.first),p.second,boost::move(nh));
  352. }
  353. node_type extract(const_iterator position)
  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_RND_INDEX_CHECK_INVARIANT;
  359. return this->final_extract_(
  360. static_cast<final_node_type*>(position.get_node()));
  361. }
  362. iterator erase(iterator position)
  363. {
  364. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  365. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  366. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  367. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  368. this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
  369. return position;
  370. }
  371. iterator erase(iterator first,iterator last)
  372. {
  373. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
  374. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
  375. BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
  376. BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
  377. BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
  378. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  379. difference_type n=static_cast<difference_type>(last-first);
  380. relocate(end(),first,last);
  381. while(n--)pop_back();
  382. return last;
  383. }
  384. bool replace(iterator position,const value_type& x)
  385. {
  386. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  387. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  388. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  389. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  390. return this->final_replace_(
  391. x,static_cast<final_node_type*>(position.get_node()));
  392. }
  393. bool replace(iterator position,BOOST_RV_REF(value_type) x)
  394. {
  395. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  396. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  397. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  398. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  399. return this->final_replace_rv_(
  400. x,static_cast<final_node_type*>(position.get_node()));
  401. }
  402. template<typename Modifier>
  403. bool modify(iterator position,Modifier mod)
  404. {
  405. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  406. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  407. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  408. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  409. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  410. /* MSVC++ 6.0 optimizer on safe mode code chokes if this
  411. * this is not added. Left it for all compilers as it does no
  412. * harm.
  413. */
  414. position.detach();
  415. #endif
  416. return this->final_modify_(
  417. mod,static_cast<final_node_type*>(position.get_node()));
  418. }
  419. template<typename Modifier,typename Rollback>
  420. bool modify(iterator position,Modifier mod,Rollback back_)
  421. {
  422. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  423. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
  424. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  425. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  426. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  427. /* MSVC++ 6.0 optimizer on safe mode code chokes if this
  428. * this is not added. Left it for all compilers as it does no
  429. * harm.
  430. */
  431. position.detach();
  432. #endif
  433. return this->final_modify_(
  434. mod,back_,static_cast<final_node_type*>(position.get_node()));
  435. }
  436. void swap(random_access_index<SuperMeta,TagList>& x)
  437. {
  438. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  439. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x);
  440. this->final_swap_(x.final());
  441. }
  442. void clear()BOOST_NOEXCEPT
  443. {
  444. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  445. this->final_clear_();
  446. }
  447. /* list operations */
  448. void splice(iterator position,random_access_index<SuperMeta,TagList>& x)
  449. {
  450. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  451. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  452. BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x);
  453. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  454. iterator first=x.begin(),last=x.end();
  455. size_type n=0;
  456. BOOST_TRY{
  457. while(first!=last){
  458. if(push_back(*first).second){
  459. first=x.erase(first);
  460. ++n;
  461. }
  462. else ++first;
  463. }
  464. }
  465. BOOST_CATCH(...){
  466. relocate(position,end()-n,end());
  467. BOOST_RETHROW;
  468. }
  469. BOOST_CATCH_END
  470. relocate(position,end()-n,end());
  471. }
  472. void splice(
  473. iterator position,random_access_index<SuperMeta,TagList>& x,iterator i)
  474. {
  475. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  476. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  477. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
  478. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
  479. BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
  480. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  481. if(&x==this)relocate(position,i);
  482. else{
  483. if(insert(position,*i).second){
  484. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  485. /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following
  486. * workaround is needed. Left it for all compilers as it does no
  487. * harm.
  488. */
  489. i.detach();
  490. x.erase(x.make_iterator(i.get_node()));
  491. #else
  492. x.erase(i);
  493. #endif
  494. }
  495. }
  496. }
  497. void splice(
  498. iterator position,random_access_index<SuperMeta,TagList>& x,
  499. iterator first,iterator last)
  500. {
  501. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  502. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  503. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
  504. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
  505. BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x);
  506. BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
  507. BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
  508. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  509. if(&x==this)relocate(position,first,last);
  510. else{
  511. size_type n=0;
  512. BOOST_TRY{
  513. while(first!=last){
  514. if(push_back(*first).second){
  515. first=x.erase(first);
  516. ++n;
  517. }
  518. else ++first;
  519. }
  520. }
  521. BOOST_CATCH(...){
  522. relocate(position,end()-n,end());
  523. BOOST_RETHROW;
  524. }
  525. BOOST_CATCH_END
  526. relocate(position,end()-n,end());
  527. }
  528. }
  529. void remove(value_param_type value)
  530. {
  531. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  532. difference_type n=
  533. end()-make_iterator(
  534. random_access_index_remove<index_node_type>(
  535. ptrs,
  536. ::boost::bind<bool>(
  537. std::equal_to<value_type>(),::boost::arg<1>(),value)));
  538. while(n--)pop_back();
  539. }
  540. template<typename Predicate>
  541. void remove_if(Predicate pred)
  542. {
  543. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  544. difference_type n=
  545. end()-make_iterator(
  546. random_access_index_remove<index_node_type>(ptrs,pred));
  547. while(n--)pop_back();
  548. }
  549. void unique()
  550. {
  551. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  552. difference_type n=
  553. end()-make_iterator(
  554. random_access_index_unique<index_node_type>(
  555. ptrs,std::equal_to<value_type>()));
  556. while(n--)pop_back();
  557. }
  558. template <class BinaryPredicate>
  559. void unique(BinaryPredicate binary_pred)
  560. {
  561. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  562. difference_type n=
  563. end()-make_iterator(
  564. random_access_index_unique<index_node_type>(ptrs,binary_pred));
  565. while(n--)pop_back();
  566. }
  567. void merge(random_access_index<SuperMeta,TagList>& x)
  568. {
  569. if(this!=&x){
  570. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  571. size_type s=size();
  572. splice(end(),x);
  573. random_access_index_inplace_merge<index_node_type>(
  574. get_allocator(),ptrs,ptrs.at(s),std::less<value_type>());
  575. }
  576. }
  577. template <typename Compare>
  578. void merge(random_access_index<SuperMeta,TagList>& x,Compare comp)
  579. {
  580. if(this!=&x){
  581. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  582. size_type s=size();
  583. splice(end(),x);
  584. random_access_index_inplace_merge<index_node_type>(
  585. get_allocator(),ptrs,ptrs.at(s),comp);
  586. }
  587. }
  588. void sort()
  589. {
  590. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  591. random_access_index_sort<index_node_type>(
  592. get_allocator(),ptrs,std::less<value_type>());
  593. }
  594. template <typename Compare>
  595. void sort(Compare comp)
  596. {
  597. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  598. random_access_index_sort<index_node_type>(
  599. get_allocator(),ptrs,comp);
  600. }
  601. void reverse()BOOST_NOEXCEPT
  602. {
  603. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  604. node_impl_type::reverse(ptrs.begin(),ptrs.end());
  605. }
  606. /* rearrange operations */
  607. void relocate(iterator position,iterator i)
  608. {
  609. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  610. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  611. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
  612. BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
  613. BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this);
  614. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  615. if(position!=i)relocate(position.get_node(),i.get_node());
  616. }
  617. void relocate(iterator position,iterator first,iterator last)
  618. {
  619. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  620. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  621. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
  622. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
  623. BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
  624. BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
  625. BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
  626. BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last);
  627. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  628. if(position!=last)relocate(
  629. position.get_node(),first.get_node(),last.get_node());
  630. }
  631. template<typename InputIterator>
  632. void rearrange(InputIterator first)
  633. {
  634. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  635. for(node_impl_ptr_pointer p0=ptrs.begin(),p0_end=ptrs.end();
  636. p0!=p0_end;++first,++p0){
  637. const value_type& v1=*first;
  638. node_impl_ptr_pointer p1=node_from_value<index_node_type>(&v1)->up();
  639. std::swap(*p0,*p1);
  640. (*p0)->up()=p0;
  641. (*p1)->up()=p1;
  642. }
  643. }
  644. BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
  645. random_access_index(
  646. const ctor_args_list& args_list,const allocator_type& al):
  647. super(args_list.get_tail(),al),
  648. ptrs(al,header()->impl(),0)
  649. {
  650. }
  651. random_access_index(const random_access_index<SuperMeta,TagList>& x):
  652. super(x),
  653. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  654. safe_super(),
  655. #endif
  656. ptrs(x.get_allocator(),header()->impl(),x.size())
  657. {
  658. /* The actual copying takes place in subsequent call to copy_().
  659. */
  660. }
  661. random_access_index(
  662. const random_access_index<SuperMeta,TagList>& x,do_not_copy_elements_tag):
  663. super(x,do_not_copy_elements_tag()),
  664. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  665. safe_super(),
  666. #endif
  667. ptrs(x.get_allocator(),header()->impl(),0)
  668. {
  669. }
  670. ~random_access_index()
  671. {
  672. /* the container is guaranteed to be empty by now */
  673. }
  674. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  675. iterator make_iterator(index_node_type* node)
  676. {return iterator(node,this);}
  677. const_iterator make_iterator(index_node_type* node)const
  678. {return const_iterator(node,const_cast<random_access_index*>(this));}
  679. #else
  680. iterator make_iterator(index_node_type* node){return iterator(node);}
  681. const_iterator make_iterator(index_node_type* node)const
  682. {return const_iterator(node);}
  683. #endif
  684. void copy_(
  685. const random_access_index<SuperMeta,TagList>& x,const copy_map_type& map)
  686. {
  687. for(node_impl_ptr_pointer begin_org=x.ptrs.begin(),
  688. begin_cpy=ptrs.begin(),
  689. end_org=x.ptrs.end();
  690. begin_org!=end_org;++begin_org,++begin_cpy){
  691. *begin_cpy=
  692. static_cast<index_node_type*>(
  693. map.find(
  694. static_cast<final_node_type*>(
  695. index_node_type::from_impl(*begin_org))))->impl();
  696. (*begin_cpy)->up()=begin_cpy;
  697. }
  698. super::copy_(x,map);
  699. }
  700. template<typename Variant>
  701. final_node_type* insert_(
  702. value_param_type v,final_node_type*& x,Variant variant)
  703. {
  704. ptrs.room_for_one();
  705. final_node_type* res=super::insert_(v,x,variant);
  706. if(res==x)ptrs.push_back(static_cast<index_node_type*>(x)->impl());
  707. return res;
  708. }
  709. template<typename Variant>
  710. final_node_type* insert_(
  711. value_param_type v,index_node_type* position,
  712. final_node_type*& x,Variant variant)
  713. {
  714. ptrs.room_for_one();
  715. final_node_type* res=super::insert_(v,position,x,variant);
  716. if(res==x)ptrs.push_back(static_cast<index_node_type*>(x)->impl());
  717. return res;
  718. }
  719. void extract_(index_node_type* x)
  720. {
  721. ptrs.erase(x->impl());
  722. super::extract_(x);
  723. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  724. detach_iterators(x);
  725. #endif
  726. }
  727. void delete_all_nodes_()
  728. {
  729. for(node_impl_ptr_pointer x=ptrs.begin(),x_end=ptrs.end();x!=x_end;++x){
  730. this->final_delete_node_(
  731. static_cast<final_node_type*>(index_node_type::from_impl(*x)));
  732. }
  733. }
  734. void clear_()
  735. {
  736. super::clear_();
  737. ptrs.clear();
  738. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  739. safe_super::detach_dereferenceable_iterators();
  740. #endif
  741. }
  742. template<typename BoolConstant>
  743. void swap_(
  744. random_access_index<SuperMeta,TagList>& x,BoolConstant swap_allocators)
  745. {
  746. ptrs.swap(x.ptrs,swap_allocators);
  747. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  748. safe_super::swap(x);
  749. #endif
  750. super::swap_(x,swap_allocators);
  751. }
  752. void swap_elements_(random_access_index<SuperMeta,TagList>& x)
  753. {
  754. ptrs.swap(x.ptrs);
  755. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  756. safe_super::swap(x);
  757. #endif
  758. super::swap_elements_(x);
  759. }
  760. template<typename Variant>
  761. bool replace_(value_param_type v,index_node_type* x,Variant variant)
  762. {
  763. return super::replace_(v,x,variant);
  764. }
  765. bool modify_(index_node_type* x)
  766. {
  767. BOOST_TRY{
  768. if(!super::modify_(x)){
  769. ptrs.erase(x->impl());
  770. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  771. detach_iterators(x);
  772. #endif
  773. return false;
  774. }
  775. else return true;
  776. }
  777. BOOST_CATCH(...){
  778. ptrs.erase(x->impl());
  779. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  780. detach_iterators(x);
  781. #endif
  782. BOOST_RETHROW;
  783. }
  784. BOOST_CATCH_END
  785. }
  786. bool modify_rollback_(index_node_type* x)
  787. {
  788. return super::modify_rollback_(x);
  789. }
  790. bool check_rollback_(index_node_type* x)const
  791. {
  792. return super::check_rollback_(x);
  793. }
  794. #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
  795. /* serialization */
  796. template<typename Archive>
  797. void save_(
  798. Archive& ar,const unsigned int version,const index_saver_type& sm)const
  799. {
  800. sm.save(begin(),end(),ar,version);
  801. super::save_(ar,version,sm);
  802. }
  803. template<typename Archive>
  804. void load_(
  805. Archive& ar,const unsigned int version,const index_loader_type& lm)
  806. {
  807. {
  808. typedef random_access_index_loader<
  809. index_node_type,allocator_type> loader;
  810. loader ld(get_allocator(),ptrs);
  811. lm.load(
  812. ::boost::bind(
  813. &loader::rearrange,&ld,::boost::arg<1>(),::boost::arg<2>()),
  814. ar,version);
  815. } /* exit scope so that ld frees its resources */
  816. super::load_(ar,version,lm);
  817. }
  818. #endif
  819. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
  820. /* invariant stuff */
  821. bool invariant_()const
  822. {
  823. if(size()>capacity())return false;
  824. if(size()==0||begin()==end()){
  825. if(size()!=0||begin()!=end())return false;
  826. }
  827. else{
  828. size_type s=0;
  829. for(const_iterator it=begin(),it_end=end();;++it,++s){
  830. if(*(it.get_node()->up())!=it.get_node()->impl())return false;
  831. if(it==it_end)break;
  832. }
  833. if(s!=size())return false;
  834. }
  835. return super::invariant_();
  836. }
  837. /* This forwarding function eases things for the boost::mem_fn construct
  838. * in BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT. Actually,
  839. * final_check_invariant is already an inherited member function of index.
  840. */
  841. void check_invariant_()const{this->final_check_invariant_();}
  842. #endif
  843. private:
  844. index_node_type* header()const{return this->final_header();}
  845. static void relocate(index_node_type* position,index_node_type* x)
  846. {
  847. node_impl_type::relocate(position->up(),x->up());
  848. }
  849. static void relocate(
  850. index_node_type* position,index_node_type* first,index_node_type* last)
  851. {
  852. node_impl_type::relocate(
  853. position->up(),first->up(),last->up());
  854. }
  855. #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
  856. void detach_iterators(index_node_type* x)
  857. {
  858. iterator it=make_iterator(x);
  859. safe_mode::detach_equivalent_iterators(it);
  860. }
  861. #endif
  862. template <class InputIterator>
  863. void assign_iter(InputIterator first,InputIterator last,mpl::true_)
  864. {
  865. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  866. clear();
  867. for(;first!=last;++first)this->final_insert_ref_(*first);
  868. }
  869. void assign_iter(size_type n,value_param_type value,mpl::false_)
  870. {
  871. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  872. clear();
  873. for(size_type i=0;i<n;++i)push_back(value);
  874. }
  875. template<typename InputIterator>
  876. void insert_iter(
  877. iterator position,InputIterator first,InputIterator last,mpl::true_)
  878. {
  879. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  880. size_type s=0;
  881. BOOST_TRY{
  882. for(;first!=last;++first){
  883. if(this->final_insert_ref_(*first).second)++s;
  884. }
  885. }
  886. BOOST_CATCH(...){
  887. relocate(position,end()-s,end());
  888. BOOST_RETHROW;
  889. }
  890. BOOST_CATCH_END
  891. relocate(position,end()-s,end());
  892. }
  893. void insert_iter(
  894. iterator position,size_type n,value_param_type x,mpl::false_)
  895. {
  896. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  897. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  898. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  899. size_type s=0;
  900. BOOST_TRY{
  901. while(n--){
  902. if(push_back(x).second)++s;
  903. }
  904. }
  905. BOOST_CATCH(...){
  906. relocate(position,end()-s,end());
  907. BOOST_RETHROW;
  908. }
  909. BOOST_CATCH_END
  910. relocate(position,end()-s,end());
  911. }
  912. template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
  913. std::pair<iterator,bool> emplace_front_impl(
  914. BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
  915. {
  916. return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
  917. }
  918. template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
  919. std::pair<iterator,bool> emplace_back_impl(
  920. BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
  921. {
  922. return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
  923. }
  924. template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
  925. std::pair<iterator,bool> emplace_impl(
  926. iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
  927. {
  928. BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
  929. BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
  930. BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
  931. std::pair<final_node_type*,bool> p=
  932. this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
  933. if(p.second&&position.get_node()!=header()){
  934. relocate(position.get_node(),p.first);
  935. }
  936. return std::pair<iterator,bool>(make_iterator(p.first),p.second);
  937. }
  938. ptr_array ptrs;
  939. #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
  940. BOOST_WORKAROUND(__MWERKS__,<=0x3003)
  941. #pragma parse_mfunc_templ reset
  942. #endif
  943. };
  944. /* comparison */
  945. template<
  946. typename SuperMeta1,typename TagList1,
  947. typename SuperMeta2,typename TagList2
  948. >
  949. bool operator==(
  950. const random_access_index<SuperMeta1,TagList1>& x,
  951. const random_access_index<SuperMeta2,TagList2>& y)
  952. {
  953. return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
  954. }
  955. template<
  956. typename SuperMeta1,typename TagList1,
  957. typename SuperMeta2,typename TagList2
  958. >
  959. bool operator<(
  960. const random_access_index<SuperMeta1,TagList1>& x,
  961. const random_access_index<SuperMeta2,TagList2>& y)
  962. {
  963. return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
  964. }
  965. template<
  966. typename SuperMeta1,typename TagList1,
  967. typename SuperMeta2,typename TagList2
  968. >
  969. bool operator!=(
  970. const random_access_index<SuperMeta1,TagList1>& x,
  971. const random_access_index<SuperMeta2,TagList2>& y)
  972. {
  973. return !(x==y);
  974. }
  975. template<
  976. typename SuperMeta1,typename TagList1,
  977. typename SuperMeta2,typename TagList2
  978. >
  979. bool operator>(
  980. const random_access_index<SuperMeta1,TagList1>& x,
  981. const random_access_index<SuperMeta2,TagList2>& y)
  982. {
  983. return y<x;
  984. }
  985. template<
  986. typename SuperMeta1,typename TagList1,
  987. typename SuperMeta2,typename TagList2
  988. >
  989. bool operator>=(
  990. const random_access_index<SuperMeta1,TagList1>& x,
  991. const random_access_index<SuperMeta2,TagList2>& y)
  992. {
  993. return !(x<y);
  994. }
  995. template<
  996. typename SuperMeta1,typename TagList1,
  997. typename SuperMeta2,typename TagList2
  998. >
  999. bool operator<=(
  1000. const random_access_index<SuperMeta1,TagList1>& x,
  1001. const random_access_index<SuperMeta2,TagList2>& y)
  1002. {
  1003. return !(x>y);
  1004. }
  1005. /* specialized algorithms */
  1006. template<typename SuperMeta,typename TagList>
  1007. void swap(
  1008. random_access_index<SuperMeta,TagList>& x,
  1009. random_access_index<SuperMeta,TagList>& y)
  1010. {
  1011. x.swap(y);
  1012. }
  1013. } /* namespace multi_index::detail */
  1014. /* random access index specifier */
  1015. template <typename TagList>
  1016. struct random_access
  1017. {
  1018. BOOST_STATIC_ASSERT(detail::is_tag<TagList>::value);
  1019. template<typename Super>
  1020. struct node_class
  1021. {
  1022. typedef detail::random_access_index_node<Super> type;
  1023. };
  1024. template<typename SuperMeta>
  1025. struct index_class
  1026. {
  1027. typedef detail::random_access_index<
  1028. SuperMeta,typename TagList::type> type;
  1029. };
  1030. };
  1031. } /* namespace multi_index */
  1032. } /* namespace boost */
  1033. /* Boost.Foreach compatibility */
  1034. template<typename SuperMeta,typename TagList>
  1035. inline boost::mpl::true_* boost_foreach_is_noncopyable(
  1036. boost::multi_index::detail::random_access_index<SuperMeta,TagList>*&,
  1037. boost_foreach_argument_dependent_lookup_hack)
  1038. {
  1039. return 0;
  1040. }
  1041. #undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT
  1042. #undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF
  1043. #endif