1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/multi_index_container.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1027 @@
1.4 +/* Multiply indexed container.
1.5 + *
1.6 + * Copyright 2003-2007 Joaquín M López Muñoz.
1.7 + * Distributed under the Boost Software License, Version 1.0.
1.8 + * (See accompanying file LICENSE_1_0.txt or copy at
1.9 + * http://www.boost.org/LICENSE_1_0.txt)
1.10 + *
1.11 + * See http://www.boost.org/libs/multi_index for library home page.
1.12 + */
1.13 +
1.14 +#ifndef BOOST_MULTI_INDEX_HPP
1.15 +#define BOOST_MULTI_INDEX_HPP
1.16 +
1.17 +#if defined(_MSC_VER)&&(_MSC_VER>=1200)
1.18 +#pragma once
1.19 +#endif
1.20 +
1.21 +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
1.22 +#include <algorithm>
1.23 +#include <boost/detail/allocator_utilities.hpp>
1.24 +#include <boost/detail/no_exceptions_support.hpp>
1.25 +#include <boost/detail/workaround.hpp>
1.26 +#include <boost/mpl/at.hpp>
1.27 +#include <boost/mpl/contains.hpp>
1.28 +#include <boost/mpl/find_if.hpp>
1.29 +#include <boost/mpl/identity.hpp>
1.30 +#include <boost/mpl/int.hpp>
1.31 +#include <boost/mpl/size.hpp>
1.32 +#include <boost/mpl/deref.hpp>
1.33 +#include <boost/multi_index_container_fwd.hpp>
1.34 +#include <boost/multi_index/detail/access_specifier.hpp>
1.35 +#include <boost/multi_index/detail/base_type.hpp>
1.36 +#include <boost/multi_index/detail/converter.hpp>
1.37 +#include <boost/multi_index/detail/def_ctor_tuple_cons.hpp>
1.38 +#include <boost/multi_index/detail/header_holder.hpp>
1.39 +#include <boost/multi_index/detail/has_tag.hpp>
1.40 +#include <boost/multi_index/detail/no_duplicate_tags.hpp>
1.41 +#include <boost/multi_index/detail/prevent_eti.hpp>
1.42 +#include <boost/multi_index/detail/safe_mode.hpp>
1.43 +#include <boost/multi_index/detail/scope_guard.hpp>
1.44 +#include <boost/static_assert.hpp>
1.45 +#include <boost/type_traits/is_same.hpp>
1.46 +#include <boost/utility/base_from_member.hpp>
1.47 +
1.48 +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
1.49 +#include <boost/multi_index/detail/archive_constructed.hpp>
1.50 +#include <boost/serialization/nvp.hpp>
1.51 +#include <boost/serialization/split_member.hpp>
1.52 +#include <boost/throw_exception.hpp>
1.53 +#endif
1.54 +
1.55 +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
1.56 +#include <boost/multi_index/detail/invariant_assert.hpp>
1.57 +#define BOOST_MULTI_INDEX_CHECK_INVARIANT \
1.58 + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
1.59 + detail::make_obj_guard(*this,&multi_index_container::check_invariant_); \
1.60 + BOOST_JOIN(check_invariant_,__LINE__).touch();
1.61 +#else
1.62 +#define BOOST_MULTI_INDEX_CHECK_INVARIANT
1.63 +#endif
1.64 +
1.65 +namespace boost{
1.66 +
1.67 +namespace multi_index{
1.68 +
1.69 +template<typename Value,typename IndexSpecifierList,typename Allocator>
1.70 +class multi_index_container:
1.71 + private ::boost::base_from_member<
1.72 + typename boost::detail::allocator::rebind_to<
1.73 + Allocator,
1.74 + typename detail::multi_index_node_type<
1.75 + Value,IndexSpecifierList,Allocator>::type
1.76 + >::type>,
1.77 + BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder<
1.78 + typename detail::multi_index_node_type<
1.79 + Value,IndexSpecifierList,Allocator>::type,
1.80 + multi_index_container<Value,IndexSpecifierList,Allocator> >,
1.81 + public detail::multi_index_base_type<
1.82 + Value,IndexSpecifierList,Allocator>::type
1.83 +{
1.84 +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
1.85 + BOOST_WORKAROUND(__MWERKS__,<=0x3003)
1.86 +/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
1.87 + * lifetime of const references bound to temporaries --precisely what
1.88 + * scopeguards are.
1.89 + */
1.90 +
1.91 +#pragma parse_mfunc_templ off
1.92 +#endif
1.93 +
1.94 +private:
1.95 +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
1.96 + template <typename,typename,typename> friend class detail::index_base;
1.97 + template <typename,typename> friend class detail::header_holder;
1.98 + template <typename,typename> friend class detail::converter;
1.99 +#endif
1.100 +
1.101 + typedef typename detail::multi_index_base_type<
1.102 + Value,IndexSpecifierList,Allocator>::type super;
1.103 + typedef ::boost::base_from_member<
1.104 + typename boost::detail::allocator::rebind_to<
1.105 + Allocator,
1.106 + typename super::node_type
1.107 + >::type> bfm_allocator;
1.108 + typedef detail::header_holder<
1.109 + typename super::node_type,
1.110 + multi_index_container> bfm_header;
1.111 +
1.112 +#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
1.113 + /* see definition of index_type_list below */
1.114 + typedef typename super::index_type_list super_index_type_list;
1.115 +#endif
1.116 +
1.117 +public:
1.118 + /* All types are inherited from super, a few are explicitly
1.119 + * brought forward here to save us some typename's.
1.120 + */
1.121 +
1.122 +#if defined(BOOST_MSVC)
1.123 + typedef
1.124 + detail::default_constructible_tuple_cons<
1.125 + typename super::ctor_args_list> ctor_args_list;
1.126 +#else
1.127 + typedef typename super::ctor_args_list ctor_args_list;
1.128 +#endif
1.129 +
1.130 + typedef IndexSpecifierList index_specifier_type_list;
1.131 +
1.132 +#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
1.133 + /* MSVC++ 6.0 chokes on moderately long index lists (around 6 indices
1.134 + * or more), with errors ranging from corrupt exes to duplicate
1.135 + * comdats. The following type hiding hack alleviates this condition;
1.136 + * best results combined with type hiding of the indexed_by construct
1.137 + * itself, as explained in the "Compiler specifics" section of
1.138 + * the documentation.
1.139 + */
1.140 +
1.141 + struct index_type_list:super_index_type_list
1.142 + {
1.143 + typedef index_type_list type;
1.144 + typedef typename super_index_type_list::back back;
1.145 + typedef mpl::v_iter<type,0> begin;
1.146 + typedef mpl::v_iter<
1.147 + type,
1.148 + mpl::size<super_index_type_list>::value> end;
1.149 + };
1.150 +#else
1.151 + typedef typename super::index_type_list index_type_list;
1.152 +#endif
1.153 +
1.154 + typedef typename super::iterator_type_list iterator_type_list;
1.155 + typedef typename super::const_iterator_type_list const_iterator_type_list;
1.156 + typedef typename super::value_type value_type;
1.157 + typedef typename super::final_allocator_type allocator_type;
1.158 + typedef typename super::iterator iterator;
1.159 + typedef typename super::const_iterator const_iterator;
1.160 +
1.161 + BOOST_STATIC_ASSERT(
1.162 + detail::no_duplicate_tags_in_index_list<index_type_list>::value);
1.163 +
1.164 + /* global project() needs to see this publicly */
1.165 +
1.166 + typedef typename super::node_type node_type;
1.167 +
1.168 + /* construct/copy/destroy */
1.169 +
1.170 + explicit multi_index_container(
1.171 +
1.172 +#if BOOST_WORKAROUND(__IBMCPP__,<=600)
1.173 + /* VisualAge seems to have an ETI issue with the default values
1.174 + * for arguments args_list and al.
1.175 + */
1.176 +
1.177 + const ctor_args_list& args_list=
1.178 + typename mpl::identity<multi_index_container>::type::
1.179 + ctor_args_list(),
1.180 + const allocator_type& al=
1.181 + typename mpl::identity<multi_index_container>::type::
1.182 + allocator_type()):
1.183 +#else
1.184 + const ctor_args_list& args_list=ctor_args_list(),
1.185 + const allocator_type& al=allocator_type()):
1.186 +#endif
1.187 +
1.188 + bfm_allocator(al),
1.189 + super(args_list,bfm_allocator::member),
1.190 + node_count(0)
1.191 + {
1.192 + BOOST_MULTI_INDEX_CHECK_INVARIANT;
1.193 + }
1.194 +
1.195 + template<typename InputIterator>
1.196 + multi_index_container(
1.197 + InputIterator first,InputIterator last,
1.198 +
1.199 +#if BOOST_WORKAROUND(__IBMCPP__,<=600)
1.200 + /* VisualAge seems to have an ETI issue with the default values
1.201 + * for arguments args_list and al.
1.202 + */
1.203 +
1.204 + const ctor_args_list& args_list=
1.205 + typename mpl::identity<multi_index_container>::type::
1.206 + ctor_args_list(),
1.207 + const allocator_type& al=
1.208 + typename mpl::identity<multi_index_container>::type::
1.209 + allocator_type()):
1.210 +#else
1.211 + const ctor_args_list& args_list=ctor_args_list(),
1.212 + const allocator_type& al=allocator_type()):
1.213 +#endif
1.214 +
1.215 + bfm_allocator(al),
1.216 + super(args_list,bfm_allocator::member),
1.217 + node_count(0)
1.218 + {
1.219 + BOOST_MULTI_INDEX_CHECK_INVARIANT;
1.220 + BOOST_TRY{
1.221 + iterator hint=super::end();
1.222 + for(;first!=last;++first){
1.223 + hint=super::make_iterator(insert_(*first,hint.get_node()).first);
1.224 + }
1.225 + }
1.226 + BOOST_CATCH(...){
1.227 + clear_();
1.228 + BOOST_RETHROW;
1.229 + }
1.230 + BOOST_CATCH_END
1.231 + }
1.232 +
1.233 + multi_index_container(
1.234 + const multi_index_container<Value,IndexSpecifierList,Allocator>& x):
1.235 + bfm_allocator(x.bfm_allocator::member),
1.236 + bfm_header(),
1.237 + super(x),
1.238 + node_count(0)
1.239 + {
1.240 + copy_map_type map(bfm_allocator::member,x.size(),x.header(),header());
1.241 + for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){
1.242 + map.clone(it.get_node());
1.243 + }
1.244 + super::copy_(x,map);
1.245 + map.release();
1.246 + node_count=x.size();
1.247 +
1.248 + /* Not until this point are the indices required to be consistent,
1.249 + * hence the position of the invariant checker.
1.250 + */
1.251 +
1.252 + BOOST_MULTI_INDEX_CHECK_INVARIANT;
1.253 + }
1.254 +
1.255 + ~multi_index_container()
1.256 + {
1.257 + delete_all_nodes_();
1.258 + }
1.259 +
1.260 + multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
1.261 + const multi_index_container<Value,IndexSpecifierList,Allocator>& x)
1.262 + {
1.263 + BOOST_MULTI_INDEX_CHECK_INVARIANT;
1.264 + multi_index_container<Value,IndexSpecifierList,Allocator> tmp(x);
1.265 + this->swap(tmp);
1.266 + return *this;
1.267 + }
1.268 +
1.269 + allocator_type get_allocator()const
1.270 + {
1.271 + return allocator_type(bfm_allocator::member);
1.272 + }
1.273 +
1.274 + /* retrieval of indices by number */
1.275 +
1.276 +#if !defined(BOOST_NO_MEMBER_TEMPLATES)
1.277 + template<int N>
1.278 + struct nth_index
1.279 + {
1.280 + BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
1.281 + typedef typename mpl::at_c<index_type_list,N>::type type;
1.282 + };
1.283 +
1.284 + template<int N>
1.285 + typename nth_index<N>::type& get(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
1.286 + {
1.287 + BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
1.288 + return *this;
1.289 + }
1.290 +
1.291 + template<int N>
1.292 + const typename nth_index<N>::type& get(
1.293 + BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int,N))const
1.294 + {
1.295 + BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
1.296 + return *this;
1.297 + }
1.298 +#endif
1.299 +
1.300 + /* retrieval of indices by tag */
1.301 +
1.302 +#if !defined(BOOST_NO_MEMBER_TEMPLATES)
1.303 + template<typename Tag>
1.304 + struct index
1.305 + {
1.306 + typedef typename mpl::find_if<
1.307 + index_type_list,
1.308 + detail::has_tag<Tag>
1.309 + >::type iter;
1.310 +
1.311 + BOOST_STATIC_CONSTANT(
1.312 + bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
1.313 + BOOST_STATIC_ASSERT(index_found);
1.314 +
1.315 + typedef typename mpl::deref<iter>::type type;
1.316 + };
1.317 +
1.318 + template<typename Tag>
1.319 + typename index<Tag>::type& get(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))
1.320 + {
1.321 + return *this;
1.322 + }
1.323 +
1.324 + template<typename Tag>
1.325 + const typename index<Tag>::type& get(
1.326 + BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))const
1.327 + {
1.328 + return *this;
1.329 + }
1.330 +#endif
1.331 +
1.332 + /* projection of iterators by number */
1.333 +
1.334 +#if !defined(BOOST_NO_MEMBER_TEMPLATES)
1.335 + template<int N>
1.336 + struct nth_index_iterator
1.337 + {
1.338 + typedef typename nth_index<N>::type::iterator type;
1.339 + };
1.340 +
1.341 + template<int N>
1.342 + struct nth_index_const_iterator
1.343 + {
1.344 + typedef typename nth_index<N>::type::const_iterator type;
1.345 + };
1.346 +
1.347 + template<int N,typename IteratorType>
1.348 + typename nth_index_iterator<N>::type project(
1.349 + IteratorType it
1.350 + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
1.351 + {
1.352 + typedef typename nth_index<N>::type index;
1.353 +
1.354 + BOOST_STATIC_ASSERT(
1.355 + (mpl::contains<iterator_type_list,IteratorType>::value));
1.356 +
1.357 + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1.358 + BOOST_MULTI_INDEX_CHECK_IS_OWNER(
1.359 + it,static_cast<typename IteratorType::container_type&>(*this));
1.360 +
1.361 + return index::make_iterator(static_cast<node_type*>(it.get_node()));
1.362 + }
1.363 +
1.364 + template<int N,typename IteratorType>
1.365 + typename nth_index_const_iterator<N>::type project(
1.366 + IteratorType it
1.367 + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))const
1.368 + {
1.369 + typedef typename nth_index<N>::type index;
1.370 +
1.371 + BOOST_STATIC_ASSERT((
1.372 + mpl::contains<iterator_type_list,IteratorType>::value||
1.373 + mpl::contains<const_iterator_type_list,IteratorType>::value));
1.374 +
1.375 + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1.376 + BOOST_MULTI_INDEX_CHECK_IS_OWNER(
1.377 + it,static_cast<const typename IteratorType::container_type&>(*this));
1.378 + return index::make_iterator(static_cast<node_type*>(it.get_node()));
1.379 + }
1.380 +#endif
1.381 +
1.382 + /* projection of iterators by tag */
1.383 +
1.384 +#if !defined(BOOST_NO_MEMBER_TEMPLATES)
1.385 + template<typename Tag>
1.386 + struct index_iterator
1.387 + {
1.388 + typedef typename index<Tag>::type::iterator type;
1.389 + };
1.390 +
1.391 + template<typename Tag>
1.392 + struct index_const_iterator
1.393 + {
1.394 + typedef typename index<Tag>::type::const_iterator type;
1.395 + };
1.396 +
1.397 + template<typename Tag,typename IteratorType>
1.398 + typename index_iterator<Tag>::type project(
1.399 + IteratorType it
1.400 + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
1.401 + {
1.402 + typedef typename index<Tag>::type index;
1.403 +
1.404 + BOOST_STATIC_ASSERT(
1.405 + (mpl::contains<iterator_type_list,IteratorType>::value));
1.406 +
1.407 + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1.408 + BOOST_MULTI_INDEX_CHECK_IS_OWNER(
1.409 + it,static_cast<typename IteratorType::container_type&>(*this));
1.410 + return index::make_iterator(static_cast<node_type*>(it.get_node()));
1.411 + }
1.412 +
1.413 + template<typename Tag,typename IteratorType>
1.414 + typename index_const_iterator<Tag>::type project(
1.415 + IteratorType it
1.416 + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))const
1.417 + {
1.418 + typedef typename index<Tag>::type index;
1.419 +
1.420 + BOOST_STATIC_ASSERT((
1.421 + mpl::contains<iterator_type_list,IteratorType>::value||
1.422 + mpl::contains<const_iterator_type_list,IteratorType>::value));
1.423 +
1.424 + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1.425 + BOOST_MULTI_INDEX_CHECK_IS_OWNER(
1.426 + it,static_cast<const typename IteratorType::container_type&>(*this));
1.427 + return index::make_iterator(static_cast<node_type*>(it.get_node()));
1.428 + }
1.429 +#endif
1.430 +
1.431 +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
1.432 + typedef typename super::copy_map_type copy_map_type;
1.433 +
1.434 + node_type* header()const
1.435 + {
1.436 + return bfm_header::member;
1.437 + }
1.438 +
1.439 + node_type* allocate_node()
1.440 + {
1.441 + return bfm_allocator::member.allocate(1);
1.442 + }
1.443 +
1.444 + void deallocate_node(node_type* x)
1.445 + {
1.446 + bfm_allocator::member.deallocate(x,1);
1.447 + }
1.448 +
1.449 + bool empty_()const
1.450 + {
1.451 + return node_count==0;
1.452 + }
1.453 +
1.454 + std::size_t size_()const
1.455 + {
1.456 + return node_count;
1.457 + }
1.458 +
1.459 + std::size_t max_size_()const
1.460 + {
1.461 + return static_cast<std::size_t >(-1);
1.462 + }
1.463 +
1.464 + std::pair<node_type*,bool> insert_(const Value& v)
1.465 + {
1.466 + node_type* x=allocate_node();
1.467 + BOOST_TRY{
1.468 + node_type* res=super::insert_(v,x);
1.469 + if(res==x){
1.470 + ++node_count;
1.471 + return std::pair<node_type*,bool>(res,true);
1.472 + }
1.473 + else{
1.474 + deallocate_node(x);
1.475 + return std::pair<node_type*,bool>(res,false);
1.476 + }
1.477 + }
1.478 + BOOST_CATCH(...){
1.479 + deallocate_node(x);
1.480 + BOOST_RETHROW;
1.481 + }
1.482 + BOOST_CATCH_END
1.483 + }
1.484 +
1.485 + std::pair<node_type*,bool> insert_(const Value& v,node_type* position)
1.486 + {
1.487 + node_type* x=allocate_node();
1.488 + BOOST_TRY{
1.489 + node_type* res=super::insert_(v,position,x);
1.490 + if(res==x){
1.491 + ++node_count;
1.492 + return std::pair<node_type*,bool>(res,true);
1.493 + }
1.494 + else{
1.495 + deallocate_node(x);
1.496 + return std::pair<node_type*,bool>(res,false);
1.497 + }
1.498 + }
1.499 + BOOST_CATCH(...){
1.500 + deallocate_node(x);
1.501 + BOOST_RETHROW;
1.502 + }
1.503 + BOOST_CATCH_END
1.504 + }
1.505 +
1.506 + void erase_(node_type* x)
1.507 + {
1.508 + super::erase_(x);
1.509 + deallocate_node(x);
1.510 + --node_count;
1.511 + }
1.512 +
1.513 + void delete_node_(node_type* x)
1.514 + {
1.515 + super::delete_node_(x);
1.516 + deallocate_node(x);
1.517 + }
1.518 +
1.519 + void delete_all_nodes_()
1.520 + {
1.521 + super::delete_all_nodes_();
1.522 + }
1.523 +
1.524 + void clear_()
1.525 + {
1.526 + delete_all_nodes_();
1.527 + super::clear_();
1.528 + node_count=0;
1.529 + }
1.530 +
1.531 + void swap_(multi_index_container<Value,IndexSpecifierList,Allocator>& x)
1.532 + {
1.533 + std::swap(bfm_header::member,x.bfm_header::member);
1.534 + super::swap_(x);
1.535 + std::swap(node_count,x.node_count);
1.536 + }
1.537 +
1.538 + bool replace_(const Value& k,node_type* x)
1.539 + {
1.540 + return super::replace_(k,x);
1.541 + }
1.542 +
1.543 + template<typename Modifier>
1.544 + bool modify_(Modifier mod,node_type* x)
1.545 + {
1.546 + mod(const_cast<value_type&>(x->value()));
1.547 +
1.548 + BOOST_TRY{
1.549 + if(!super::modify_(x)){
1.550 + deallocate_node(x);
1.551 + --node_count;
1.552 + return false;
1.553 + }
1.554 + else return true;
1.555 + }
1.556 + BOOST_CATCH(...){
1.557 + deallocate_node(x);
1.558 + --node_count;
1.559 + BOOST_RETHROW;
1.560 + }
1.561 + BOOST_CATCH_END
1.562 + }
1.563 +
1.564 +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
1.565 + /* serialization */
1.566 +
1.567 + friend class boost::serialization::access;
1.568 +
1.569 + BOOST_SERIALIZATION_SPLIT_MEMBER()
1.570 +
1.571 + typedef typename super::index_saver_type index_saver_type;
1.572 + typedef typename super::index_loader_type index_loader_type;
1.573 +
1.574 + template<class Archive>
1.575 + void save(Archive& ar,const unsigned int version)const
1.576 + {
1.577 + const std::size_t s=size_();
1.578 + ar<<serialization::make_nvp("count",s);
1.579 + index_saver_type sm(bfm_allocator::member,s);
1.580 +
1.581 + for(iterator it=super::begin(),it_end=super::end();it!=it_end;++it){
1.582 + ar<<serialization::make_nvp("item",*it);
1.583 + sm.add(it.get_node(),ar,version);
1.584 + }
1.585 + sm.add_track(header(),ar,version);
1.586 +
1.587 + super::save_(ar,version,sm);
1.588 + }
1.589 +
1.590 + template<class Archive>
1.591 + void load(Archive& ar,const unsigned int version)
1.592 + {
1.593 + BOOST_MULTI_INDEX_CHECK_INVARIANT;
1.594 +
1.595 + clear_();
1.596 +
1.597 + std::size_t s;
1.598 + ar>>serialization::make_nvp("count",s);
1.599 + index_loader_type lm(bfm_allocator::member,s);
1.600 +
1.601 + for(std::size_t n=0;n<s;++n){
1.602 + detail::archive_constructed<Value> value("item",ar,version);
1.603 + std::pair<node_type*,bool> p=insert_(
1.604 + value.get(),super::end().get_node());
1.605 + if(!p.second)throw_exception(
1.606 + archive::archive_exception(
1.607 + archive::archive_exception::other_exception));
1.608 + ar.reset_object_address(&p.first->value(),&value.get());
1.609 + lm.add(p.first,ar,version);
1.610 + }
1.611 + lm.add_track(header(),ar,version);
1.612 +
1.613 + super::load_(ar,version,lm);
1.614 + }
1.615 +#endif
1.616 +
1.617 +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
1.618 + /* invariant stuff */
1.619 +
1.620 + bool invariant_()const
1.621 + {
1.622 + return super::invariant_();
1.623 + }
1.624 +
1.625 + void check_invariant_()const
1.626 + {
1.627 + BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_());
1.628 + }
1.629 +#endif
1.630 +
1.631 +private:
1.632 + std::size_t node_count;
1.633 +
1.634 +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
1.635 + BOOST_WORKAROUND(__MWERKS__,<=0x3003)
1.636 +#pragma parse_mfunc_templ reset
1.637 +#endif
1.638 +};
1.639 +
1.640 +/* retrieval of indices by number */
1.641 +
1.642 +template<typename MultiIndexContainer,int N>
1.643 +struct nth_index
1.644 +{
1.645 + BOOST_STATIC_CONSTANT(
1.646 + int,
1.647 + M=mpl::size<typename MultiIndexContainer::index_type_list>::type::value);
1.648 + BOOST_STATIC_ASSERT(N>=0&&N<M);
1.649 + typedef typename mpl::at_c<
1.650 + typename MultiIndexContainer::index_type_list,N>::type type;
1.651 +};
1.652 +
1.653 +template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
1.654 +typename nth_index<
1.655 + multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
1.656 +get(
1.657 + multi_index_container<Value,IndexSpecifierList,Allocator>& m
1.658 + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
1.659 +{
1.660 + typedef multi_index_container<
1.661 + Value,IndexSpecifierList,Allocator> multi_index_type;
1.662 + typedef typename nth_index<
1.663 + multi_index_container<
1.664 + Value,IndexSpecifierList,Allocator>,
1.665 + N
1.666 + >::type index;
1.667 +
1.668 + BOOST_STATIC_ASSERT(N>=0&&
1.669 + N<
1.670 + mpl::size<
1.671 + BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
1.672 + >::type::value);
1.673 +
1.674 + return detail::converter<multi_index_type,index>::index(m);
1.675 +}
1.676 +
1.677 +template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
1.678 +const typename nth_index<
1.679 + multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
1.680 +get(
1.681 + const multi_index_container<Value,IndexSpecifierList,Allocator>& m
1.682 + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
1.683 +{
1.684 + typedef multi_index_container<
1.685 + Value,IndexSpecifierList,Allocator> multi_index_type;
1.686 + typedef typename nth_index<
1.687 + multi_index_container<
1.688 + Value,IndexSpecifierList,Allocator>,
1.689 + N
1.690 + >::type index;
1.691 +
1.692 + BOOST_STATIC_ASSERT(N>=0&&
1.693 + N<
1.694 + mpl::size<
1.695 + BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
1.696 + >::type::value);
1.697 +
1.698 + return detail::converter<multi_index_type,index>::index(m);
1.699 +}
1.700 +
1.701 +/* retrieval of indices by tag */
1.702 +
1.703 +template<typename MultiIndexContainer,typename Tag>
1.704 +struct index
1.705 +{
1.706 + typedef typename MultiIndexContainer::index_type_list index_type_list;
1.707 +
1.708 + typedef typename mpl::find_if<
1.709 + index_type_list,
1.710 + detail::has_tag<Tag>
1.711 + >::type iter;
1.712 +
1.713 + BOOST_STATIC_CONSTANT(
1.714 + bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
1.715 + BOOST_STATIC_ASSERT(index_found);
1.716 +
1.717 + typedef typename mpl::deref<iter>::type type;
1.718 +};
1.719 +
1.720 +template<
1.721 + typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
1.722 +>
1.723 +typename ::boost::multi_index::index<
1.724 + multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
1.725 +get(
1.726 + multi_index_container<Value,IndexSpecifierList,Allocator>& m
1.727 + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
1.728 +{
1.729 + typedef multi_index_container<
1.730 + Value,IndexSpecifierList,Allocator> multi_index_type;
1.731 + typedef typename ::boost::multi_index::index<
1.732 + multi_index_container<
1.733 + Value,IndexSpecifierList,Allocator>,
1.734 + Tag
1.735 + >::type index;
1.736 +
1.737 + return detail::converter<multi_index_type,index>::index(m);
1.738 +}
1.739 +
1.740 +template<
1.741 + typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
1.742 +>
1.743 +const typename ::boost::multi_index::index<
1.744 + multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
1.745 +get(
1.746 + const multi_index_container<Value,IndexSpecifierList,Allocator>& m
1.747 + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
1.748 +{
1.749 + typedef multi_index_container<
1.750 + Value,IndexSpecifierList,Allocator> multi_index_type;
1.751 + typedef typename ::boost::multi_index::index<
1.752 + multi_index_container<
1.753 + Value,IndexSpecifierList,Allocator>,
1.754 + Tag
1.755 + >::type index;
1.756 +
1.757 + return detail::converter<multi_index_type,index>::index(m);
1.758 +}
1.759 +
1.760 +/* projection of iterators by number */
1.761 +
1.762 +template<typename MultiIndexContainer,int N>
1.763 +struct nth_index_iterator
1.764 +{
1.765 + typedef typename detail::prevent_eti<
1.766 + nth_index<MultiIndexContainer,N>,
1.767 + typename nth_index<MultiIndexContainer,N>::type>::type::iterator type;
1.768 +};
1.769 +
1.770 +template<typename MultiIndexContainer,int N>
1.771 +struct nth_index_const_iterator
1.772 +{
1.773 + typedef typename detail::prevent_eti<
1.774 + nth_index<MultiIndexContainer,N>,
1.775 + typename nth_index<MultiIndexContainer,N>::type
1.776 + >::type::const_iterator type;
1.777 +};
1.778 +
1.779 +template<
1.780 + int N,typename IteratorType,
1.781 + typename Value,typename IndexSpecifierList,typename Allocator>
1.782 +typename nth_index_iterator<
1.783 + multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
1.784 +project(
1.785 + multi_index_container<Value,IndexSpecifierList,Allocator>& m,
1.786 + IteratorType it
1.787 + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
1.788 +{
1.789 + typedef multi_index_container<
1.790 + Value,IndexSpecifierList,Allocator> multi_index_type;
1.791 + typedef typename nth_index<multi_index_type,N>::type index;
1.792 +
1.793 +#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
1.794 + BOOST_STATIC_ASSERT((
1.795 + mpl::contains<
1.796 + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
1.797 + IteratorType>::value));
1.798 +#endif
1.799 +
1.800 + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1.801 +
1.802 +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
1.803 + typedef detail::converter<
1.804 + multi_index_type,
1.805 + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
1.806 + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
1.807 +#endif
1.808 +
1.809 + return detail::converter<multi_index_type,index>::iterator(
1.810 + m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
1.811 +}
1.812 +
1.813 +template<
1.814 + int N,typename IteratorType,
1.815 + typename Value,typename IndexSpecifierList,typename Allocator>
1.816 +typename nth_index_const_iterator<
1.817 + multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
1.818 +project(
1.819 + const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
1.820 + IteratorType it
1.821 + BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
1.822 +{
1.823 + typedef multi_index_container<
1.824 + Value,IndexSpecifierList,Allocator> multi_index_type;
1.825 + typedef typename nth_index<multi_index_type,N>::type index;
1.826 +
1.827 +#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
1.828 + BOOST_STATIC_ASSERT((
1.829 + mpl::contains<
1.830 + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
1.831 + IteratorType>::value||
1.832 + mpl::contains<
1.833 + BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
1.834 + IteratorType>::value));
1.835 +#endif
1.836 +
1.837 + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1.838 +
1.839 +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
1.840 + typedef detail::converter<
1.841 + multi_index_type,
1.842 + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
1.843 + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
1.844 +#endif
1.845 +
1.846 + return detail::converter<multi_index_type,index>::const_iterator(
1.847 + m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
1.848 +}
1.849 +
1.850 +/* projection of iterators by tag */
1.851 +
1.852 +template<typename MultiIndexContainer,typename Tag>
1.853 +struct index_iterator
1.854 +{
1.855 + typedef typename ::boost::multi_index::index<
1.856 + MultiIndexContainer,Tag>::type::iterator type;
1.857 +};
1.858 +
1.859 +template<typename MultiIndexContainer,typename Tag>
1.860 +struct index_const_iterator
1.861 +{
1.862 + typedef typename ::boost::multi_index::index<
1.863 + MultiIndexContainer,Tag>::type::const_iterator type;
1.864 +};
1.865 +
1.866 +template<
1.867 + typename Tag,typename IteratorType,
1.868 + typename Value,typename IndexSpecifierList,typename Allocator>
1.869 +typename index_iterator<
1.870 + multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
1.871 +project(
1.872 + multi_index_container<Value,IndexSpecifierList,Allocator>& m,
1.873 + IteratorType it
1.874 + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
1.875 +{
1.876 + typedef multi_index_container<
1.877 + Value,IndexSpecifierList,Allocator> multi_index_type;
1.878 + typedef typename ::boost::multi_index::index<
1.879 + multi_index_type,Tag>::type index;
1.880 +
1.881 +#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
1.882 + BOOST_STATIC_ASSERT((
1.883 + mpl::contains<
1.884 + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
1.885 + IteratorType>::value));
1.886 +#endif
1.887 +
1.888 + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1.889 +
1.890 +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
1.891 + typedef detail::converter<
1.892 + multi_index_type,
1.893 + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
1.894 + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
1.895 +#endif
1.896 +
1.897 + return detail::converter<multi_index_type,index>::iterator(
1.898 + m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
1.899 +}
1.900 +
1.901 +template<
1.902 + typename Tag,typename IteratorType,
1.903 + typename Value,typename IndexSpecifierList,typename Allocator>
1.904 +typename index_const_iterator<
1.905 + multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
1.906 +project(
1.907 + const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
1.908 + IteratorType it
1.909 + BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
1.910 +{
1.911 + typedef multi_index_container<
1.912 + Value,IndexSpecifierList,Allocator> multi_index_type;
1.913 + typedef typename ::boost::multi_index::index<
1.914 + multi_index_type,Tag>::type index;
1.915 +
1.916 +#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
1.917 + BOOST_STATIC_ASSERT((
1.918 + mpl::contains<
1.919 + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
1.920 + IteratorType>::value||
1.921 + mpl::contains<
1.922 + BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
1.923 + IteratorType>::value));
1.924 +#endif
1.925 +
1.926 + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
1.927 +
1.928 +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
1.929 + typedef detail::converter<
1.930 + multi_index_type,
1.931 + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
1.932 + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
1.933 +#endif
1.934 +
1.935 + return detail::converter<multi_index_type,index>::const_iterator(
1.936 + m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
1.937 +}
1.938 +
1.939 +/* Comparison. Simple forward to first index. */
1.940 +
1.941 +template<
1.942 + typename Value1,typename IndexSpecifierList1,typename Allocator1,
1.943 + typename Value2,typename IndexSpecifierList2,typename Allocator2
1.944 +>
1.945 +bool operator==(
1.946 + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1.947 + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1.948 +{
1.949 + return get<0>(x)==get<0>(y);
1.950 +}
1.951 +
1.952 +template<
1.953 + typename Value1,typename IndexSpecifierList1,typename Allocator1,
1.954 + typename Value2,typename IndexSpecifierList2,typename Allocator2
1.955 +>
1.956 +bool operator<(
1.957 + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1.958 + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1.959 +{
1.960 + return get<0>(x)<get<0>(y);
1.961 +}
1.962 +
1.963 +template<
1.964 + typename Value1,typename IndexSpecifierList1,typename Allocator1,
1.965 + typename Value2,typename IndexSpecifierList2,typename Allocator2
1.966 +>
1.967 +bool operator!=(
1.968 + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1.969 + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1.970 +{
1.971 + return get<0>(x)!=get<0>(y);
1.972 +}
1.973 +
1.974 +template<
1.975 + typename Value1,typename IndexSpecifierList1,typename Allocator1,
1.976 + typename Value2,typename IndexSpecifierList2,typename Allocator2
1.977 +>
1.978 +bool operator>(
1.979 + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1.980 + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1.981 +{
1.982 + return get<0>(x)>get<0>(y);
1.983 +}
1.984 +
1.985 +template<
1.986 + typename Value1,typename IndexSpecifierList1,typename Allocator1,
1.987 + typename Value2,typename IndexSpecifierList2,typename Allocator2
1.988 +>
1.989 +bool operator>=(
1.990 + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1.991 + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1.992 +{
1.993 + return get<0>(x)>=get<0>(y);
1.994 +}
1.995 +
1.996 +template<
1.997 + typename Value1,typename IndexSpecifierList1,typename Allocator1,
1.998 + typename Value2,typename IndexSpecifierList2,typename Allocator2
1.999 +>
1.1000 +bool operator<=(
1.1001 + const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
1.1002 + const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
1.1003 +{
1.1004 + return get<0>(x)<=get<0>(y);
1.1005 +}
1.1006 +
1.1007 +/* specialized algorithms */
1.1008 +
1.1009 +template<typename Value,typename IndexSpecifierList,typename Allocator>
1.1010 +void swap(
1.1011 + multi_index_container<Value,IndexSpecifierList,Allocator>& x,
1.1012 + multi_index_container<Value,IndexSpecifierList,Allocator>& y)
1.1013 +{
1.1014 + x.swap(y);
1.1015 +}
1.1016 +
1.1017 +} /* namespace multi_index */
1.1018 +
1.1019 +/* Associated global functions are promoted to namespace boost, except
1.1020 + * comparison operators and swap, which are meant to be Koenig looked-up.
1.1021 + */
1.1022 +
1.1023 +using multi_index::get;
1.1024 +using multi_index::project;
1.1025 +
1.1026 +} /* namespace boost */
1.1027 +
1.1028 +#undef BOOST_MULTI_INDEX_CHECK_INVARIANT
1.1029 +
1.1030 +#endif