1
/* Multiply indexed container.
3
* Copyright 2003-2009 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)
8
* See http://www.boost.org/libs/multi_index for library home page.
11
#ifndef BOOST_MULTI_INDEX_HPP
12
#define BOOST_MULTI_INDEX_HPP
14
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
18
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
20
#include <boost/detail/allocator_utilities.hpp>
21
#include <boost/detail/no_exceptions_support.hpp>
22
#include <boost/detail/workaround.hpp>
23
#include <boost/mpl/at.hpp>
24
#include <boost/mpl/contains.hpp>
25
#include <boost/mpl/find_if.hpp>
26
#include <boost/mpl/identity.hpp>
27
#include <boost/mpl/int.hpp>
28
#include <boost/mpl/size.hpp>
29
#include <boost/mpl/deref.hpp>
30
#include <boost/multi_index_container_fwd.hpp>
31
#include <boost/multi_index/detail/access_specifier.hpp>
32
#include <boost/multi_index/detail/adl_swap.hpp>
33
#include <boost/multi_index/detail/base_type.hpp>
34
#include <boost/multi_index/detail/converter.hpp>
35
#include <boost/multi_index/detail/header_holder.hpp>
36
#include <boost/multi_index/detail/has_tag.hpp>
37
#include <boost/multi_index/detail/no_duplicate_tags.hpp>
38
#include <boost/multi_index/detail/prevent_eti.hpp>
39
#include <boost/multi_index/detail/safe_mode.hpp>
40
#include <boost/multi_index/detail/scope_guard.hpp>
41
#include <boost/static_assert.hpp>
42
#include <boost/type_traits/is_same.hpp>
43
#include <boost/utility/base_from_member.hpp>
45
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
46
#include <boost/multi_index/detail/archive_constructed.hpp>
47
#include <boost/serialization/collection_size_type.hpp>
48
#include <boost/serialization/nvp.hpp>
49
#include <boost/serialization/split_member.hpp>
50
#include <boost/serialization/version.hpp>
51
#include <boost/throw_exception.hpp>
54
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
55
#include <boost/multi_index/detail/invariant_assert.hpp>
56
#define BOOST_MULTI_INDEX_CHECK_INVARIANT \
57
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
58
detail::make_obj_guard(*this,&multi_index_container::check_invariant_); \
59
BOOST_JOIN(check_invariant_,__LINE__).touch();
61
#define BOOST_MULTI_INDEX_CHECK_INVARIANT
66
namespace multi_index{
68
template<typename Value,typename IndexSpecifierList,typename Allocator>
69
class multi_index_container:
70
private ::boost::base_from_member<
71
typename boost::detail::allocator::rebind_to<
73
typename detail::multi_index_node_type<
74
Value,IndexSpecifierList,Allocator>::type
76
BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder<
77
typename detail::prevent_eti<
79
typename boost::detail::allocator::rebind_to<
81
typename detail::multi_index_node_type<
82
Value,IndexSpecifierList,Allocator>::type
85
multi_index_container<Value,IndexSpecifierList,Allocator> >,
86
public detail::multi_index_base_type<
87
Value,IndexSpecifierList,Allocator>::type
89
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
90
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
91
/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
92
* lifetime of const references bound to temporaries --precisely what
96
#pragma parse_mfunc_templ off
100
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
101
template <typename,typename,typename> friend class detail::index_base;
102
template <typename,typename> friend struct detail::header_holder;
103
template <typename,typename> friend struct detail::converter;
106
typedef typename detail::multi_index_base_type<
107
Value,IndexSpecifierList,Allocator>::type super;
109
boost::detail::allocator::rebind_to<
111
typename super::node_type
112
>::type node_allocator;
113
typedef ::boost::base_from_member<
114
node_allocator> bfm_allocator;
115
typedef detail::header_holder<
116
typename detail::prevent_eti<
120
multi_index_container> bfm_header;
122
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
123
/* see definition of index_type_list below */
124
typedef typename super::index_type_list super_index_type_list;
128
/* All types are inherited from super, a few are explicitly
129
* brought forward here to save us some typename's.
132
typedef typename super::ctor_args_list ctor_args_list;
133
typedef IndexSpecifierList index_specifier_type_list;
135
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
136
/* MSVC++ 6.0 chokes on moderately long index lists (around 6 indices
137
* or more), with errors ranging from corrupt exes to duplicate
138
* comdats. The following type hiding hack alleviates this condition;
139
* best results combined with type hiding of the indexed_by construct
140
* itself, as explained in the "Compiler specifics" section of
144
struct index_type_list:super_index_type_list
146
typedef index_type_list type;
147
typedef typename super_index_type_list::back back;
148
typedef mpl::v_iter<type,0> begin;
151
mpl::size<super_index_type_list>::value> end;
154
typedef typename super::index_type_list index_type_list;
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;
161
typedef typename super::iterator iterator;
162
typedef typename super::const_iterator const_iterator;
165
detail::no_duplicate_tags_in_index_list<index_type_list>::value);
167
/* global project() needs to see this publicly */
169
typedef typename super::node_type node_type;
171
/* construct/copy/destroy */
173
explicit multi_index_container(
175
#if BOOST_WORKAROUND(__IBMCPP__,<=600)
176
/* VisualAge seems to have an ETI issue with the default values
177
* for arguments args_list and al.
180
const ctor_args_list& args_list=
181
typename mpl::identity<multi_index_container>::type::
183
const allocator_type& al=
184
typename mpl::identity<multi_index_container>::type::
187
const ctor_args_list& args_list=ctor_args_list(),
188
const allocator_type& al=allocator_type()):
192
super(args_list,bfm_allocator::member),
195
BOOST_MULTI_INDEX_CHECK_INVARIANT;
198
explicit multi_index_container(const allocator_type& al):
200
super(ctor_args_list(),bfm_allocator::member),
203
BOOST_MULTI_INDEX_CHECK_INVARIANT;
206
template<typename InputIterator>
207
multi_index_container(
208
InputIterator first,InputIterator last,
210
#if BOOST_WORKAROUND(__IBMCPP__,<=600)
211
/* VisualAge seems to have an ETI issue with the default values
212
* for arguments args_list and al.
215
const ctor_args_list& args_list=
216
typename mpl::identity<multi_index_container>::type::
218
const allocator_type& al=
219
typename mpl::identity<multi_index_container>::type::
222
const ctor_args_list& args_list=ctor_args_list(),
223
const allocator_type& al=allocator_type()):
227
super(args_list,bfm_allocator::member),
230
BOOST_MULTI_INDEX_CHECK_INVARIANT;
232
iterator hint=super::end();
233
for(;first!=last;++first){
234
hint=super::make_iterator(insert_(*first,hint.get_node()).first);
244
multi_index_container(
245
const multi_index_container<Value,IndexSpecifierList,Allocator>& x):
246
bfm_allocator(x.bfm_allocator::member),
251
copy_map_type map(bfm_allocator::member,x.size(),x.header(),header());
252
for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){
253
map.clone(it.get_node());
259
/* Not until this point are the indices required to be consistent,
260
* hence the position of the invariant checker.
263
BOOST_MULTI_INDEX_CHECK_INVARIANT;
266
~multi_index_container()
271
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
272
multi_index_container<Value,IndexSpecifierList,Allocator> x)
274
BOOST_MULTI_INDEX_CHECK_INVARIANT;
279
allocator_type get_allocator()const
281
return allocator_type(bfm_allocator::member);
284
/* retrieval of indices by number */
286
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
290
BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
291
typedef typename mpl::at_c<index_type_list,N>::type type;
295
typename nth_index<N>::type& get(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
297
BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
302
const typename nth_index<N>::type& get(
303
BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int,N))const
305
BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
310
/* retrieval of indices by tag */
312
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
313
template<typename Tag>
316
typedef typename mpl::find_if<
321
BOOST_STATIC_CONSTANT(
322
bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
323
BOOST_STATIC_ASSERT(index_found);
325
typedef typename mpl::deref<iter>::type type;
328
template<typename Tag>
329
typename index<Tag>::type& get(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))
334
template<typename Tag>
335
const typename index<Tag>::type& get(
336
BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))const
342
/* projection of iterators by number */
344
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
346
struct nth_index_iterator
348
typedef typename nth_index<N>::type::iterator type;
352
struct nth_index_const_iterator
354
typedef typename nth_index<N>::type::const_iterator type;
357
template<int N,typename IteratorType>
358
typename nth_index_iterator<N>::type project(
360
BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
362
typedef typename nth_index<N>::type index;
364
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
366
(mpl::contains<iterator_type_list,IteratorType>::value));
369
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
370
BOOST_MULTI_INDEX_CHECK_IS_OWNER(
371
it,static_cast<typename IteratorType::container_type&>(*this));
373
return index::make_iterator(static_cast<node_type*>(it.get_node()));
376
template<int N,typename IteratorType>
377
typename nth_index_const_iterator<N>::type project(
379
BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))const
381
typedef typename nth_index<N>::type index;
383
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
384
BOOST_STATIC_ASSERT((
385
mpl::contains<iterator_type_list,IteratorType>::value||
386
mpl::contains<const_iterator_type_list,IteratorType>::value));
389
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
390
BOOST_MULTI_INDEX_CHECK_IS_OWNER(
391
it,static_cast<const typename IteratorType::container_type&>(*this));
392
return index::make_iterator(static_cast<node_type*>(it.get_node()));
396
/* projection of iterators by tag */
398
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
399
template<typename Tag>
400
struct index_iterator
402
typedef typename index<Tag>::type::iterator type;
405
template<typename Tag>
406
struct index_const_iterator
408
typedef typename index<Tag>::type::const_iterator type;
411
template<typename Tag,typename IteratorType>
412
typename index_iterator<Tag>::type project(
414
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
416
typedef typename index<Tag>::type index;
418
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
420
(mpl::contains<iterator_type_list,IteratorType>::value));
423
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
424
BOOST_MULTI_INDEX_CHECK_IS_OWNER(
425
it,static_cast<typename IteratorType::container_type&>(*this));
426
return index::make_iterator(static_cast<node_type*>(it.get_node()));
429
template<typename Tag,typename IteratorType>
430
typename index_const_iterator<Tag>::type project(
432
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))const
434
typedef typename index<Tag>::type index;
436
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
437
BOOST_STATIC_ASSERT((
438
mpl::contains<iterator_type_list,IteratorType>::value||
439
mpl::contains<const_iterator_type_list,IteratorType>::value));
442
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
443
BOOST_MULTI_INDEX_CHECK_IS_OWNER(
444
it,static_cast<const typename IteratorType::container_type&>(*this));
445
return index::make_iterator(static_cast<node_type*>(it.get_node()));
449
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
450
typedef typename super::copy_map_type copy_map_type;
452
node_type* header()const
454
return &*bfm_header::member;
457
node_type* allocate_node()
459
return &*bfm_allocator::member.allocate(1);
462
void deallocate_node(node_type* x)
464
typedef typename node_allocator::pointer node_pointer;
465
bfm_allocator::member.deallocate(static_cast<node_pointer>(x),1);
470
return node_count==0;
473
std::size_t size_()const
478
std::size_t max_size_()const
480
return static_cast<std::size_t >(-1);
483
std::pair<node_type*,bool> insert_(const Value& v)
485
node_type* x=allocate_node();
487
node_type* res=super::insert_(v,x);
490
return std::pair<node_type*,bool>(res,true);
494
return std::pair<node_type*,bool>(res,false);
504
std::pair<node_type*,bool> insert_(const Value& v,node_type* position)
506
node_type* x=allocate_node();
508
node_type* res=super::insert_(v,position,x);
511
return std::pair<node_type*,bool>(res,true);
515
return std::pair<node_type*,bool>(res,false);
525
void erase_(node_type* x)
532
void delete_node_(node_type* x)
534
super::delete_node_(x);
538
void delete_all_nodes_()
540
super::delete_all_nodes_();
550
void swap_(multi_index_container<Value,IndexSpecifierList,Allocator>& x)
552
if(bfm_allocator::member!=x.bfm_allocator::member){
553
detail::adl_swap(bfm_allocator::member,x.bfm_allocator::member);
555
std::swap(bfm_header::member,x.bfm_header::member);
557
std::swap(node_count,x.node_count);
560
bool replace_(const Value& k,node_type* x)
562
return super::replace_(k,x);
565
template<typename Modifier>
566
bool modify_(Modifier& mod,node_type* x)
568
mod(const_cast<value_type&>(x->value()));
571
if(!super::modify_(x)){
586
template<typename Modifier,typename Rollback>
587
bool modify_(Modifier& mod,Rollback& back,node_type* x)
589
mod(const_cast<value_type&>(x->value()));
593
b=super::modify_rollback_(x);
597
back(const_cast<value_type&>(x->value()));
610
back(const_cast<value_type&>(x->value()));
622
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
625
friend class boost::serialization::access;
627
BOOST_SERIALIZATION_SPLIT_MEMBER()
629
typedef typename super::index_saver_type index_saver_type;
630
typedef typename super::index_loader_type index_loader_type;
632
template<class Archive>
633
void save(Archive& ar,const unsigned int version)const
636
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
637
const serialization::collection_size_type s(size_());
638
ar<<serialization::make_nvp("count",s);
640
const std::size_t s=size_();
641
ar<<serialization::make_nvp("count",s);
644
index_saver_type sm(bfm_allocator::member,s);
646
for(iterator it=super::begin(),it_end=super::end();it!=it_end;++it){
647
ar<<serialization::make_nvp("item",*it);
648
sm.add(it.get_node(),ar,version);
650
sm.add_track(header(),ar,version);
652
super::save_(ar,version,sm);
655
template<class Archive>
656
void load(Archive& ar,const unsigned int version)
658
BOOST_MULTI_INDEX_CHECK_INVARIANT;
662
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
663
serialization::collection_size_type s;
666
ar>>serialization::make_nvp("count",sz);
670
ar>>serialization::make_nvp("count",s);
674
ar>>serialization::make_nvp("count",s);
677
index_loader_type lm(bfm_allocator::member,s);
679
for(std::size_t n=0;n<s;++n){
680
detail::archive_constructed<Value> value("item",ar,version);
681
std::pair<node_type*,bool> p=insert_(
682
value.get(),super::end().get_node());
683
if(!p.second)throw_exception(
684
archive::archive_exception(
685
archive::archive_exception::other_exception));
686
ar.reset_object_address(&p.first->value(),&value.get());
687
lm.add(p.first,ar,version);
689
lm.add_track(header(),ar,version);
691
super::load_(ar,version,lm);
695
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
696
/* invariant stuff */
698
bool invariant_()const
700
return super::invariant_();
703
void check_invariant_()const
705
BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_());
710
std::size_t node_count;
712
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
713
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
714
#pragma parse_mfunc_templ reset
718
/* retrieval of indices by number */
720
template<typename MultiIndexContainer,int N>
723
BOOST_STATIC_CONSTANT(
725
M=mpl::size<typename MultiIndexContainer::index_type_list>::type::value);
726
BOOST_STATIC_ASSERT(N>=0&&N<M);
727
typedef typename mpl::at_c<
728
typename MultiIndexContainer::index_type_list,N>::type type;
731
template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
733
multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
735
multi_index_container<Value,IndexSpecifierList,Allocator>& m
736
BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
738
typedef multi_index_container<
739
Value,IndexSpecifierList,Allocator> multi_index_type;
740
typedef typename nth_index<
741
multi_index_container<
742
Value,IndexSpecifierList,Allocator>,
746
BOOST_STATIC_ASSERT(N>=0&&
749
BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
752
return detail::converter<multi_index_type,index>::index(m);
755
template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
756
const typename nth_index<
757
multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
759
const multi_index_container<Value,IndexSpecifierList,Allocator>& m
760
BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
762
typedef multi_index_container<
763
Value,IndexSpecifierList,Allocator> multi_index_type;
764
typedef typename nth_index<
765
multi_index_container<
766
Value,IndexSpecifierList,Allocator>,
770
BOOST_STATIC_ASSERT(N>=0&&
773
BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
776
return detail::converter<multi_index_type,index>::index(m);
779
/* retrieval of indices by tag */
781
template<typename MultiIndexContainer,typename Tag>
784
typedef typename MultiIndexContainer::index_type_list index_type_list;
786
typedef typename mpl::find_if<
791
BOOST_STATIC_CONSTANT(
792
bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
793
BOOST_STATIC_ASSERT(index_found);
795
typedef typename mpl::deref<iter>::type type;
799
typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
801
typename ::boost::multi_index::index<
802
multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
804
multi_index_container<Value,IndexSpecifierList,Allocator>& m
805
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
807
typedef multi_index_container<
808
Value,IndexSpecifierList,Allocator> multi_index_type;
809
typedef typename ::boost::multi_index::index<
810
multi_index_container<
811
Value,IndexSpecifierList,Allocator>,
815
return detail::converter<multi_index_type,index>::index(m);
819
typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
821
const typename ::boost::multi_index::index<
822
multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
824
const multi_index_container<Value,IndexSpecifierList,Allocator>& m
825
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
827
typedef multi_index_container<
828
Value,IndexSpecifierList,Allocator> multi_index_type;
829
typedef typename ::boost::multi_index::index<
830
multi_index_container<
831
Value,IndexSpecifierList,Allocator>,
835
return detail::converter<multi_index_type,index>::index(m);
838
/* projection of iterators by number */
840
template<typename MultiIndexContainer,int N>
841
struct nth_index_iterator
843
typedef typename detail::prevent_eti<
844
nth_index<MultiIndexContainer,N>,
845
typename nth_index<MultiIndexContainer,N>::type>::type::iterator type;
848
template<typename MultiIndexContainer,int N>
849
struct nth_index_const_iterator
851
typedef typename detail::prevent_eti<
852
nth_index<MultiIndexContainer,N>,
853
typename nth_index<MultiIndexContainer,N>::type
854
>::type::const_iterator type;
858
int N,typename IteratorType,
859
typename Value,typename IndexSpecifierList,typename Allocator>
860
typename nth_index_iterator<
861
multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
863
multi_index_container<Value,IndexSpecifierList,Allocator>& m,
865
BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
867
typedef multi_index_container<
868
Value,IndexSpecifierList,Allocator> multi_index_type;
869
typedef typename nth_index<multi_index_type,N>::type index;
871
#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
872
(!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
873
BOOST_STATIC_ASSERT((
875
BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
876
IteratorType>::value));
879
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
881
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
882
typedef detail::converter<
884
BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
885
BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
888
return detail::converter<multi_index_type,index>::iterator(
889
m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
893
int N,typename IteratorType,
894
typename Value,typename IndexSpecifierList,typename Allocator>
895
typename nth_index_const_iterator<
896
multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
898
const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
900
BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
902
typedef multi_index_container<
903
Value,IndexSpecifierList,Allocator> multi_index_type;
904
typedef typename nth_index<multi_index_type,N>::type index;
906
#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
907
(!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
908
BOOST_STATIC_ASSERT((
910
BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
911
IteratorType>::value||
913
BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
914
IteratorType>::value));
917
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
919
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
920
typedef detail::converter<
922
BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
923
BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
926
return detail::converter<multi_index_type,index>::const_iterator(
927
m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
930
/* projection of iterators by tag */
932
template<typename MultiIndexContainer,typename Tag>
933
struct index_iterator
935
typedef typename ::boost::multi_index::index<
936
MultiIndexContainer,Tag>::type::iterator type;
939
template<typename MultiIndexContainer,typename Tag>
940
struct index_const_iterator
942
typedef typename ::boost::multi_index::index<
943
MultiIndexContainer,Tag>::type::const_iterator type;
947
typename Tag,typename IteratorType,
948
typename Value,typename IndexSpecifierList,typename Allocator>
949
typename index_iterator<
950
multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
952
multi_index_container<Value,IndexSpecifierList,Allocator>& m,
954
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
956
typedef multi_index_container<
957
Value,IndexSpecifierList,Allocator> multi_index_type;
958
typedef typename ::boost::multi_index::index<
959
multi_index_type,Tag>::type index;
961
#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
962
(!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
963
BOOST_STATIC_ASSERT((
965
BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
966
IteratorType>::value));
969
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
971
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
972
typedef detail::converter<
974
BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
975
BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
978
return detail::converter<multi_index_type,index>::iterator(
979
m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
983
typename Tag,typename IteratorType,
984
typename Value,typename IndexSpecifierList,typename Allocator>
985
typename index_const_iterator<
986
multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
988
const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
990
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
992
typedef multi_index_container<
993
Value,IndexSpecifierList,Allocator> multi_index_type;
994
typedef typename ::boost::multi_index::index<
995
multi_index_type,Tag>::type index;
997
#if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
998
(!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
999
BOOST_STATIC_ASSERT((
1001
BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
1002
IteratorType>::value||
1004
BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
1005
IteratorType>::value));
1008
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1010
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
1011
typedef detail::converter<
1013
BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
1014
BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
1017
return detail::converter<multi_index_type,index>::const_iterator(
1018
m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
1021
/* Comparison. Simple forward to first index. */
1024
typename Value1,typename IndexSpecifierList1,typename Allocator1,
1025
typename Value2,typename IndexSpecifierList2,typename Allocator2
1028
const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1029
const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1031
return get<0>(x)==get<0>(y);
1035
typename Value1,typename IndexSpecifierList1,typename Allocator1,
1036
typename Value2,typename IndexSpecifierList2,typename Allocator2
1039
const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1040
const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1042
return get<0>(x)<get<0>(y);
1046
typename Value1,typename IndexSpecifierList1,typename Allocator1,
1047
typename Value2,typename IndexSpecifierList2,typename Allocator2
1050
const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1051
const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1053
return get<0>(x)!=get<0>(y);
1057
typename Value1,typename IndexSpecifierList1,typename Allocator1,
1058
typename Value2,typename IndexSpecifierList2,typename Allocator2
1061
const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1062
const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1064
return get<0>(x)>get<0>(y);
1068
typename Value1,typename IndexSpecifierList1,typename Allocator1,
1069
typename Value2,typename IndexSpecifierList2,typename Allocator2
1072
const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1073
const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1075
return get<0>(x)>=get<0>(y);
1079
typename Value1,typename IndexSpecifierList1,typename Allocator1,
1080
typename Value2,typename IndexSpecifierList2,typename Allocator2
1083
const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1084
const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1086
return get<0>(x)<=get<0>(y);
1089
/* specialized algorithms */
1091
template<typename Value,typename IndexSpecifierList,typename Allocator>
1093
multi_index_container<Value,IndexSpecifierList,Allocator>& x,
1094
multi_index_container<Value,IndexSpecifierList,Allocator>& y)
1099
} /* namespace multi_index */
1101
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)&&\
1102
!defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
1103
/* Serialization class version bump as we now serialize the size
1104
* through boost::serialization::collection_size_type.
1107
namespace serialization {
1108
template<typename Value,typename IndexSpecifierList,typename Allocator>
1110
boost::multi_index_container<Value,IndexSpecifierList,Allocator>
1113
BOOST_STATIC_CONSTANT(unsigned int,value=1);
1115
} /* namespace serialization */
1118
/* Associated global functions are promoted to namespace boost, except
1119
* comparison operators and swap, which are meant to be Koenig looked-up.
1122
using multi_index::get;
1123
using multi_index::project;
1125
} /* namespace boost */
1127
#undef BOOST_MULTI_INDEX_CHECK_INVARIANT