]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/multi_index_container.hpp
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / boost / boost / multi_index_container.hpp
CommitLineData
7c673cae
FG
1/* Multiply indexed container.
2 *
1e59de90 3 * Copyright 2003-2021 Joaquin M Lopez Munoz.
7c673cae
FG
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
11#ifndef BOOST_MULTI_INDEX_HPP
12#define BOOST_MULTI_INDEX_HPP
13
14#if defined(_MSC_VER)
15#pragma once
16#endif
17
18#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
19#include <algorithm>
11fdf7f2 20#include <boost/core/addressof.hpp>
20effc67 21#include <boost/core/no_exceptions_support.hpp>
7c673cae
FG
22#include <boost/detail/workaround.hpp>
23#include <boost/move/core.hpp>
92f5a8d4 24#include <boost/move/utility_core.hpp>
7c673cae
FG
25#include <boost/mpl/at.hpp>
26#include <boost/mpl/contains.hpp>
27#include <boost/mpl/find_if.hpp>
28#include <boost/mpl/identity.hpp>
29#include <boost/mpl/int.hpp>
30#include <boost/mpl/size.hpp>
31#include <boost/mpl/deref.hpp>
32#include <boost/multi_index_container_fwd.hpp>
33#include <boost/multi_index/detail/access_specifier.hpp>
34#include <boost/multi_index/detail/adl_swap.hpp>
92f5a8d4 35#include <boost/multi_index/detail/allocator_traits.hpp>
7c673cae
FG
36#include <boost/multi_index/detail/base_type.hpp>
37#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
38#include <boost/multi_index/detail/converter.hpp>
39#include <boost/multi_index/detail/header_holder.hpp>
40#include <boost/multi_index/detail/has_tag.hpp>
1e59de90 41#include <boost/multi_index/detail/invalidate_iterators.hpp>
7c673cae
FG
42#include <boost/multi_index/detail/no_duplicate_tags.hpp>
43#include <boost/multi_index/detail/safe_mode.hpp>
44#include <boost/multi_index/detail/scope_guard.hpp>
45#include <boost/multi_index/detail/vartempl_support.hpp>
46#include <boost/static_assert.hpp>
f67539c2 47#include <boost/type_traits/integral_constant.hpp>
7c673cae
FG
48#include <boost/type_traits/is_same.hpp>
49#include <boost/utility/base_from_member.hpp>
50
51#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
52#include <initializer_list>
53#endif
54
55#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
56#include <boost/multi_index/detail/archive_constructed.hpp>
57#include <boost/multi_index/detail/serialization_version.hpp>
58#include <boost/serialization/collection_size_type.hpp>
59#include <boost/serialization/nvp.hpp>
60#include <boost/serialization/split_member.hpp>
61#include <boost/serialization/version.hpp>
62#include <boost/throw_exception.hpp>
63#endif
64
65#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
66#include <boost/multi_index/detail/invariant_assert.hpp>
67#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) \
68 detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
69 detail::make_obj_guard(x,&multi_index_container::check_invariant_); \
70 BOOST_JOIN(check_invariant_,__LINE__).touch();
71#define BOOST_MULTI_INDEX_CHECK_INVARIANT \
72 BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(*this)
73#else
74#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x)
75#define BOOST_MULTI_INDEX_CHECK_INVARIANT
76#endif
77
78namespace boost{
79
80namespace multi_index{
81
f67539c2
TL
82namespace detail{
83
84struct unequal_alloc_move_ctor_tag{};
85
86} /* namespace multi_index::detail */
87
7c673cae
FG
88#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
89#pragma warning(push)
90#pragma warning(disable:4522) /* spurious warning on multiple operator=()'s */
91#endif
92
93template<typename Value,typename IndexSpecifierList,typename Allocator>
94class multi_index_container:
95 private ::boost::base_from_member<
92f5a8d4 96 typename detail::rebind_alloc_for<
7c673cae
FG
97 Allocator,
98 typename detail::multi_index_node_type<
99 Value,IndexSpecifierList,Allocator>::type
92f5a8d4
TL
100 >::type
101 >,
7c673cae 102 BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder<
92f5a8d4
TL
103 typename detail::allocator_traits<
104 typename detail::rebind_alloc_for<
11fdf7f2
TL
105 Allocator,
106 typename detail::multi_index_node_type<
107 Value,IndexSpecifierList,Allocator>::type
108 >::type
11fdf7f2 109 >::pointer,
7c673cae
FG
110 multi_index_container<Value,IndexSpecifierList,Allocator> >,
111 public detail::multi_index_base_type<
112 Value,IndexSpecifierList,Allocator>::type
113{
114#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
115 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
116/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
117 * lifetime of const references bound to temporaries --precisely what
118 * scopeguards are.
119 */
120
121#pragma parse_mfunc_templ off
122#endif
123
124private:
125 BOOST_COPYABLE_AND_MOVABLE(multi_index_container)
126
127#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
128 template <typename,typename,typename> friend class detail::index_base;
129 template <typename,typename> friend struct detail::header_holder;
130 template <typename,typename> friend struct detail::converter;
131#endif
132
133 typedef typename detail::multi_index_base_type<
f67539c2 134 Value,IndexSpecifierList,Allocator>::type super;
92f5a8d4 135 typedef typename detail::rebind_alloc_for<
7c673cae 136 Allocator,
20effc67 137 typename super::index_node_type
92f5a8d4
TL
138 >::type node_allocator;
139 typedef detail::allocator_traits<node_allocator> node_alloc_traits;
140 typedef typename node_alloc_traits::pointer node_pointer;
7c673cae 141 typedef ::boost::base_from_member<
92f5a8d4 142 node_allocator> bfm_allocator;
7c673cae 143 typedef detail::header_holder<
11fdf7f2 144 node_pointer,
92f5a8d4 145 multi_index_container> bfm_header;
7c673cae 146
7c673cae
FG
147public:
148 /* All types are inherited from super, a few are explicitly
149 * brought forward here to save us some typename's.
150 */
151
152 typedef typename super::ctor_args_list ctor_args_list;
153 typedef IndexSpecifierList index_specifier_type_list;
154
155 typedef typename super::index_type_list index_type_list;
156
157 typedef typename super::iterator_type_list iterator_type_list;
158 typedef typename super::const_iterator_type_list const_iterator_type_list;
159 typedef typename super::value_type value_type;
160 typedef typename super::final_allocator_type allocator_type;
92f5a8d4 161 typedef typename super::size_type size_type;
7c673cae
FG
162 typedef typename super::iterator iterator;
163 typedef typename super::const_iterator const_iterator;
164
165 BOOST_STATIC_ASSERT(
166 detail::no_duplicate_tags_in_index_list<index_type_list>::value);
167
168 /* global project() needs to see this publicly */
169
20effc67 170 typedef typename super::final_node_type final_node_type;
7c673cae
FG
171
172 /* construct/copy/destroy */
173
92f5a8d4
TL
174 multi_index_container():
175 bfm_allocator(allocator_type()),
176 super(ctor_args_list(),bfm_allocator::member),
177 node_count(0)
178 {
179 BOOST_MULTI_INDEX_CHECK_INVARIANT;
180 }
181
7c673cae 182 explicit multi_index_container(
92f5a8d4 183 const ctor_args_list& args_list,
7c673cae
FG
184
185#if BOOST_WORKAROUND(__IBMCPP__,<=600)
92f5a8d4
TL
186 /* VisualAge seems to have an ETI issue with the default value for
187 * argument al.
7c673cae
FG
188 */
189
7c673cae
FG
190 const allocator_type& al=
191 typename mpl::identity<multi_index_container>::type::
192 allocator_type()):
193#else
7c673cae
FG
194 const allocator_type& al=allocator_type()):
195#endif
196
197 bfm_allocator(al),
198 super(args_list,bfm_allocator::member),
199 node_count(0)
200 {
201 BOOST_MULTI_INDEX_CHECK_INVARIANT;
202 }
203
204 explicit multi_index_container(const allocator_type& al):
205 bfm_allocator(al),
206 super(ctor_args_list(),bfm_allocator::member),
207 node_count(0)
208 {
209 BOOST_MULTI_INDEX_CHECK_INVARIANT;
210 }
211
212 template<typename InputIterator>
213 multi_index_container(
214 InputIterator first,InputIterator last,
215
216#if BOOST_WORKAROUND(__IBMCPP__,<=600)
217 /* VisualAge seems to have an ETI issue with the default values
218 * for arguments args_list and al.
219 */
220
221 const ctor_args_list& args_list=
222 typename mpl::identity<multi_index_container>::type::
223 ctor_args_list(),
224 const allocator_type& al=
225 typename mpl::identity<multi_index_container>::type::
226 allocator_type()):
227#else
228 const ctor_args_list& args_list=ctor_args_list(),
229 const allocator_type& al=allocator_type()):
230#endif
231
232 bfm_allocator(al),
233 super(args_list,bfm_allocator::member),
234 node_count(0)
235 {
236 BOOST_MULTI_INDEX_CHECK_INVARIANT;
237 BOOST_TRY{
238 iterator hint=super::end();
239 for(;first!=last;++first){
240 hint=super::make_iterator(
241 insert_ref_(*first,hint.get_node()).first);
242 ++hint;
243 }
244 }
245 BOOST_CATCH(...){
246 clear_();
247 BOOST_RETHROW;
248 }
249 BOOST_CATCH_END
250 }
251
252#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
253 multi_index_container(
254 std::initializer_list<Value> list,
255 const ctor_args_list& args_list=ctor_args_list(),
256 const allocator_type& al=allocator_type()):
257 bfm_allocator(al),
258 super(args_list,bfm_allocator::member),
259 node_count(0)
260 {
261 BOOST_MULTI_INDEX_CHECK_INVARIANT;
262 BOOST_TRY{
263 typedef const Value* init_iterator;
264
265 iterator hint=super::end();
266 for(init_iterator first=list.begin(),last=list.end();
267 first!=last;++first){
268 hint=super::make_iterator(insert_(*first,hint.get_node()).first);
269 ++hint;
270 }
271 }
272 BOOST_CATCH(...){
273 clear_();
274 BOOST_RETHROW;
275 }
276 BOOST_CATCH_END
277 }
278#endif
279
280 multi_index_container(
281 const multi_index_container<Value,IndexSpecifierList,Allocator>& x):
f67539c2
TL
282 bfm_allocator(
283 node_alloc_traits::select_on_container_copy_construction(
284 x.bfm_allocator::member)),
7c673cae
FG
285 bfm_header(),
286 super(x),
287 node_count(0)
288 {
f67539c2 289 copy_construct_from(x);
7c673cae
FG
290 }
291
292 multi_index_container(BOOST_RV_REF(multi_index_container) x):
f67539c2 293 bfm_allocator(boost::move(x.bfm_allocator::member)),
7c673cae
FG
294 bfm_header(),
295 super(x,detail::do_not_copy_elements_tag()),
296 node_count(0)
297 {
298 BOOST_MULTI_INDEX_CHECK_INVARIANT;
299 BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x);
300 swap_elements_(x);
301 }
302
f67539c2
TL
303 multi_index_container(
304 const multi_index_container<Value,IndexSpecifierList,Allocator>& x,
305 const allocator_type& al):
306 bfm_allocator(al),
307 bfm_header(),
308 super(x),
309 node_count(0)
310 {
311 copy_construct_from(x);
312 }
313
314 multi_index_container(
315 BOOST_RV_REF(multi_index_container) x,const allocator_type& al):
316 bfm_allocator(al),
317 bfm_header(),
318 super(x,detail::do_not_copy_elements_tag()),
319 node_count(0)
320 {
321 BOOST_MULTI_INDEX_CHECK_INVARIANT;
322 BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x);
323
324 if(al==x.get_allocator()){
325 swap_elements_(x);
326 }
327 else{
328 multi_index_container y(x,al,detail::unequal_alloc_move_ctor_tag());
329 swap_elements_(y);
330 }
331 }
332
7c673cae
FG
333 ~multi_index_container()
334 {
335 delete_all_nodes_();
336 }
337
338#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
339 /* As per http://www.boost.org/doc/html/move/emulation_limitations.html
340 * #move.emulation_limitations.assignment_operator
341 */
342
343 multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
344 const multi_index_container<Value,IndexSpecifierList,Allocator>& x)
345 {
f67539c2
TL
346 multi_index_container y(
347 x,
348 node_alloc_traits::propagate_on_container_copy_assignment::value?
349 x.get_allocator():this->get_allocator());
350 swap_(y,boost::true_type() /* swap_allocators */);
7c673cae
FG
351 return *this;
352 }
353#endif
354
355 multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
356 BOOST_COPY_ASSIGN_REF(multi_index_container) x)
357 {
f67539c2
TL
358 multi_index_container y(
359 x,
360 node_alloc_traits::propagate_on_container_copy_assignment::value?
361 x.get_allocator():this->get_allocator());
362 swap_(y,boost::true_type() /* swap_allocators */);
7c673cae
FG
363 return *this;
364 }
365
366 multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
367 BOOST_RV_REF(multi_index_container) x)
368 {
20effc67 369#include <boost/multi_index/detail/define_if_constexpr_macro.hpp>
f67539c2
TL
370
371 BOOST_MULTI_INDEX_IF_CONSTEXPR(
372 node_alloc_traits::propagate_on_container_move_assignment::value){
373 swap_(x,boost::true_type() /* swap_allocators */);
374 }
375 else if(this->get_allocator()==x.get_allocator()){
376 swap_(x,boost::false_type() /* swap_allocators */);
377 }
378 else{
379 multi_index_container y(boost::move(x),this->get_allocator());
380 swap_(y,boost::false_type() /* swap_allocators */);
381 }
7c673cae 382 return *this;
f67539c2 383
20effc67 384#include <boost/multi_index/detail/undef_if_constexpr_macro.hpp>
7c673cae
FG
385 }
386
387#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
388 multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
389 std::initializer_list<Value> list)
390 {
391 BOOST_MULTI_INDEX_CHECK_INVARIANT;
392 typedef const Value* init_iterator;
393
394 multi_index_container x(*this,detail::do_not_copy_elements_tag());
395 iterator hint=x.end();
396 for(init_iterator first=list.begin(),last=list.end();
397 first!=last;++first){
398 hint=x.make_iterator(x.insert_(*first,hint.get_node()).first);
399 ++hint;
400 }
401 x.swap_elements_(*this);
402 return*this;
403 }
404#endif
405
406 allocator_type get_allocator()const BOOST_NOEXCEPT
407 {
408 return allocator_type(bfm_allocator::member);
409 }
410
411 /* retrieval of indices by number */
412
413#if !defined(BOOST_NO_MEMBER_TEMPLATES)
414 template<int N>
415 struct nth_index
416 {
417 BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
418 typedef typename mpl::at_c<index_type_list,N>::type type;
419 };
420
421 template<int N>
422 typename nth_index<N>::type& get()BOOST_NOEXCEPT
423 {
424 BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
425 return *this;
426 }
427
428 template<int N>
429 const typename nth_index<N>::type& get()const BOOST_NOEXCEPT
430 {
431 BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
432 return *this;
433 }
434#endif
435
436 /* retrieval of indices by tag */
437
438#if !defined(BOOST_NO_MEMBER_TEMPLATES)
439 template<typename Tag>
440 struct index
441 {
442 typedef typename mpl::find_if<
443 index_type_list,
444 detail::has_tag<Tag>
445 >::type iter;
446
447 BOOST_STATIC_CONSTANT(
448 bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
449 BOOST_STATIC_ASSERT(index_found);
450
451 typedef typename mpl::deref<iter>::type type;
452 };
453
454 template<typename Tag>
455 typename index<Tag>::type& get()BOOST_NOEXCEPT
456 {
457 return *this;
458 }
459
460 template<typename Tag>
461 const typename index<Tag>::type& get()const BOOST_NOEXCEPT
462 {
463 return *this;
464 }
465#endif
466
467 /* projection of iterators by number */
468
469#if !defined(BOOST_NO_MEMBER_TEMPLATES)
470 template<int N>
471 struct nth_index_iterator
472 {
473 typedef typename nth_index<N>::type::iterator type;
474 };
475
476 template<int N>
477 struct nth_index_const_iterator
478 {
479 typedef typename nth_index<N>::type::const_iterator type;
480 };
481
482 template<int N,typename IteratorType>
483 typename nth_index_iterator<N>::type project(IteratorType it)
484 {
485 typedef typename nth_index<N>::type index_type;
486
487#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
488 BOOST_STATIC_ASSERT(
489 (mpl::contains<iterator_type_list,IteratorType>::value));
490#endif
491
492 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1e59de90 493 BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,*this);
20effc67
TL
494 return index_type::make_iterator(
495 static_cast<final_node_type*>(it.get_node()));
7c673cae
FG
496 }
497
498 template<int N,typename IteratorType>
499 typename nth_index_const_iterator<N>::type project(IteratorType it)const
500 {
501 typedef typename nth_index<N>::type index_type;
502
503#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
504 BOOST_STATIC_ASSERT((
505 mpl::contains<iterator_type_list,IteratorType>::value||
506 mpl::contains<const_iterator_type_list,IteratorType>::value));
507#endif
508
509 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1e59de90 510 BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,*this);
20effc67
TL
511 return index_type::make_iterator(
512 static_cast<final_node_type*>(it.get_node()));
7c673cae
FG
513 }
514#endif
515
516 /* projection of iterators by tag */
517
518#if !defined(BOOST_NO_MEMBER_TEMPLATES)
519 template<typename Tag>
520 struct index_iterator
521 {
522 typedef typename index<Tag>::type::iterator type;
523 };
524
525 template<typename Tag>
526 struct index_const_iterator
527 {
528 typedef typename index<Tag>::type::const_iterator type;
529 };
530
531 template<typename Tag,typename IteratorType>
532 typename index_iterator<Tag>::type project(IteratorType it)
533 {
534 typedef typename index<Tag>::type index_type;
535
536#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
537 BOOST_STATIC_ASSERT(
538 (mpl::contains<iterator_type_list,IteratorType>::value));
539#endif
540
541 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1e59de90 542 BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,*this);
20effc67
TL
543 return index_type::make_iterator(
544 static_cast<final_node_type*>(it.get_node()));
7c673cae
FG
545 }
546
547 template<typename Tag,typename IteratorType>
548 typename index_const_iterator<Tag>::type project(IteratorType it)const
549 {
550 typedef typename index<Tag>::type index_type;
551
552#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
553 BOOST_STATIC_ASSERT((
554 mpl::contains<iterator_type_list,IteratorType>::value||
555 mpl::contains<const_iterator_type_list,IteratorType>::value));
556#endif
557
558 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1e59de90 559 BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,*this);
20effc67
TL
560 return index_type::make_iterator(
561 static_cast<final_node_type*>(it.get_node()));
7c673cae
FG
562 }
563#endif
564
565BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
20effc67
TL
566 typedef typename super::final_node_handle_type final_node_handle_type;
567 typedef typename super::copy_map_type copy_map_type;
7c673cae 568
f67539c2
TL
569 multi_index_container(
570 multi_index_container<Value,IndexSpecifierList,Allocator>& x,
571 const allocator_type& al,
572 detail::unequal_alloc_move_ctor_tag):
573 bfm_allocator(al),
574 bfm_header(),
575 super(x),
576 node_count(0)
577 {
578 BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x);
579 BOOST_TRY{
580 copy_map_type map(bfm_allocator::member,x.size(),x.header(),header());
581 for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){
582 map.move_clone(it.get_node());
583 }
584 super::copy_(x,map);
585 map.release();
586 node_count=x.size();
587 x.clear();
588 }
589 BOOST_CATCH(...){
590 x.clear();
591 BOOST_RETHROW;
592 }
593 BOOST_CATCH_END
594
595 /* Not until this point are the indices required to be consistent,
596 * hence the position of the invariant checker.
597 */
598
599 BOOST_MULTI_INDEX_CHECK_INVARIANT;
600 }
601
7c673cae
FG
602#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
603 multi_index_container(
604 const multi_index_container<Value,IndexSpecifierList,Allocator>& x,
605 detail::do_not_copy_elements_tag):
606 bfm_allocator(x.bfm_allocator::member),
607 bfm_header(),
608 super(x,detail::do_not_copy_elements_tag()),
609 node_count(0)
610 {
611 BOOST_MULTI_INDEX_CHECK_INVARIANT;
612 }
613#endif
614
f67539c2
TL
615 void copy_construct_from(
616 const multi_index_container<Value,IndexSpecifierList,Allocator>& x)
617 {
618 copy_map_type map(bfm_allocator::member,x.size(),x.header(),header());
619 for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){
620 map.copy_clone(it.get_node());
621 }
622 super::copy_(x,map);
623 map.release();
624 node_count=x.size();
625
626 /* Not until this point are the indices required to be consistent,
627 * hence the position of the invariant checker.
628 */
629
630 BOOST_MULTI_INDEX_CHECK_INVARIANT;
631 }
632
20effc67 633 final_node_type* header()const
7c673cae
FG
634 {
635 return &*bfm_header::member;
636 }
637
20effc67 638 final_node_type* allocate_node()
7c673cae 639 {
92f5a8d4 640 return &*node_alloc_traits::allocate(bfm_allocator::member,1);
7c673cae
FG
641 }
642
20effc67 643 void deallocate_node(final_node_type* x)
7c673cae 644 {
92f5a8d4
TL
645 node_alloc_traits::deallocate(
646 bfm_allocator::member,static_cast<node_pointer>(x),1);
647 }
648
20effc67 649 void construct_value(final_node_type* x,const Value& v)
92f5a8d4
TL
650 {
651 node_alloc_traits::construct(
652 bfm_allocator::member,boost::addressof(x->value()),v);
653 }
654
20effc67 655 void construct_value(final_node_type* x,BOOST_RV_REF(Value) v)
92f5a8d4
TL
656 {
657 node_alloc_traits::construct(
658 bfm_allocator::member,boost::addressof(x->value()),boost::move(v));
659 }
660
661 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
20effc67 662 void,construct_value,vartempl_construct_value_impl,final_node_type*,x)
92f5a8d4 663
20effc67 664 void destroy_value(final_node_type* x)
92f5a8d4
TL
665 {
666 node_alloc_traits::destroy(
667 bfm_allocator::member,boost::addressof(x->value()));
7c673cae
FG
668 }
669
670 bool empty_()const
671 {
672 return node_count==0;
673 }
674
92f5a8d4 675 size_type size_()const
7c673cae
FG
676 {
677 return node_count;
678 }
679
92f5a8d4 680 size_type max_size_()const
7c673cae 681 {
92f5a8d4 682 return static_cast<size_type>(-1);
7c673cae
FG
683 }
684
685 template<typename Variant>
20effc67 686 std::pair<final_node_type*,bool> insert_(const Value& v,Variant variant)
7c673cae 687 {
20effc67
TL
688 final_node_type* x=0;
689 final_node_type* res=super::insert_(v,x,variant);
7c673cae
FG
690 if(res==x){
691 ++node_count;
20effc67 692 return std::pair<final_node_type*,bool>(res,true);
7c673cae
FG
693 }
694 else{
20effc67 695 return std::pair<final_node_type*,bool>(res,false);
7c673cae
FG
696 }
697 }
698
20effc67 699 std::pair<final_node_type*,bool> insert_(const Value& v)
7c673cae
FG
700 {
701 return insert_(v,detail::lvalue_tag());
702 }
703
20effc67 704 std::pair<final_node_type*,bool> insert_rv_(const Value& v)
7c673cae
FG
705 {
706 return insert_(v,detail::rvalue_tag());
707 }
708
709 template<typename T>
20effc67 710 std::pair<final_node_type*,bool> insert_ref_(T& t)
7c673cae 711 {
20effc67 712 final_node_type* x=allocate_node();
7c673cae 713 BOOST_TRY{
92f5a8d4 714 construct_value(x,t);
7c673cae 715 BOOST_TRY{
20effc67
TL
716 final_node_type* res=super::insert_(
717 x->value(),x,detail::emplaced_tag());
7c673cae
FG
718 if(res==x){
719 ++node_count;
20effc67 720 return std::pair<final_node_type*,bool>(res,true);
7c673cae
FG
721 }
722 else{
20effc67
TL
723 delete_node_(x);
724 return std::pair<final_node_type*,bool>(res,false);
7c673cae
FG
725 }
726 }
727 BOOST_CATCH(...){
92f5a8d4 728 destroy_value(x);
7c673cae
FG
729 BOOST_RETHROW;
730 }
731 BOOST_CATCH_END
732 }
733 BOOST_CATCH(...){
734 deallocate_node(x);
735 BOOST_RETHROW;
736 }
737 BOOST_CATCH_END
738 }
739
20effc67 740 std::pair<final_node_type*,bool> insert_ref_(const value_type& x)
7c673cae
FG
741 {
742 return insert_(x);
743 }
744
20effc67 745 std::pair<final_node_type*,bool> insert_ref_(value_type& x)
7c673cae
FG
746 {
747 return insert_(x);
748 }
749
20effc67
TL
750 std::pair<final_node_type*,bool> insert_nh_(final_node_handle_type& nh)
751 {
752 if(!nh)return std::pair<final_node_type*,bool>(header(),false);
753 else{
754 final_node_type* x=nh.node;
755 final_node_type* res=super::insert_(
756 x->value(),x,detail::emplaced_tag());
757 if(res==x){
758 nh.release_node();
759 ++node_count;
760 return std::pair<final_node_type*,bool>(res,true);
761 }
762 else return std::pair<final_node_type*,bool>(res,false);
763 }
764 }
765
1e59de90
TL
766 template<typename Index>
767 std::pair<final_node_type*,bool> transfer_(Index& x,final_node_type* n)
768 {
769 final_node_type* res=super::insert_(n->value(),n,&super::final(x));
770 if(res==n){
771 ++node_count;
772 return std::pair<final_node_type*,bool>(res,true);
773 }
774 else{
775 return std::pair<final_node_type*,bool>(res,false);
776 }
777 }
778
7c673cae 779 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
20effc67 780 std::pair<final_node_type*,bool> emplace_(
7c673cae
FG
781 BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
782 {
20effc67 783 final_node_type* x=allocate_node();
7c673cae 784 BOOST_TRY{
92f5a8d4 785 construct_value(x,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
7c673cae 786 BOOST_TRY{
20effc67
TL
787 final_node_type* res=super::insert_(
788 x->value(),x,detail::emplaced_tag());
7c673cae
FG
789 if(res==x){
790 ++node_count;
20effc67 791 return std::pair<final_node_type*,bool>(res,true);
7c673cae
FG
792 }
793 else{
20effc67
TL
794 delete_node_(x);
795 return std::pair<final_node_type*,bool>(res,false);
7c673cae
FG
796 }
797 }
798 BOOST_CATCH(...){
92f5a8d4 799 destroy_value(x);
7c673cae
FG
800 BOOST_RETHROW;
801 }
802 BOOST_CATCH_END
803 }
804 BOOST_CATCH(...){
805 deallocate_node(x);
806 BOOST_RETHROW;
807 }
808 BOOST_CATCH_END
809 }
810
811 template<typename Variant>
20effc67
TL
812 std::pair<final_node_type*,bool> insert_(
813 const Value& v,final_node_type* position,Variant variant)
7c673cae 814 {
20effc67
TL
815 final_node_type* x=0;
816 final_node_type* res=super::insert_(v,position,x,variant);
7c673cae
FG
817 if(res==x){
818 ++node_count;
20effc67 819 return std::pair<final_node_type*,bool>(res,true);
7c673cae
FG
820 }
821 else{
20effc67 822 return std::pair<final_node_type*,bool>(res,false);
7c673cae
FG
823 }
824 }
825
20effc67
TL
826 std::pair<final_node_type*,bool> insert_(
827 const Value& v,final_node_type* position)
7c673cae
FG
828 {
829 return insert_(v,position,detail::lvalue_tag());
830 }
831
20effc67
TL
832 std::pair<final_node_type*,bool> insert_rv_(
833 const Value& v,final_node_type* position)
7c673cae
FG
834 {
835 return insert_(v,position,detail::rvalue_tag());
836 }
837
838 template<typename T>
20effc67
TL
839 std::pair<final_node_type*,bool> insert_ref_(
840 T& t,final_node_type* position)
7c673cae 841 {
20effc67 842 final_node_type* x=allocate_node();
7c673cae 843 BOOST_TRY{
92f5a8d4 844 construct_value(x,t);
7c673cae 845 BOOST_TRY{
20effc67 846 final_node_type* res=super::insert_(
7c673cae
FG
847 x->value(),position,x,detail::emplaced_tag());
848 if(res==x){
849 ++node_count;
20effc67 850 return std::pair<final_node_type*,bool>(res,true);
7c673cae
FG
851 }
852 else{
20effc67
TL
853 delete_node_(x);
854 return std::pair<final_node_type*,bool>(res,false);
7c673cae
FG
855 }
856 }
857 BOOST_CATCH(...){
92f5a8d4 858 destroy_value(x);
7c673cae
FG
859 BOOST_RETHROW;
860 }
861 BOOST_CATCH_END
862 }
863 BOOST_CATCH(...){
864 deallocate_node(x);
865 BOOST_RETHROW;
866 }
867 BOOST_CATCH_END
868 }
869
20effc67
TL
870 std::pair<final_node_type*,bool> insert_ref_(
871 const value_type& x,final_node_type* position)
7c673cae
FG
872 {
873 return insert_(x,position);
874 }
875
20effc67
TL
876 std::pair<final_node_type*,bool> insert_ref_(
877 value_type& x,final_node_type* position)
7c673cae
FG
878 {
879 return insert_(x,position);
880 }
881
20effc67
TL
882 std::pair<final_node_type*,bool> insert_nh_(
883 final_node_handle_type& nh,final_node_type* position)
884 {
885 if(!nh)return std::pair<final_node_type*,bool>(header(),false);
886 else{
887 final_node_type* x=nh.node;
888 final_node_type* res=super::insert_(
889 x->value(),position,x,detail::emplaced_tag());
890 if(res==x){
891 nh.release_node();
892 ++node_count;
893 return std::pair<final_node_type*,bool>(res,true);
894 }
895 else return std::pair<final_node_type*,bool>(res,false);
896 }
897 }
898
7c673cae 899 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
20effc67
TL
900 std::pair<final_node_type*,bool> emplace_hint_(
901 final_node_type* position,
7c673cae
FG
902 BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
903 {
20effc67 904 final_node_type* x=allocate_node();
7c673cae 905 BOOST_TRY{
92f5a8d4 906 construct_value(x,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
7c673cae 907 BOOST_TRY{
20effc67 908 final_node_type* res=super::insert_(
7c673cae
FG
909 x->value(),position,x,detail::emplaced_tag());
910 if(res==x){
911 ++node_count;
20effc67 912 return std::pair<final_node_type*,bool>(res,true);
7c673cae
FG
913 }
914 else{
20effc67
TL
915 delete_node_(x);
916 return std::pair<final_node_type*,bool>(res,false);
7c673cae
FG
917 }
918 }
919 BOOST_CATCH(...){
92f5a8d4 920 destroy_value(x);
7c673cae
FG
921 BOOST_RETHROW;
922 }
923 BOOST_CATCH_END
924 }
925 BOOST_CATCH(...){
926 deallocate_node(x);
927 BOOST_RETHROW;
928 }
929 BOOST_CATCH_END
930 }
931
20effc67 932 final_node_handle_type extract_(final_node_type* x)
7c673cae
FG
933 {
934 --node_count;
1e59de90 935 super::extract_(x,detail::invalidate_iterators());
20effc67 936 return final_node_handle_type(x,get_allocator());
7c673cae
FG
937 }
938
1e59de90
TL
939 template<typename Dst>
940 void extract_for_transfer_(final_node_type* x,Dst dst)
941 {
942 --node_count;
943 super::extract_(x,dst);
944 }
945
20effc67 946 void erase_(final_node_type* x)
7c673cae 947 {
20effc67 948 --node_count;
1e59de90 949 super::extract_(x,detail::invalidate_iterators());
20effc67
TL
950 delete_node_(x);
951 }
952
953 void delete_node_(final_node_type* x)
954 {
955 destroy_value(x);
7c673cae
FG
956 deallocate_node(x);
957 }
958
959 void delete_all_nodes_()
960 {
961 super::delete_all_nodes_();
962 }
963
964 void clear_()
965 {
966 delete_all_nodes_();
967 super::clear_();
968 node_count=0;
969 }
970
1e59de90
TL
971 template<typename Index>
972 void transfer_range_(
973 Index& x,
974 BOOST_DEDUCED_TYPENAME Index::iterator first,
975 BOOST_DEDUCED_TYPENAME Index::iterator last)
976 {
977 while(first!=last){
978 transfer_(x,static_cast<final_node_type*>((first++).get_node()));
979 }
980 }
981
7c673cae
FG
982 void swap_(multi_index_container<Value,IndexSpecifierList,Allocator>& x)
983 {
f67539c2
TL
984 swap_(
985 x,
986 boost::integral_constant<
987 bool,node_alloc_traits::propagate_on_container_swap::value>());
988 }
989
990 void swap_(
991 multi_index_container<Value,IndexSpecifierList,Allocator>& x,
992 boost::true_type swap_allocators)
993 {
994 detail::adl_swap(bfm_allocator::member,x.bfm_allocator::member);
995 std::swap(bfm_header::member,x.bfm_header::member);
996 super::swap_(x,swap_allocators);
997 std::swap(node_count,x.node_count);
998 }
999
1000 void swap_(
1001 multi_index_container<Value,IndexSpecifierList,Allocator>& x,
1002 boost::false_type swap_allocators)
1003 {
7c673cae 1004 std::swap(bfm_header::member,x.bfm_header::member);
f67539c2 1005 super::swap_(x,swap_allocators);
7c673cae
FG
1006 std::swap(node_count,x.node_count);
1007 }
1008
1009 void swap_elements_(
1010 multi_index_container<Value,IndexSpecifierList,Allocator>& x)
1011 {
1012 std::swap(bfm_header::member,x.bfm_header::member);
1013 super::swap_elements_(x);
1014 std::swap(node_count,x.node_count);
1015 }
1016
20effc67 1017 bool replace_(const Value& k,final_node_type* x)
7c673cae
FG
1018 {
1019 return super::replace_(k,x,detail::lvalue_tag());
1020 }
1021
20effc67 1022 bool replace_rv_(const Value& k,final_node_type* x)
7c673cae
FG
1023 {
1024 return super::replace_(k,x,detail::rvalue_tag());
1025 }
1026
1027 template<typename Modifier>
20effc67 1028 bool modify_(Modifier& mod,final_node_type* x)
7c673cae 1029 {
b32b8144
FG
1030 BOOST_TRY{
1031 mod(const_cast<value_type&>(x->value()));
1032 }
1033 BOOST_CATCH(...){
1034 this->erase_(x);
1035 BOOST_RETHROW;
1036 }
1037 BOOST_CATCH_END
7c673cae
FG
1038
1039 BOOST_TRY{
1040 if(!super::modify_(x)){
20effc67 1041 delete_node_(x);
7c673cae
FG
1042 --node_count;
1043 return false;
1044 }
1045 else return true;
1046 }
1047 BOOST_CATCH(...){
20effc67 1048 delete_node_(x);
7c673cae
FG
1049 --node_count;
1050 BOOST_RETHROW;
1051 }
1052 BOOST_CATCH_END
1053 }
1054
1055 template<typename Modifier,typename Rollback>
20effc67 1056 bool modify_(Modifier& mod,Rollback& back_,final_node_type* x)
7c673cae 1057 {
b32b8144
FG
1058 BOOST_TRY{
1059 mod(const_cast<value_type&>(x->value()));
1060 }
1061 BOOST_CATCH(...){
1062 this->erase_(x);
1063 BOOST_RETHROW;
1064 }
1065 BOOST_CATCH_END
7c673cae
FG
1066
1067 bool b;
1068 BOOST_TRY{
1069 b=super::modify_rollback_(x);
1070 }
1071 BOOST_CATCH(...){
1072 BOOST_TRY{
1073 back_(const_cast<value_type&>(x->value()));
b32b8144 1074 if(!super::check_rollback_(x))this->erase_(x);
7c673cae
FG
1075 BOOST_RETHROW;
1076 }
1077 BOOST_CATCH(...){
1078 this->erase_(x);
1079 BOOST_RETHROW;
1080 }
1081 BOOST_CATCH_END
1082 }
1083 BOOST_CATCH_END
1084
1085 BOOST_TRY{
1086 if(!b){
1087 back_(const_cast<value_type&>(x->value()));
b32b8144 1088 if(!super::check_rollback_(x))this->erase_(x);
7c673cae
FG
1089 return false;
1090 }
1091 else return true;
1092 }
1093 BOOST_CATCH(...){
1094 this->erase_(x);
1095 BOOST_RETHROW;
1096 }
1097 BOOST_CATCH_END
1098 }
1099
1100#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
1101 /* serialization */
1102
1103 friend class boost::serialization::access;
1104
1105 BOOST_SERIALIZATION_SPLIT_MEMBER()
1106
1107 typedef typename super::index_saver_type index_saver_type;
1108 typedef typename super::index_loader_type index_loader_type;
1109
1110 template<class Archive>
1111 void save(Archive& ar,const unsigned int version)const
1112 {
1113 const serialization::collection_size_type s(size_());
1114 const detail::serialization_version<value_type> value_version;
1115 ar<<serialization::make_nvp("count",s);
1116 ar<<serialization::make_nvp("value_version",value_version);
1117
1118 index_saver_type sm(bfm_allocator::member,s);
1119
1120 for(iterator it=super::begin(),it_end=super::end();it!=it_end;++it){
11fdf7f2
TL
1121 serialization::save_construct_data_adl(
1122 ar,boost::addressof(*it),value_version);
7c673cae
FG
1123 ar<<serialization::make_nvp("item",*it);
1124 sm.add(it.get_node(),ar,version);
1125 }
1126 sm.add_track(header(),ar,version);
1127
1128 super::save_(ar,version,sm);
1129 }
1130
1131 template<class Archive>
1132 void load(Archive& ar,const unsigned int version)
1133 {
1134 BOOST_MULTI_INDEX_CHECK_INVARIANT;
1135
1136 clear_();
1137 serialization::collection_size_type s;
1138 detail::serialization_version<value_type> value_version;
1139 if(version<1){
1140 std::size_t sz;
1141 ar>>serialization::make_nvp("count",sz);
1142 s=static_cast<serialization::collection_size_type>(sz);
1143 }
1144 else{
1145 ar>>serialization::make_nvp("count",s);
1146 }
1147 if(version<2){
1148 value_version=0;
1149 }
1150 else{
1151 ar>>serialization::make_nvp("value_version",value_version);
1152 }
1153
1154 index_loader_type lm(bfm_allocator::member,s);
1155
1156 for(std::size_t n=0;n<s;++n){
1157 detail::archive_constructed<Value> value("item",ar,value_version);
20effc67 1158 std::pair<final_node_type*,bool> p=insert_rv_(
7c673cae
FG
1159 value.get(),super::end().get_node());
1160 if(!p.second)throw_exception(
1161 archive::archive_exception(
1162 archive::archive_exception::other_exception));
11fdf7f2
TL
1163 ar.reset_object_address(
1164 boost::addressof(p.first->value()),boost::addressof(value.get()));
7c673cae
FG
1165 lm.add(p.first,ar,version);
1166 }
1167 lm.add_track(header(),ar,version);
1168
1169 super::load_(ar,version,lm);
1170 }
1171#endif
1172
1173#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
1174 /* invariant stuff */
1175
1176 bool invariant_()const
1177 {
1178 return super::invariant_();
1179 }
1180
1181 void check_invariant_()const
1182 {
1183 BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_());
1184 }
1185#endif
1186
1187private:
92f5a8d4
TL
1188 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
1189 void vartempl_construct_value_impl(
20effc67 1190 final_node_type* x,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
92f5a8d4
TL
1191 {
1192 node_alloc_traits::construct(
1193 bfm_allocator::member,boost::addressof(x->value()),
1194 BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
1195 }
1196
1197 size_type node_count;
7c673cae
FG
1198
1199#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
1200 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
1201#pragma parse_mfunc_templ reset
1202#endif
1203};
1204
1205#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
1206#pragma warning(pop) /* C4522 */
1207#endif
1208
1209/* retrieval of indices by number */
1210
1211template<typename MultiIndexContainer,int N>
1212struct nth_index
1213{
1214 BOOST_STATIC_CONSTANT(
1215 int,
1216 M=mpl::size<typename MultiIndexContainer::index_type_list>::type::value);
1217 BOOST_STATIC_ASSERT(N>=0&&N<M);
1218 typedef typename mpl::at_c<
1219 typename MultiIndexContainer::index_type_list,N>::type type;
1220};
1221
1222template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
1223typename nth_index<
1224 multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
1225get(
1226 multi_index_container<Value,IndexSpecifierList,Allocator>& m)BOOST_NOEXCEPT
1227{
1228 typedef multi_index_container<
1229 Value,IndexSpecifierList,Allocator> multi_index_type;
1230 typedef typename nth_index<
1231 multi_index_container<
1232 Value,IndexSpecifierList,Allocator>,
1233 N
1234 >::type index_type;
1235
1236 BOOST_STATIC_ASSERT(N>=0&&
1237 N<
1238 mpl::size<
1239 BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
1240 >::type::value);
1241
1242 return detail::converter<multi_index_type,index_type>::index(m);
1243}
1244
1245template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
1246const typename nth_index<
1247 multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
1248get(
1249 const multi_index_container<Value,IndexSpecifierList,Allocator>& m
1250)BOOST_NOEXCEPT
1251{
1252 typedef multi_index_container<
1253 Value,IndexSpecifierList,Allocator> multi_index_type;
1254 typedef typename nth_index<
1255 multi_index_container<
1256 Value,IndexSpecifierList,Allocator>,
1257 N
1258 >::type index_type;
1259
1260 BOOST_STATIC_ASSERT(N>=0&&
1261 N<
1262 mpl::size<
1263 BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
1264 >::type::value);
1265
1266 return detail::converter<multi_index_type,index_type>::index(m);
1267}
1268
1269/* retrieval of indices by tag */
1270
1271template<typename MultiIndexContainer,typename Tag>
1272struct index
1273{
1274 typedef typename MultiIndexContainer::index_type_list index_type_list;
1275
1276 typedef typename mpl::find_if<
1277 index_type_list,
1278 detail::has_tag<Tag>
1279 >::type iter;
1280
1281 BOOST_STATIC_CONSTANT(
1282 bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
1283 BOOST_STATIC_ASSERT(index_found);
1284
1285 typedef typename mpl::deref<iter>::type type;
1286};
1287
1288template<
1289 typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
1290>
1291typename ::boost::multi_index::index<
1292 multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
1293get(
1294 multi_index_container<Value,IndexSpecifierList,Allocator>& m)BOOST_NOEXCEPT
1295{
1296 typedef multi_index_container<
1297 Value,IndexSpecifierList,Allocator> multi_index_type;
1298 typedef typename ::boost::multi_index::index<
1299 multi_index_container<
1300 Value,IndexSpecifierList,Allocator>,
1301 Tag
1302 >::type index_type;
1303
1304 return detail::converter<multi_index_type,index_type>::index(m);
1305}
1306
1307template<
1308 typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
1309>
1310const typename ::boost::multi_index::index<
1311 multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
1312get(
1313 const multi_index_container<Value,IndexSpecifierList,Allocator>& m
1314)BOOST_NOEXCEPT
1315{
1316 typedef multi_index_container<
1317 Value,IndexSpecifierList,Allocator> multi_index_type;
1318 typedef typename ::boost::multi_index::index<
1319 multi_index_container<
1320 Value,IndexSpecifierList,Allocator>,
1321 Tag
1322 >::type index_type;
1323
1324 return detail::converter<multi_index_type,index_type>::index(m);
1325}
1326
1327/* projection of iterators by number */
1328
1329template<typename MultiIndexContainer,int N>
1330struct nth_index_iterator
1331{
1332 typedef typename nth_index<MultiIndexContainer,N>::type::iterator type;
1333};
1334
1335template<typename MultiIndexContainer,int N>
1336struct nth_index_const_iterator
1337{
1338 typedef typename nth_index<MultiIndexContainer,N>::type::const_iterator type;
1339};
1340
1341template<
1342 int N,typename IteratorType,
1343 typename Value,typename IndexSpecifierList,typename Allocator>
1344typename nth_index_iterator<
1345 multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
1346project(
1347 multi_index_container<Value,IndexSpecifierList,Allocator>& m,
1348 IteratorType it)
1349{
1350 typedef multi_index_container<
1351 Value,IndexSpecifierList,Allocator> multi_index_type;
1352 typedef typename nth_index<multi_index_type,N>::type index_type;
1353
1354#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
1355 BOOST_STATIC_ASSERT((
1356 mpl::contains<
1357 BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
1358 IteratorType>::value));
1359#endif
1360
1361 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1e59de90 1362 BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,m);
7c673cae 1363 return detail::converter<multi_index_type,index_type>::iterator(
20effc67 1364 m,static_cast<typename multi_index_type::final_node_type*>(it.get_node()));
7c673cae
FG
1365}
1366
1367template<
1368 int N,typename IteratorType,
1369 typename Value,typename IndexSpecifierList,typename Allocator>
1370typename nth_index_const_iterator<
1371 multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
1372project(
1373 const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
1374 IteratorType it)
1375{
1376 typedef multi_index_container<
1377 Value,IndexSpecifierList,Allocator> multi_index_type;
1378 typedef typename nth_index<multi_index_type,N>::type index_type;
1379
1380#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
1381 BOOST_STATIC_ASSERT((
1382 mpl::contains<
1383 BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
1384 IteratorType>::value||
1385 mpl::contains<
1386 BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
1387 IteratorType>::value));
1388#endif
1389
1390 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1e59de90 1391 BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,m);
7c673cae 1392 return detail::converter<multi_index_type,index_type>::const_iterator(
20effc67 1393 m,static_cast<typename multi_index_type::final_node_type*>(it.get_node()));
7c673cae
FG
1394}
1395
1396/* projection of iterators by tag */
1397
1398template<typename MultiIndexContainer,typename Tag>
1399struct index_iterator
1400{
1401 typedef typename ::boost::multi_index::index<
1402 MultiIndexContainer,Tag>::type::iterator type;
1403};
1404
1405template<typename MultiIndexContainer,typename Tag>
1406struct index_const_iterator
1407{
1408 typedef typename ::boost::multi_index::index<
1409 MultiIndexContainer,Tag>::type::const_iterator type;
1410};
1411
1412template<
1413 typename Tag,typename IteratorType,
1414 typename Value,typename IndexSpecifierList,typename Allocator>
1415typename index_iterator<
1416 multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
1417project(
1418 multi_index_container<Value,IndexSpecifierList,Allocator>& m,
1419 IteratorType it)
1420{
1421 typedef multi_index_container<
1422 Value,IndexSpecifierList,Allocator> multi_index_type;
1423 typedef typename ::boost::multi_index::index<
1424 multi_index_type,Tag>::type index_type;
1425
1426#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
1427 BOOST_STATIC_ASSERT((
1428 mpl::contains<
1429 BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
1430 IteratorType>::value));
1431#endif
1432
1433 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1e59de90 1434 BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,m);
7c673cae 1435 return detail::converter<multi_index_type,index_type>::iterator(
20effc67 1436 m,static_cast<typename multi_index_type::final_node_type*>(it.get_node()));
7c673cae
FG
1437}
1438
1439template<
1440 typename Tag,typename IteratorType,
1441 typename Value,typename IndexSpecifierList,typename Allocator>
1442typename index_const_iterator<
1443 multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
1444project(
1445 const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
1446 IteratorType it)
1447{
1448 typedef multi_index_container<
1449 Value,IndexSpecifierList,Allocator> multi_index_type;
1450 typedef typename ::boost::multi_index::index<
1451 multi_index_type,Tag>::type index_type;
1452
1453#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
1454 BOOST_STATIC_ASSERT((
1455 mpl::contains<
1456 BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
1457 IteratorType>::value||
1458 mpl::contains<
1459 BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
1460 IteratorType>::value));
1461#endif
1462
1463 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1e59de90 1464 BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,m);
7c673cae 1465 return detail::converter<multi_index_type,index_type>::const_iterator(
20effc67 1466 m,static_cast<typename multi_index_type::final_node_type*>(it.get_node()));
7c673cae
FG
1467}
1468
1469/* Comparison. Simple forward to first index. */
1470
1471template<
1472 typename Value1,typename IndexSpecifierList1,typename Allocator1,
1473 typename Value2,typename IndexSpecifierList2,typename Allocator2
1474>
1475bool operator==(
1476 const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1477 const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1478{
1479 return get<0>(x)==get<0>(y);
1480}
1481
1482template<
1483 typename Value1,typename IndexSpecifierList1,typename Allocator1,
1484 typename Value2,typename IndexSpecifierList2,typename Allocator2
1485>
1486bool operator<(
1487 const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1488 const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1489{
1490 return get<0>(x)<get<0>(y);
1491}
1492
1493template<
1494 typename Value1,typename IndexSpecifierList1,typename Allocator1,
1495 typename Value2,typename IndexSpecifierList2,typename Allocator2
1496>
1497bool operator!=(
1498 const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1499 const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1500{
1501 return get<0>(x)!=get<0>(y);
1502}
1503
1504template<
1505 typename Value1,typename IndexSpecifierList1,typename Allocator1,
1506 typename Value2,typename IndexSpecifierList2,typename Allocator2
1507>
1508bool operator>(
1509 const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1510 const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1511{
1512 return get<0>(x)>get<0>(y);
1513}
1514
1515template<
1516 typename Value1,typename IndexSpecifierList1,typename Allocator1,
1517 typename Value2,typename IndexSpecifierList2,typename Allocator2
1518>
1519bool operator>=(
1520 const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1521 const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1522{
1523 return get<0>(x)>=get<0>(y);
1524}
1525
1526template<
1527 typename Value1,typename IndexSpecifierList1,typename Allocator1,
1528 typename Value2,typename IndexSpecifierList2,typename Allocator2
1529>
1530bool operator<=(
1531 const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1532 const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1533{
1534 return get<0>(x)<=get<0>(y);
1535}
1536
1537/* specialized algorithms */
1538
1539template<typename Value,typename IndexSpecifierList,typename Allocator>
1540void swap(
1541 multi_index_container<Value,IndexSpecifierList,Allocator>& x,
1542 multi_index_container<Value,IndexSpecifierList,Allocator>& y)
1543{
1544 x.swap(y);
1545}
1546
1547} /* namespace multi_index */
1548
1549#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
1550/* class version = 1 : we now serialize the size through
1551 * boost::serialization::collection_size_type.
1552 * class version = 2 : proper use of {save|load}_construct_data.
1553 */
1554
1555namespace serialization {
1556template<typename Value,typename IndexSpecifierList,typename Allocator>
1557struct version<
1558 boost::multi_index_container<Value,IndexSpecifierList,Allocator>
1559>
1560{
1561 BOOST_STATIC_CONSTANT(int,value=2);
1562};
1563} /* namespace serialization */
1564#endif
1565
1566/* Associated global functions are promoted to namespace boost, except
1567 * comparison operators and swap, which are meant to be Koenig looked-up.
1568 */
1569
1570using multi_index::get;
1571using multi_index::project;
1572
1573} /* namespace boost */
1574
1575#undef BOOST_MULTI_INDEX_CHECK_INVARIANT
1576#undef BOOST_MULTI_INDEX_CHECK_INVARIANT_OF
1577
1578#endif