1 /* Multiply indexed container.
3 * Copyright 2003-2010 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/multi_index/detail/serialization_version.hpp>
48 #include <boost/serialization/collection_size_type.hpp>
49 #include <boost/serialization/nvp.hpp>
50 #include <boost/serialization/split_member.hpp>
51 #include <boost/serialization/version.hpp>
52 #include <boost/throw_exception.hpp>
55 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
56 #include <boost/multi_index/detail/invariant_assert.hpp>
57 #define BOOST_MULTI_INDEX_CHECK_INVARIANT \
58 detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
59 detail::make_obj_guard(*this,&multi_index_container::check_invariant_); \
60 BOOST_JOIN(check_invariant_,__LINE__).touch();
62 #define BOOST_MULTI_INDEX_CHECK_INVARIANT
67 namespace multi_index
{
69 template<typename Value
,typename IndexSpecifierList
,typename Allocator
>
70 class multi_index_container
:
71 private ::boost::base_from_member
<
72 typename
boost::detail::allocator::rebind_to
<
74 typename
detail::multi_index_node_type
<
75 Value
,IndexSpecifierList
,Allocator
>::type
77 BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS
detail::header_holder
<
78 typename
detail::prevent_eti
<
80 typename
boost::detail::allocator::rebind_to
<
82 typename
detail::multi_index_node_type
<
83 Value
,IndexSpecifierList
,Allocator
>::type
86 multi_index_container
<Value
,IndexSpecifierList
,Allocator
> >,
87 public detail::multi_index_base_type
<
88 Value
,IndexSpecifierList
,Allocator
>::type
90 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
91 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
92 /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
93 * lifetime of const references bound to temporaries --precisely what
97 #pragma parse_mfunc_templ off
101 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
102 template <typename
,typename
,typename
> friend class detail::index_base
;
103 template <typename
,typename
> friend struct detail::header_holder
;
104 template <typename
,typename
> friend struct detail::converter
;
107 typedef typename
detail::multi_index_base_type
<
108 Value
,IndexSpecifierList
,Allocator
>::type super
;
110 boost::detail::allocator::rebind_to
<
112 typename
super::node_type
113 >::type node_allocator
;
114 typedef ::boost::base_from_member
<
115 node_allocator
> bfm_allocator
;
116 typedef detail::header_holder
<
117 typename
detail::prevent_eti
<
121 multi_index_container
> bfm_header
;
123 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
124 /* see definition of index_type_list below */
125 typedef typename
super::index_type_list super_index_type_list
;
129 /* All types are inherited from super, a few are explicitly
130 * brought forward here to save us some typename's.
133 typedef typename
super::ctor_args_list ctor_args_list
;
134 typedef IndexSpecifierList index_specifier_type_list
;
136 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
137 /* MSVC++ 6.0 chokes on moderately long index lists (around 6 indices
138 * or more), with errors ranging from corrupt exes to duplicate
139 * comdats. The following type hiding hack alleviates this condition;
140 * best results combined with type hiding of the indexed_by construct
141 * itself, as explained in the "Compiler specifics" section of
145 struct index_type_list
:super_index_type_list
147 typedef index_type_list type
;
148 typedef typename
super_index_type_list::back back
;
149 typedef mpl::v_iter
<type
,0> begin
;
152 mpl::size
<super_index_type_list
>::value
> end
;
155 typedef typename
super::index_type_list index_type_list
;
158 typedef typename
super::iterator_type_list iterator_type_list
;
159 typedef typename
super::const_iterator_type_list const_iterator_type_list
;
160 typedef typename
super::value_type value_type
;
161 typedef typename
super::final_allocator_type allocator_type
;
162 typedef typename
super::iterator iterator
;
163 typedef typename
super::const_iterator const_iterator
;
166 detail::no_duplicate_tags_in_index_list
<index_type_list
>::value
);
168 /* global project() needs to see this publicly */
170 typedef typename
super::node_type node_type
;
172 /* construct/copy/destroy */
174 explicit multi_index_container(
176 #if BOOST_WORKAROUND(__IBMCPP__,<=600)
177 /* VisualAge seems to have an ETI issue with the default values
178 * for arguments args_list and al.
181 const ctor_args_list
& args_list
=
182 typename
mpl::identity
<multi_index_container
>::type::
184 const allocator_type
& al
=
185 typename
mpl::identity
<multi_index_container
>::type::
188 const ctor_args_list
& args_list
=ctor_args_list(),
189 const allocator_type
& al
=allocator_type()):
193 super(args_list
,bfm_allocator::member
),
196 BOOST_MULTI_INDEX_CHECK_INVARIANT
;
199 explicit multi_index_container(const allocator_type
& al
):
201 super(ctor_args_list(),bfm_allocator::member
),
204 BOOST_MULTI_INDEX_CHECK_INVARIANT
;
207 template<typename InputIterator
>
208 multi_index_container(
209 InputIterator first
,InputIterator last
,
211 #if BOOST_WORKAROUND(__IBMCPP__,<=600)
212 /* VisualAge seems to have an ETI issue with the default values
213 * for arguments args_list and al.
216 const ctor_args_list
& args_list
=
217 typename
mpl::identity
<multi_index_container
>::type::
219 const allocator_type
& al
=
220 typename
mpl::identity
<multi_index_container
>::type::
223 const ctor_args_list
& args_list
=ctor_args_list(),
224 const allocator_type
& al
=allocator_type()):
228 super(args_list
,bfm_allocator::member
),
231 BOOST_MULTI_INDEX_CHECK_INVARIANT
;
233 iterator hint
=super::end();
234 for(;first
!=last
;++first
){
235 hint
=super::make_iterator(insert_(*first
,hint
.get_node()).first
);
245 multi_index_container(
246 const multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& x
):
247 bfm_allocator(x
.bfm_allocator::member
),
252 copy_map_type
map(bfm_allocator::member
,x
.size(),x
.header(),header());
253 for(const_iterator it
=x
.begin(),it_end
=x
.end();it
!=it_end
;++it
){
254 map
.clone(it
.get_node());
260 /* Not until this point are the indices required to be consistent,
261 * hence the position of the invariant checker.
264 BOOST_MULTI_INDEX_CHECK_INVARIANT
;
267 ~multi_index_container()
272 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& operator=(
273 multi_index_container
<Value
,IndexSpecifierList
,Allocator
> x
)
275 BOOST_MULTI_INDEX_CHECK_INVARIANT
;
280 allocator_type
get_allocator()const
282 return allocator_type(bfm_allocator::member
);
285 /* retrieval of indices by number */
287 #if !defined(BOOST_NO_MEMBER_TEMPLATES)
291 BOOST_STATIC_ASSERT(N
>=0&&N
<mpl::size
<index_type_list
>::type::value
);
292 typedef typename
mpl::at_c
<index_type_list
,N
>::type type
;
296 typename nth_index
<N
>::type
& get(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int,N
))
298 BOOST_STATIC_ASSERT(N
>=0&&N
<mpl::size
<index_type_list
>::type::value
);
303 const typename nth_index
<N
>::type
& get(
304 BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int,N
))const
306 BOOST_STATIC_ASSERT(N
>=0&&N
<mpl::size
<index_type_list
>::type::value
);
311 /* retrieval of indices by tag */
313 #if !defined(BOOST_NO_MEMBER_TEMPLATES)
314 template<typename Tag
>
317 typedef typename
mpl::find_if
<
322 BOOST_STATIC_CONSTANT(
323 bool,index_found
=!(is_same
<iter
,typename
mpl::end
<index_type_list
>::type
>::value
));
324 BOOST_STATIC_ASSERT(index_found
);
326 typedef typename
mpl::deref
<iter
>::type type
;
329 template<typename Tag
>
330 typename index
<Tag
>::type
& get(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag
))
335 template<typename Tag
>
336 const typename index
<Tag
>::type
& get(
337 BOOST_EXPLICIT_TEMPLATE_TYPE(Tag
))const
343 /* projection of iterators by number */
345 #if !defined(BOOST_NO_MEMBER_TEMPLATES)
347 struct nth_index_iterator
349 typedef typename nth_index
<N
>::type::iterator type
;
353 struct nth_index_const_iterator
355 typedef typename nth_index
<N
>::type::const_iterator type
;
358 template<int N
,typename IteratorType
>
359 typename nth_index_iterator
<N
>::type
project(
361 BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N
))
363 typedef typename nth_index
<N
>::type index
;
365 #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
367 (mpl::contains
<iterator_type_list
,IteratorType
>::value
));
370 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it
);
371 BOOST_MULTI_INDEX_CHECK_IS_OWNER(
372 it
,static_cast<typename
IteratorType::container_type
&>(*this));
374 return index::make_iterator(static_cast<node_type
*>(it
.get_node()));
377 template<int N
,typename IteratorType
>
378 typename nth_index_const_iterator
<N
>::type
project(
380 BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N
))const
382 typedef typename nth_index
<N
>::type index
;
384 #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
385 BOOST_STATIC_ASSERT((
386 mpl::contains
<iterator_type_list
,IteratorType
>::value
||
387 mpl::contains
<const_iterator_type_list
,IteratorType
>::value
));
390 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it
);
391 BOOST_MULTI_INDEX_CHECK_IS_OWNER(
392 it
,static_cast<const typename
IteratorType::container_type
&>(*this));
393 return index::make_iterator(static_cast<node_type
*>(it
.get_node()));
397 /* projection of iterators by tag */
399 #if !defined(BOOST_NO_MEMBER_TEMPLATES)
400 template<typename Tag
>
401 struct index_iterator
403 typedef typename index
<Tag
>::type::iterator type
;
406 template<typename Tag
>
407 struct index_const_iterator
409 typedef typename index
<Tag
>::type::const_iterator type
;
412 template<typename Tag
,typename IteratorType
>
413 typename index_iterator
<Tag
>::type
project(
415 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag
))
417 typedef typename index
<Tag
>::type index
;
419 #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
421 (mpl::contains
<iterator_type_list
,IteratorType
>::value
));
424 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it
);
425 BOOST_MULTI_INDEX_CHECK_IS_OWNER(
426 it
,static_cast<typename
IteratorType::container_type
&>(*this));
427 return index::make_iterator(static_cast<node_type
*>(it
.get_node()));
430 template<typename Tag
,typename IteratorType
>
431 typename index_const_iterator
<Tag
>::type
project(
433 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag
))const
435 typedef typename index
<Tag
>::type index
;
437 #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
438 BOOST_STATIC_ASSERT((
439 mpl::contains
<iterator_type_list
,IteratorType
>::value
||
440 mpl::contains
<const_iterator_type_list
,IteratorType
>::value
));
443 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it
);
444 BOOST_MULTI_INDEX_CHECK_IS_OWNER(
445 it
,static_cast<const typename
IteratorType::container_type
&>(*this));
446 return index::make_iterator(static_cast<node_type
*>(it
.get_node()));
450 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS
:
451 typedef typename
super::copy_map_type copy_map_type
;
453 node_type
* header()const
455 return &*bfm_header::member
;
458 node_type
* allocate_node()
460 return &*bfm_allocator::member
.allocate(1);
463 void deallocate_node(node_type
* x
)
465 typedef typename
node_allocator::pointer node_pointer
;
466 bfm_allocator::member
.deallocate(static_cast<node_pointer
>(x
),1);
471 return node_count
==0;
474 std::size_t size_()const
479 std::size_t max_size_()const
481 return static_cast<std::size_t >(-1);
484 std::pair
<node_type
*,bool> insert_(const Value
& v
)
486 node_type
* x
=allocate_node();
488 node_type
* res
=super::insert_(v
,x
);
491 return std::pair
<node_type
*,bool>(res
,true);
495 return std::pair
<node_type
*,bool>(res
,false);
505 std::pair
<node_type
*,bool> insert_(const Value
& v
,node_type
* position
)
507 node_type
* x
=allocate_node();
509 node_type
* res
=super::insert_(v
,position
,x
);
512 return std::pair
<node_type
*,bool>(res
,true);
516 return std::pair
<node_type
*,bool>(res
,false);
526 void erase_(node_type
* x
)
533 void delete_node_(node_type
* x
)
535 super::delete_node_(x
);
539 void delete_all_nodes_()
541 super::delete_all_nodes_();
551 void swap_(multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& x
)
553 if(bfm_allocator::member
!=x
.bfm_allocator::member
){
554 detail::adl_swap(bfm_allocator::member
,x
.bfm_allocator::member
);
556 std::swap(bfm_header::member
,x
.bfm_header::member
);
558 std::swap(node_count
,x
.node_count
);
561 bool replace_(const Value
& k
,node_type
* x
)
563 return super::replace_(k
,x
);
566 template<typename Modifier
>
567 bool modify_(Modifier
& mod
,node_type
* x
)
569 mod(const_cast<value_type
&>(x
->value()));
572 if(!super::modify_(x
)){
587 template<typename Modifier
,typename Rollback
>
588 bool modify_(Modifier
& mod
,Rollback
& back
,node_type
* x
)
590 mod(const_cast<value_type
&>(x
->value()));
594 b
=super::modify_rollback_(x
);
598 back(const_cast<value_type
&>(x
->value()));
611 back(const_cast<value_type
&>(x
->value()));
623 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
626 friend class boost::serialization::access
;
628 BOOST_SERIALIZATION_SPLIT_MEMBER()
630 typedef typename
super::index_saver_type index_saver_type
;
631 typedef typename
super::index_loader_type index_loader_type
;
633 template<class Archive
>
634 void save(Archive
& ar
,const unsigned int version
)const
637 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
638 const serialization::collection_size_type
s(size_());
639 const detail::serialization_version
<value_type
> value_version
;
640 ar
<<serialization::make_nvp("count",s
);
641 ar
<<serialization::make_nvp("value_version",value_version
);
643 const std::size_t s
=size_();
644 const unsigned int value_version
=0;
645 ar
<<serialization::make_nvp("count",s
);
648 index_saver_type
sm(bfm_allocator::member
,s
);
650 for(iterator it
=super::begin(),it_end
=super::end();it
!=it_end
;++it
){
651 serialization::save_construct_data_adl(ar
,&*it
,value_version
);
652 ar
<<serialization::make_nvp("item",*it
);
653 sm
.add(it
.get_node(),ar
,version
);
655 sm
.add_track(header(),ar
,version
);
657 super::save_(ar
,version
,sm
);
660 template<class Archive
>
661 void load(Archive
& ar
,const unsigned int version
)
663 BOOST_MULTI_INDEX_CHECK_INVARIANT
;
667 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
668 serialization::collection_size_type s
;
669 detail::serialization_version
<value_type
> value_version
;
672 ar
>>serialization::make_nvp("count",sz
);
676 ar
>>serialization::make_nvp("count",s
);
682 ar
>>serialization::make_nvp("value_version",value_version
);
686 unsigned int value_version
=0;
687 ar
>>serialization::make_nvp("count",s
);
690 index_loader_type
lm(bfm_allocator::member
,s
);
692 for(std::size_t n
=0;n
<s
;++n
){
693 detail::archive_constructed
<Value
> value("item",ar
,value_version
);
694 std::pair
<node_type
*,bool> p
=insert_(
695 value
.get(),super::end().get_node());
696 if(!p
.second
)throw_exception(
697 archive::archive_exception(
698 archive::archive_exception::other_exception
));
699 ar
.reset_object_address(&p
.first
->value(),&value
.get());
700 lm
.add(p
.first
,ar
,version
);
702 lm
.add_track(header(),ar
,version
);
704 super::load_(ar
,version
,lm
);
708 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
709 /* invariant stuff */
711 bool invariant_()const
713 return super::invariant_();
716 void check_invariant_()const
718 BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_());
723 std::size_t node_count
;
725 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
726 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
727 #pragma parse_mfunc_templ reset
731 /* retrieval of indices by number */
733 template<typename MultiIndexContainer
,int N
>
736 BOOST_STATIC_CONSTANT(
738 M
=mpl::size
<typename
MultiIndexContainer::index_type_list
>::type::value
);
739 BOOST_STATIC_ASSERT(N
>=0&&N
<M
);
740 typedef typename
mpl::at_c
<
741 typename
MultiIndexContainer::index_type_list
,N
>::type type
;
744 template<int N
,typename Value
,typename IndexSpecifierList
,typename Allocator
>
746 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>,N
>::type
&
748 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& m
749 BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N
))
751 typedef multi_index_container
<
752 Value
,IndexSpecifierList
,Allocator
> multi_index_type
;
753 typedef typename nth_index
<
754 multi_index_container
<
755 Value
,IndexSpecifierList
,Allocator
>,
759 BOOST_STATIC_ASSERT(N
>=0&&
762 BOOST_DEDUCED_TYPENAME
multi_index_type::index_type_list
765 return detail::converter
<multi_index_type
,index
>::index(m
);
768 template<int N
,typename Value
,typename IndexSpecifierList
,typename Allocator
>
769 const typename nth_index
<
770 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>,N
>::type
&
772 const multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& m
773 BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N
))
775 typedef multi_index_container
<
776 Value
,IndexSpecifierList
,Allocator
> multi_index_type
;
777 typedef typename nth_index
<
778 multi_index_container
<
779 Value
,IndexSpecifierList
,Allocator
>,
783 BOOST_STATIC_ASSERT(N
>=0&&
786 BOOST_DEDUCED_TYPENAME
multi_index_type::index_type_list
789 return detail::converter
<multi_index_type
,index
>::index(m
);
792 /* retrieval of indices by tag */
794 template<typename MultiIndexContainer
,typename Tag
>
797 typedef typename
MultiIndexContainer::index_type_list index_type_list
;
799 typedef typename
mpl::find_if
<
804 BOOST_STATIC_CONSTANT(
805 bool,index_found
=!(is_same
<iter
,typename
mpl::end
<index_type_list
>::type
>::value
));
806 BOOST_STATIC_ASSERT(index_found
);
808 typedef typename
mpl::deref
<iter
>::type type
;
812 typename Tag
,typename Value
,typename IndexSpecifierList
,typename Allocator
814 typename ::boost::multi_index::index
<
815 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>,Tag
>::type
&
817 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& m
818 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag
))
820 typedef multi_index_container
<
821 Value
,IndexSpecifierList
,Allocator
> multi_index_type
;
822 typedef typename ::boost::multi_index::index
<
823 multi_index_container
<
824 Value
,IndexSpecifierList
,Allocator
>,
828 return detail::converter
<multi_index_type
,index
>::index(m
);
832 typename Tag
,typename Value
,typename IndexSpecifierList
,typename Allocator
834 const typename ::boost::multi_index::index
<
835 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>,Tag
>::type
&
837 const multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& m
838 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag
))
840 typedef multi_index_container
<
841 Value
,IndexSpecifierList
,Allocator
> multi_index_type
;
842 typedef typename ::boost::multi_index::index
<
843 multi_index_container
<
844 Value
,IndexSpecifierList
,Allocator
>,
848 return detail::converter
<multi_index_type
,index
>::index(m
);
851 /* projection of iterators by number */
853 template<typename MultiIndexContainer
,int N
>
854 struct nth_index_iterator
856 typedef typename
detail::prevent_eti
<
857 nth_index
<MultiIndexContainer
,N
>,
858 typename nth_index
<MultiIndexContainer
,N
>::type
>::type::iterator type
;
861 template<typename MultiIndexContainer
,int N
>
862 struct nth_index_const_iterator
864 typedef typename
detail::prevent_eti
<
865 nth_index
<MultiIndexContainer
,N
>,
866 typename nth_index
<MultiIndexContainer
,N
>::type
867 >::type::const_iterator type
;
871 int N
,typename IteratorType
,
872 typename Value
,typename IndexSpecifierList
,typename Allocator
>
873 typename nth_index_iterator
<
874 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>,N
>::type
876 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& m
,
878 BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N
))
880 typedef multi_index_container
<
881 Value
,IndexSpecifierList
,Allocator
> multi_index_type
;
882 typedef typename nth_index
<multi_index_type
,N
>::type index
;
884 #if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
885 (!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
886 BOOST_STATIC_ASSERT((
888 BOOST_DEDUCED_TYPENAME
multi_index_type::iterator_type_list
,
889 IteratorType
>::value
));
892 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it
);
894 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
895 typedef detail::converter
<
897 BOOST_DEDUCED_TYPENAME
IteratorType::container_type
> converter
;
898 BOOST_MULTI_INDEX_CHECK_IS_OWNER(it
,converter::index(m
));
901 return detail::converter
<multi_index_type
,index
>::iterator(
902 m
,static_cast<typename
multi_index_type::node_type
*>(it
.get_node()));
906 int N
,typename IteratorType
,
907 typename Value
,typename IndexSpecifierList
,typename Allocator
>
908 typename nth_index_const_iterator
<
909 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>,N
>::type
911 const multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& m
,
913 BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N
))
915 typedef multi_index_container
<
916 Value
,IndexSpecifierList
,Allocator
> multi_index_type
;
917 typedef typename nth_index
<multi_index_type
,N
>::type index
;
919 #if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
920 (!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
921 BOOST_STATIC_ASSERT((
923 BOOST_DEDUCED_TYPENAME
multi_index_type::iterator_type_list
,
924 IteratorType
>::value
||
926 BOOST_DEDUCED_TYPENAME
multi_index_type::const_iterator_type_list
,
927 IteratorType
>::value
));
930 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it
);
932 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
933 typedef detail::converter
<
935 BOOST_DEDUCED_TYPENAME
IteratorType::container_type
> converter
;
936 BOOST_MULTI_INDEX_CHECK_IS_OWNER(it
,converter::index(m
));
939 return detail::converter
<multi_index_type
,index
>::const_iterator(
940 m
,static_cast<typename
multi_index_type::node_type
*>(it
.get_node()));
943 /* projection of iterators by tag */
945 template<typename MultiIndexContainer
,typename Tag
>
946 struct index_iterator
948 typedef typename ::boost::multi_index::index
<
949 MultiIndexContainer
,Tag
>::type::iterator type
;
952 template<typename MultiIndexContainer
,typename Tag
>
953 struct index_const_iterator
955 typedef typename ::boost::multi_index::index
<
956 MultiIndexContainer
,Tag
>::type::const_iterator type
;
960 typename Tag
,typename IteratorType
,
961 typename Value
,typename IndexSpecifierList
,typename Allocator
>
962 typename index_iterator
<
963 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>,Tag
>::type
965 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& m
,
967 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag
))
969 typedef multi_index_container
<
970 Value
,IndexSpecifierList
,Allocator
> multi_index_type
;
971 typedef typename ::boost::multi_index::index
<
972 multi_index_type
,Tag
>::type index
;
974 #if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
975 (!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
976 BOOST_STATIC_ASSERT((
978 BOOST_DEDUCED_TYPENAME
multi_index_type::iterator_type_list
,
979 IteratorType
>::value
));
982 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it
);
984 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
985 typedef detail::converter
<
987 BOOST_DEDUCED_TYPENAME
IteratorType::container_type
> converter
;
988 BOOST_MULTI_INDEX_CHECK_IS_OWNER(it
,converter::index(m
));
991 return detail::converter
<multi_index_type
,index
>::iterator(
992 m
,static_cast<typename
multi_index_type::node_type
*>(it
.get_node()));
996 typename Tag
,typename IteratorType
,
997 typename Value
,typename IndexSpecifierList
,typename Allocator
>
998 typename index_const_iterator
<
999 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>,Tag
>::type
1001 const multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& m
,
1003 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag
))
1005 typedef multi_index_container
<
1006 Value
,IndexSpecifierList
,Allocator
> multi_index_type
;
1007 typedef typename ::boost::multi_index::index
<
1008 multi_index_type
,Tag
>::type index
;
1010 #if (!defined(BOOST_MSVC)||!(BOOST_MSVC<1310))&& /* MSVC++ 6.0/7.0 fails */\
1011 (!defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580)) /* as does Sun C++ 5.7 */
1012 BOOST_STATIC_ASSERT((
1014 BOOST_DEDUCED_TYPENAME
multi_index_type::iterator_type_list
,
1015 IteratorType
>::value
||
1017 BOOST_DEDUCED_TYPENAME
multi_index_type::const_iterator_type_list
,
1018 IteratorType
>::value
));
1021 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it
);
1023 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
1024 typedef detail::converter
<
1026 BOOST_DEDUCED_TYPENAME
IteratorType::container_type
> converter
;
1027 BOOST_MULTI_INDEX_CHECK_IS_OWNER(it
,converter::index(m
));
1030 return detail::converter
<multi_index_type
,index
>::const_iterator(
1031 m
,static_cast<typename
multi_index_type::node_type
*>(it
.get_node()));
1034 /* Comparison. Simple forward to first index. */
1037 typename Value1
,typename IndexSpecifierList1
,typename Allocator1
,
1038 typename Value2
,typename IndexSpecifierList2
,typename Allocator2
1041 const multi_index_container
<Value1
,IndexSpecifierList1
,Allocator1
>& x
,
1042 const multi_index_container
<Value2
,IndexSpecifierList2
,Allocator2
>& y
)
1044 return get
<0>(x
)==get
<0>(y
);
1048 typename Value1
,typename IndexSpecifierList1
,typename Allocator1
,
1049 typename Value2
,typename IndexSpecifierList2
,typename Allocator2
1052 const multi_index_container
<Value1
,IndexSpecifierList1
,Allocator1
>& x
,
1053 const multi_index_container
<Value2
,IndexSpecifierList2
,Allocator2
>& y
)
1055 return get
<0>(x
)<get
<0>(y
);
1059 typename Value1
,typename IndexSpecifierList1
,typename Allocator1
,
1060 typename Value2
,typename IndexSpecifierList2
,typename Allocator2
1063 const multi_index_container
<Value1
,IndexSpecifierList1
,Allocator1
>& x
,
1064 const multi_index_container
<Value2
,IndexSpecifierList2
,Allocator2
>& y
)
1066 return get
<0>(x
)!=get
<0>(y
);
1070 typename Value1
,typename IndexSpecifierList1
,typename Allocator1
,
1071 typename Value2
,typename IndexSpecifierList2
,typename Allocator2
1074 const multi_index_container
<Value1
,IndexSpecifierList1
,Allocator1
>& x
,
1075 const multi_index_container
<Value2
,IndexSpecifierList2
,Allocator2
>& y
)
1077 return get
<0>(x
)>get
<0>(y
);
1081 typename Value1
,typename IndexSpecifierList1
,typename Allocator1
,
1082 typename Value2
,typename IndexSpecifierList2
,typename Allocator2
1085 const multi_index_container
<Value1
,IndexSpecifierList1
,Allocator1
>& x
,
1086 const multi_index_container
<Value2
,IndexSpecifierList2
,Allocator2
>& y
)
1088 return get
<0>(x
)>=get
<0>(y
);
1092 typename Value1
,typename IndexSpecifierList1
,typename Allocator1
,
1093 typename Value2
,typename IndexSpecifierList2
,typename Allocator2
1096 const multi_index_container
<Value1
,IndexSpecifierList1
,Allocator1
>& x
,
1097 const multi_index_container
<Value2
,IndexSpecifierList2
,Allocator2
>& y
)
1099 return get
<0>(x
)<=get
<0>(y
);
1102 /* specialized algorithms */
1104 template<typename Value
,typename IndexSpecifierList
,typename Allocator
>
1106 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& x
,
1107 multi_index_container
<Value
,IndexSpecifierList
,Allocator
>& y
)
1112 } /* namespace multi_index */
1114 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)&&\
1115 !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
1116 /* class version = 1 : we now serialize the size through
1117 * boost::serialization::collection_size_type.
1118 * class version = 2 : proper use of {save|load}_construct_data.
1121 namespace serialization
{
1122 template<typename Value
,typename IndexSpecifierList
,typename Allocator
>
1124 boost::multi_index_container
<Value
,IndexSpecifierList
,Allocator
>
1127 BOOST_STATIC_CONSTANT(int,value
=2);
1129 } /* namespace serialization */
1132 /* Associated global functions are promoted to namespace boost, except
1133 * comparison operators and swap, which are meant to be Koenig looked-up.
1136 using multi_index::get
;
1137 using multi_index::project
;
1139 } /* namespace boost */
1141 #undef BOOST_MULTI_INDEX_CHECK_INVARIANT