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