?????????? ????????? - ??????????????? - /home/agenciai/public_html/cd38d8/multi_index.zip
???????
PK 3L�[��R�� � mem_fun.hppnu �[��� /* Copyright 2003-2019 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_MEM_FUN_HPP #define BOOST_MULTI_INDEX_MEM_FUN_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/mpl/if.hpp> #include <boost/type_traits/remove_reference.hpp> #include <boost/utility/enable_if.hpp> #if !defined(BOOST_NO_SFINAE) #include <boost/type_traits/is_convertible.hpp> #endif namespace boost{ template<class T> class reference_wrapper; /* fwd decl. */ namespace multi_index{ /* mem_fun implements a read-only key extractor based on a given non-const * member function of a class. * Also, the following variations are provided: * const_mem_fun: const member functions * volatile_mem_fun: volatile member functions * cv_mem_fun: const volatile member functions * ref_mem_fun: ref-qualifed member functions (C++11) * cref_mem_fun: const ref-qualifed member functions (C++11) * vref_mem_fun: volatile ref-qualifed member functions (C++11) * cvref_mem_fun: const volatile ref-qualifed member functions (C++11) * * All of these classes are overloaded to support boost::referece_wrappers * of T and "chained pointers" to T's. By chained pointer to T we mean a type * P such that, given a p of Type P * *...n...*x is convertible to T&, for some n>=1. * Examples of chained pointers are raw and smart pointers, iterators and * arbitrary combinations of these (vg. T** or unique_ptr<T*>.) */ namespace detail{ template< class Class,typename Type, typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction > struct const_mem_fun_impl { typedef typename remove_reference<Type>::type result_type; template<typename ChainedPtr> #if !defined(BOOST_NO_SFINAE) typename disable_if< is_convertible<const ChainedPtr&,const Class&>,Type>::type #else Type #endif operator()(const ChainedPtr& x)const { return operator()(*x); } Type operator()(const Class& x)const { return (x.*PtrToMemberFunction)(); } Type operator()(const reference_wrapper<const Class>& x)const { return operator()(x.get()); } Type operator()(const reference_wrapper<Class>& x)const { return operator()(x.get()); } }; template< class Class,typename Type, typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction > struct mem_fun_impl { typedef typename remove_reference<Type>::type result_type; template<typename ChainedPtr> #if !defined(BOOST_NO_SFINAE) typename disable_if< is_convertible<ChainedPtr&,Class&>,Type>::type #else Type #endif operator()(const ChainedPtr& x)const { return operator()(*x); } Type operator()(Class& x)const { return (x.*PtrToMemberFunction)(); } Type operator()(const reference_wrapper<Class>& x)const { return operator()(x.get()); } }; } /* namespace multi_index::detail */ template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const> struct const_mem_fun:detail::const_mem_fun_impl< Class,Type,Type (Class::*)()const,PtrToMemberFunction >{}; template< class Class,typename Type, Type (Class::*PtrToMemberFunction)()const volatile > struct cv_mem_fun:detail::const_mem_fun_impl< Class,Type,Type (Class::*)()const volatile,PtrToMemberFunction >{}; template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()> struct mem_fun: detail::mem_fun_impl<Class,Type,Type (Class::*)(),PtrToMemberFunction>{}; template< class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile > struct volatile_mem_fun:detail::mem_fun_impl< Class,Type,Type (Class::*)()volatile,PtrToMemberFunction >{}; #if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) template< class Class,typename Type,Type (Class::*PtrToMemberFunction)()const& > struct cref_mem_fun:detail::const_mem_fun_impl< Class,Type,Type (Class::*)()const&,PtrToMemberFunction >{}; template< class Class,typename Type, Type (Class::*PtrToMemberFunction)()const volatile& > struct cvref_mem_fun:detail::const_mem_fun_impl< Class,Type,Type (Class::*)()const volatile&,PtrToMemberFunction >{}; template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()&> struct ref_mem_fun: detail::mem_fun_impl<Class,Type,Type (Class::*)()&,PtrToMemberFunction>{}; template< class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile& > struct vref_mem_fun:detail::mem_fun_impl< Class,Type,Type (Class::*)()volatile&,PtrToMemberFunction >{}; #endif /* MSVC++ 6.0 has problems with const member functions as non-type template * parameters, somehow it takes them as non-const. const_mem_fun_explicit * workarounds this deficiency by accepting an extra type parameter that * specifies the signature of the member function. The workaround was found at: * Daniel, C.:"Re: weird typedef problem in VC", * news:microsoft.public.vc.language, 21st nov 2002, * http://groups.google.com/groups? * hl=en&lr=&ie=UTF-8&selm=ukwvg3O0BHA.1512%40tkmsftngp05 * * MSVC++ 6.0 support has been dropped and [const_]mem_fun_explicit is * deprecated. */ template< class Class,typename Type, typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction > struct const_mem_fun_explicit { typedef typename remove_reference<Type>::type result_type; template<typename ChainedPtr> #if !defined(BOOST_NO_SFINAE) typename disable_if< is_convertible<const ChainedPtr&,const Class&>,Type>::type #else Type #endif operator()(const ChainedPtr& x)const { return operator()(*x); } Type operator()(const Class& x)const { return (x.*PtrToMemberFunction)(); } Type operator()(const reference_wrapper<const Class>& x)const { return operator()(x.get()); } Type operator()(const reference_wrapper<Class>& x)const { return operator()(x.get()); } }; template< class Class,typename Type, typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction > struct mem_fun_explicit { typedef typename remove_reference<Type>::type result_type; template<typename ChainedPtr> #if !defined(BOOST_NO_SFINAE) typename disable_if< is_convertible<ChainedPtr&,Class&>,Type>::type #else Type #endif operator()(const ChainedPtr& x)const { return operator()(*x); } Type operator()(Class& x)const { return (x.*PtrToMemberFunction)(); } Type operator()(const reference_wrapper<Class>& x)const { return operator()(x.get()); } }; /* BOOST_MULTI_INDEX_CONST_MEM_FUN and BOOST_MULTI_INDEX_MEM_FUN used to * resolve to [const_]mem_fun_explicit for MSVC++ 6.0 and to * [const_]mem_fun otherwise. Support for this compiler having been dropped, * they are now just wrappers over [const_]mem_fun kept for backwards- * compatibility reasons. */ #define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \ ::boost::multi_index::const_mem_fun< Class,Type,&Class::MemberFunName > #define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \ ::boost::multi_index::mem_fun< Class,Type,&Class::MemberFunName > } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�=�cq( q( ranked_index.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_RANKED_INDEX_HPP #define BOOST_MULTI_INDEX_RANKED_INDEX_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/multi_index/detail/ord_index_impl.hpp> #include <boost/multi_index/detail/rnk_index_ops.hpp> #include <boost/multi_index/ranked_index_fwd.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* ranked_index augments a given ordered index to provide rank operations */ template<typename OrderedIndexNodeImpl> struct ranked_node:OrderedIndexNodeImpl { typedef typename OrderedIndexNodeImpl::size_type size_type; size_type size; }; template<typename OrderedIndexImpl> class ranked_index:public OrderedIndexImpl { typedef OrderedIndexImpl super; protected: typedef typename super::index_node_type index_node_type; typedef typename super::node_impl_pointer node_impl_pointer; public: typedef typename super::ctor_args_list ctor_args_list; typedef typename super::allocator_type allocator_type; typedef typename super::iterator iterator; typedef typename super::size_type size_type; /* rank operations */ iterator nth(size_type n)const { return this->make_iterator(index_node_type::from_impl( ranked_index_nth(n,this->header()->impl()))); } size_type rank(iterator position)const { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); return ranked_index_rank( position.get_node()->impl(),this->header()->impl()); } template<typename CompatibleKey> size_type find_rank(const CompatibleKey& x)const { return ranked_index_find_rank( this->root(),this->header(),this->key,x,this->comp_); } template<typename CompatibleKey,typename CompatibleCompare> size_type find_rank( const CompatibleKey& x,const CompatibleCompare& comp)const { return ranked_index_find_rank( this->root(),this->header(),this->key,x,comp); } template<typename CompatibleKey> size_type lower_bound_rank(const CompatibleKey& x)const { return ranked_index_lower_bound_rank( this->root(),this->header(),this->key,x,this->comp_); } template<typename CompatibleKey,typename CompatibleCompare> size_type lower_bound_rank( const CompatibleKey& x,const CompatibleCompare& comp)const { return ranked_index_lower_bound_rank( this->root(),this->header(),this->key,x,comp); } template<typename CompatibleKey> size_type upper_bound_rank(const CompatibleKey& x)const { return ranked_index_upper_bound_rank( this->root(),this->header(),this->key,x,this->comp_); } template<typename CompatibleKey,typename CompatibleCompare> size_type upper_bound_rank( const CompatibleKey& x,const CompatibleCompare& comp)const { return ranked_index_upper_bound_rank( this->root(),this->header(),this->key,x,comp); } template<typename CompatibleKey> std::pair<size_type,size_type> equal_range_rank( const CompatibleKey& x)const { return ranked_index_equal_range_rank( this->root(),this->header(),this->key,x,this->comp_); } template<typename CompatibleKey,typename CompatibleCompare> std::pair<size_type,size_type> equal_range_rank( const CompatibleKey& x,const CompatibleCompare& comp)const { return ranked_index_equal_range_rank( this->root(),this->header(),this->key,x,comp); } template<typename LowerBounder,typename UpperBounder> std::pair<size_type,size_type> range_rank(LowerBounder lower,UpperBounder upper)const { typedef typename mpl::if_< is_same<LowerBounder,unbounded_type>, BOOST_DEDUCED_TYPENAME mpl::if_< is_same<UpperBounder,unbounded_type>, both_unbounded_tag, lower_unbounded_tag >::type, BOOST_DEDUCED_TYPENAME mpl::if_< is_same<UpperBounder,unbounded_type>, upper_unbounded_tag, none_unbounded_tag >::type >::type dispatch; return range_rank(lower,upper,dispatch()); } protected: ranked_index(const ranked_index& x):super(x){}; ranked_index(const ranked_index& x,do_not_copy_elements_tag): super(x,do_not_copy_elements_tag()){}; ranked_index( const ctor_args_list& args_list,const allocator_type& al): super(args_list,al){} private: template<typename LowerBounder,typename UpperBounder> std::pair<size_type,size_type> range_rank(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const { index_node_type* y=this->header(); index_node_type* z=this->root(); if(!z)return std::pair<size_type,size_type>(0,0); size_type s=z->impl()->size; do{ if(!lower(this->key(z->value()))){ z=index_node_type::from_impl(z->right()); } else if(!upper(this->key(z->value()))){ y=z; s-=ranked_node_size(y->right())+1; z=index_node_type::from_impl(z->left()); } else{ return std::pair<size_type,size_type>( s-z->impl()->size+ lower_range_rank(index_node_type::from_impl(z->left()),z,lower), s-ranked_node_size(z->right())+ upper_range_rank(index_node_type::from_impl(z->right()),y,upper)); } }while(z); return std::pair<size_type,size_type>(s,s); } template<typename LowerBounder,typename UpperBounder> std::pair<size_type,size_type> range_rank(LowerBounder,UpperBounder upper,lower_unbounded_tag)const { return std::pair<size_type,size_type>( 0, upper_range_rank(this->root(),this->header(),upper)); } template<typename LowerBounder,typename UpperBounder> std::pair<size_type,size_type> range_rank(LowerBounder lower,UpperBounder,upper_unbounded_tag)const { return std::pair<size_type,size_type>( lower_range_rank(this->root(),this->header(),lower), this->size()); } template<typename LowerBounder,typename UpperBounder> std::pair<size_type,size_type> range_rank(LowerBounder,UpperBounder,both_unbounded_tag)const { return std::pair<size_type,size_type>(0,this->size()); } template<typename LowerBounder> size_type lower_range_rank( index_node_type* top,index_node_type* y,LowerBounder lower)const { if(!top)return 0; size_type s=top->impl()->size; do{ if(lower(this->key(top->value()))){ y=top; s-=ranked_node_size(y->right())+1; top=index_node_type::from_impl(top->left()); } else top=index_node_type::from_impl(top->right()); }while(top); return s; } template<typename UpperBounder> size_type upper_range_rank( index_node_type* top,index_node_type* y,UpperBounder upper)const { if(!top)return 0; size_type s=top->impl()->size; do{ if(!upper(this->key(top->value()))){ y=top; s-=ranked_node_size(y->right())+1; top=index_node_type::from_impl(top->left()); } else top=index_node_type::from_impl(top->right()); }while(top); return s; } }; /* augmenting policy for ordered_index */ struct rank_policy { template<typename OrderedIndexNodeImpl> struct augmented_node { typedef ranked_node<OrderedIndexNodeImpl> type; }; template<typename OrderedIndexImpl> struct augmented_interface { typedef ranked_index<OrderedIndexImpl> type; }; /* algorithmic stuff */ template<typename Pointer> static void add(Pointer x,Pointer root) { x->size=1; while(x!=root){ x=x->parent(); ++(x->size); } } template<typename Pointer> static void remove(Pointer x,Pointer root) { while(x!=root){ x=x->parent(); --(x->size); } } template<typename Pointer> static void copy(Pointer x,Pointer y) { y->size=x->size; } template<typename Pointer> static void rotate_left(Pointer x,Pointer y) /* in: x==y->left() */ { y->size=x->size; x->size=ranked_node_size(x->left())+ranked_node_size(x->right())+1; } template<typename Pointer> static void rotate_right(Pointer x,Pointer y) /* in: x==y->right() */ { rotate_left(x,y); } #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) /* invariant stuff */ template<typename Pointer> static bool invariant(Pointer x) { return x->size==ranked_node_size(x->left())+ranked_node_size(x->right())+1; } #endif }; } /* namespace multi_index::detail */ /* ranked_index specifiers */ template<typename Arg1,typename Arg2,typename Arg3> struct ranked_unique { typedef typename detail::ordered_index_args< Arg1,Arg2,Arg3> index_args; typedef typename index_args::tag_list_type::type tag_list_type; typedef typename index_args::key_from_value_type key_from_value_type; typedef typename index_args::compare_type compare_type; template<typename Super> struct node_class { typedef detail::ordered_index_node<detail::rank_policy,Super> type; }; template<typename SuperMeta> struct index_class { typedef detail::ordered_index< key_from_value_type,compare_type, SuperMeta,tag_list_type,detail::ordered_unique_tag, detail::rank_policy> type; }; }; template<typename Arg1,typename Arg2,typename Arg3> struct ranked_non_unique { typedef detail::ordered_index_args< Arg1,Arg2,Arg3> index_args; typedef typename index_args::tag_list_type::type tag_list_type; typedef typename index_args::key_from_value_type key_from_value_type; typedef typename index_args::compare_type compare_type; template<typename Super> struct node_class { typedef detail::ordered_index_node<detail::rank_policy,Super> type; }; template<typename SuperMeta> struct index_class { typedef detail::ordered_index< key_from_value_type,compare_type, SuperMeta,tag_list_type,detail::ordered_non_unique_tag, detail::rank_policy> type; }; }; } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[��cw w hashed_index_fwd.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_HASHED_INDEX_FWD_HPP #define BOOST_MULTI_INDEX_HASHED_INDEX_FWD_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/multi_index/detail/hash_index_args.hpp> namespace boost{ namespace multi_index{ namespace detail{ template< typename KeyFromValue,typename Hash,typename Pred, typename SuperMeta,typename TagList,typename Category > class hashed_index; template< typename KeyFromValue,typename Hash,typename Pred, typename SuperMeta,typename TagList,typename Category > bool operator==( const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x, const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& y); template< typename KeyFromValue,typename Hash,typename Pred, typename SuperMeta,typename TagList,typename Category > bool operator!=( const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x, const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& y); template< typename KeyFromValue,typename Hash,typename Pred, typename SuperMeta,typename TagList,typename Category > void swap( hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x, hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& y); } /* namespace multi_index::detail */ /* hashed_index specifiers */ template< typename Arg1,typename Arg2=mpl::na, typename Arg3=mpl::na,typename Arg4=mpl::na > struct hashed_unique; template< typename Arg1,typename Arg2=mpl::na, typename Arg3=mpl::na,typename Arg4=mpl::na > struct hashed_non_unique; } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�Ur�z z key_extractors.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_KEY_EXTRACTORS_HPP #define BOOST_MULTI_INDEX_KEY_EXTRACTORS_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/multi_index/composite_key.hpp> #include <boost/multi_index/identity.hpp> #include <boost/multi_index/global_fun.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/mem_fun.hpp> #endif PK 3L�[�`t+� +� hashed_index.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_HASHED_INDEX_HPP #define BOOST_MULTI_INDEX_HASHED_INDEX_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/call_traits.hpp> #include <boost/core/addressof.hpp> #include <boost/core/no_exceptions_support.hpp> #include <boost/detail/workaround.hpp> #include <boost/foreach_fwd.hpp> #include <boost/limits.hpp> #include <boost/move/core.hpp> #include <boost/move/utility_core.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/if.hpp> #include <boost/mpl/push_front.hpp> #include <boost/multi_index/detail/access_specifier.hpp> #include <boost/multi_index/detail/adl_swap.hpp> #include <boost/multi_index/detail/allocator_traits.hpp> #include <boost/multi_index/detail/auto_space.hpp> #include <boost/multi_index/detail/bucket_array.hpp> #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp> #include <boost/multi_index/detail/hash_index_iterator.hpp> #include <boost/multi_index/detail/index_node_base.hpp> #include <boost/multi_index/detail/modify_key_adaptor.hpp> #include <boost/multi_index/detail/node_handle.hpp> #include <boost/multi_index/detail/promotes_arg.hpp> #include <boost/multi_index/detail/safe_mode.hpp> #include <boost/multi_index/detail/scope_guard.hpp> #include <boost/multi_index/detail/vartempl_support.hpp> #include <boost/multi_index/hashed_index_fwd.hpp> #include <boost/tuple/tuple.hpp> #include <boost/type_traits/is_same.hpp> #include <cmath> #include <cstddef> #include <functional> #include <iterator> #include <utility> #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include <initializer_list> #endif #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include <boost/serialization/nvp.hpp> #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) #define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ detail::make_obj_guard(x,&hashed_index::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch(); #define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \ BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(*this) #else #define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) #define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT #endif namespace boost{ namespace multi_index{ namespace detail{ /* hashed_index adds a layer of hashed indexing to a given Super */ /* Most of the implementation of unique and non-unique indices is * shared. We tell from one another on instantiation time by using * Category tags defined in hash_index_node.hpp. */ template< typename KeyFromValue,typename Hash,typename Pred, typename SuperMeta,typename TagList,typename Category > class hashed_index: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) ,public safe_mode::safe_container< hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category> > #endif { #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ BOOST_WORKAROUND(__MWERKS__,<=0x3003) /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the * lifetime of const references bound to temporaries --precisely what * scopeguards are. */ #pragma parse_mfunc_templ off #endif typedef typename SuperMeta::type super; protected: typedef hashed_index_node< typename super::index_node_type> index_node_type; private: typedef typename index_node_type:: template node_alg<Category>::type node_alg; typedef typename index_node_type::impl_type node_impl_type; typedef typename node_impl_type::pointer node_impl_pointer; typedef typename node_impl_type::base_pointer node_impl_base_pointer; typedef bucket_array< typename super::final_allocator_type> bucket_array_type; public: /* types */ typedef typename KeyFromValue::result_type key_type; typedef typename index_node_type::value_type value_type; typedef KeyFromValue key_from_value; typedef Hash hasher; typedef Pred key_equal; typedef typename super::final_allocator_type allocator_type; private: typedef allocator_traits<allocator_type> alloc_traits; public: typedef typename alloc_traits::pointer pointer; typedef typename alloc_traits::const_pointer const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef typename alloc_traits::size_type size_type; typedef typename alloc_traits::difference_type difference_type; typedef tuple<size_type, key_from_value,hasher,key_equal> ctor_args; #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) typedef safe_mode::safe_iterator< hashed_index_iterator< index_node_type,bucket_array_type, Category, hashed_index_global_iterator_tag>, hashed_index> iterator; #else typedef hashed_index_iterator< index_node_type,bucket_array_type, Category,hashed_index_global_iterator_tag> iterator; #endif typedef iterator const_iterator; typedef hashed_index_iterator< index_node_type,bucket_array_type, Category,hashed_index_local_iterator_tag> local_iterator; typedef local_iterator const_local_iterator; typedef typename super::final_node_handle_type node_type; typedef detail::insert_return_type< iterator,node_type> insert_return_type; typedef TagList tag_list; protected: typedef typename super::final_node_type final_node_type; typedef tuples::cons< ctor_args, typename super::ctor_args_list> ctor_args_list; typedef typename mpl::push_front< typename super::index_type_list, hashed_index>::type index_type_list; typedef typename mpl::push_front< typename super::iterator_type_list, iterator>::type iterator_type_list; typedef typename mpl::push_front< typename super::const_iterator_type_list, const_iterator>::type const_iterator_type_list; typedef typename super::copy_map_type copy_map_type; #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) typedef typename super::index_saver_type index_saver_type; typedef typename super::index_loader_type index_loader_type; #endif private: #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) typedef safe_mode::safe_container< hashed_index> safe_super; #endif typedef typename call_traits<value_type>::param_type value_param_type; typedef typename call_traits< key_type>::param_type key_param_type; /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL * expansion. */ typedef std::pair<iterator,bool> emplace_return_type; public: /* construct/destroy/copy * Default and copy ctors are in the protected section as indices are * not supposed to be created on their own. No range ctor either. */ hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& operator=( const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x) { this->final()=x.final(); return *this; } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& operator=( std::initializer_list<value_type> list) { this->final()=list; return *this; } #endif allocator_type get_allocator()const BOOST_NOEXCEPT { return this->final().get_allocator(); } /* size and capacity */ bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} size_type size()const BOOST_NOEXCEPT{return this->final_size_();} size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} /* iterators */ iterator begin()BOOST_NOEXCEPT { return make_iterator( index_node_type::from_impl(header()->next()->prior())); } const_iterator begin()const BOOST_NOEXCEPT { return make_iterator( index_node_type::from_impl(header()->next()->prior())); } iterator end()BOOST_NOEXCEPT{return make_iterator(header());} const_iterator end()const BOOST_NOEXCEPT{return make_iterator(header());} const_iterator cbegin()const BOOST_NOEXCEPT{return begin();} const_iterator cend()const BOOST_NOEXCEPT{return end();} iterator iterator_to(const value_type& x) { return make_iterator( node_from_value<index_node_type>(boost::addressof(x))); } const_iterator iterator_to(const value_type& x)const { return make_iterator( node_from_value<index_node_type>(boost::addressof(x))); } /* modifiers */ BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( emplace_return_type,emplace,emplace_impl) BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( iterator,emplace_hint,emplace_hint_impl,iterator,position) std::pair<iterator,bool> insert(const value_type& x) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_(x); return std::pair<iterator,bool>(make_iterator(p.first),p.second); } std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_rv_(x); return std::pair<iterator,bool>(make_iterator(p.first),p.second); } iterator insert(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_( x,static_cast<final_node_type*>(position.get_node())); return make_iterator(p.first); } iterator insert(iterator position,BOOST_RV_REF(value_type) x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_rv_( x,static_cast<final_node_type*>(position.get_node())); return make_iterator(p.first); } template<typename InputIterator> void insert(InputIterator first,InputIterator last) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; for(;first!=last;++first)this->final_insert_ref_(*first); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) void insert(std::initializer_list<value_type> list) { insert(list.begin(),list.end()); } #endif insert_return_type insert(BOOST_RV_REF(node_type) nh) { if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh); return insert_return_type(make_iterator(p.first),p.second,boost::move(nh)); } iterator insert(const_iterator position,BOOST_RV_REF(node_type) nh) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_nh_( nh,static_cast<final_node_type*>(position.get_node())); return make_iterator(p.first); } node_type extract(const_iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; return this->final_extract_( static_cast<final_node_type*>(position.get_node())); } node_type extract(key_param_type x) { iterator position=find(x); if(position==end())return node_type(); else return extract(position); } iterator erase(iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; this->final_erase_(static_cast<final_node_type*>(position++.get_node())); return position; } size_type erase(key_param_type k) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; std::size_t buc=buckets.position(hash_(k)); for(node_impl_pointer x=buckets.at(buc)->prior(); x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ if(eq_(k,key(index_node_type::from_impl(x)->value()))){ node_impl_pointer y=end_of_range(x); size_type s=0; do{ node_impl_pointer z=node_alg::after(x); this->final_erase_( static_cast<final_node_type*>(index_node_type::from_impl(x))); x=z; ++s; }while(x!=y); return s; } } return 0; } iterator erase(iterator first,iterator last) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; while(first!=last){ first=erase(first); } return first; } bool replace(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; return this->final_replace_( x,static_cast<final_node_type*>(position.get_node())); } bool replace(iterator position,BOOST_RV_REF(value_type) x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; return this->final_replace_rv_( x,static_cast<final_node_type*>(position.get_node())); } template<typename Modifier> bool modify(iterator position,Modifier mod) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) /* MSVC++ 6.0 optimizer on safe mode code chokes if this * this is not added. Left it for all compilers as it does no * harm. */ position.detach(); #endif return this->final_modify_( mod,static_cast<final_node_type*>(position.get_node())); } template<typename Modifier,typename Rollback> bool modify(iterator position,Modifier mod,Rollback back_) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) /* MSVC++ 6.0 optimizer on safe mode code chokes if this * this is not added. Left it for all compilers as it does no * harm. */ position.detach(); #endif return this->final_modify_( mod,back_,static_cast<final_node_type*>(position.get_node())); } template<typename Modifier> bool modify_key(iterator position,Modifier mod) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; return modify( position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key)); } template<typename Modifier,typename Rollback> bool modify_key(iterator position,Modifier mod,Rollback back_) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; return modify( position, modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key), modify_key_adaptor<Rollback,value_type,KeyFromValue>(back_,key)); } void clear()BOOST_NOEXCEPT { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; this->final_clear_(); } void swap(hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x); this->final_swap_(x.final()); } /* observers */ key_from_value key_extractor()const{return key;} hasher hash_function()const{return hash_;} key_equal key_eq()const{return eq_;} /* lookup */ /* Internally, these ops rely on const_iterator being the same * type as iterator. */ /* Implementation note: When CompatibleKey is consistently promoted to * KeyFromValue::result_type for equality comparison, the promotion is made * once in advance to increase efficiency. */ template<typename CompatibleKey> iterator find(const CompatibleKey& k)const { return find(k,hash_,eq_); } template< typename CompatibleKey,typename CompatibleHash,typename CompatiblePred > iterator find( const CompatibleKey& k, const CompatibleHash& hash,const CompatiblePred& eq)const { return find( k,hash,eq,promotes_1st_arg<CompatiblePred,CompatibleKey,key_type>()); } template<typename CompatibleKey> size_type count(const CompatibleKey& k)const { return count(k,hash_,eq_); } template< typename CompatibleKey,typename CompatibleHash,typename CompatiblePred > size_type count( const CompatibleKey& k, const CompatibleHash& hash,const CompatiblePred& eq)const { return count( k,hash,eq,promotes_1st_arg<CompatiblePred,CompatibleKey,key_type>()); } template<typename CompatibleKey> std::pair<iterator,iterator> equal_range(const CompatibleKey& k)const { return equal_range(k,hash_,eq_); } template< typename CompatibleKey,typename CompatibleHash,typename CompatiblePred > std::pair<iterator,iterator> equal_range( const CompatibleKey& k, const CompatibleHash& hash,const CompatiblePred& eq)const { return equal_range( k,hash,eq,promotes_1st_arg<CompatiblePred,CompatibleKey,key_type>()); } /* bucket interface */ size_type bucket_count()const BOOST_NOEXCEPT { return static_cast<size_type>(buckets.size()); } size_type max_bucket_count()const BOOST_NOEXCEPT{return static_cast<size_type>(-1);} size_type bucket_size(size_type n)const { size_type res=0; for(node_impl_pointer x=buckets.at(n)->prior(); x!=node_impl_pointer(0);x=node_alg::after_local(x)){ ++res; } return res; } size_type bucket(key_param_type k)const { return static_cast<size_type>(buckets.position(hash_(k))); } local_iterator begin(size_type n) { return const_cast<const hashed_index*>(this)->begin(n); } const_local_iterator begin(size_type n)const { node_impl_pointer x=buckets.at(n)->prior(); if(x==node_impl_pointer(0))return end(n); return make_local_iterator(index_node_type::from_impl(x)); } local_iterator end(size_type n) { return const_cast<const hashed_index*>(this)->end(n); } const_local_iterator end(size_type)const { return make_local_iterator(0); } const_local_iterator cbegin(size_type n)const{return begin(n);} const_local_iterator cend(size_type n)const{return end(n);} local_iterator local_iterator_to(const value_type& x) { return make_local_iterator( node_from_value<index_node_type>(boost::addressof(x))); } const_local_iterator local_iterator_to(const value_type& x)const { return make_local_iterator( node_from_value<index_node_type>(boost::addressof(x))); } /* hash policy */ float load_factor()const BOOST_NOEXCEPT {return static_cast<float>(size())/bucket_count();} float max_load_factor()const BOOST_NOEXCEPT{return mlf;} void max_load_factor(float z){mlf=z;calculate_max_load();} void rehash(size_type n) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; if(size()<=max_load&&n<=bucket_count())return; size_type bc =(std::numeric_limits<size_type>::max)(); float fbc=1.0f+static_cast<float>(size())/mlf; if(bc>fbc){ bc=static_cast<size_type>(fbc); if(bc<n)bc=n; } unchecked_rehash(bc); } void reserve(size_type n) { rehash(static_cast<size_type>(std::ceil(static_cast<float>(n)/mlf))); } BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: hashed_index(const ctor_args_list& args_list,const allocator_type& al): super(args_list.get_tail(),al), key(tuples::get<1>(args_list.get_head())), hash_(tuples::get<2>(args_list.get_head())), eq_(tuples::get<3>(args_list.get_head())), buckets(al,header()->impl(),tuples::get<0>(args_list.get_head())), mlf(1.0f) { calculate_max_load(); } hashed_index( const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x): super(x), #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super(), #endif key(x.key), hash_(x.hash_), eq_(x.eq_), buckets(x.get_allocator(),header()->impl(),x.buckets.size()), mlf(x.mlf), max_load(x.max_load) { /* Copy ctor just takes the internal configuration objects from x. The rest * is done in subsequent call to copy_(). */ } hashed_index( const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x, do_not_copy_elements_tag): super(x,do_not_copy_elements_tag()), #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super(), #endif key(x.key), hash_(x.hash_), eq_(x.eq_), buckets(x.get_allocator(),header()->impl(),0), mlf(1.0f) { calculate_max_load(); } ~hashed_index() { /* the container is guaranteed to be empty by now */ } #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) iterator make_iterator(index_node_type* node) { return iterator(node,this); } const_iterator make_iterator(index_node_type* node)const { return const_iterator(node,const_cast<hashed_index*>(this)); } #else iterator make_iterator(index_node_type* node) { return iterator(node); } const_iterator make_iterator(index_node_type* node)const { return const_iterator(node); } #endif local_iterator make_local_iterator(index_node_type* node) { return local_iterator(node); } const_local_iterator make_local_iterator(index_node_type* node)const { return const_local_iterator(node); } void copy_( const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x, const copy_map_type& map) { copy_(x,map,Category()); } void copy_( const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x, const copy_map_type& map,hashed_unique_tag) { if(x.size()!=0){ node_impl_pointer end_org=x.header()->impl(), org=end_org, cpy=header()->impl(); do{ node_impl_pointer prev_org=org->prior(), prev_cpy= static_cast<index_node_type*>(map.find(static_cast<final_node_type*>( index_node_type::from_impl(prev_org))))->impl(); cpy->prior()=prev_cpy; if(node_alg::is_first_of_bucket(org)){ node_impl_base_pointer buc_org=prev_org->next(), buc_cpy= buckets.begin()+(buc_org-x.buckets.begin()); prev_cpy->next()=buc_cpy; buc_cpy->prior()=cpy; } else{ prev_cpy->next()=node_impl_type::base_pointer_from(cpy); } org=prev_org; cpy=prev_cpy; }while(org!=end_org); } super::copy_(x,map); } void copy_( const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x, const copy_map_type& map,hashed_non_unique_tag) { if(x.size()!=0){ node_impl_pointer end_org=x.header()->impl(), org=end_org, cpy=header()->impl(); do{ node_impl_pointer next_org=node_alg::after(org), next_cpy= static_cast<index_node_type*>(map.find(static_cast<final_node_type*>( index_node_type::from_impl(next_org))))->impl(); if(node_alg::is_first_of_bucket(next_org)){ node_impl_base_pointer buc_org=org->next(), buc_cpy= buckets.begin()+(buc_org-x.buckets.begin()); cpy->next()=buc_cpy; buc_cpy->prior()=next_cpy; next_cpy->prior()=cpy; } else{ if(org->next()==node_impl_type::base_pointer_from(next_org)){ cpy->next()=node_impl_type::base_pointer_from(next_cpy); } else{ cpy->next()= node_impl_type::base_pointer_from( static_cast<index_node_type*>( map.find(static_cast<final_node_type*>( index_node_type::from_impl( node_impl_type::pointer_from(org->next())))))->impl()); } if(next_org->prior()!=org){ next_cpy->prior()= static_cast<index_node_type*>( map.find(static_cast<final_node_type*>( index_node_type::from_impl(next_org->prior()))))->impl(); } else{ next_cpy->prior()=cpy; } } org=next_org; cpy=next_cpy; }while(org!=end_org); } super::copy_(x,map); } template<typename Variant> final_node_type* insert_( value_param_type v,final_node_type*& x,Variant variant) { reserve_for_insert(size()+1); std::size_t buc=find_bucket(v); link_info pos(buckets.at(buc)); if(!link_point(v,pos)){ return static_cast<final_node_type*>( index_node_type::from_impl(node_impl_type::pointer_from(pos))); } final_node_type* res=super::insert_(v,x,variant); if(res==x)link(static_cast<index_node_type*>(x),pos); return res; } template<typename Variant> final_node_type* insert_( value_param_type v,index_node_type* position, final_node_type*& x,Variant variant) { reserve_for_insert(size()+1); std::size_t buc=find_bucket(v); link_info pos(buckets.at(buc)); if(!link_point(v,pos)){ return static_cast<final_node_type*>( index_node_type::from_impl(node_impl_type::pointer_from(pos))); } final_node_type* res=super::insert_(v,position,x,variant); if(res==x)link(static_cast<index_node_type*>(x),pos); return res; } void extract_(index_node_type* x) { unlink(x); super::extract_(x); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) detach_iterators(x); #endif } void delete_all_nodes_() { delete_all_nodes_(Category()); } void delete_all_nodes_(hashed_unique_tag) { for(node_impl_pointer x_end=header()->impl(),x=x_end->prior();x!=x_end;){ node_impl_pointer y=x->prior(); this->final_delete_node_( static_cast<final_node_type*>(index_node_type::from_impl(x))); x=y; } } void delete_all_nodes_(hashed_non_unique_tag) { for(node_impl_pointer x_end=header()->impl(),x=x_end->prior();x!=x_end;){ node_impl_pointer y=x->prior(); if(y->next()!=node_impl_type::base_pointer_from(x)&& y->next()->prior()!=x){ /* n-1 of group */ /* Make the second node prior() pointer back-linked so that it won't * refer to a deleted node when the time for its own destruction comes. */ node_impl_pointer first=node_impl_type::pointer_from(y->next()); first->next()->prior()=first; } this->final_delete_node_( static_cast<final_node_type*>(index_node_type::from_impl(x))); x=y; } } void clear_() { super::clear_(); buckets.clear(header()->impl()); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super::detach_dereferenceable_iterators(); #endif } template<typename BoolConstant> void swap_( hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x, BoolConstant swap_allocators) { adl_swap(key,x.key); adl_swap(hash_,x.hash_); adl_swap(eq_,x.eq_); buckets.swap(x.buckets,swap_allocators); std::swap(mlf,x.mlf); std::swap(max_load,x.max_load); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super::swap(x); #endif super::swap_(x,swap_allocators); } void swap_elements_( hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x) { buckets.swap(x.buckets); std::swap(mlf,x.mlf); std::swap(max_load,x.max_load); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super::swap(x); #endif super::swap_elements_(x); } template<typename Variant> bool replace_(value_param_type v,index_node_type* x,Variant variant) { if(eq_(key(v),key(x->value()))){ return super::replace_(v,x,variant); } unlink_undo undo; unlink(x,undo); BOOST_TRY{ std::size_t buc=find_bucket(v); link_info pos(buckets.at(buc)); if(link_point(v,pos)&&super::replace_(v,x,variant)){ link(x,pos); return true; } undo(); return false; } BOOST_CATCH(...){ undo(); BOOST_RETHROW; } BOOST_CATCH_END } bool modify_(index_node_type* x) { std::size_t buc; bool b; BOOST_TRY{ buc=find_bucket(x->value()); b=in_place(x->impl(),key(x->value()),buc); } BOOST_CATCH(...){ extract_(x); BOOST_RETHROW; } BOOST_CATCH_END if(!b){ unlink(x); BOOST_TRY{ link_info pos(buckets.at(buc)); if(!link_point(x->value(),pos)){ super::extract_(x); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) detach_iterators(x); #endif return false; } link(x,pos); } BOOST_CATCH(...){ super::extract_(x); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) detach_iterators(x); #endif BOOST_RETHROW; } BOOST_CATCH_END } BOOST_TRY{ if(!super::modify_(x)){ unlink(x); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) detach_iterators(x); #endif return false; } else return true; } BOOST_CATCH(...){ unlink(x); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) detach_iterators(x); #endif BOOST_RETHROW; } BOOST_CATCH_END } bool modify_rollback_(index_node_type* x) { std::size_t buc=find_bucket(x->value()); if(in_place(x->impl(),key(x->value()),buc)){ return super::modify_rollback_(x); } unlink_undo undo; unlink(x,undo); BOOST_TRY{ link_info pos(buckets.at(buc)); if(link_point(x->value(),pos)&&super::modify_rollback_(x)){ link(x,pos); return true; } undo(); return false; } BOOST_CATCH(...){ undo(); BOOST_RETHROW; } BOOST_CATCH_END } bool check_rollback_(index_node_type* x)const { std::size_t buc=find_bucket(x->value()); return in_place(x->impl(),key(x->value()),buc)&&super::check_rollback_(x); } /* comparison */ #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) /* defect macro refers to class, not function, templates, but anyway */ template<typename K,typename H,typename P,typename S,typename T,typename C> friend bool operator==( const hashed_index<K,H,P,S,T,C>&,const hashed_index<K,H,P,S,T,C>& y); #endif bool equals(const hashed_index& x)const{return equals(x,Category());} bool equals(const hashed_index& x,hashed_unique_tag)const { if(size()!=x.size())return false; for(const_iterator it=begin(),it_end=end(),it2_end=x.end(); it!=it_end;++it){ const_iterator it2=x.find(key(*it)); if(it2==it2_end||!(*it==*it2))return false; } return true; } bool equals(const hashed_index& x,hashed_non_unique_tag)const { if(size()!=x.size())return false; for(const_iterator it=begin(),it_end=end();it!=it_end;){ const_iterator it2,it2_last; boost::tie(it2,it2_last)=x.equal_range(key(*it)); if(it2==it2_last)return false; const_iterator it_last=make_iterator( index_node_type::from_impl(end_of_range(it.get_node()->impl()))); if(std::distance(it,it_last)!=std::distance(it2,it2_last))return false; /* From is_permutation code in * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3068.pdf */ for(;it!=it_last;++it,++it2){ if(!(*it==*it2))break; } if(it!=it_last){ for(const_iterator scan=it;scan!=it_last;++scan){ if(std::find(it,scan,*scan)!=scan)continue; difference_type matches=std::count(it2,it2_last,*scan); if(matches==0||matches!=std::count(scan,it_last,*scan))return false; } it=it_last; } } return true; } #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) /* serialization */ template<typename Archive> void save_( Archive& ar,const unsigned int version,const index_saver_type& sm)const { ar<<serialization::make_nvp("position",buckets); super::save_(ar,version,sm); } template<typename Archive> void load_(Archive& ar,const unsigned int version,const index_loader_type& lm) { ar>>serialization::make_nvp("position",buckets); super::load_(ar,version,lm); } #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) /* invariant stuff */ bool invariant_()const { if(size()==0||begin()==end()){ if(size()!=0||begin()!=end())return false; } else{ size_type s0=0; for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s0){} if(s0!=size())return false; size_type s1=0; for(size_type buc=0;buc<bucket_count();++buc){ size_type ss1=0; for(const_local_iterator it=begin(buc),it_end=end(buc); it!=it_end;++it,++ss1){ if(find_bucket(*it)!=buc)return false; } if(ss1!=bucket_size(buc))return false; s1+=ss1; } if(s1!=size())return false; } return super::invariant_(); } /* This forwarding function eases things for the boost::mem_fn construct * in BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT. Actually, * final_check_invariant is already an inherited member function of index. */ void check_invariant_()const{this->final_check_invariant_();} #endif private: index_node_type* header()const{return this->final_header();} std::size_t find_bucket(value_param_type v)const { return bucket(key(v)); } struct link_info_non_unique { link_info_non_unique(node_impl_base_pointer pos): first(pos),last(node_impl_base_pointer(0)){} operator const node_impl_base_pointer&()const{return this->first;} node_impl_base_pointer first,last; }; typedef typename mpl::if_< is_same<Category,hashed_unique_tag>, node_impl_base_pointer, link_info_non_unique >::type link_info; bool link_point(value_param_type v,link_info& pos) { return link_point(v,pos,Category()); } bool link_point( value_param_type v,node_impl_base_pointer& pos,hashed_unique_tag) { for(node_impl_pointer x=pos->prior();x!=node_impl_pointer(0); x=node_alg::after_local(x)){ if(eq_(key(v),key(index_node_type::from_impl(x)->value()))){ pos=node_impl_type::base_pointer_from(x); return false; } } return true; } bool link_point( value_param_type v,link_info_non_unique& pos,hashed_non_unique_tag) { for(node_impl_pointer x=pos.first->prior();x!=node_impl_pointer(0); x=node_alg::next_to_inspect(x)){ if(eq_(key(v),key(index_node_type::from_impl(x)->value()))){ pos.first=node_impl_type::base_pointer_from(x); pos.last=node_impl_type::base_pointer_from(last_of_range(x)); return true; } } return true; } node_impl_pointer last_of_range(node_impl_pointer x)const { return last_of_range(x,Category()); } node_impl_pointer last_of_range(node_impl_pointer x,hashed_unique_tag)const { return x; } node_impl_pointer last_of_range( node_impl_pointer x,hashed_non_unique_tag)const { node_impl_base_pointer y=x->next(); node_impl_pointer z=y->prior(); if(z==x){ /* range of size 1 or 2 */ node_impl_pointer yy=node_impl_type::pointer_from(y); return eq_( key(index_node_type::from_impl(x)->value()), key(index_node_type::from_impl(yy)->value()))?yy:x; } else if(z->prior()==x) /* last of bucket */ return x; else /* group of size>2 */ return z; } node_impl_pointer end_of_range(node_impl_pointer x)const { return end_of_range(x,Category()); } node_impl_pointer end_of_range(node_impl_pointer x,hashed_unique_tag)const { return node_alg::after(last_of_range(x)); } node_impl_pointer end_of_range( node_impl_pointer x,hashed_non_unique_tag)const { node_impl_base_pointer y=x->next(); node_impl_pointer z=y->prior(); if(z==x){ /* range of size 1 or 2 */ node_impl_pointer yy=node_impl_type::pointer_from(y); if(!eq_( key(index_node_type::from_impl(x)->value()), key(index_node_type::from_impl(yy)->value())))yy=x; return yy->next()->prior()==yy? node_impl_type::pointer_from(yy->next()): yy->next()->prior(); } else if(z->prior()==x) /* last of bucket */ return z; else /* group of size>2 */ return z->next()->prior()==z? node_impl_type::pointer_from(z->next()): z->next()->prior(); } void link(index_node_type* x,const link_info& pos) { link(x,pos,Category()); } void link(index_node_type* x,node_impl_base_pointer pos,hashed_unique_tag) { node_alg::link(x->impl(),pos,header()->impl()); } void link( index_node_type* x,const link_info_non_unique& pos,hashed_non_unique_tag) { if(pos.last==node_impl_base_pointer(0)){ node_alg::link(x->impl(),pos.first,header()->impl()); } else{ node_alg::link( x->impl(), node_impl_type::pointer_from(pos.first), node_impl_type::pointer_from(pos.last)); } } void unlink(index_node_type* x) { node_alg::unlink(x->impl()); } typedef typename node_alg::unlink_undo unlink_undo; void unlink(index_node_type* x,unlink_undo& undo) { node_alg::unlink(x->impl(),undo); } void calculate_max_load() { float fml=mlf*static_cast<float>(bucket_count()); max_load=(std::numeric_limits<size_type>::max)(); if(max_load>fml)max_load=static_cast<size_type>(fml); } void reserve_for_insert(size_type n) { if(n>max_load){ size_type bc =(std::numeric_limits<size_type>::max)(); float fbc=1.0f+static_cast<float>(n)/mlf; if(bc>fbc)bc =static_cast<size_type>(fbc); unchecked_rehash(bc); } } void unchecked_rehash(size_type n){unchecked_rehash(n,Category());} void unchecked_rehash(size_type n,hashed_unique_tag) { node_impl_type cpy_end_node; node_impl_pointer cpy_end=node_impl_pointer(&cpy_end_node), end_=header()->impl(); bucket_array_type buckets_cpy(get_allocator(),cpy_end,n); if(size()!=0){ auto_space< std::size_t,allocator_type> hashes(get_allocator(),size()); auto_space< node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); std::size_t i=0,size_=size(); bool within_bucket=false; BOOST_TRY{ for(;i!=size_;++i){ node_impl_pointer x=end_->prior(); /* only this can possibly throw */ std::size_t h=hash_(key(index_node_type::from_impl(x)->value())); hashes.data()[i]=h; node_ptrs.data()[i]=x; within_bucket=!node_alg::unlink_last(end_); node_alg::link(x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); } } BOOST_CATCH(...){ if(i!=0){ std::size_t prev_buc=buckets.position(hashes.data()[i-1]); if(!within_bucket)prev_buc=~prev_buc; for(std::size_t j=i;j--;){ std::size_t buc=buckets.position(hashes.data()[j]); node_impl_pointer x=node_ptrs.data()[j]; if(buc==prev_buc)node_alg::append(x,end_); else node_alg::link(x,buckets.at(buc),end_); prev_buc=buc; } } BOOST_RETHROW; } BOOST_CATCH_END } end_->prior()=cpy_end->prior()!=cpy_end?cpy_end->prior():end_; end_->next()=cpy_end->next(); end_->prior()->next()->prior()=end_->next()->prior()->prior()=end_; buckets.swap(buckets_cpy); calculate_max_load(); } void unchecked_rehash(size_type n,hashed_non_unique_tag) { node_impl_type cpy_end_node; node_impl_pointer cpy_end=node_impl_pointer(&cpy_end_node), end_=header()->impl(); bucket_array_type buckets_cpy(get_allocator(),cpy_end,n); if(size()!=0){ auto_space< std::size_t,allocator_type> hashes(get_allocator(),size()); auto_space< node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); std::size_t i=0; bool within_bucket=false; BOOST_TRY{ for(;;++i){ node_impl_pointer x=end_->prior(); if(x==end_)break; /* only this can possibly throw */ std::size_t h=hash_(key(index_node_type::from_impl(x)->value())); hashes.data()[i]=h; node_ptrs.data()[i]=x; std::pair<node_impl_pointer,bool> p= node_alg::unlink_last_group(end_); node_alg::link_range( p.first,x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); within_bucket=!(p.second); } } BOOST_CATCH(...){ if(i!=0){ std::size_t prev_buc=buckets.position(hashes.data()[i-1]); if(!within_bucket)prev_buc=~prev_buc; for(std::size_t j=i;j--;){ std::size_t buc=buckets.position(hashes.data()[j]); node_impl_pointer x=node_ptrs.data()[j], y= x->prior()->next()!=node_impl_type::base_pointer_from(x)&& x->prior()->next()->prior()!=x? node_impl_type::pointer_from(x->prior()->next()):x; node_alg::unlink_range(y,x); if(buc==prev_buc)node_alg::append_range(y,x,end_); else node_alg::link_range(y,x,buckets.at(buc),end_); prev_buc=buc; } } BOOST_RETHROW; } BOOST_CATCH_END } end_->prior()=cpy_end->prior()!=cpy_end?cpy_end->prior():end_; end_->next()=cpy_end->next(); end_->prior()->next()->prior()=end_->next()->prior()->prior()=end_; buckets.swap(buckets_cpy); calculate_max_load(); } bool in_place(node_impl_pointer x,key_param_type k,std::size_t buc)const { return in_place(x,k,buc,Category()); } bool in_place( node_impl_pointer x,key_param_type k,std::size_t buc, hashed_unique_tag)const { bool found=false; for(node_impl_pointer y=buckets.at(buc)->prior(); y!=node_impl_pointer(0);y=node_alg::after_local(y)){ if(y==x)found=true; else if(eq_(k,key(index_node_type::from_impl(y)->value())))return false; } return found; } bool in_place( node_impl_pointer x,key_param_type k,std::size_t buc, hashed_non_unique_tag)const { bool found=false; int range_size=0; for(node_impl_pointer y=buckets.at(buc)->prior();y!=node_impl_pointer(0);){ if(node_alg::is_first_of_group(y)){ /* group of 3 or more */ if(y==x){ /* in place <-> equal to some other member of the group */ return eq_( k, key(index_node_type::from_impl( node_impl_type::pointer_from(y->next()))->value())); } else{ node_impl_pointer z= node_alg::after_local(y->next()->prior()); /* end of range */ if(eq_(k,key(index_node_type::from_impl(y)->value()))){ if(found)return false; /* x lies outside */ do{ if(y==x)return true; y=node_alg::after_local(y); }while(y!=z); return false; /* x not found */ } else{ if(range_size==1&&!found)return false; if(range_size==2)return found; range_size=0; y=z; /* skip range (and potentially x, too, which is fine) */ } } } else{ /* group of 1 or 2 */ if(y==x){ if(range_size==1)return true; range_size=1; found=true; } else if(eq_(k,key(index_node_type::from_impl(y)->value()))){ if(range_size==0&&found)return false; if(range_size==1&&!found)return false; if(range_size==2)return false; ++range_size; } else{ if(range_size==1&&!found)return false; if(range_size==2)return found; range_size=0; } y=node_alg::after_local(y); } } return found; } #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) void detach_iterators(index_node_type* x) { iterator it=make_iterator(x); safe_mode::detach_equivalent_iterators(it); } #endif template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool>p= this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); return std::pair<iterator,bool>(make_iterator(p.first),p.second); } template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> iterator emplace_hint_impl( iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool>p= this->final_emplace_hint_( static_cast<final_node_type*>(position.get_node()), BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); return make_iterator(p.first); } template< typename CompatibleHash,typename CompatiblePred > iterator find( const key_type& k, const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const { return find(k,hash,eq,mpl::false_()); } template< typename CompatibleKey,typename CompatibleHash,typename CompatiblePred > iterator find( const CompatibleKey& k, const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const { std::size_t buc=buckets.position(hash(k)); for(node_impl_pointer x=buckets.at(buc)->prior(); x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ if(eq(k,key(index_node_type::from_impl(x)->value()))){ return make_iterator(index_node_type::from_impl(x)); } } return end(); } template< typename CompatibleHash,typename CompatiblePred > size_type count( const key_type& k, const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const { return count(k,hash,eq,mpl::false_()); } template< typename CompatibleKey,typename CompatibleHash,typename CompatiblePred > size_type count( const CompatibleKey& k, const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const { std::size_t buc=buckets.position(hash(k)); for(node_impl_pointer x=buckets.at(buc)->prior(); x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ if(eq(k,key(index_node_type::from_impl(x)->value()))){ size_type res=0; node_impl_pointer y=end_of_range(x); do{ ++res; x=node_alg::after(x); }while(x!=y); return res; } } return 0; } template< typename CompatibleHash,typename CompatiblePred > std::pair<iterator,iterator> equal_range( const key_type& k, const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const { return equal_range(k,hash,eq,mpl::false_()); } template< typename CompatibleKey,typename CompatibleHash,typename CompatiblePred > std::pair<iterator,iterator> equal_range( const CompatibleKey& k, const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const { std::size_t buc=buckets.position(hash(k)); for(node_impl_pointer x=buckets.at(buc)->prior(); x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ if(eq(k,key(index_node_type::from_impl(x)->value()))){ return std::pair<iterator,iterator>( make_iterator(index_node_type::from_impl(x)), make_iterator(index_node_type::from_impl(end_of_range(x)))); } } return std::pair<iterator,iterator>(end(),end()); } key_from_value key; hasher hash_; key_equal eq_; bucket_array_type buckets; float mlf; size_type max_load; #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ BOOST_WORKAROUND(__MWERKS__,<=0x3003) #pragma parse_mfunc_templ reset #endif }; /* comparison */ template< typename KeyFromValue,typename Hash,typename Pred, typename SuperMeta,typename TagList,typename Category > bool operator==( const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x, const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& y) { return x.equals(y); } template< typename KeyFromValue,typename Hash,typename Pred, typename SuperMeta,typename TagList,typename Category > bool operator!=( const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x, const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& y) { return !(x==y); } /* specialized algorithms */ template< typename KeyFromValue,typename Hash,typename Pred, typename SuperMeta,typename TagList,typename Category > void swap( hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x, hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& y) { x.swap(y); } } /* namespace multi_index::detail */ /* hashed index specifiers */ template<typename Arg1,typename Arg2,typename Arg3,typename Arg4> struct hashed_unique { typedef typename detail::hashed_index_args< Arg1,Arg2,Arg3,Arg4> index_args; typedef typename index_args::tag_list_type::type tag_list_type; typedef typename index_args::key_from_value_type key_from_value_type; typedef typename index_args::hash_type hash_type; typedef typename index_args::pred_type pred_type; template<typename Super> struct node_class { typedef detail::hashed_index_node<Super> type; }; template<typename SuperMeta> struct index_class { typedef detail::hashed_index< key_from_value_type,hash_type,pred_type, SuperMeta,tag_list_type,detail::hashed_unique_tag> type; }; }; template<typename Arg1,typename Arg2,typename Arg3,typename Arg4> struct hashed_non_unique { typedef typename detail::hashed_index_args< Arg1,Arg2,Arg3,Arg4> index_args; typedef typename index_args::tag_list_type::type tag_list_type; typedef typename index_args::key_from_value_type key_from_value_type; typedef typename index_args::hash_type hash_type; typedef typename index_args::pred_type pred_type; template<typename Super> struct node_class { typedef detail::hashed_index_node<Super> type; }; template<typename SuperMeta> struct index_class { typedef detail::hashed_index< key_from_value_type,hash_type,pred_type, SuperMeta,tag_list_type,detail::hashed_non_unique_tag> type; }; }; } /* namespace multi_index */ } /* namespace boost */ /* Boost.Foreach compatibility */ template< typename KeyFromValue,typename Hash,typename Pred, typename SuperMeta,typename TagList,typename Category > inline boost::mpl::true_* boost_foreach_is_noncopyable( boost::multi_index::detail::hashed_index< KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>*&, boost_foreach_argument_dependent_lookup_hack) { return 0; } #undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT #undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF #endif PK 3L�[���R R tag.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_TAG_HPP #define BOOST_MULTI_INDEX_TAG_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/multi_index/detail/no_duplicate_tags.hpp> #include <boost/mpl/identity.hpp> #include <boost/mpl/transform.hpp> #include <boost/mpl/vector.hpp> #include <boost/preprocessor/facilities/intercept.hpp> #include <boost/preprocessor/repetition/enum_binary_params.hpp> #include <boost/preprocessor/repetition/enum_params.hpp> #include <boost/static_assert.hpp> #include <boost/type_traits/is_base_and_derived.hpp> /* A wrapper of mpl::vector used to hide MPL from the user. * tag contains types used as tag names for indices in get() functions. */ /* This user_definable macro limits the number of elements of a tag; * useful for shortening resulting symbol names (MSVC++ 6.0, for instance, * has problems coping with very long symbol names.) */ #if !defined(BOOST_MULTI_INDEX_LIMIT_TAG_SIZE) #define BOOST_MULTI_INDEX_LIMIT_TAG_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE #endif #if BOOST_MULTI_INDEX_LIMIT_TAG_SIZE<BOOST_MPL_LIMIT_VECTOR_SIZE #define BOOST_MULTI_INDEX_TAG_SIZE BOOST_MULTI_INDEX_LIMIT_TAG_SIZE #else #define BOOST_MULTI_INDEX_TAG_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE #endif namespace boost{ namespace multi_index{ namespace detail{ struct tag_marker{}; template<typename T> struct is_tag { BOOST_STATIC_CONSTANT(bool,value=(is_base_and_derived<tag_marker,T>::value)); }; } /* namespace multi_index::detail */ template< BOOST_PP_ENUM_BINARY_PARAMS( BOOST_MULTI_INDEX_TAG_SIZE, typename T, =mpl::na BOOST_PP_INTERCEPT) > struct tag:private detail::tag_marker { /* The mpl::transform pass produces shorter symbols (without * trailing mpl::na's.) */ typedef typename mpl::transform< mpl::vector<BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_TAG_SIZE,T)>, mpl::identity<mpl::_1> >::type type; BOOST_STATIC_ASSERT(detail::no_duplicate_tags<type>::value); }; } /* namespace multi_index */ } /* namespace boost */ #undef BOOST_MULTI_INDEX_TAG_SIZE #endif PK 3L�[�kA�� � composite_key.hppnu �[��� /* Copyright 2003-2015 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP #define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/functional/hash_fwd.hpp> #include <boost/multi_index/detail/access_specifier.hpp> #include <boost/mpl/eval_if.hpp> #include <boost/mpl/identity.hpp> #include <boost/mpl/if.hpp> #include <boost/mpl/or.hpp> #include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/control/expr_if.hpp> #include <boost/preprocessor/list/at.hpp> #include <boost/preprocessor/repetition/enum.hpp> #include <boost/preprocessor/repetition/enum_params.hpp> #include <boost/static_assert.hpp> #include <boost/tuple/tuple.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/utility/enable_if.hpp> #include <functional> #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) #include <boost/ref.hpp> #endif #if !defined(BOOST_NO_SFINAE) #include <boost/type_traits/is_convertible.hpp> #endif #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #include <boost/multi_index/detail/cons_stdtuple.hpp> #endif /* A composite key stores n key extractors and "computes" the * result on a given value as a packed reference to the value and * the composite key itself. Actual invocations to the component * key extractors are lazily performed when executing an operation * on composite_key results (equality, comparison, hashing.) * As the other key extractors in Boost.MultiIndex, composite_key<T,...> * is overloaded to work on chained pointers to T and reference_wrappers * of T. */ /* This user_definable macro limits the number of elements of a composite * key; useful for shortening resulting symbol names (MSVC++ 6.0, for * instance has problems coping with very long symbol names.) * NB: This cannot exceed the maximum number of arguments of * boost::tuple. In Boost 1.32, the limit is 10. */ #if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE) #define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10 #endif /* maximum number of key extractors in a composite key */ #if BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE<10 /* max length of a tuple */ #define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE \ BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE #else #define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE 10 #endif /* BOOST_PP_ENUM of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */ #define BOOST_MULTI_INDEX_CK_ENUM(macro,data) \ BOOST_PP_ENUM(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,macro,data) /* BOOST_PP_ENUM_PARAMS of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */ #define BOOST_MULTI_INDEX_CK_ENUM_PARAMS(param) \ BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,param) /* if n==0 -> text0 * otherwise -> textn=tuples::null_type */ #define BOOST_MULTI_INDEX_CK_TEMPLATE_PARM(z,n,text) \ typename BOOST_PP_CAT(text,n) BOOST_PP_EXPR_IF(n,=tuples::null_type) /* const textn& kn=textn() */ #define BOOST_MULTI_INDEX_CK_CTOR_ARG(z,n,text) \ const BOOST_PP_CAT(text,n)& BOOST_PP_CAT(k,n) = BOOST_PP_CAT(text,n)() /* typename list(0)<list(1),n>::type */ #define BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N(z,n,list) \ BOOST_DEDUCED_TYPENAME BOOST_PP_LIST_AT(list,0)< \ BOOST_PP_LIST_AT(list,1),n \ >::type namespace boost{ template<class T> class reference_wrapper; /* fwd decl. */ namespace multi_index{ namespace detail{ /* n-th key extractor of a composite key */ template<typename CompositeKey,int N> struct nth_key_from_value { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename mpl::eval_if_c< N<tuples::length<key_extractor_tuple>::value, tuples::element<N,key_extractor_tuple>, mpl::identity<tuples::null_type> >::type type; }; /* nth_composite_key_##name<CompositeKey,N>::type yields * functor<nth_key_from_value<CompositeKey,N> >, or tuples::null_type * if N exceeds the length of the composite key. */ #define BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(name,functor) \ template<typename KeyFromValue> \ struct BOOST_PP_CAT(key_,name) \ { \ typedef functor<typename KeyFromValue::result_type> type; \ }; \ \ template<> \ struct BOOST_PP_CAT(key_,name)<tuples::null_type> \ { \ typedef tuples::null_type type; \ }; \ \ template<typename CompositeKey,int N> \ struct BOOST_PP_CAT(nth_composite_key_,name) \ { \ typedef typename nth_key_from_value<CompositeKey,N>::type key_from_value; \ typedef typename BOOST_PP_CAT(key_,name)<key_from_value>::type type; \ }; /* nth_composite_key_equal_to * nth_composite_key_less * nth_composite_key_greater * nth_composite_key_hash */ BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(equal_to,std::equal_to) BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(less,std::less) BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(greater,std::greater) BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(hash,boost::hash) /* used for defining equality and comparison ops of composite_key_result */ #define BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO(z,n,text) text struct generic_operator_equal { template<typename T,typename Q> bool operator()(const T& x,const Q& y)const{return x==y;} }; typedef tuple< BOOST_MULTI_INDEX_CK_ENUM( BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO, detail::generic_operator_equal)> generic_operator_equal_tuple; struct generic_operator_less { template<typename T,typename Q> bool operator()(const T& x,const Q& y)const{return x<y;} }; typedef tuple< BOOST_MULTI_INDEX_CK_ENUM( BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO, detail::generic_operator_less)> generic_operator_less_tuple; /* Metaprogramming machinery for implementing equality, comparison and * hashing operations of composite_key_result. * * equal_* checks for equality between composite_key_results and * between those and tuples, accepting a tuple of basic equality functors. * compare_* does lexicographical comparison. * hash_* computes a combination of elementwise hash values. */ template < typename KeyCons1,typename Value1, typename KeyCons2, typename Value2, typename EqualCons > struct equal_ckey_ckey; /* fwd decl. */ template < typename KeyCons1,typename Value1, typename KeyCons2, typename Value2, typename EqualCons > struct equal_ckey_ckey_terminal { static bool compare( const KeyCons1&,const Value1&, const KeyCons2&,const Value2&, const EqualCons&) { return true; } }; template < typename KeyCons1,typename Value1, typename KeyCons2, typename Value2, typename EqualCons > struct equal_ckey_ckey_normal { static bool compare( const KeyCons1& c0,const Value1& v0, const KeyCons2& c1,const Value2& v1, const EqualCons& eq) { if(!eq.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return false; return equal_ckey_ckey< BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1, BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2, BOOST_DEDUCED_TYPENAME EqualCons::tail_type >::compare(c0.get_tail(),v0,c1.get_tail(),v1,eq.get_tail()); } }; template < typename KeyCons1,typename Value1, typename KeyCons2, typename Value2, typename EqualCons > struct equal_ckey_ckey: mpl::if_< mpl::or_< is_same<KeyCons1,tuples::null_type>, is_same<KeyCons2,tuples::null_type> >, equal_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>, equal_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,EqualCons> >::type { }; template < typename KeyCons,typename Value, typename ValCons,typename EqualCons > struct equal_ckey_cval; /* fwd decl. */ template < typename KeyCons,typename Value, typename ValCons,typename EqualCons > struct equal_ckey_cval_terminal { static bool compare( const KeyCons&,const Value&,const ValCons&,const EqualCons&) { return true; } static bool compare( const ValCons&,const KeyCons&,const Value&,const EqualCons&) { return true; } }; template < typename KeyCons,typename Value, typename ValCons,typename EqualCons > struct equal_ckey_cval_normal { static bool compare( const KeyCons& c,const Value& v,const ValCons& vc, const EqualCons& eq) { if(!eq.get_head()(c.get_head()(v),vc.get_head()))return false; return equal_ckey_cval< BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, BOOST_DEDUCED_TYPENAME ValCons::tail_type, BOOST_DEDUCED_TYPENAME EqualCons::tail_type >::compare(c.get_tail(),v,vc.get_tail(),eq.get_tail()); } static bool compare( const ValCons& vc,const KeyCons& c,const Value& v, const EqualCons& eq) { if(!eq.get_head()(vc.get_head(),c.get_head()(v)))return false; return equal_ckey_cval< BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, BOOST_DEDUCED_TYPENAME ValCons::tail_type, BOOST_DEDUCED_TYPENAME EqualCons::tail_type >::compare(vc.get_tail(),c.get_tail(),v,eq.get_tail()); } }; template < typename KeyCons,typename Value, typename ValCons,typename EqualCons > struct equal_ckey_cval: mpl::if_< mpl::or_< is_same<KeyCons,tuples::null_type>, is_same<ValCons,tuples::null_type> >, equal_ckey_cval_terminal<KeyCons,Value,ValCons,EqualCons>, equal_ckey_cval_normal<KeyCons,Value,ValCons,EqualCons> >::type { }; template < typename KeyCons1,typename Value1, typename KeyCons2, typename Value2, typename CompareCons > struct compare_ckey_ckey; /* fwd decl. */ template < typename KeyCons1,typename Value1, typename KeyCons2, typename Value2, typename CompareCons > struct compare_ckey_ckey_terminal { static bool compare( const KeyCons1&,const Value1&, const KeyCons2&,const Value2&, const CompareCons&) { return false; } }; template < typename KeyCons1,typename Value1, typename KeyCons2, typename Value2, typename CompareCons > struct compare_ckey_ckey_normal { static bool compare( const KeyCons1& c0,const Value1& v0, const KeyCons2& c1,const Value2& v1, const CompareCons& comp) { if(comp.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return true; if(comp.get_head()(c1.get_head()(v1),c0.get_head()(v0)))return false; return compare_ckey_ckey< BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1, BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2, BOOST_DEDUCED_TYPENAME CompareCons::tail_type >::compare(c0.get_tail(),v0,c1.get_tail(),v1,comp.get_tail()); } }; template < typename KeyCons1,typename Value1, typename KeyCons2, typename Value2, typename CompareCons > struct compare_ckey_ckey: mpl::if_< mpl::or_< is_same<KeyCons1,tuples::null_type>, is_same<KeyCons2,tuples::null_type> >, compare_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>, compare_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,CompareCons> >::type { }; template < typename KeyCons,typename Value, typename ValCons,typename CompareCons > struct compare_ckey_cval; /* fwd decl. */ template < typename KeyCons,typename Value, typename ValCons,typename CompareCons > struct compare_ckey_cval_terminal { static bool compare( const KeyCons&,const Value&,const ValCons&,const CompareCons&) { return false; } static bool compare( const ValCons&,const KeyCons&,const Value&,const CompareCons&) { return false; } }; template < typename KeyCons,typename Value, typename ValCons,typename CompareCons > struct compare_ckey_cval_normal { static bool compare( const KeyCons& c,const Value& v,const ValCons& vc, const CompareCons& comp) { if(comp.get_head()(c.get_head()(v),vc.get_head()))return true; if(comp.get_head()(vc.get_head(),c.get_head()(v)))return false; return compare_ckey_cval< BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, BOOST_DEDUCED_TYPENAME ValCons::tail_type, BOOST_DEDUCED_TYPENAME CompareCons::tail_type >::compare(c.get_tail(),v,vc.get_tail(),comp.get_tail()); } static bool compare( const ValCons& vc,const KeyCons& c,const Value& v, const CompareCons& comp) { if(comp.get_head()(vc.get_head(),c.get_head()(v)))return true; if(comp.get_head()(c.get_head()(v),vc.get_head()))return false; return compare_ckey_cval< BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, BOOST_DEDUCED_TYPENAME ValCons::tail_type, BOOST_DEDUCED_TYPENAME CompareCons::tail_type >::compare(vc.get_tail(),c.get_tail(),v,comp.get_tail()); } }; template < typename KeyCons,typename Value, typename ValCons,typename CompareCons > struct compare_ckey_cval: mpl::if_< mpl::or_< is_same<KeyCons,tuples::null_type>, is_same<ValCons,tuples::null_type> >, compare_ckey_cval_terminal<KeyCons,Value,ValCons,CompareCons>, compare_ckey_cval_normal<KeyCons,Value,ValCons,CompareCons> >::type { }; template<typename KeyCons,typename Value,typename HashCons> struct hash_ckey; /* fwd decl. */ template<typename KeyCons,typename Value,typename HashCons> struct hash_ckey_terminal { static std::size_t hash( const KeyCons&,const Value&,const HashCons&,std::size_t carry) { return carry; } }; template<typename KeyCons,typename Value,typename HashCons> struct hash_ckey_normal { static std::size_t hash( const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0) { /* same hashing formula as boost::hash_combine */ carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2); return hash_ckey< BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, BOOST_DEDUCED_TYPENAME HashCons::tail_type >::hash(c.get_tail(),v,h.get_tail(),carry); } }; template<typename KeyCons,typename Value,typename HashCons> struct hash_ckey: mpl::if_< is_same<KeyCons,tuples::null_type>, hash_ckey_terminal<KeyCons,Value,HashCons>, hash_ckey_normal<KeyCons,Value,HashCons> >::type { }; template<typename ValCons,typename HashCons> struct hash_cval; /* fwd decl. */ template<typename ValCons,typename HashCons> struct hash_cval_terminal { static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry) { return carry; } }; template<typename ValCons,typename HashCons> struct hash_cval_normal { static std::size_t hash( const ValCons& vc,const HashCons& h,std::size_t carry=0) { carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2); return hash_cval< BOOST_DEDUCED_TYPENAME ValCons::tail_type, BOOST_DEDUCED_TYPENAME HashCons::tail_type >::hash(vc.get_tail(),h.get_tail(),carry); } }; template<typename ValCons,typename HashCons> struct hash_cval: mpl::if_< is_same<ValCons,tuples::null_type>, hash_cval_terminal<ValCons,HashCons>, hash_cval_normal<ValCons,HashCons> >::type { }; } /* namespace multi_index::detail */ /* composite_key_result */ #if defined(BOOST_MSVC) #pragma warning(push) #pragma warning(disable:4512) #endif template<typename CompositeKey> struct composite_key_result { typedef CompositeKey composite_key_type; typedef typename composite_key_type::value_type value_type; composite_key_result( const composite_key_type& composite_key_,const value_type& value_): composite_key(composite_key_),value(value_) {} const composite_key_type& composite_key; const value_type& value; }; #if defined(BOOST_MSVC) #pragma warning(pop) #endif /* composite_key */ template< typename Value, BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue) > struct composite_key: private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)> { private: typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)> super; public: typedef super key_extractor_tuple; typedef Value value_type; typedef composite_key_result<composite_key> result_type; composite_key( BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)): super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) {} composite_key(const key_extractor_tuple& x):super(x){} const key_extractor_tuple& key_extractors()const{return *this;} key_extractor_tuple& key_extractors(){return *this;} template<typename ChainedPtr> #if !defined(BOOST_NO_SFINAE) typename disable_if< is_convertible<const ChainedPtr&,const value_type&>,result_type>::type #else result_type #endif operator()(const ChainedPtr& x)const { return operator()(*x); } result_type operator()(const value_type& x)const { return result_type(*this,x); } result_type operator()(const reference_wrapper<const value_type>& x)const { return result_type(*this,x.get()); } result_type operator()(const reference_wrapper<value_type>& x)const { return result_type(*this,x.get()); } }; /* comparison operators */ /* == */ template<typename CompositeKey1,typename CompositeKey2> inline bool operator==( const composite_key_result<CompositeKey1>& x, const composite_key_result<CompositeKey2>& y) { typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; typedef typename CompositeKey1::value_type value_type1; typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; typedef typename CompositeKey2::value_type value_type2; BOOST_STATIC_ASSERT( tuples::length<key_extractor_tuple1>::value== tuples::length<key_extractor_tuple2>::value); return detail::equal_ckey_ckey< key_extractor_tuple1,value_type1, key_extractor_tuple2,value_type2, detail::generic_operator_equal_tuple >::compare( x.composite_key.key_extractors(),x.value, y.composite_key.key_extractors(),y.value, detail::generic_operator_equal_tuple()); } template< typename CompositeKey, BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) > inline bool operator==( const composite_key_result<CompositeKey>& x, const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y) { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple; BOOST_STATIC_ASSERT( tuples::length<key_extractor_tuple>::value== tuples::length<key_tuple>::value); return detail::equal_ckey_cval< key_extractor_tuple,value_type, key_tuple,detail::generic_operator_equal_tuple >::compare( x.composite_key.key_extractors(),x.value, y,detail::generic_operator_equal_tuple()); } template < BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), typename CompositeKey > inline bool operator==( const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x, const composite_key_result<CompositeKey>& y) { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple; BOOST_STATIC_ASSERT( tuples::length<key_extractor_tuple>::value== tuples::length<key_tuple>::value); return detail::equal_ckey_cval< key_extractor_tuple,value_type, key_tuple,detail::generic_operator_equal_tuple >::compare( x,y.composite_key.key_extractors(), y.value,detail::generic_operator_equal_tuple()); } #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template<typename CompositeKey,typename... Values> inline bool operator==( const composite_key_result<CompositeKey>& x, const std::tuple<Values...>& y) { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef std::tuple<Values...> key_tuple; typedef typename detail::cons_stdtuple_ctor< key_tuple>::result_type cons_key_tuple; BOOST_STATIC_ASSERT( static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)== std::tuple_size<key_tuple>::value); return detail::equal_ckey_cval< key_extractor_tuple,value_type, cons_key_tuple,detail::generic_operator_equal_tuple >::compare( x.composite_key.key_extractors(),x.value, detail::make_cons_stdtuple(y),detail::generic_operator_equal_tuple()); } template<typename CompositeKey,typename... Values> inline bool operator==( const std::tuple<Values...>& x, const composite_key_result<CompositeKey>& y) { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef std::tuple<Values...> key_tuple; typedef typename detail::cons_stdtuple_ctor< key_tuple>::result_type cons_key_tuple; BOOST_STATIC_ASSERT( static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)== std::tuple_size<key_tuple>::value); return detail::equal_ckey_cval< key_extractor_tuple,value_type, cons_key_tuple,detail::generic_operator_equal_tuple >::compare( detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), y.value,detail::generic_operator_equal_tuple()); } #endif /* < */ template<typename CompositeKey1,typename CompositeKey2> inline bool operator<( const composite_key_result<CompositeKey1>& x, const composite_key_result<CompositeKey2>& y) { typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; typedef typename CompositeKey1::value_type value_type1; typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; typedef typename CompositeKey2::value_type value_type2; return detail::compare_ckey_ckey< key_extractor_tuple1,value_type1, key_extractor_tuple2,value_type2, detail::generic_operator_less_tuple >::compare( x.composite_key.key_extractors(),x.value, y.composite_key.key_extractors(),y.value, detail::generic_operator_less_tuple()); } template < typename CompositeKey, BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) > inline bool operator<( const composite_key_result<CompositeKey>& x, const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y) { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple; return detail::compare_ckey_cval< key_extractor_tuple,value_type, key_tuple,detail::generic_operator_less_tuple >::compare( x.composite_key.key_extractors(),x.value, y,detail::generic_operator_less_tuple()); } template < BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), typename CompositeKey > inline bool operator<( const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x, const composite_key_result<CompositeKey>& y) { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple; return detail::compare_ckey_cval< key_extractor_tuple,value_type, key_tuple,detail::generic_operator_less_tuple >::compare( x,y.composite_key.key_extractors(), y.value,detail::generic_operator_less_tuple()); } #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template<typename CompositeKey,typename... Values> inline bool operator<( const composite_key_result<CompositeKey>& x, const std::tuple<Values...>& y) { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef std::tuple<Values...> key_tuple; typedef typename detail::cons_stdtuple_ctor< key_tuple>::result_type cons_key_tuple; return detail::compare_ckey_cval< key_extractor_tuple,value_type, cons_key_tuple,detail::generic_operator_less_tuple >::compare( x.composite_key.key_extractors(),x.value, detail::make_cons_stdtuple(y),detail::generic_operator_less_tuple()); } template<typename CompositeKey,typename... Values> inline bool operator<( const std::tuple<Values...>& x, const composite_key_result<CompositeKey>& y) { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef std::tuple<Values...> key_tuple; typedef typename detail::cons_stdtuple_ctor< key_tuple>::result_type cons_key_tuple; return detail::compare_ckey_cval< key_extractor_tuple,value_type, cons_key_tuple,detail::generic_operator_less_tuple >::compare( detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), y.value,detail::generic_operator_less_tuple()); } #endif /* rest of comparison operators */ #define BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(t1,t2,a1,a2) \ template<t1,t2> inline bool operator!=(const a1& x,const a2& y) \ { \ return !(x==y); \ } \ \ template<t1,t2> inline bool operator>(const a1& x,const a2& y) \ { \ return y<x; \ } \ \ template<t1,t2> inline bool operator>=(const a1& x,const a2& y) \ { \ return !(x<y); \ } \ \ template<t1,t2> inline bool operator<=(const a1& x,const a2& y) \ { \ return !(y<x); \ } BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( typename CompositeKey1, typename CompositeKey2, composite_key_result<CompositeKey1>, composite_key_result<CompositeKey2> ) BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( typename CompositeKey, BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), composite_key_result<CompositeKey>, tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> ) BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), typename CompositeKey, tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>, composite_key_result<CompositeKey> ) #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( typename CompositeKey, typename... Values, composite_key_result<CompositeKey>, std::tuple<Values...> ) BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( typename CompositeKey, typename... Values, std::tuple<Values...>, composite_key_result<CompositeKey> ) #endif /* composite_key_equal_to */ template < BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred) > struct composite_key_equal_to: private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)> { private: typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)> super; public: typedef super key_eq_tuple; composite_key_equal_to( BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Pred)): super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) {} composite_key_equal_to(const key_eq_tuple& x):super(x){} const key_eq_tuple& key_eqs()const{return *this;} key_eq_tuple& key_eqs(){return *this;} template<typename CompositeKey1,typename CompositeKey2> bool operator()( const composite_key_result<CompositeKey1> & x, const composite_key_result<CompositeKey2> & y)const { typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; typedef typename CompositeKey1::value_type value_type1; typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; typedef typename CompositeKey2::value_type value_type2; BOOST_STATIC_ASSERT( tuples::length<key_extractor_tuple1>::value<= tuples::length<key_eq_tuple>::value&& tuples::length<key_extractor_tuple1>::value== tuples::length<key_extractor_tuple2>::value); return detail::equal_ckey_ckey< key_extractor_tuple1,value_type1, key_extractor_tuple2,value_type2, key_eq_tuple >::compare( x.composite_key.key_extractors(),x.value, y.composite_key.key_extractors(),y.value, key_eqs()); } template < typename CompositeKey, BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) > bool operator()( const composite_key_result<CompositeKey>& x, const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple; BOOST_STATIC_ASSERT( tuples::length<key_extractor_tuple>::value<= tuples::length<key_eq_tuple>::value&& tuples::length<key_extractor_tuple>::value== tuples::length<key_tuple>::value); return detail::equal_ckey_cval< key_extractor_tuple,value_type, key_tuple,key_eq_tuple >::compare(x.composite_key.key_extractors(),x.value,y,key_eqs()); } template < BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), typename CompositeKey > bool operator()( const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x, const composite_key_result<CompositeKey>& y)const { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple; BOOST_STATIC_ASSERT( tuples::length<key_tuple>::value<= tuples::length<key_eq_tuple>::value&& tuples::length<key_tuple>::value== tuples::length<key_extractor_tuple>::value); return detail::equal_ckey_cval< key_extractor_tuple,value_type, key_tuple,key_eq_tuple >::compare(x,y.composite_key.key_extractors(),y.value,key_eqs()); } #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template<typename CompositeKey,typename... Values> bool operator()( const composite_key_result<CompositeKey>& x, const std::tuple<Values...>& y)const { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef std::tuple<Values...> key_tuple; typedef typename detail::cons_stdtuple_ctor< key_tuple>::result_type cons_key_tuple; BOOST_STATIC_ASSERT( tuples::length<key_extractor_tuple>::value<= tuples::length<key_eq_tuple>::value&& static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)== std::tuple_size<key_tuple>::value); return detail::equal_ckey_cval< key_extractor_tuple,value_type, cons_key_tuple,key_eq_tuple >::compare( x.composite_key.key_extractors(),x.value, detail::make_cons_stdtuple(y),key_eqs()); } template<typename CompositeKey,typename... Values> bool operator()( const std::tuple<Values...>& x, const composite_key_result<CompositeKey>& y)const { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef std::tuple<Values...> key_tuple; typedef typename detail::cons_stdtuple_ctor< key_tuple>::result_type cons_key_tuple; BOOST_STATIC_ASSERT( std::tuple_size<key_tuple>::value<= static_cast<std::size_t>(tuples::length<key_eq_tuple>::value)&& std::tuple_size<key_tuple>::value== static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)); return detail::equal_ckey_cval< key_extractor_tuple,value_type, cons_key_tuple,key_eq_tuple >::compare( detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), y.value,key_eqs()); } #endif }; /* composite_key_compare */ template < BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Compare) > struct composite_key_compare: private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)> { private: typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)> super; public: typedef super key_comp_tuple; composite_key_compare( BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Compare)): super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) {} composite_key_compare(const key_comp_tuple& x):super(x){} const key_comp_tuple& key_comps()const{return *this;} key_comp_tuple& key_comps(){return *this;} template<typename CompositeKey1,typename CompositeKey2> bool operator()( const composite_key_result<CompositeKey1> & x, const composite_key_result<CompositeKey2> & y)const { typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; typedef typename CompositeKey1::value_type value_type1; typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; typedef typename CompositeKey2::value_type value_type2; BOOST_STATIC_ASSERT( tuples::length<key_extractor_tuple1>::value<= tuples::length<key_comp_tuple>::value|| tuples::length<key_extractor_tuple2>::value<= tuples::length<key_comp_tuple>::value); return detail::compare_ckey_ckey< key_extractor_tuple1,value_type1, key_extractor_tuple2,value_type2, key_comp_tuple >::compare( x.composite_key.key_extractors(),x.value, y.composite_key.key_extractors(),y.value, key_comps()); } #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) template<typename CompositeKey,typename Value> bool operator()( const composite_key_result<CompositeKey>& x, const Value& y)const { return operator()(x,boost::make_tuple(boost::cref(y))); } #endif template < typename CompositeKey, BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) > bool operator()( const composite_key_result<CompositeKey>& x, const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple; BOOST_STATIC_ASSERT( tuples::length<key_extractor_tuple>::value<= tuples::length<key_comp_tuple>::value|| tuples::length<key_tuple>::value<= tuples::length<key_comp_tuple>::value); return detail::compare_ckey_cval< key_extractor_tuple,value_type, key_tuple,key_comp_tuple >::compare(x.composite_key.key_extractors(),x.value,y,key_comps()); } #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) template<typename Value,typename CompositeKey> bool operator()( const Value& x, const composite_key_result<CompositeKey>& y)const { return operator()(boost::make_tuple(boost::cref(x)),y); } #endif template < BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), typename CompositeKey > bool operator()( const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x, const composite_key_result<CompositeKey>& y)const { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple; BOOST_STATIC_ASSERT( tuples::length<key_tuple>::value<= tuples::length<key_comp_tuple>::value|| tuples::length<key_extractor_tuple>::value<= tuples::length<key_comp_tuple>::value); return detail::compare_ckey_cval< key_extractor_tuple,value_type, key_tuple,key_comp_tuple >::compare(x,y.composite_key.key_extractors(),y.value,key_comps()); } #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template<typename CompositeKey,typename... Values> bool operator()( const composite_key_result<CompositeKey>& x, const std::tuple<Values...>& y)const { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef std::tuple<Values...> key_tuple; typedef typename detail::cons_stdtuple_ctor< key_tuple>::result_type cons_key_tuple; BOOST_STATIC_ASSERT( tuples::length<key_extractor_tuple>::value<= tuples::length<key_comp_tuple>::value|| std::tuple_size<key_tuple>::value<= static_cast<std::size_t>(tuples::length<key_comp_tuple>::value)); return detail::compare_ckey_cval< key_extractor_tuple,value_type, cons_key_tuple,key_comp_tuple >::compare( x.composite_key.key_extractors(),x.value, detail::make_cons_stdtuple(y),key_comps()); } template<typename CompositeKey,typename... Values> bool operator()( const std::tuple<Values...>& x, const composite_key_result<CompositeKey>& y)const { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; typedef std::tuple<Values...> key_tuple; typedef typename detail::cons_stdtuple_ctor< key_tuple>::result_type cons_key_tuple; BOOST_STATIC_ASSERT( std::tuple_size<key_tuple>::value<= static_cast<std::size_t>(tuples::length<key_comp_tuple>::value)|| tuples::length<key_extractor_tuple>::value<= tuples::length<key_comp_tuple>::value); return detail::compare_ckey_cval< key_extractor_tuple,value_type, cons_key_tuple,key_comp_tuple >::compare( detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), y.value,key_comps()); } #endif }; /* composite_key_hash */ template < BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Hash) > struct composite_key_hash: private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)> { private: typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)> super; public: typedef super key_hasher_tuple; composite_key_hash( BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Hash)): super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) {} composite_key_hash(const key_hasher_tuple& x):super(x){} const key_hasher_tuple& key_hash_functions()const{return *this;} key_hasher_tuple& key_hash_functions(){return *this;} template<typename CompositeKey> std::size_t operator()(const composite_key_result<CompositeKey> & x)const { typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; typedef typename CompositeKey::value_type value_type; BOOST_STATIC_ASSERT( tuples::length<key_extractor_tuple>::value== tuples::length<key_hasher_tuple>::value); return detail::hash_ckey< key_extractor_tuple,value_type, key_hasher_tuple >::hash(x.composite_key.key_extractors(),x.value,key_hash_functions()); } template<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)> std::size_t operator()( const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x)const { typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple; BOOST_STATIC_ASSERT( tuples::length<key_tuple>::value== tuples::length<key_hasher_tuple>::value); return detail::hash_cval< key_tuple,key_hasher_tuple >::hash(x,key_hash_functions()); } #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template<typename... Values> std::size_t operator()(const std::tuple<Values...>& x)const { typedef std::tuple<Values...> key_tuple; typedef typename detail::cons_stdtuple_ctor< key_tuple>::result_type cons_key_tuple; BOOST_STATIC_ASSERT( std::tuple_size<key_tuple>::value== static_cast<std::size_t>(tuples::length<key_hasher_tuple>::value)); return detail::hash_cval< cons_key_tuple,key_hasher_tuple >::hash(detail::make_cons_stdtuple(x),key_hash_functions()); } #endif }; /* Instantiations of the former functors with "natural" basic components: * composite_key_result_equal_to uses std::equal_to of the values. * composite_key_result_less uses std::less. * composite_key_result_greater uses std::greater. * composite_key_result_hash uses boost::hash. */ #define BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER \ composite_key_equal_to< \ BOOST_MULTI_INDEX_CK_ENUM( \ BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ /* the argument is a PP list */ \ (detail::nth_composite_key_equal_to, \ (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ BOOST_PP_NIL))) \ > template<typename CompositeKeyResult> struct composite_key_result_equal_to: BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER { private: typedef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER super; public: typedef CompositeKeyResult first_argument_type; typedef first_argument_type second_argument_type; typedef bool result_type; using super::operator(); }; #define BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER \ composite_key_compare< \ BOOST_MULTI_INDEX_CK_ENUM( \ BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ /* the argument is a PP list */ \ (detail::nth_composite_key_less, \ (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ BOOST_PP_NIL))) \ > template<typename CompositeKeyResult> struct composite_key_result_less: BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER { private: typedef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER super; public: typedef CompositeKeyResult first_argument_type; typedef first_argument_type second_argument_type; typedef bool result_type; using super::operator(); }; #define BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER \ composite_key_compare< \ BOOST_MULTI_INDEX_CK_ENUM( \ BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ /* the argument is a PP list */ \ (detail::nth_composite_key_greater, \ (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ BOOST_PP_NIL))) \ > template<typename CompositeKeyResult> struct composite_key_result_greater: BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER { private: typedef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER super; public: typedef CompositeKeyResult first_argument_type; typedef first_argument_type second_argument_type; typedef bool result_type; using super::operator(); }; #define BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER \ composite_key_hash< \ BOOST_MULTI_INDEX_CK_ENUM( \ BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ /* the argument is a PP list */ \ (detail::nth_composite_key_hash, \ (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ BOOST_PP_NIL))) \ > template<typename CompositeKeyResult> struct composite_key_result_hash: BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER { private: typedef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER super; public: typedef CompositeKeyResult argument_type; typedef std::size_t result_type; using super::operator(); }; } /* namespace multi_index */ } /* namespace boost */ /* Specializations of std::equal_to, std::less, std::greater and boost::hash * for composite_key_results enabling interoperation with tuples of values. */ namespace std{ template<typename CompositeKey> struct equal_to<boost::multi_index::composite_key_result<CompositeKey> >: boost::multi_index::composite_key_result_equal_to< boost::multi_index::composite_key_result<CompositeKey> > { }; template<typename CompositeKey> struct less<boost::multi_index::composite_key_result<CompositeKey> >: boost::multi_index::composite_key_result_less< boost::multi_index::composite_key_result<CompositeKey> > { }; template<typename CompositeKey> struct greater<boost::multi_index::composite_key_result<CompositeKey> >: boost::multi_index::composite_key_result_greater< boost::multi_index::composite_key_result<CompositeKey> > { }; } /* namespace std */ namespace boost{ template<typename CompositeKey> struct hash<boost::multi_index::composite_key_result<CompositeKey> >: boost::multi_index::composite_key_result_hash< boost::multi_index::composite_key_result<CompositeKey> > { }; } /* namespace boost */ #undef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER #undef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER #undef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER #undef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER #undef BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS #undef BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO #undef BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR #undef BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N #undef BOOST_MULTI_INDEX_CK_CTOR_ARG #undef BOOST_MULTI_INDEX_CK_TEMPLATE_PARM #undef BOOST_MULTI_INDEX_CK_ENUM_PARAMS #undef BOOST_MULTI_INDEX_CK_ENUM #undef BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE #endif PK 3L�[=6 u u ordered_index.hppnu �[��� /* Copyright 2003-2015 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_HPP #define BOOST_MULTI_INDEX_ORDERED_INDEX_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/multi_index/detail/ord_index_impl.hpp> #include <boost/multi_index/ordered_index_fwd.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* no augment policy for plain ordered indices */ struct null_augment_policy { template<typename OrderedIndexImpl> struct augmented_interface { typedef OrderedIndexImpl type; }; template<typename OrderedIndexNodeImpl> struct augmented_node { typedef OrderedIndexNodeImpl type; }; template<typename Pointer> static void add(Pointer,Pointer){} template<typename Pointer> static void remove(Pointer,Pointer){} template<typename Pointer> static void copy(Pointer,Pointer){} template<typename Pointer> static void rotate_left(Pointer,Pointer){} template<typename Pointer> static void rotate_right(Pointer,Pointer){} #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) /* invariant stuff */ template<typename Pointer> static bool invariant(Pointer){return true;} #endif }; } /* namespace multi_index::detail */ /* ordered_index specifiers */ template<typename Arg1,typename Arg2,typename Arg3> struct ordered_unique { typedef typename detail::ordered_index_args< Arg1,Arg2,Arg3> index_args; typedef typename index_args::tag_list_type::type tag_list_type; typedef typename index_args::key_from_value_type key_from_value_type; typedef typename index_args::compare_type compare_type; template<typename Super> struct node_class { typedef detail::ordered_index_node<detail::null_augment_policy,Super> type; }; template<typename SuperMeta> struct index_class { typedef detail::ordered_index< key_from_value_type,compare_type, SuperMeta,tag_list_type,detail::ordered_unique_tag, detail::null_augment_policy> type; }; }; template<typename Arg1,typename Arg2,typename Arg3> struct ordered_non_unique { typedef detail::ordered_index_args< Arg1,Arg2,Arg3> index_args; typedef typename index_args::tag_list_type::type tag_list_type; typedef typename index_args::key_from_value_type key_from_value_type; typedef typename index_args::compare_type compare_type; template<typename Super> struct node_class { typedef detail::ordered_index_node<detail::null_augment_policy,Super> type; }; template<typename SuperMeta> struct index_class { typedef detail::ordered_index< key_from_value_type,compare_type, SuperMeta,tag_list_type,detail::ordered_non_unique_tag, detail::null_augment_policy> type; }; }; } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[� ��~ �~ sequenced_index.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP #define BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/bind/bind.hpp> #include <boost/call_traits.hpp> #include <boost/core/addressof.hpp> #include <boost/core/no_exceptions_support.hpp> #include <boost/detail/workaround.hpp> #include <boost/foreach_fwd.hpp> #include <boost/iterator/reverse_iterator.hpp> #include <boost/move/core.hpp> #include <boost/move/utility_core.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/not.hpp> #include <boost/mpl/push_front.hpp> #include <boost/multi_index/detail/access_specifier.hpp> #include <boost/multi_index/detail/allocator_traits.hpp> #include <boost/multi_index/detail/bidir_node_iterator.hpp> #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp> #include <boost/multi_index/detail/index_node_base.hpp> #include <boost/multi_index/detail/node_handle.hpp> #include <boost/multi_index/detail/safe_mode.hpp> #include <boost/multi_index/detail/scope_guard.hpp> #include <boost/multi_index/detail/seq_index_node.hpp> #include <boost/multi_index/detail/seq_index_ops.hpp> #include <boost/multi_index/detail/vartempl_support.hpp> #include <boost/multi_index/sequenced_index_fwd.hpp> #include <boost/tuple/tuple.hpp> #include <boost/type_traits/is_integral.hpp> #include <functional> #include <utility> #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include<initializer_list> #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ detail::make_obj_guard(x,&sequenced_index::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch(); #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(*this) #else #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT #endif namespace boost{ namespace multi_index{ namespace detail{ /* sequenced_index adds a layer of sequenced indexing to a given Super */ template<typename SuperMeta,typename TagList> class sequenced_index: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) ,public safe_mode::safe_container< sequenced_index<SuperMeta,TagList> > #endif { #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ BOOST_WORKAROUND(__MWERKS__,<=0x3003) /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the * lifetime of const references bound to temporaries --precisely what * scopeguards are. */ #pragma parse_mfunc_templ off #endif typedef typename SuperMeta::type super; protected: typedef sequenced_index_node< typename super::index_node_type> index_node_type; private: typedef typename index_node_type::impl_type node_impl_type; public: /* types */ typedef typename index_node_type::value_type value_type; typedef tuples::null_type ctor_args; typedef typename super::final_allocator_type allocator_type; typedef value_type& reference; typedef const value_type& const_reference; #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) typedef safe_mode::safe_iterator< bidir_node_iterator<index_node_type>, sequenced_index> iterator; #else typedef bidir_node_iterator<index_node_type> iterator; #endif typedef iterator const_iterator; private: typedef allocator_traits<allocator_type> alloc_traits; public: typedef typename alloc_traits::pointer pointer; typedef typename alloc_traits::const_pointer const_pointer; typedef typename alloc_traits::size_type size_type; typedef typename alloc_traits::difference_type difference_type; typedef typename boost::reverse_iterator<iterator> reverse_iterator; typedef typename boost::reverse_iterator<const_iterator> const_reverse_iterator; typedef typename super::final_node_handle_type node_type; typedef detail::insert_return_type< iterator,node_type> insert_return_type; typedef TagList tag_list; protected: typedef typename super::final_node_type final_node_type; typedef tuples::cons< ctor_args, typename super::ctor_args_list> ctor_args_list; typedef typename mpl::push_front< typename super::index_type_list, sequenced_index>::type index_type_list; typedef typename mpl::push_front< typename super::iterator_type_list, iterator>::type iterator_type_list; typedef typename mpl::push_front< typename super::const_iterator_type_list, const_iterator>::type const_iterator_type_list; typedef typename super::copy_map_type copy_map_type; #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) typedef typename super::index_saver_type index_saver_type; typedef typename super::index_loader_type index_loader_type; #endif private: #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) typedef safe_mode::safe_container< sequenced_index> safe_super; #endif typedef typename call_traits<value_type>::param_type value_param_type; /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL * expansion. */ typedef std::pair<iterator,bool> emplace_return_type; public: /* construct/copy/destroy * Default and copy ctors are in the protected section as indices are * not supposed to be created on their own. No range ctor either. */ sequenced_index<SuperMeta,TagList>& operator=( const sequenced_index<SuperMeta,TagList>& x) { this->final()=x.final(); return *this; } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) sequenced_index<SuperMeta,TagList>& operator=( std::initializer_list<value_type> list) { this->final()=list; return *this; } #endif template <class InputIterator> void assign(InputIterator first,InputIterator last) { assign_iter(first,last,mpl::not_<is_integral<InputIterator> >()); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) void assign(std::initializer_list<value_type> list) { assign(list.begin(),list.end()); } #endif void assign(size_type n,value_param_type value) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; clear(); for(size_type i=0;i<n;++i)push_back(value); } allocator_type get_allocator()const BOOST_NOEXCEPT { return this->final().get_allocator(); } /* iterators */ iterator begin()BOOST_NOEXCEPT {return make_iterator(index_node_type::from_impl(header()->next()));} const_iterator begin()const BOOST_NOEXCEPT {return make_iterator(index_node_type::from_impl(header()->next()));} iterator end()BOOST_NOEXCEPT{return make_iterator(header());} const_iterator end()const BOOST_NOEXCEPT{return make_iterator(header());} reverse_iterator rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} const_reverse_iterator rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} reverse_iterator rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} const_reverse_iterator rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} const_iterator cbegin()const BOOST_NOEXCEPT{return begin();} const_iterator cend()const BOOST_NOEXCEPT{return end();} const_reverse_iterator crbegin()const BOOST_NOEXCEPT{return rbegin();} const_reverse_iterator crend()const BOOST_NOEXCEPT{return rend();} iterator iterator_to(const value_type& x) { return make_iterator( node_from_value<index_node_type>(boost::addressof(x))); } const_iterator iterator_to(const value_type& x)const { return make_iterator( node_from_value<index_node_type>(boost::addressof(x))); } /* capacity */ bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} size_type size()const BOOST_NOEXCEPT{return this->final_size_();} size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} void resize(size_type n) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; if(n>size()){ for(size_type m=n-size();m--;) this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); } else if(n<size()){for(size_type m=size()-n;m--;)pop_back();} } void resize(size_type n,value_param_type x) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; if(n>size())insert(end(),static_cast<size_type>(n-size()),x); else if(n<size())for(size_type m=size()-n;m--;)pop_back(); } /* access: no non-const versions provided as sequenced_index * handles const elements. */ const_reference front()const{return *begin();} const_reference back()const{return *--end();} /* modifiers */ BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( emplace_return_type,emplace_front,emplace_front_impl) std::pair<iterator,bool> push_front(const value_type& x) {return insert(begin(),x);} std::pair<iterator,bool> push_front(BOOST_RV_REF(value_type) x) {return insert(begin(),boost::move(x));} void pop_front(){erase(begin());} BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( emplace_return_type,emplace_back,emplace_back_impl) std::pair<iterator,bool> push_back(const value_type& x) {return insert(end(),x);} std::pair<iterator,bool> push_back(BOOST_RV_REF(value_type) x) {return insert(end(),boost::move(x));} void pop_back(){erase(--end());} BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( emplace_return_type,emplace,emplace_impl,iterator,position) std::pair<iterator,bool> insert(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_(x); if(p.second&&position.get_node()!=header()){ relink(position.get_node(),p.first); } return std::pair<iterator,bool>(make_iterator(p.first),p.second); } std::pair<iterator,bool> insert(iterator position,BOOST_RV_REF(value_type) x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_rv_(x); if(p.second&&position.get_node()!=header()){ relink(position.get_node(),p.first); } return std::pair<iterator,bool>(make_iterator(p.first),p.second); } void insert(iterator position,size_type n,value_param_type x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; for(size_type i=0;i<n;++i)insert(position,x); } template<typename InputIterator> void insert(iterator position,InputIterator first,InputIterator last) { insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >()); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) void insert(iterator position,std::initializer_list<value_type> list) { insert(position,list.begin(),list.end()); } #endif insert_return_type insert(const_iterator position,BOOST_RV_REF(node_type) nh) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh); if(p.second&&position.get_node()!=header()){ relink(position.get_node(),p.first); } return insert_return_type(make_iterator(p.first),p.second,boost::move(nh)); } node_type extract(const_iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; return this->final_extract_( static_cast<final_node_type*>(position.get_node())); } iterator erase(iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; this->final_erase_(static_cast<final_node_type*>(position++.get_node())); return position; } iterator erase(iterator first,iterator last) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; while(first!=last){ first=erase(first); } return first; } bool replace(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; return this->final_replace_( x,static_cast<final_node_type*>(position.get_node())); } bool replace(iterator position,BOOST_RV_REF(value_type) x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; return this->final_replace_rv_( x,static_cast<final_node_type*>(position.get_node())); } template<typename Modifier> bool modify(iterator position,Modifier mod) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) /* MSVC++ 6.0 optimizer on safe mode code chokes if this * this is not added. Left it for all compilers as it does no * harm. */ position.detach(); #endif return this->final_modify_( mod,static_cast<final_node_type*>(position.get_node())); } template<typename Modifier,typename Rollback> bool modify(iterator position,Modifier mod,Rollback back_) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) /* MSVC++ 6.0 optimizer on safe mode code chokes if this * this is not added. Left it for all compilers as it does no * harm. */ position.detach(); #endif return this->final_modify_( mod,back_,static_cast<final_node_type*>(position.get_node())); } void swap(sequenced_index<SuperMeta,TagList>& x) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x); this->final_swap_(x.final()); } void clear()BOOST_NOEXCEPT { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; this->final_clear_(); } /* list operations */ void splice(iterator position,sequenced_index<SuperMeta,TagList>& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; iterator first=x.begin(),last=x.end(); while(first!=last){ if(insert(position,*first).second)first=x.erase(first); else ++first; } } void splice(iterator position,sequenced_index<SuperMeta,TagList>& x,iterator i) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; if(&x==this){ if(position!=i)relink(position.get_node(),i.get_node()); } else{ if(insert(position,*i).second){ #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following * workaround is needed. Left it for all compilers as it does no * harm. */ i.detach(); x.erase(x.make_iterator(i.get_node())); #else x.erase(i); #endif } } } void splice( iterator position,sequenced_index<SuperMeta,TagList>& x, iterator first,iterator last) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x); BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; if(&x==this){ BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); if(position!=last)relink( position.get_node(),first.get_node(),last.get_node()); } else{ while(first!=last){ if(insert(position,*first).second)first=x.erase(first); else ++first; } } } void remove(value_param_type value) { sequenced_index_remove( *this, ::boost::bind<bool>( std::equal_to<value_type>(),::boost::arg<1>(),value)); } template<typename Predicate> void remove_if(Predicate pred) { sequenced_index_remove(*this,pred); } void unique() { sequenced_index_unique(*this,std::equal_to<value_type>()); } template <class BinaryPredicate> void unique(BinaryPredicate binary_pred) { sequenced_index_unique(*this,binary_pred); } void merge(sequenced_index<SuperMeta,TagList>& x) { sequenced_index_merge(*this,x,std::less<value_type>()); } template <typename Compare> void merge(sequenced_index<SuperMeta,TagList>& x,Compare comp) { sequenced_index_merge(*this,x,comp); } void sort() { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; sequenced_index_sort(header(),std::less<value_type>()); } template <typename Compare> void sort(Compare comp) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; sequenced_index_sort(header(),comp); } void reverse()BOOST_NOEXCEPT { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; node_impl_type::reverse(header()->impl()); } /* rearrange operations */ void relocate(iterator position,iterator i) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; if(position!=i)relink(position.get_node(),i.get_node()); } void relocate(iterator position,iterator first,iterator last) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; if(position!=last)relink( position.get_node(),first.get_node(),last.get_node()); } template<typename InputIterator> void rearrange(InputIterator first) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; index_node_type* pos=header(); for(size_type s=size();s--;){ const value_type& v=*first++; relink(pos,node_from_value<index_node_type>(&v)); } } BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: sequenced_index(const ctor_args_list& args_list,const allocator_type& al): super(args_list.get_tail(),al) { empty_initialize(); } sequenced_index(const sequenced_index<SuperMeta,TagList>& x): super(x) #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) ,safe_super() #endif { /* the actual copying takes place in subsequent call to copy_() */ } sequenced_index( const sequenced_index<SuperMeta,TagList>& x,do_not_copy_elements_tag): super(x,do_not_copy_elements_tag()) #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) ,safe_super() #endif { empty_initialize(); } ~sequenced_index() { /* the container is guaranteed to be empty by now */ } #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) iterator make_iterator(index_node_type* node) {return iterator(node,this);} const_iterator make_iterator(index_node_type* node)const {return const_iterator(node,const_cast<sequenced_index*>(this));} #else iterator make_iterator(index_node_type* node){return iterator(node);} const_iterator make_iterator(index_node_type* node)const {return const_iterator(node);} #endif void copy_( const sequenced_index<SuperMeta,TagList>& x,const copy_map_type& map) { index_node_type* org=x.header(); index_node_type* cpy=header(); do{ index_node_type* next_org=index_node_type::from_impl(org->next()); index_node_type* next_cpy=map.find( static_cast<final_node_type*>(next_org)); cpy->next()=next_cpy->impl(); next_cpy->prior()=cpy->impl(); org=next_org; cpy=next_cpy; }while(org!=x.header()); super::copy_(x,map); } template<typename Variant> final_node_type* insert_( value_param_type v,final_node_type*& x,Variant variant) { final_node_type* res=super::insert_(v,x,variant); if(res==x)link(static_cast<index_node_type*>(x)); return res; } template<typename Variant> final_node_type* insert_( value_param_type v,index_node_type* position, final_node_type*& x,Variant variant) { final_node_type* res=super::insert_(v,position,x,variant); if(res==x)link(static_cast<index_node_type*>(x)); return res; } void extract_(index_node_type* x) { unlink(x); super::extract_(x); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) detach_iterators(x); #endif } void delete_all_nodes_() { for(index_node_type* x=index_node_type::from_impl(header()->next()); x!=header();){ index_node_type* y=index_node_type::from_impl(x->next()); this->final_delete_node_(static_cast<final_node_type*>(x)); x=y; } } void clear_() { super::clear_(); empty_initialize(); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super::detach_dereferenceable_iterators(); #endif } template<typename BoolConstant> void swap_( sequenced_index<SuperMeta,TagList>& x,BoolConstant swap_allocators) { #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super::swap(x); #endif super::swap_(x,swap_allocators); } void swap_elements_(sequenced_index<SuperMeta,TagList>& x) { #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super::swap(x); #endif super::swap_elements_(x); } template<typename Variant> bool replace_(value_param_type v,index_node_type* x,Variant variant) { return super::replace_(v,x,variant); } bool modify_(index_node_type* x) { BOOST_TRY{ if(!super::modify_(x)){ unlink(x); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) detach_iterators(x); #endif return false; } else return true; } BOOST_CATCH(...){ unlink(x); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) detach_iterators(x); #endif BOOST_RETHROW; } BOOST_CATCH_END } bool modify_rollback_(index_node_type* x) { return super::modify_rollback_(x); } bool check_rollback_(index_node_type* x)const { return super::check_rollback_(x); } #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) /* serialization */ template<typename Archive> void save_( Archive& ar,const unsigned int version,const index_saver_type& sm)const { sm.save(begin(),end(),ar,version); super::save_(ar,version,sm); } template<typename Archive> void load_( Archive& ar,const unsigned int version,const index_loader_type& lm) { lm.load( ::boost::bind( &sequenced_index::rearranger,this,::boost::arg<1>(),::boost::arg<2>()), ar,version); super::load_(ar,version,lm); } #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) /* invariant stuff */ bool invariant_()const { if(size()==0||begin()==end()){ if(size()!=0||begin()!=end()|| header()->next()!=header()->impl()|| header()->prior()!=header()->impl())return false; } else{ size_type s=0; for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s){ if(it.get_node()->next()->prior()!=it.get_node()->impl())return false; if(it.get_node()->prior()->next()!=it.get_node()->impl())return false; } if(s!=size())return false; } return super::invariant_(); } /* This forwarding function eases things for the boost::mem_fn construct * in BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT. Actually, * final_check_invariant is already an inherited member function of index. */ void check_invariant_()const{this->final_check_invariant_();} #endif private: index_node_type* header()const{return this->final_header();} void empty_initialize() { header()->prior()=header()->next()=header()->impl(); } void link(index_node_type* x) { node_impl_type::link(x->impl(),header()->impl()); } static void unlink(index_node_type* x) { node_impl_type::unlink(x->impl()); } static void relink(index_node_type* position,index_node_type* x) { node_impl_type::relink(position->impl(),x->impl()); } static void relink( index_node_type* position,index_node_type* first,index_node_type* last) { node_impl_type::relink( position->impl(),first->impl(),last->impl()); } #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) void rearranger(index_node_type* position,index_node_type *x) { if(!position)position=header(); index_node_type::increment(position); if(position!=x)relink(position,x); } #endif #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) void detach_iterators(index_node_type* x) { iterator it=make_iterator(x); safe_mode::detach_equivalent_iterators(it); } #endif template <class InputIterator> void assign_iter(InputIterator first,InputIterator last,mpl::true_) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; clear(); for(;first!=last;++first)this->final_insert_ref_(*first); } void assign_iter(size_type n,value_param_type value,mpl::false_) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; clear(); for(size_type i=0;i<n;++i)push_back(value); } template<typename InputIterator> void insert_iter( iterator position,InputIterator first,InputIterator last,mpl::true_) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; for(;first!=last;++first){ std::pair<final_node_type*,bool> p= this->final_insert_ref_(*first); if(p.second&&position.get_node()!=header()){ relink(position.get_node(),p.first); } } } void insert_iter( iterator position,size_type n,value_param_type x,mpl::false_) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; for(size_type i=0;i<n;++i)insert(position,x); } template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> std::pair<iterator,bool> emplace_front_impl( BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) { return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); } template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> std::pair<iterator,bool> emplace_back_impl( BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) { return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); } template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> std::pair<iterator,bool> emplace_impl( iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p= this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); if(p.second&&position.get_node()!=header()){ relink(position.get_node(),p.first); } return std::pair<iterator,bool>(make_iterator(p.first),p.second); } #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ BOOST_WORKAROUND(__MWERKS__,<=0x3003) #pragma parse_mfunc_templ reset #endif }; /* comparison */ template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator==( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y) { return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); } template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator<( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y) { return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); } template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator!=( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y) { return !(x==y); } template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator>( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y) { return y<x; } template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator>=( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y) { return !(x<y); } template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator<=( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y) { return !(x>y); } /* specialized algorithms */ template<typename SuperMeta,typename TagList> void swap( sequenced_index<SuperMeta,TagList>& x, sequenced_index<SuperMeta,TagList>& y) { x.swap(y); } } /* namespace multi_index::detail */ /* sequenced index specifier */ template <typename TagList> struct sequenced { BOOST_STATIC_ASSERT(detail::is_tag<TagList>::value); template<typename Super> struct node_class { typedef detail::sequenced_index_node<Super> type; }; template<typename SuperMeta> struct index_class { typedef detail::sequenced_index<SuperMeta,typename TagList::type> type; }; }; } /* namespace multi_index */ } /* namespace boost */ /* Boost.Foreach compatibility */ template<typename SuperMeta,typename TagList> inline boost::mpl::true_* boost_foreach_is_noncopyable( boost::multi_index::detail::sequenced_index<SuperMeta,TagList>*&, boost_foreach_argument_dependent_lookup_hack) { return 0; } #undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT #undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF #endif PK 3L�[Ea7� � identity.hppnu �[��� /* Copyright 2003-2015 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_IDENTITY_HPP #define BOOST_MULTI_INDEX_IDENTITY_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> #include <boost/detail/workaround.hpp> #include <boost/mpl/if.hpp> #include <boost/multi_index/identity_fwd.hpp> #include <boost/type_traits/is_const.hpp> #include <boost/type_traits/remove_const.hpp> #include <boost/utility/enable_if.hpp> #if !defined(BOOST_NO_SFINAE) #include <boost/type_traits/is_convertible.hpp> #endif namespace boost{ template<class Type> class reference_wrapper; /* fwd decl. */ namespace multi_index{ namespace detail{ /* identity is a do-nothing key extractor that returns the [const] Type& * object passed. * Additionally, identity is overloaded to support referece_wrappers * of Type and "chained pointers" to Type's. By chained pointer to Type we * mean a type P such that, given a p of type P * *...n...*x is convertible to Type&, for some n>=1. * Examples of chained pointers are raw and smart pointers, iterators and * arbitrary combinations of these (vg. Type** or unique_ptr<Type*>.) */ template<typename Type> struct const_identity_base { typedef Type result_type; template<typename ChainedPtr> #if !defined(BOOST_NO_SFINAE) typename disable_if<is_convertible<const ChainedPtr&,Type&>,Type&>::type #else Type& #endif operator()(const ChainedPtr& x)const { return operator()(*x); } Type& operator()(Type& x)const { return x; } Type& operator()(const reference_wrapper<Type>& x)const { return x.get(); } Type& operator()( const reference_wrapper<typename remove_const<Type>::type>& x #if BOOST_WORKAROUND(BOOST_MSVC,==1310) /* http://lists.boost.org/Archives/boost/2015/10/226135.php */ ,int=0 #endif )const { return x.get(); } }; template<typename Type> struct non_const_identity_base { typedef Type result_type; /* templatized for pointer-like types */ template<typename ChainedPtr> #if !defined(BOOST_NO_SFINAE) typename disable_if< is_convertible<const ChainedPtr&,const Type&>,Type&>::type #else Type& #endif operator()(const ChainedPtr& x)const { return operator()(*x); } const Type& operator()(const Type& x)const { return x; } Type& operator()(Type& x)const { return x; } const Type& operator()(const reference_wrapper<const Type>& x)const { return x.get(); } Type& operator()(const reference_wrapper<Type>& x)const { return x.get(); } }; } /* namespace multi_index::detail */ template<class Type> struct identity: mpl::if_c< is_const<Type>::value, detail::const_identity_base<Type>,detail::non_const_identity_base<Type> >::type { }; } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�( ( identity_fwd.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_IDENTITY_FWD_HPP #define BOOST_MULTI_INDEX_IDENTITY_FWD_HPP #if defined(_MSC_VER) #pragma once #endif namespace boost{ namespace multi_index{ template<class Type> struct identity; } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[3Ÿ� � random_access_index_fwd.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_FWD_HPP #define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_FWD_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/multi_index/tag.hpp> namespace boost{ namespace multi_index{ namespace detail{ template<typename SuperMeta,typename TagList> class random_access_index; template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator==( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y); template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator<( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y); template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator!=( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y); template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator>( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y); template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator>=( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y); template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator<=( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y); template<typename SuperMeta,typename TagList> void swap( random_access_index<SuperMeta,TagList>& x, random_access_index<SuperMeta,TagList>& y); } /* namespace multi_index::detail */ /* index specifiers */ template <typename TagList=tag<> > struct random_access; } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[���D D key.hppnu �[��� /* Copyright 2003-2019 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_KEY_HPP #define BOOST_MULTI_INDEX_KEY_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/multi_index/composite_key.hpp> #include <boost/multi_index/global_fun.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/mem_fun.hpp> #if __cplusplus>=201703L||\ defined(BOOST_MSVC)&&defined(__cpp_nontype_template_parameter_auto) #define BOOST_MULTI_INDEX_KEY_SUPPORTED #include <boost/multi_index/detail/is_function.hpp> #include <boost/preprocessor/facilities/empty.hpp> #include <type_traits> namespace boost{ namespace multi_index{ /* C++17 terse key specification syntax */ namespace detail{ template<typename T,T,typename=void> struct typed_key_impl; template<typename Class,typename Type,Type Class::*PtrToMember> struct typed_key_impl< Type Class::*,PtrToMember, typename std::enable_if<!is_function<Type>::value>::type > { using value_type=Class; using type=member<Class,Type,PtrToMember>; }; #define BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(qualifier,extractor) \ template< \ typename Class,typename Type,Type (Class::*PtrToMemberFunction)()qualifier \ > \ struct typed_key_impl<Type (Class::*)()qualifier,PtrToMemberFunction> \ { \ using value_type=Class; \ using type=extractor<Class,Type,PtrToMemberFunction>; \ }; BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL( ,mem_fun) BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const ,const_mem_fun) BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(volatile ,volatile_mem_fun) BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const volatile ,cv_mem_fun) BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(& ,ref_mem_fun) BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const& ,cref_mem_fun) BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(volatile& ,vref_mem_fun) BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const volatile& ,cvref_mem_fun) #undef BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL template<class Value,typename Type,Type (*PtrToFunction)(Value)> struct typed_key_impl<Type (*)(Value),PtrToFunction> { using value_type=Value; using type=global_fun<Value,Type,PtrToFunction>; }; template<typename T> struct remove_noexcept{using type=T;}; #define BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(qualifier) \ template<typename R,typename C,typename... Args> \ struct remove_noexcept<R(C::*)(Args...)qualifier noexcept> \ {using type=R(C::*)(Args...)qualifier;}; \ \ template<typename R,typename C,typename... Args> \ struct remove_noexcept<R(C::*)(Args...,...)qualifier noexcept> \ {using type=R(C::*)(Args...,...)qualifier;}; BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(BOOST_PP_EMPTY()) /* VS warns without dummy arg */ BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const) BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile) BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile) BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(&) BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const&) BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile&) BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile&) BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(&&) BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const&&) BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile&&) BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile&&) #undef BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT template<typename R,typename... Args> struct remove_noexcept<R(*)(Args...)noexcept>{using type=R(*)(Args...);}; template<typename R,typename... Args> struct remove_noexcept<R(*)(Args...,...)noexcept> {using type=R(*)(Args...,...);}; template<typename T> using remove_noexcept_t=typename remove_noexcept<T>::type; template<auto... Keys> struct key_impl; template<auto Key> struct key_impl<Key>:typed_key_impl<remove_noexcept_t<decltype(Key)>,Key>{}; template<typename... Ts> struct least_generic; template<typename T0,typename... Ts> struct least_generic<T0,Ts...> { using type=T0; }; template<typename T0,typename T1,typename... Ts> struct least_generic<T0,T1,Ts...> { static_assert( std::is_convertible<const T0&,const T1&>::value|| std::is_convertible<const T1&,const T0&>::value, "one type should be convertible to the other"); using type=typename least_generic< typename std::conditional< std::is_convertible<const T0&,const T1&>::value,T0,T1 >::type, Ts... >::type; }; template<auto Key0,auto... Keys> struct key_impl<Key0,Keys...> { using value_type=typename least_generic< typename std::decay<typename key_impl<Key0>::value_type>::type, typename std::decay<typename key_impl<Keys>::value_type>::type... >::type; using type=composite_key< value_type, typename key_impl<Key0>::type, typename key_impl<Keys>::type... >; }; template<typename=composite_key<void,void>> struct composite_key_size; template<typename... Args> struct composite_key_size<composite_key<Args...>> { static constexpr auto value=sizeof...(Args)-1; }; template<auto... Keys> struct limited_size_key_impl { static_assert( sizeof...(Keys)<=composite_key_size<>::value, "specified number of keys must meet the limits of " "boost::multi_index::composite_key"); using type=typename key_impl<Keys...>::type; }; } /* namespace multi_index::detail */ template<auto... Keys> using key=typename detail::limited_size_key_impl<Keys...>::type; } /* namespace multi_index */ } /* namespace boost */ #endif #endif PK 3L�[mK��z z sequenced_index_fwd.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_FWD_HPP #define BOOST_MULTI_INDEX_SEQUENCED_INDEX_FWD_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/multi_index/tag.hpp> namespace boost{ namespace multi_index{ namespace detail{ template<typename SuperMeta,typename TagList> class sequenced_index; template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator==( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y); template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator<( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y); template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator!=( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y); template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator>( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y); template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator>=( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y); template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator<=( const sequenced_index<SuperMeta1,TagList1>& x, const sequenced_index<SuperMeta2,TagList2>& y); template<typename SuperMeta,typename TagList> void swap( sequenced_index<SuperMeta,TagList>& x, sequenced_index<SuperMeta,TagList>& y); } /* namespace multi_index::detail */ /* index specifiers */ template <typename TagList=tag<> > struct sequenced; } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�"�f'� '� random_access_index.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP #define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/bind/bind.hpp> #include <boost/call_traits.hpp> #include <boost/core/addressof.hpp> #include <boost/core/no_exceptions_support.hpp> #include <boost/detail/workaround.hpp> #include <boost/foreach_fwd.hpp> #include <boost/iterator/reverse_iterator.hpp> #include <boost/move/core.hpp> #include <boost/move/utility_core.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/not.hpp> #include <boost/mpl/push_front.hpp> #include <boost/multi_index/detail/access_specifier.hpp> #include <boost/multi_index/detail/allocator_traits.hpp> #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp> #include <boost/multi_index/detail/index_node_base.hpp> #include <boost/multi_index/detail/node_handle.hpp> #include <boost/multi_index/detail/rnd_node_iterator.hpp> #include <boost/multi_index/detail/rnd_index_node.hpp> #include <boost/multi_index/detail/rnd_index_ops.hpp> #include <boost/multi_index/detail/rnd_index_ptr_array.hpp> #include <boost/multi_index/detail/safe_mode.hpp> #include <boost/multi_index/detail/scope_guard.hpp> #include <boost/multi_index/detail/vartempl_support.hpp> #include <boost/multi_index/random_access_index_fwd.hpp> #include <boost/throw_exception.hpp> #include <boost/tuple/tuple.hpp> #include <boost/type_traits/is_integral.hpp> #include <functional> #include <stdexcept> #include <utility> #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include<initializer_list> #endif #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include <boost/multi_index/detail/rnd_index_loader.hpp> #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) #define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ detail::make_obj_guard(x,&random_access_index::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch(); #define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \ BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(*this) #else #define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) #define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT #endif namespace boost{ namespace multi_index{ namespace detail{ /* random_access_index adds a layer of random access indexing * to a given Super */ template<typename SuperMeta,typename TagList> class random_access_index: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) ,public safe_mode::safe_container< random_access_index<SuperMeta,TagList> > #endif { #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ BOOST_WORKAROUND(__MWERKS__,<=0x3003) /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the * lifetime of const references bound to temporaries --precisely what * scopeguards are. */ #pragma parse_mfunc_templ off #endif typedef typename SuperMeta::type super; protected: typedef random_access_index_node< typename super::index_node_type> index_node_type; private: typedef typename index_node_type::impl_type node_impl_type; typedef random_access_index_ptr_array< typename super::final_allocator_type> ptr_array; typedef typename ptr_array::pointer node_impl_ptr_pointer; public: /* types */ typedef typename index_node_type::value_type value_type; typedef tuples::null_type ctor_args; typedef typename super::final_allocator_type allocator_type; typedef value_type& reference; typedef const value_type& const_reference; #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) typedef safe_mode::safe_iterator< rnd_node_iterator<index_node_type>, random_access_index> iterator; #else typedef rnd_node_iterator<index_node_type> iterator; #endif typedef iterator const_iterator; private: typedef allocator_traits<allocator_type> alloc_traits; public: typedef typename alloc_traits::pointer pointer; typedef typename alloc_traits::const_pointer const_pointer; typedef typename alloc_traits::size_type size_type; typedef typename alloc_traits::difference_type difference_type; typedef typename boost::reverse_iterator<iterator> reverse_iterator; typedef typename boost::reverse_iterator<const_iterator> const_reverse_iterator; typedef typename super::final_node_handle_type node_type; typedef detail::insert_return_type< iterator,node_type> insert_return_type; typedef TagList tag_list; protected: typedef typename super::final_node_type final_node_type; typedef tuples::cons< ctor_args, typename super::ctor_args_list> ctor_args_list; typedef typename mpl::push_front< typename super::index_type_list, random_access_index>::type index_type_list; typedef typename mpl::push_front< typename super::iterator_type_list, iterator>::type iterator_type_list; typedef typename mpl::push_front< typename super::const_iterator_type_list, const_iterator>::type const_iterator_type_list; typedef typename super::copy_map_type copy_map_type; #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) typedef typename super::index_saver_type index_saver_type; typedef typename super::index_loader_type index_loader_type; #endif private: #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) typedef safe_mode::safe_container< random_access_index> safe_super; #endif typedef typename call_traits< value_type>::param_type value_param_type; /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL * expansion. */ typedef std::pair<iterator,bool> emplace_return_type; public: /* construct/copy/destroy * Default and copy ctors are in the protected section as indices are * not supposed to be created on their own. No range ctor either. */ random_access_index<SuperMeta,TagList>& operator=( const random_access_index<SuperMeta,TagList>& x) { this->final()=x.final(); return *this; } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) random_access_index<SuperMeta,TagList>& operator=( std::initializer_list<value_type> list) { this->final()=list; return *this; } #endif template <class InputIterator> void assign(InputIterator first,InputIterator last) { assign_iter(first,last,mpl::not_<is_integral<InputIterator> >()); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) void assign(std::initializer_list<value_type> list) { assign(list.begin(),list.end()); } #endif void assign(size_type n,value_param_type value) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; clear(); for(size_type i=0;i<n;++i)push_back(value); } allocator_type get_allocator()const BOOST_NOEXCEPT { return this->final().get_allocator(); } /* iterators */ iterator begin()BOOST_NOEXCEPT {return make_iterator(index_node_type::from_impl(*ptrs.begin()));} const_iterator begin()const BOOST_NOEXCEPT {return make_iterator(index_node_type::from_impl(*ptrs.begin()));} iterator end()BOOST_NOEXCEPT{return make_iterator(header());} const_iterator end()const BOOST_NOEXCEPT{return make_iterator(header());} reverse_iterator rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} const_reverse_iterator rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} reverse_iterator rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} const_reverse_iterator rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} const_iterator cbegin()const BOOST_NOEXCEPT{return begin();} const_iterator cend()const BOOST_NOEXCEPT{return end();} const_reverse_iterator crbegin()const BOOST_NOEXCEPT{return rbegin();} const_reverse_iterator crend()const BOOST_NOEXCEPT{return rend();} iterator iterator_to(const value_type& x) { return make_iterator( node_from_value<index_node_type>(boost::addressof(x))); } const_iterator iterator_to(const value_type& x)const { return make_iterator( node_from_value<index_node_type>(boost::addressof(x))); } /* capacity */ bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} size_type size()const BOOST_NOEXCEPT{return this->final_size_();} size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} size_type capacity()const BOOST_NOEXCEPT{return ptrs.capacity();} void reserve(size_type n) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; ptrs.reserve(n); } void shrink_to_fit() { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; ptrs.shrink_to_fit(); } void resize(size_type n) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; if(n>size()) for(size_type m=n-size();m--;) this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); else if(n<size())erase(begin()+n,end()); } void resize(size_type n,value_param_type x) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; if(n>size())for(size_type m=n-size();m--;)this->final_insert_(x); else if(n<size())erase(begin()+n,end()); } /* access: no non-const versions provided as random_access_index * handles const elements. */ const_reference operator[](size_type n)const { BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(n<size(),safe_mode::out_of_bounds); return index_node_type::from_impl(*ptrs.at(n))->value(); } const_reference at(size_type n)const { if(n>=size())throw_exception(std::out_of_range("random access index")); return index_node_type::from_impl(*ptrs.at(n))->value(); } const_reference front()const{return operator[](0);} const_reference back()const{return operator[](size()-1);} /* modifiers */ BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( emplace_return_type,emplace_front,emplace_front_impl) std::pair<iterator,bool> push_front(const value_type& x) {return insert(begin(),x);} std::pair<iterator,bool> push_front(BOOST_RV_REF(value_type) x) {return insert(begin(),boost::move(x));} void pop_front(){erase(begin());} BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( emplace_return_type,emplace_back,emplace_back_impl) std::pair<iterator,bool> push_back(const value_type& x) {return insert(end(),x);} std::pair<iterator,bool> push_back(BOOST_RV_REF(value_type) x) {return insert(end(),boost::move(x));} void pop_back(){erase(--end());} BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( emplace_return_type,emplace,emplace_impl,iterator,position) std::pair<iterator,bool> insert(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_(x); if(p.second&&position.get_node()!=header()){ relocate(position.get_node(),p.first); } return std::pair<iterator,bool>(make_iterator(p.first),p.second); } std::pair<iterator,bool> insert(iterator position,BOOST_RV_REF(value_type) x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_rv_(x); if(p.second&&position.get_node()!=header()){ relocate(position.get_node(),p.first); } return std::pair<iterator,bool>(make_iterator(p.first),p.second); } void insert(iterator position,size_type n,value_param_type x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; size_type s=0; BOOST_TRY{ while(n--){ if(push_back(x).second)++s; } } BOOST_CATCH(...){ relocate(position,end()-s,end()); BOOST_RETHROW; } BOOST_CATCH_END relocate(position,end()-s,end()); } template<typename InputIterator> void insert(iterator position,InputIterator first,InputIterator last) { insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >()); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) void insert(iterator position,std::initializer_list<value_type> list) { insert(position,list.begin(),list.end()); } #endif insert_return_type insert(const_iterator position,BOOST_RV_REF(node_type) nh) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); if(nh)BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,nh); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p=this->final_insert_nh_(nh); if(p.second&&position.get_node()!=header()){ relocate(position.get_node(),p.first); } return insert_return_type(make_iterator(p.first),p.second,boost::move(nh)); } node_type extract(const_iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; return this->final_extract_( static_cast<final_node_type*>(position.get_node())); } iterator erase(iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; this->final_erase_(static_cast<final_node_type*>(position++.get_node())); return position; } iterator erase(iterator first,iterator last) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; difference_type n=static_cast<difference_type>(last-first); relocate(end(),first,last); while(n--)pop_back(); return last; } bool replace(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; return this->final_replace_( x,static_cast<final_node_type*>(position.get_node())); } bool replace(iterator position,BOOST_RV_REF(value_type) x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; return this->final_replace_rv_( x,static_cast<final_node_type*>(position.get_node())); } template<typename Modifier> bool modify(iterator position,Modifier mod) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) /* MSVC++ 6.0 optimizer on safe mode code chokes if this * this is not added. Left it for all compilers as it does no * harm. */ position.detach(); #endif return this->final_modify_( mod,static_cast<final_node_type*>(position.get_node())); } template<typename Modifier,typename Rollback> bool modify(iterator position,Modifier mod,Rollback back_) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) /* MSVC++ 6.0 optimizer on safe mode code chokes if this * this is not added. Left it for all compilers as it does no * harm. */ position.detach(); #endif return this->final_modify_( mod,back_,static_cast<final_node_type*>(position.get_node())); } void swap(random_access_index<SuperMeta,TagList>& x) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x); this->final_swap_(x.final()); } void clear()BOOST_NOEXCEPT { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; this->final_clear_(); } /* list operations */ void splice(iterator position,random_access_index<SuperMeta,TagList>& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; iterator first=x.begin(),last=x.end(); size_type n=0; BOOST_TRY{ while(first!=last){ if(push_back(*first).second){ first=x.erase(first); ++n; } else ++first; } } BOOST_CATCH(...){ relocate(position,end()-n,end()); BOOST_RETHROW; } BOOST_CATCH_END relocate(position,end()-n,end()); } void splice( iterator position,random_access_index<SuperMeta,TagList>& x,iterator i) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; if(&x==this)relocate(position,i); else{ if(insert(position,*i).second){ #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following * workaround is needed. Left it for all compilers as it does no * harm. */ i.detach(); x.erase(x.make_iterator(i.get_node())); #else x.erase(i); #endif } } } void splice( iterator position,random_access_index<SuperMeta,TagList>& x, iterator first,iterator last) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x); BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; if(&x==this)relocate(position,first,last); else{ size_type n=0; BOOST_TRY{ while(first!=last){ if(push_back(*first).second){ first=x.erase(first); ++n; } else ++first; } } BOOST_CATCH(...){ relocate(position,end()-n,end()); BOOST_RETHROW; } BOOST_CATCH_END relocate(position,end()-n,end()); } } void remove(value_param_type value) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; difference_type n= end()-make_iterator( random_access_index_remove<index_node_type>( ptrs, ::boost::bind<bool>( std::equal_to<value_type>(),::boost::arg<1>(),value))); while(n--)pop_back(); } template<typename Predicate> void remove_if(Predicate pred) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; difference_type n= end()-make_iterator( random_access_index_remove<index_node_type>(ptrs,pred)); while(n--)pop_back(); } void unique() { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; difference_type n= end()-make_iterator( random_access_index_unique<index_node_type>( ptrs,std::equal_to<value_type>())); while(n--)pop_back(); } template <class BinaryPredicate> void unique(BinaryPredicate binary_pred) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; difference_type n= end()-make_iterator( random_access_index_unique<index_node_type>(ptrs,binary_pred)); while(n--)pop_back(); } void merge(random_access_index<SuperMeta,TagList>& x) { if(this!=&x){ BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; size_type s=size(); splice(end(),x); random_access_index_inplace_merge<index_node_type>( get_allocator(),ptrs,ptrs.at(s),std::less<value_type>()); } } template <typename Compare> void merge(random_access_index<SuperMeta,TagList>& x,Compare comp) { if(this!=&x){ BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; size_type s=size(); splice(end(),x); random_access_index_inplace_merge<index_node_type>( get_allocator(),ptrs,ptrs.at(s),comp); } } void sort() { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; random_access_index_sort<index_node_type>( get_allocator(),ptrs,std::less<value_type>()); } template <typename Compare> void sort(Compare comp) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; random_access_index_sort<index_node_type>( get_allocator(),ptrs,comp); } void reverse()BOOST_NOEXCEPT { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; node_impl_type::reverse(ptrs.begin(),ptrs.end()); } /* rearrange operations */ void relocate(iterator position,iterator i) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; if(position!=i)relocate(position.get_node(),i.get_node()); } void relocate(iterator position,iterator first,iterator last) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; if(position!=last)relocate( position.get_node(),first.get_node(),last.get_node()); } template<typename InputIterator> void rearrange(InputIterator first) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; for(node_impl_ptr_pointer p0=ptrs.begin(),p0_end=ptrs.end(); p0!=p0_end;++first,++p0){ const value_type& v1=*first; node_impl_ptr_pointer p1=node_from_value<index_node_type>(&v1)->up(); std::swap(*p0,*p1); (*p0)->up()=p0; (*p1)->up()=p1; } } BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: random_access_index( const ctor_args_list& args_list,const allocator_type& al): super(args_list.get_tail(),al), ptrs(al,header()->impl(),0) { } random_access_index(const random_access_index<SuperMeta,TagList>& x): super(x), #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super(), #endif ptrs(x.get_allocator(),header()->impl(),x.size()) { /* The actual copying takes place in subsequent call to copy_(). */ } random_access_index( const random_access_index<SuperMeta,TagList>& x,do_not_copy_elements_tag): super(x,do_not_copy_elements_tag()), #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super(), #endif ptrs(x.get_allocator(),header()->impl(),0) { } ~random_access_index() { /* the container is guaranteed to be empty by now */ } #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) iterator make_iterator(index_node_type* node) {return iterator(node,this);} const_iterator make_iterator(index_node_type* node)const {return const_iterator(node,const_cast<random_access_index*>(this));} #else iterator make_iterator(index_node_type* node){return iterator(node);} const_iterator make_iterator(index_node_type* node)const {return const_iterator(node);} #endif void copy_( const random_access_index<SuperMeta,TagList>& x,const copy_map_type& map) { for(node_impl_ptr_pointer begin_org=x.ptrs.begin(), begin_cpy=ptrs.begin(), end_org=x.ptrs.end(); begin_org!=end_org;++begin_org,++begin_cpy){ *begin_cpy= static_cast<index_node_type*>( map.find( static_cast<final_node_type*>( index_node_type::from_impl(*begin_org))))->impl(); (*begin_cpy)->up()=begin_cpy; } super::copy_(x,map); } template<typename Variant> final_node_type* insert_( value_param_type v,final_node_type*& x,Variant variant) { ptrs.room_for_one(); final_node_type* res=super::insert_(v,x,variant); if(res==x)ptrs.push_back(static_cast<index_node_type*>(x)->impl()); return res; } template<typename Variant> final_node_type* insert_( value_param_type v,index_node_type* position, final_node_type*& x,Variant variant) { ptrs.room_for_one(); final_node_type* res=super::insert_(v,position,x,variant); if(res==x)ptrs.push_back(static_cast<index_node_type*>(x)->impl()); return res; } void extract_(index_node_type* x) { ptrs.erase(x->impl()); super::extract_(x); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) detach_iterators(x); #endif } void delete_all_nodes_() { for(node_impl_ptr_pointer x=ptrs.begin(),x_end=ptrs.end();x!=x_end;++x){ this->final_delete_node_( static_cast<final_node_type*>(index_node_type::from_impl(*x))); } } void clear_() { super::clear_(); ptrs.clear(); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super::detach_dereferenceable_iterators(); #endif } template<typename BoolConstant> void swap_( random_access_index<SuperMeta,TagList>& x,BoolConstant swap_allocators) { ptrs.swap(x.ptrs,swap_allocators); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super::swap(x); #endif super::swap_(x,swap_allocators); } void swap_elements_(random_access_index<SuperMeta,TagList>& x) { ptrs.swap(x.ptrs); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) safe_super::swap(x); #endif super::swap_elements_(x); } template<typename Variant> bool replace_(value_param_type v,index_node_type* x,Variant variant) { return super::replace_(v,x,variant); } bool modify_(index_node_type* x) { BOOST_TRY{ if(!super::modify_(x)){ ptrs.erase(x->impl()); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) detach_iterators(x); #endif return false; } else return true; } BOOST_CATCH(...){ ptrs.erase(x->impl()); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) detach_iterators(x); #endif BOOST_RETHROW; } BOOST_CATCH_END } bool modify_rollback_(index_node_type* x) { return super::modify_rollback_(x); } bool check_rollback_(index_node_type* x)const { return super::check_rollback_(x); } #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) /* serialization */ template<typename Archive> void save_( Archive& ar,const unsigned int version,const index_saver_type& sm)const { sm.save(begin(),end(),ar,version); super::save_(ar,version,sm); } template<typename Archive> void load_( Archive& ar,const unsigned int version,const index_loader_type& lm) { { typedef random_access_index_loader< index_node_type,allocator_type> loader; loader ld(get_allocator(),ptrs); lm.load( ::boost::bind( &loader::rearrange,&ld,::boost::arg<1>(),::boost::arg<2>()), ar,version); } /* exit scope so that ld frees its resources */ super::load_(ar,version,lm); } #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) /* invariant stuff */ bool invariant_()const { if(size()>capacity())return false; if(size()==0||begin()==end()){ if(size()!=0||begin()!=end())return false; } else{ size_type s=0; for(const_iterator it=begin(),it_end=end();;++it,++s){ if(*(it.get_node()->up())!=it.get_node()->impl())return false; if(it==it_end)break; } if(s!=size())return false; } return super::invariant_(); } /* This forwarding function eases things for the boost::mem_fn construct * in BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT. Actually, * final_check_invariant is already an inherited member function of index. */ void check_invariant_()const{this->final_check_invariant_();} #endif private: index_node_type* header()const{return this->final_header();} static void relocate(index_node_type* position,index_node_type* x) { node_impl_type::relocate(position->up(),x->up()); } static void relocate( index_node_type* position,index_node_type* first,index_node_type* last) { node_impl_type::relocate( position->up(),first->up(),last->up()); } #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) void detach_iterators(index_node_type* x) { iterator it=make_iterator(x); safe_mode::detach_equivalent_iterators(it); } #endif template <class InputIterator> void assign_iter(InputIterator first,InputIterator last,mpl::true_) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; clear(); for(;first!=last;++first)this->final_insert_ref_(*first); } void assign_iter(size_type n,value_param_type value,mpl::false_) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; clear(); for(size_type i=0;i<n;++i)push_back(value); } template<typename InputIterator> void insert_iter( iterator position,InputIterator first,InputIterator last,mpl::true_) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; size_type s=0; BOOST_TRY{ for(;first!=last;++first){ if(this->final_insert_ref_(*first).second)++s; } } BOOST_CATCH(...){ relocate(position,end()-s,end()); BOOST_RETHROW; } BOOST_CATCH_END relocate(position,end()-s,end()); } void insert_iter( iterator position,size_type n,value_param_type x,mpl::false_) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; size_type s=0; BOOST_TRY{ while(n--){ if(push_back(x).second)++s; } } BOOST_CATCH(...){ relocate(position,end()-s,end()); BOOST_RETHROW; } BOOST_CATCH_END relocate(position,end()-s,end()); } template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> std::pair<iterator,bool> emplace_front_impl( BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) { return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); } template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> std::pair<iterator,bool> emplace_back_impl( BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) { return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); } template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> std::pair<iterator,bool> emplace_impl( iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; std::pair<final_node_type*,bool> p= this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); if(p.second&&position.get_node()!=header()){ relocate(position.get_node(),p.first); } return std::pair<iterator,bool>(make_iterator(p.first),p.second); } ptr_array ptrs; #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ BOOST_WORKAROUND(__MWERKS__,<=0x3003) #pragma parse_mfunc_templ reset #endif }; /* comparison */ template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator==( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y) { return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); } template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator<( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y) { return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); } template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator!=( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y) { return !(x==y); } template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator>( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y) { return y<x; } template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator>=( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y) { return !(x<y); } template< typename SuperMeta1,typename TagList1, typename SuperMeta2,typename TagList2 > bool operator<=( const random_access_index<SuperMeta1,TagList1>& x, const random_access_index<SuperMeta2,TagList2>& y) { return !(x>y); } /* specialized algorithms */ template<typename SuperMeta,typename TagList> void swap( random_access_index<SuperMeta,TagList>& x, random_access_index<SuperMeta,TagList>& y) { x.swap(y); } } /* namespace multi_index::detail */ /* random access index specifier */ template <typename TagList> struct random_access { BOOST_STATIC_ASSERT(detail::is_tag<TagList>::value); template<typename Super> struct node_class { typedef detail::random_access_index_node<Super> type; }; template<typename SuperMeta> struct index_class { typedef detail::random_access_index< SuperMeta,typename TagList::type> type; }; }; } /* namespace multi_index */ } /* namespace boost */ /* Boost.Foreach compatibility */ template<typename SuperMeta,typename TagList> inline boost::mpl::true_* boost_foreach_is_noncopyable( boost::multi_index::detail::random_access_index<SuperMeta,TagList>*&, boost_foreach_argument_dependent_lookup_hack) { return 0; } #undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT #undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF #endif PK 3L�[�-4�Z Z ordered_index_fwd.hppnu �[��� /* Copyright 2003-2015 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_FWD_HPP #define BOOST_MULTI_INDEX_ORDERED_INDEX_FWD_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/multi_index/detail/ord_index_args.hpp> #include <boost/multi_index/detail/ord_index_impl_fwd.hpp> namespace boost{ namespace multi_index{ /* ordered_index specifiers */ template<typename Arg1,typename Arg2=mpl::na,typename Arg3=mpl::na> struct ordered_unique; template<typename Arg1,typename Arg2=mpl::na,typename Arg3=mpl::na> struct ordered_non_unique; } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[Fz B B detail/invariant_assert.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP #define BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP #if defined(_MSC_VER) #pragma once #endif #if !defined(BOOST_MULTI_INDEX_INVARIANT_ASSERT) #include <boost/assert.hpp> #define BOOST_MULTI_INDEX_INVARIANT_ASSERT BOOST_ASSERT #endif #endif PK 3L�[ɒ�? ? detail/rnd_node_iterator.hppnu �[��� /* Copyright 2003-2018 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_RND_NODE_ITERATOR_HPP #define BOOST_MULTI_INDEX_DETAIL_RND_NODE_ITERATOR_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/operators.hpp> #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include <boost/serialization/nvp.hpp> #include <boost/serialization/split_member.hpp> #endif namespace boost{ namespace multi_index{ namespace detail{ /* Iterator class for node-based indices with random access iterators. */ template<typename Node> class rnd_node_iterator: public random_access_iterator_helper< rnd_node_iterator<Node>, typename Node::value_type, typename Node::difference_type, const typename Node::value_type*, const typename Node::value_type&> { public: /* coverity[uninit_ctor]: suppress warning */ rnd_node_iterator(){} explicit rnd_node_iterator(Node* node_):node(node_){} const typename Node::value_type& operator*()const { return node->value(); } rnd_node_iterator& operator++() { Node::increment(node); return *this; } rnd_node_iterator& operator--() { Node::decrement(node); return *this; } rnd_node_iterator& operator+=(typename Node::difference_type n) { Node::advance(node,n); return *this; } rnd_node_iterator& operator-=(typename Node::difference_type n) { Node::advance(node,-n); return *this; } #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) /* Serialization. As for why the following is public, * see explanation in safe_mode_iterator notes in safe_mode.hpp. */ BOOST_SERIALIZATION_SPLIT_MEMBER() typedef typename Node::base_type node_base_type; template<class Archive> void save(Archive& ar,const unsigned int)const { node_base_type* bnode=node; ar<<serialization::make_nvp("pointer",bnode); } template<class Archive> void load(Archive& ar,const unsigned int) { node_base_type* bnode; ar>>serialization::make_nvp("pointer",bnode); node=static_cast<Node*>(bnode); } #endif /* get_node is not to be used by the user */ typedef Node node_type; Node* get_node()const{return node;} private: Node* node; }; template<typename Node> bool operator==( const rnd_node_iterator<Node>& x, const rnd_node_iterator<Node>& y) { return x.get_node()==y.get_node(); } template<typename Node> bool operator<( const rnd_node_iterator<Node>& x, const rnd_node_iterator<Node>& y) { return Node::distance(x.get_node(),y.get_node())>0; } template<typename Node> typename Node::difference_type operator-( const rnd_node_iterator<Node>& x, const rnd_node_iterator<Node>& y) { return Node::distance(y.get_node(),x.get_node()); } } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�v���! �! detail/rnk_index_ops.hppnu �[��� /* Copyright 2003-2018 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP #define BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/core/pointer_traits.hpp> #include <boost/mpl/and.hpp> #include <boost/multi_index/detail/promotes_arg.hpp> #include <utility> namespace boost{ namespace multi_index{ namespace detail{ /* Common code for ranked_index memfuns having templatized and * non-templatized versions. */ template<typename Pointer> struct ranked_node_size_type { typedef typename boost::pointer_traits<Pointer>:: element_type::size_type type; }; template<typename Pointer> inline typename ranked_node_size_type<Pointer>::type ranked_node_size(Pointer x) { return x!=Pointer(0)?x->size:0; } template<typename Pointer> inline Pointer ranked_index_nth( BOOST_DEDUCED_TYPENAME ranked_node_size_type<Pointer>::type n,Pointer end_) { typedef typename ranked_node_size_type<Pointer>::type size_type; Pointer top=end_->parent(); if(top==Pointer(0)||n>=top->size)return end_; for(;;){ size_type s=ranked_node_size(top->left()); if(n==s)return top; if(n<s)top=top->left(); else{ top=top->right(); n-=s+1; } } } template<typename Pointer> inline typename ranked_node_size_type<Pointer>::type ranked_index_rank(Pointer x,Pointer end_) { typedef typename ranked_node_size_type<Pointer>::type size_type; Pointer top=end_->parent(); if(top==Pointer(0))return 0; if(x==end_)return top->size; size_type s=ranked_node_size(x->left()); while(x!=top){ Pointer z=x->parent(); if(x==z->right()){ s+=ranked_node_size(z->left())+1; } x=z; } return s; } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline typename Node::size_type ranked_index_find_rank( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp) { typedef typename KeyFromValue::result_type key_type; return ranked_index_find_rank( top,y,key,x,comp, mpl::and_< promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>, promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >()); } template< typename Node,typename KeyFromValue, typename CompatibleCompare > inline typename Node::size_type ranked_index_find_rank( Node* top,Node* y,const KeyFromValue& key, const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, const CompatibleCompare& comp,mpl::true_) { return ranked_index_find_rank(top,y,key,x,comp,mpl::false_()); } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline typename Node::size_type ranked_index_find_rank( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp,mpl::false_) { typedef typename Node::size_type size_type; if(!top)return 0; size_type s=top->impl()->size, s0=s; Node* y0=y; do{ if(!comp(key(top->value()),x)){ y=top; s-=ranked_node_size(y->right())+1; top=Node::from_impl(top->left()); } else top=Node::from_impl(top->right()); }while(top); return (y==y0||comp(x,key(y->value())))?s0:s; } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline typename Node::size_type ranked_index_lower_bound_rank( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp) { typedef typename KeyFromValue::result_type key_type; return ranked_index_lower_bound_rank( top,y,key,x,comp, promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey>()); } template< typename Node,typename KeyFromValue, typename CompatibleCompare > inline typename Node::size_type ranked_index_lower_bound_rank( Node* top,Node* y,const KeyFromValue& key, const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, const CompatibleCompare& comp,mpl::true_) { return ranked_index_lower_bound_rank(top,y,key,x,comp,mpl::false_()); } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline typename Node::size_type ranked_index_lower_bound_rank( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp,mpl::false_) { typedef typename Node::size_type size_type; if(!top)return 0; size_type s=top->impl()->size; do{ if(!comp(key(top->value()),x)){ y=top; s-=ranked_node_size(y->right())+1; top=Node::from_impl(top->left()); } else top=Node::from_impl(top->right()); }while(top); return s; } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline typename Node::size_type ranked_index_upper_bound_rank( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp) { typedef typename KeyFromValue::result_type key_type; return ranked_index_upper_bound_rank( top,y,key,x,comp, promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>()); } template< typename Node,typename KeyFromValue, typename CompatibleCompare > inline typename Node::size_type ranked_index_upper_bound_rank( Node* top,Node* y,const KeyFromValue& key, const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, const CompatibleCompare& comp,mpl::true_) { return ranked_index_upper_bound_rank(top,y,key,x,comp,mpl::false_()); } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline typename Node::size_type ranked_index_upper_bound_rank( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp,mpl::false_) { typedef typename Node::size_type size_type; if(!top)return 0; size_type s=top->impl()->size; do{ if(comp(x,key(top->value()))){ y=top; s-=ranked_node_size(y->right())+1; top=Node::from_impl(top->left()); } else top=Node::from_impl(top->right()); }while(top); return s; } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline std::pair<typename Node::size_type,typename Node::size_type> ranked_index_equal_range_rank( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp) { typedef typename KeyFromValue::result_type key_type; return ranked_index_equal_range_rank( top,y,key,x,comp, mpl::and_< promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>, promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >()); } template< typename Node,typename KeyFromValue, typename CompatibleCompare > inline std::pair<typename Node::size_type,typename Node::size_type> ranked_index_equal_range_rank( Node* top,Node* y,const KeyFromValue& key, const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, const CompatibleCompare& comp,mpl::true_) { return ranked_index_equal_range_rank(top,y,key,x,comp,mpl::false_()); } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline std::pair<typename Node::size_type,typename Node::size_type> ranked_index_equal_range_rank( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp,mpl::false_) { typedef typename Node::size_type size_type; if(!top)return std::pair<size_type,size_type>(0,0); size_type s=top->impl()->size; do{ if(comp(key(top->value()),x)){ top=Node::from_impl(top->right()); } else if(comp(x,key(top->value()))){ y=top; s-=ranked_node_size(y->right())+1; top=Node::from_impl(top->left()); } else{ return std::pair<size_type,size_type>( s-top->impl()->size+ ranked_index_lower_bound_rank( Node::from_impl(top->left()),top,key,x,comp,mpl::false_()), s-ranked_node_size(top->right())+ ranked_index_upper_bound_rank( Node::from_impl(top->right()),y,key,x,comp,mpl::false_())); } }while(top); return std::pair<size_type,size_type>(s,s); } } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[R�\n2 2 detail/bucket_array.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP #define BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/multi_index/detail/allocator_traits.hpp> #include <boost/multi_index/detail/auto_space.hpp> #include <boost/multi_index/detail/hash_index_node.hpp> #include <boost/noncopyable.hpp> #include <boost/preprocessor/repetition/repeat.hpp> #include <boost/preprocessor/seq/elem.hpp> #include <boost/preprocessor/seq/enum.hpp> #include <boost/preprocessor/seq/size.hpp> #include <cstddef> #include <limits.h> #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include <boost/archive/archive_exception.hpp> #include <boost/serialization/access.hpp> #include <boost/throw_exception.hpp> #endif namespace boost{ namespace multi_index{ namespace detail{ /* bucket structure for use by hashed indices */ #define BOOST_MULTI_INDEX_BA_SIZES_32BIT \ (53ul)(97ul)(193ul)(389ul)(769ul) \ (1543ul)(3079ul)(6151ul)(12289ul)(24593ul) \ (49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \ (1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \ (50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \ (1610612741ul)(3221225473ul) #if ((((ULONG_MAX>>16)>>16)>>16)>>15)==0 /* unsigned long less than 64 bits */ #define BOOST_MULTI_INDEX_BA_SIZES \ BOOST_MULTI_INDEX_BA_SIZES_32BIT \ (4294967291ul) #else /* obtained with aid from * http://javaboutique.internet.com/prime_numb/ * http://www.rsok.com/~jrm/next_ten_primes.html * and verified with * http://www.alpertron.com.ar/ECM.HTM */ #define BOOST_MULTI_INDEX_BA_SIZES \ BOOST_MULTI_INDEX_BA_SIZES_32BIT \ (6442450939ul)(12884901893ul)(25769803751ul)(51539607551ul) \ (103079215111ul)(206158430209ul)(412316860441ul)(824633720831ul) \ (1649267441651ul)(3298534883309ul)(6597069766657ul)(13194139533299ul) \ (26388279066623ul)(52776558133303ul)(105553116266489ul)(211106232532969ul) \ (422212465066001ul)(844424930131963ul)(1688849860263953ul) \ (3377699720527861ul)(6755399441055731ul)(13510798882111483ul) \ (27021597764222939ul)(54043195528445957ul)(108086391056891903ul) \ (216172782113783843ul)(432345564227567621ul)(864691128455135207ul) \ (1729382256910270481ul)(3458764513820540933ul)(6917529027641081903ul) \ (13835058055282163729ul)(18446744073709551557ul) #endif template<bool _=true> /* templatized to have in-header static var defs */ class bucket_array_base:private noncopyable { protected: static const std::size_t sizes[ BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES)]; static std::size_t size_index(std::size_t n) { const std::size_t *bound=std::lower_bound(sizes,sizes+sizes_length,n); if(bound==sizes+sizes_length)--bound; return bound-sizes; } #define BOOST_MULTI_INDEX_BA_POSITION_CASE(z,n,_) \ case n:return hash%BOOST_PP_SEQ_ELEM(n,BOOST_MULTI_INDEX_BA_SIZES); static std::size_t position(std::size_t hash,std::size_t size_index_) { /* Accelerate hash%sizes[size_index_] by replacing with a switch on * hash%Ci expressions, each Ci a compile-time constant, which the * compiler can implement without using integer division. */ switch(size_index_){ default: /* never used */ BOOST_PP_REPEAT( BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES), BOOST_MULTI_INDEX_BA_POSITION_CASE,~) } } private: static const std::size_t sizes_length; }; template<bool _> const std::size_t bucket_array_base<_>::sizes[]={ BOOST_PP_SEQ_ENUM(BOOST_MULTI_INDEX_BA_SIZES) }; template<bool _> const std::size_t bucket_array_base<_>::sizes_length= sizeof(bucket_array_base<_>::sizes)/ sizeof(bucket_array_base<_>::sizes[0]); #undef BOOST_MULTI_INDEX_BA_POSITION_CASE #undef BOOST_MULTI_INDEX_BA_SIZES #undef BOOST_MULTI_INDEX_BA_SIZES_32BIT template<typename Allocator> class bucket_array:bucket_array_base<> { typedef bucket_array_base<> super; typedef hashed_index_base_node_impl< typename rebind_alloc_for< Allocator, char >::type > base_node_impl_type; public: typedef typename base_node_impl_type::base_pointer base_pointer; typedef typename base_node_impl_type::pointer pointer; bucket_array(const Allocator& al,pointer end_,std::size_t size_): size_index_(super::size_index(size_)), spc(al,static_cast<auto_space_size_type>(super::sizes[size_index_]+1)) { clear(end_); } std::size_t size()const { return super::sizes[size_index_]; } std::size_t position(std::size_t hash)const { return super::position(hash,size_index_); } base_pointer begin()const{return buckets();} base_pointer end()const{return buckets()+size();} base_pointer at(std::size_t n)const{return buckets()+n;} void clear(pointer end_) { for(base_pointer x=begin(),y=end();x!=y;++x)x->prior()=pointer(0); end()->prior()=end_->prior()=end_; end_->next()=end(); } void swap(bucket_array& x) { std::swap(size_index_,x.size_index_); spc.swap(x.spc); } template<typename BoolConstant> void swap(bucket_array& x,BoolConstant swap_allocators) { std::swap(size_index_,x.size_index_); spc.swap(x.spc,swap_allocators); } private: typedef auto_space<base_node_impl_type,Allocator> auto_space_type; typedef typename auto_space_type::size_type auto_space_size_type; std::size_t size_index_; auto_space_type spc; base_pointer buckets()const { return spc.data(); } #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) friend class boost::serialization::access; /* bucket_arrays do not emit any kind of serialization info. They are * fed to Boost.Serialization as hashed index iterators need to track * them during serialization. */ template<class Archive> void serialize(Archive&,const unsigned int) { } #endif }; template<typename Allocator> void swap(bucket_array<Allocator>& x,bucket_array<Allocator>& y) { x.swap(y); } } /* namespace multi_index::detail */ } /* namespace multi_index */ #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) /* bucket_arrays never get constructed directly by Boost.Serialization, * as archives are always fed pointers to previously existent * arrays. So, if this is called it means we are dealing with a * somehow invalid archive. */ #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) namespace serialization{ #else namespace multi_index{ namespace detail{ #endif template<class Archive,typename Allocator> inline void load_construct_data( Archive&,boost::multi_index::detail::bucket_array<Allocator>*, const unsigned int) { throw_exception( archive::archive_exception(archive::archive_exception::other_exception)); } #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) } /* namespace serialization */ #else } /* namespace multi_index::detail */ } /* namespace multi_index */ #endif #endif } /* namespace boost */ #endif PK 3L�[}늚i i detail/node_handle.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_NODE_HANDLE_HPP #define BOOST_MULTI_INDEX_DETAIL_NODE_HANDLE_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/core/addressof.hpp> #include <boost/detail/workaround.hpp> #include <boost/move/core.hpp> #include <boost/move/utility_core.hpp> #include <boost/multi_index_container_fwd.hpp> #include <boost/multi_index/detail/allocator_traits.hpp> #include <boost/type_traits/aligned_storage.hpp> #include <boost/type_traits/alignment_of.hpp> #include <new> namespace boost{ namespace multi_index{ namespace detail{ /* Node handle template class following [container.node] specs. */ #include <boost/multi_index/detail/define_if_constexpr_macro.hpp> template<typename Node,typename Allocator> class node_handle { public: typedef typename Node::value_type value_type; typedef Allocator allocator_type; private: typedef allocator_traits<allocator_type> alloc_traits; public: node_handle()BOOST_NOEXCEPT:node(0){} node_handle(BOOST_RV_REF(node_handle) x)BOOST_NOEXCEPT:node(x.node) { if(!x.empty()){ move_construct_allocator(boost::move(x)); x.destroy_allocator(); x.node=0; } } ~node_handle() { if(!empty()){ delete_node(); destroy_allocator(); } } node_handle& operator=(BOOST_RV_REF(node_handle) x) { if(this!=&x){ if(!empty()){ delete_node(); if(!x.empty()){ BOOST_MULTI_INDEX_IF_CONSTEXPR( alloc_traits::propagate_on_container_move_assignment::value){ move_assign_allocator(boost::move(x)); } x.destroy_allocator(); } else{ destroy_allocator(); } } else if(!x.empty()){ move_construct_allocator(boost::move(x)); x.destroy_allocator(); } node=x.node; x.node=0; } return *this; } value_type& value()const{return node->value();} allocator_type get_allocator()const{return *allocator_ptr();} #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) explicit #endif operator bool()const BOOST_NOEXCEPT{return (node!=0);} #if BOOST_WORKAROUND(BOOST_GCC_VERSION,>=70000)&&__cplusplus<201103L /* https://github.com/boostorg/config/issues/336 */ #else BOOST_ATTRIBUTE_NODISCARD #endif bool empty()const BOOST_NOEXCEPT{return (node==0);} void swap(node_handle& x) BOOST_NOEXCEPT_IF( alloc_traits::propagate_on_container_swap::value|| alloc_traits::is_always_equal::value) { if(!empty()){ if(!x.empty()){ BOOST_MULTI_INDEX_IF_CONSTEXPR( alloc_traits::propagate_on_container_swap::value){ using std::swap; swap(*allocator_ptr(),*x.allocator_ptr()); } } else{ x.move_construct_allocator(boost::move(*this)); destroy_allocator(); } } else if(!x.empty()){ move_construct_allocator(boost::move(x)); x.destroy_allocator(); } std::swap(node,x.node); } friend void swap(node_handle& x,node_handle& y) BOOST_NOEXCEPT_IF(noexcept(x.swap(y))) { x.swap(y); } private: BOOST_MOVABLE_BUT_NOT_COPYABLE(node_handle) template <typename,typename,typename> friend class boost::multi_index::multi_index_container; node_handle(Node* node_,const allocator_type& al):node(node_) { ::new (static_cast<void*>(allocator_ptr())) allocator_type(al); } void release_node() { if(!empty()){ node=0; destroy_allocator(); } } #include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp> const allocator_type* allocator_ptr()const { return reinterpret_cast<const allocator_type*>(&space); } allocator_type* allocator_ptr() { return reinterpret_cast<allocator_type*>(&space); } #include <boost/multi_index/detail/restore_wstrict_aliasing.hpp> void move_construct_allocator(BOOST_RV_REF(node_handle) x) { ::new (static_cast<void*>(allocator_ptr())) allocator_type(boost::move(*x.allocator_ptr())); } void move_assign_allocator(BOOST_RV_REF(node_handle) x) { *allocator_ptr()=boost::move(*x.allocator_ptr()); } void destroy_allocator(){allocator_ptr()->~allocator_type();} void delete_node() { typedef typename rebind_alloc_for< allocator_type,Node >::type node_allocator; typedef detail::allocator_traits<node_allocator> node_alloc_traits; typedef typename node_alloc_traits::pointer node_pointer; alloc_traits::destroy(*allocator_ptr(),boost::addressof(node->value())); node_allocator nal(*allocator_ptr()); node_alloc_traits::deallocate(nal,static_cast<node_pointer>(node),1); } Node* node; typename aligned_storage< sizeof(allocator_type), alignment_of<allocator_type>::value >::type space; }; #include <boost/multi_index/detail/undef_if_constexpr_macro.hpp> /* node handle insert return type template class following * [container.insert.return] specs. */ template<typename Iterator,typename NodeHandle> struct insert_return_type { insert_return_type( Iterator position_,bool inserted_,BOOST_RV_REF(NodeHandle) node_): position(position_),inserted(inserted_),node(boost::move(node_)){} insert_return_type(BOOST_RV_REF(insert_return_type) x): position(x.position),inserted(x.inserted),node(boost::move(x.node)){} insert_return_type& operator=(BOOST_RV_REF(insert_return_type) x) { position=x.position; inserted=x.inserted; node=boost::move(x.node); return *this; } Iterator position; bool inserted; NodeHandle node; private: BOOST_MOVABLE_BUT_NOT_COPYABLE(insert_return_type) }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[��� � detail/uintptr_type.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_UINTPTR_TYPE_HPP #define BOOST_MULTI_INDEX_DETAIL_UINTPTR_TYPE_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/mpl/bool.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* has_uintptr_type is an MPL integral constant determining whether * there exists an unsigned integral type with the same size as * void *. * uintptr_type is such a type if has_uintptr is true, or unsigned int * otherwise. * Note that uintptr_type is more restrictive than C99 uintptr_t, * where an integral type with size greater than that of void * * would be conformant. */ template<int N>struct uintptr_candidates; template<>struct uintptr_candidates<-1>{typedef unsigned int type;}; template<>struct uintptr_candidates<0> {typedef unsigned int type;}; template<>struct uintptr_candidates<1> {typedef unsigned short type;}; template<>struct uintptr_candidates<2> {typedef unsigned long type;}; #if defined(BOOST_HAS_LONG_LONG) template<>struct uintptr_candidates<3> {typedef boost::ulong_long_type type;}; #else template<>struct uintptr_candidates<3> {typedef unsigned int type;}; #endif #if defined(BOOST_HAS_MS_INT64) template<>struct uintptr_candidates<4> {typedef unsigned __int64 type;}; #else template<>struct uintptr_candidates<4> {typedef unsigned int type;}; #endif struct uintptr_aux { BOOST_STATIC_CONSTANT(int,index= sizeof(void*)==sizeof(uintptr_candidates<0>::type)?0: sizeof(void*)==sizeof(uintptr_candidates<1>::type)?1: sizeof(void*)==sizeof(uintptr_candidates<2>::type)?2: sizeof(void*)==sizeof(uintptr_candidates<3>::type)?3: sizeof(void*)==sizeof(uintptr_candidates<4>::type)?4:-1); BOOST_STATIC_CONSTANT(bool,has_uintptr_type=(index>=0)); typedef uintptr_candidates<index>::type type; }; typedef mpl::bool_<uintptr_aux::has_uintptr_type> has_uintptr_type; typedef uintptr_aux::type uintptr_type; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�y<� � detail/index_loader.hppnu �[��� /* Copyright 2003-2015 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP #define BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/archive/archive_exception.hpp> #include <boost/noncopyable.hpp> #include <boost/multi_index/detail/auto_space.hpp> #include <boost/multi_index/detail/raw_ptr.hpp> #include <boost/serialization/nvp.hpp> #include <boost/throw_exception.hpp> #include <cstddef> namespace boost{ namespace multi_index{ namespace detail{ /* Counterpart of index_saver (check index_saver.hpp for serialization * details.)* multi_index_container is in charge of supplying the info about * the base sequence, and each index can subsequently load itself using the * const interface of index_loader. */ template<typename Node,typename FinalNode,typename Allocator> class index_loader:private noncopyable { public: index_loader(const Allocator& al,std::size_t size): spc(al,size),size_(size),n(0),sorted(false) { } template<class Archive> void add(Node* node,Archive& ar,const unsigned int) { ar>>serialization::make_nvp("position",*node); entries()[n++]=node; } template<class Archive> void add_track(Node* node,Archive& ar,const unsigned int) { ar>>serialization::make_nvp("position",*node); } /* A rearranger is passed two nodes, and is expected to * reposition the second after the first. * If the first node is 0, then the second should be moved * to the beginning of the sequence. */ template<typename Rearranger,class Archive> void load(Rearranger r,Archive& ar,const unsigned int)const { FinalNode* prev=unchecked_load_node(ar); if(!prev)return; if(!sorted){ std::sort(entries(),entries()+size_); sorted=true; } check_node(prev); for(;;){ for(;;){ FinalNode* node=load_node(ar); if(!node)break; if(node==prev)prev=0; r(prev,node); prev=node; } prev=load_node(ar); if(!prev)break; } } private: Node** entries()const{return raw_ptr<Node**>(spc.data());} /* We try to delay sorting as much as possible just in case it * is not necessary, hence this version of load_node. */ template<class Archive> FinalNode* unchecked_load_node(Archive& ar)const { Node* node=0; ar>>serialization::make_nvp("pointer",node); return static_cast<FinalNode*>(node); } template<class Archive> FinalNode* load_node(Archive& ar)const { Node* node=0; ar>>serialization::make_nvp("pointer",node); check_node(node); return static_cast<FinalNode*>(node); } void check_node(Node* node)const { if(node!=0&&!std::binary_search(entries(),entries()+size_,node)){ throw_exception( archive::archive_exception( archive::archive_exception::other_exception)); } } auto_space<Node*,Allocator> spc; std::size_t size_; std::size_t n; mutable bool sorted; }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�� detail/serialization_version.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP #define BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/serialization/split_member.hpp> #include <boost/serialization/version.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* Helper class for storing and retrieving a given type serialization class * version while avoiding saving the number multiple times in the same * archive. * Behavior undefined if template partial specialization is not supported. */ template<typename T> struct serialization_version { serialization_version(): value(boost::serialization::version<serialization_version>::value){} serialization_version& operator=(unsigned int x){value=x;return *this;}; operator unsigned int()const{return value;} private: friend class boost::serialization::access; BOOST_SERIALIZATION_SPLIT_MEMBER() template<class Archive> void save(Archive&,const unsigned int)const{} template<class Archive> void load(Archive&,const unsigned int version) { this->value=version; } unsigned int value; }; } /* namespace multi_index::detail */ } /* namespace multi_index */ namespace serialization { template<typename T> struct version<boost::multi_index::detail::serialization_version<T> > { BOOST_STATIC_CONSTANT(int,value=version<T>::value); }; } /* namespace serialization */ } /* namespace boost */ #endif PK 3L�['��1� � detail/base_type.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP #define BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/detail/workaround.hpp> #include <boost/mpl/at.hpp> #include <boost/mpl/apply.hpp> #include <boost/mpl/size.hpp> #include <boost/multi_index/detail/index_base.hpp> #include <boost/multi_index/detail/is_index_list.hpp> #include <boost/static_assert.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* MPL machinery to construct a linear hierarchy of indices out of * a index list. */ struct index_applier { template<typename IndexSpecifierMeta,typename SuperMeta> struct apply { typedef typename IndexSpecifierMeta::type index_specifier; typedef typename index_specifier:: BOOST_NESTED_TEMPLATE index_class<SuperMeta>::type type; }; }; template<int N,typename Value,typename IndexSpecifierList,typename Allocator> struct nth_layer { BOOST_STATIC_CONSTANT(int,length=mpl::size<IndexSpecifierList>::value); typedef typename mpl::eval_if_c< N==length, mpl::identity<index_base<Value,IndexSpecifierList,Allocator> >, mpl::apply2< index_applier, mpl::at_c<IndexSpecifierList,N>, nth_layer<N+1,Value,IndexSpecifierList,Allocator> > >::type type; }; template<typename Value,typename IndexSpecifierList,typename Allocator> struct multi_index_base_type:nth_layer<0,Value,IndexSpecifierList,Allocator> { BOOST_STATIC_ASSERT(detail::is_index_list<IndexSpecifierList>::value); }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�o(k� � detail/index_saver.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP #define BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/multi_index/detail/index_matcher.hpp> #include <boost/noncopyable.hpp> #include <boost/serialization/nvp.hpp> #include <cstddef> namespace boost{ namespace multi_index{ namespace detail{ /* index_saver accepts a base sequence of previously saved elements * and saves a possibly reordered subsequence in an efficient manner, * serializing only the information needed to rearrange the subsequence * based on the original order of the base. * multi_index_container is in charge of supplying the info about the * base sequence, and each index can subsequently save itself using the * const interface of index_saver. */ template<typename Node,typename Allocator> class index_saver:private noncopyable { public: index_saver(const Allocator& al,std::size_t size):alg(al,size){} template<class Archive> void add(Node* node,Archive& ar,const unsigned int) { ar<<serialization::make_nvp("position",*node); alg.add(node); } template<class Archive> void add_track(Node* node,Archive& ar,const unsigned int) { ar<<serialization::make_nvp("position",*node); } template<typename IndexIterator,class Archive> void save( IndexIterator first,IndexIterator last,Archive& ar, const unsigned int)const { /* calculate ordered positions */ alg.execute(first,last); /* Given a consecutive subsequence of displaced elements * x1,...,xn, the following information is serialized: * * p0,p1,...,pn,0 * * where pi is a pointer to xi and p0 is a pointer to the element * preceding x1. Crealy, from this information is possible to * restore the original order on loading time. If x1 is the first * element in the sequence, the following is serialized instead: * * p1,p1,...,pn,0 * * For each subsequence of n elements, n+2 pointers are serialized. * An optimization policy is applied: consider for instance the * sequence * * a,B,c,D * * where B and D are displaced, but c is in its correct position. * Applying the schema described above we would serialize 6 pointers: * * p(a),p(B),0 * p(c),p(D),0 * * but this can be reduced to 5 pointers by treating c as a displaced * element: * * p(a),p(B),p(c),p(D),0 */ std::size_t last_saved=3; /* distance to last pointer saved */ for(IndexIterator it=first,prev=first;it!=last;prev=it++,++last_saved){ if(!alg.is_ordered(get_node(it))){ if(last_saved>1)save_node(get_node(prev),ar); save_node(get_node(it),ar); last_saved=0; } else if(last_saved==2)save_node(null_node(),ar); } if(last_saved<=2)save_node(null_node(),ar); /* marks the end of the serialization info for [first,last) */ save_node(null_node(),ar); } private: template<typename IndexIterator> static Node* get_node(IndexIterator it) { return it.get_node(); } static Node* null_node(){return 0;} template<typename Archive> static void save_node(Node* node,Archive& ar) { ar<<serialization::make_nvp("pointer",node); } index_matcher::algorithm<Node,Allocator> alg; }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[HΞܥ � detail/no_duplicate_tags.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP #define BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/mpl/fold.hpp> #include <boost/mpl/set/set0.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* no_duplicate_tags check at compile-time that a tag list * has no duplicate tags. * The algorithm deserves some explanation: tags * are sequentially inserted into a mpl::set if they were * not already present. Due to the magic of mpl::set * (mpl::has_key is contant time), this operation takes linear * time, and even MSVC++ 6.5 handles it gracefully (other obvious * solutions are quadratic.) */ struct duplicate_tag_mark{}; struct duplicate_tag_marker { template <typename MplSet,typename Tag> struct apply { typedef mpl::s_item< typename mpl::if_<mpl::has_key<MplSet,Tag>,duplicate_tag_mark,Tag>::type, MplSet > type; }; }; template<typename TagList> struct no_duplicate_tags { typedef typename mpl::fold< TagList, mpl::set0<>, duplicate_tag_marker >::type aux; BOOST_STATIC_CONSTANT( bool,value=!(mpl::has_key<aux,duplicate_tag_mark>::value)); }; /* Variant for an index list: duplication is checked * across all the indices. */ struct duplicate_tag_list_marker { template <typename MplSet,typename Index> struct apply:mpl::fold< BOOST_DEDUCED_TYPENAME Index::tag_list, MplSet, duplicate_tag_marker> { }; }; template<typename IndexList> struct no_duplicate_tags_in_index_list { typedef typename mpl::fold< IndexList, mpl::set0<>, duplicate_tag_list_marker >::type aux; BOOST_STATIC_CONSTANT( bool,value=!(mpl::has_key<aux,duplicate_tag_mark>::value)); }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[н�\ \ detail/converter.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP #define BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP #if defined(_MSC_VER) #pragma once #endif namespace boost{ namespace multi_index{ namespace detail{ /* converter offers means to access indices of a given multi_index_container * and for convertibilty between index iterators, so providing a * localized access point for get() and project() functions. */ template<typename MultiIndexContainer,typename Index> struct converter { static const Index& index(const MultiIndexContainer& x){return x;} static Index& index(MultiIndexContainer& x){return x;} static typename Index::const_iterator const_iterator( const MultiIndexContainer& x, typename MultiIndexContainer::final_node_type* node) { return x.Index::make_iterator(node); } static typename Index::iterator iterator( MultiIndexContainer& x, typename MultiIndexContainer::final_node_type* node) { return x.Index::make_iterator(node); } }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[6CG5 5 detail/rnd_index_node.hppnu �[��� /* Copyright 2003-2018 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_HPP #define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/integer/common_factor_rt.hpp> #include <boost/multi_index/detail/allocator_traits.hpp> #include <boost/multi_index/detail/raw_ptr.hpp> #include <cstddef> #include <functional> namespace boost{ namespace multi_index{ namespace detail{ template<typename Allocator> struct random_access_index_node_impl { typedef typename rebind_alloc_for< Allocator,random_access_index_node_impl >::type node_allocator; typedef allocator_traits<node_allocator> node_alloc_traits; typedef typename node_alloc_traits::pointer pointer; typedef typename node_alloc_traits::const_pointer const_pointer; typedef typename node_alloc_traits::difference_type difference_type; typedef typename rebind_alloc_for< Allocator,pointer >::type ptr_allocator; typedef allocator_traits<ptr_allocator> ptr_alloc_traits; typedef typename ptr_alloc_traits::pointer ptr_pointer; ptr_pointer& up(){return up_;} ptr_pointer up()const{return up_;} /* interoperability with rnd_node_iterator */ static void increment(pointer& x) { x=*(x->up()+1); } static void decrement(pointer& x) { x=*(x->up()-1); } static void advance(pointer& x,difference_type n) { x=*(x->up()+n); } static difference_type distance(pointer x,pointer y) { return static_cast<difference_type>(y->up()-x->up()); } /* algorithmic stuff */ static void relocate(ptr_pointer pos,ptr_pointer x) { pointer n=*x; if(x<pos){ extract(x,pos); *(pos-1)=n; n->up()=pos-1; } else{ while(x!=pos){ *x=*(x-1); (*x)->up()=x; --x; } *pos=n; n->up()=pos; } }; static void relocate(ptr_pointer pos,ptr_pointer first,ptr_pointer last) { ptr_pointer begin,middle,end; if(pos<first){ begin=pos; middle=first; end=last; } else{ begin=first; middle=last; end=pos; } std::ptrdiff_t n=end-begin; std::ptrdiff_t m=middle-begin; std::ptrdiff_t n_m=n-m; std::ptrdiff_t p=integer::gcd(n,m); for(std::ptrdiff_t i=0;i<p;++i){ pointer tmp=begin[i]; for(std::ptrdiff_t j=i,k;;){ if(j<n_m)k=j+m; else k=j-n_m; if(k==i){ *(begin+j)=tmp; (*(begin+j))->up()=begin+j; break; } else{ *(begin+j)=*(begin+k); (*(begin+j))->up()=begin+j; } if(k<n_m)j=k+m; else j=k-n_m; if(j==i){ *(begin+k)=tmp; (*(begin+k))->up()=begin+k; break; } else{ *(begin+k)=*(begin+j); (*(begin+k))->up()=begin+k; } } } }; static void extract(ptr_pointer x,ptr_pointer pend) { --pend; while(x!=pend){ *x=*(x+1); (*x)->up()=x; ++x; } } static void transfer( ptr_pointer pbegin0,ptr_pointer pend0,ptr_pointer pbegin1) { while(pbegin0!=pend0){ *pbegin1=*pbegin0++; (*pbegin1)->up()=pbegin1; ++pbegin1; } } static void reverse(ptr_pointer pbegin,ptr_pointer pend) { std::ptrdiff_t d=(pend-pbegin)/2; for(std::ptrdiff_t i=0;i<d;++i){ std::swap(*pbegin,*--pend); (*pbegin)->up()=pbegin; (*pend)->up()=pend; ++pbegin; } } private: ptr_pointer up_; }; template<typename Super> struct random_access_index_node_trampoline: random_access_index_node_impl< typename rebind_alloc_for< typename Super::allocator_type, char >::type > { typedef random_access_index_node_impl< typename rebind_alloc_for< typename Super::allocator_type, char >::type > impl_type; }; template<typename Super> struct random_access_index_node: Super,random_access_index_node_trampoline<Super> { private: typedef random_access_index_node_trampoline<Super> trampoline; public: typedef typename trampoline::impl_type impl_type; typedef typename trampoline::pointer impl_pointer; typedef typename trampoline::const_pointer const_impl_pointer; typedef typename trampoline::difference_type difference_type; typedef typename trampoline::ptr_pointer impl_ptr_pointer; impl_ptr_pointer& up(){return trampoline::up();} impl_ptr_pointer up()const{return trampoline::up();} impl_pointer impl() { return static_cast<impl_pointer>( static_cast<impl_type*>(static_cast<trampoline*>(this))); } const_impl_pointer impl()const { return static_cast<const_impl_pointer>( static_cast<const impl_type*>(static_cast<const trampoline*>(this))); } static random_access_index_node* from_impl(impl_pointer x) { return static_cast<random_access_index_node*>( static_cast<trampoline*>( raw_ptr<impl_type*>(x))); } static const random_access_index_node* from_impl(const_impl_pointer x) { return static_cast<const random_access_index_node*>( static_cast<const trampoline*>( raw_ptr<const impl_type*>(x))); } /* interoperability with rnd_node_iterator */ static void increment(random_access_index_node*& x) { impl_pointer xi=x->impl(); trampoline::increment(xi); x=from_impl(xi); } static void decrement(random_access_index_node*& x) { impl_pointer xi=x->impl(); trampoline::decrement(xi); x=from_impl(xi); } static void advance(random_access_index_node*& x,difference_type n) { impl_pointer xi=x->impl(); trampoline::advance(xi,n); x=from_impl(xi); } static difference_type distance( random_access_index_node* x,random_access_index_node* y) { return trampoline::distance(x->impl(),y->impl()); } }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[F�^ ^ detail/promotes_arg.hppnu �[��� /* Copyright 2003-2017 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_PROMOTES_ARG_HPP #define BOOST_MULTI_INDEX_DETAIL_PROMOTES_ARG_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/detail/workaround.hpp> /* Metafunctions to check if f(arg1,arg2) promotes either arg1 to the type of * arg2 or viceversa. By default, (i.e. if it cannot be determined), no * promotion is assumed. */ #if BOOST_WORKAROUND(BOOST_MSVC,<1400) namespace boost{ namespace multi_index{ namespace detail{ template<typename F,typename Arg1,typename Arg2> struct promotes_1st_arg:mpl::false_{}; template<typename F,typename Arg1,typename Arg2> struct promotes_2nd_arg:mpl::false_{}; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #else #include <boost/mpl/and.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/not.hpp> #include <boost/multi_index/detail/is_transparent.hpp> #include <boost/type_traits/is_convertible.hpp> namespace boost{ namespace multi_index{ namespace detail{ template<typename F,typename Arg1,typename Arg2> struct promotes_1st_arg: mpl::and_< mpl::not_<is_transparent<F,Arg1,Arg2> >, is_convertible<const Arg1,Arg2>, is_transparent<F,Arg2,Arg2> > {}; template<typename F,typename Arg1,typename Arg2> struct promotes_2nd_arg: mpl::and_< mpl::not_<is_transparent<F,Arg1,Arg2> >, is_convertible<const Arg2,Arg1>, is_transparent<F,Arg1,Arg1> > {}; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif #endif PK 3L�[f Y�* * detail/modify_key_adaptor.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP #define BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP #if defined(_MSC_VER) #pragma once #endif namespace boost{ namespace multi_index{ namespace detail{ /* Functional adaptor to resolve modify_key as a call to modify. * Preferred over compose_f_gx and stuff cause it eliminates problems * with references to references, dealing with function pointers, etc. */ template<typename Fun,typename Value,typename KeyFromValue> struct modify_key_adaptor { modify_key_adaptor(Fun f_,KeyFromValue kfv_):f(f_),kfv(kfv_){} void operator()(Value& x) { f(kfv(x)); } private: Fun f; KeyFromValue kfv; }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[����� � detail/node_type.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP #define BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/detail/workaround.hpp> #include <boost/mpl/bind.hpp> #include <boost/mpl/reverse_iter_fold.hpp> #include <boost/mpl/deref.hpp> #include <boost/multi_index_container_fwd.hpp> #include <boost/multi_index/detail/header_holder.hpp> #include <boost/multi_index/detail/index_node_base.hpp> #include <boost/multi_index/detail/is_index_list.hpp> #include <boost/static_assert.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* MPL machinery to construct the internal node type associated to an * index list. */ struct index_node_applier { template<typename IndexSpecifierIterator,typename Super> struct apply { typedef typename mpl::deref<IndexSpecifierIterator>::type index_specifier; typedef typename index_specifier:: BOOST_NESTED_TEMPLATE node_class<Super>::type type; }; }; template<typename Value,typename IndexSpecifierList,typename Allocator> struct multi_index_node_type { BOOST_STATIC_ASSERT(detail::is_index_list<IndexSpecifierList>::value); typedef typename mpl::reverse_iter_fold< IndexSpecifierList, index_node_base<Value,Allocator>, mpl::bind2<index_node_applier,mpl::_2,mpl::_1> >::type type; }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[]袒� � detail/hash_index_args.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP #define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/functional/hash.hpp> #include <boost/mpl/aux_/na.hpp> #include <boost/mpl/eval_if.hpp> #include <boost/mpl/identity.hpp> #include <boost/mpl/if.hpp> #include <boost/multi_index/tag.hpp> #include <boost/static_assert.hpp> #include <boost/type_traits/is_same.hpp> #include <functional> namespace boost{ namespace multi_index{ namespace detail{ /* Hashed index specifiers can be instantiated in two forms: * * (hashed_unique|hashed_non_unique)< * KeyFromValue, * Hash=boost::hash<KeyFromValue::result_type>, * Pred=std::equal_to<KeyFromValue::result_type> > * (hashed_unique|hashed_non_unique)< * TagList, * KeyFromValue, * Hash=boost::hash<KeyFromValue::result_type>, * Pred=std::equal_to<KeyFromValue::result_type> > * * hashed_index_args implements the machinery to accept this * argument-dependent polymorphism. */ template<typename KeyFromValue> struct index_args_default_hash { typedef ::boost::hash<typename KeyFromValue::result_type> type; }; template<typename KeyFromValue> struct index_args_default_pred { typedef std::equal_to<typename KeyFromValue::result_type> type; }; template<typename Arg1,typename Arg2,typename Arg3,typename Arg4> struct hashed_index_args { typedef is_tag<Arg1> full_form; typedef typename mpl::if_< full_form, Arg1, tag< > >::type tag_list_type; typedef typename mpl::if_< full_form, Arg2, Arg1>::type key_from_value_type; typedef typename mpl::if_< full_form, Arg3, Arg2>::type supplied_hash_type; typedef typename mpl::eval_if< mpl::is_na<supplied_hash_type>, index_args_default_hash<key_from_value_type>, mpl::identity<supplied_hash_type> >::type hash_type; typedef typename mpl::if_< full_form, Arg4, Arg3>::type supplied_pred_type; typedef typename mpl::eval_if< mpl::is_na<supplied_pred_type>, index_args_default_pred<key_from_value_type>, mpl::identity<supplied_pred_type> >::type pred_type; BOOST_STATIC_ASSERT(is_tag<tag_list_type>::value); BOOST_STATIC_ASSERT(!mpl::is_na<key_from_value_type>::value); BOOST_STATIC_ASSERT(!mpl::is_na<hash_type>::value); BOOST_STATIC_ASSERT(!mpl::is_na<pred_type>::value); }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�>'�Z Z detail/adl_swap.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP #define BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> namespace boost{ namespace multi_index{ namespace detail{ template<typename T> void adl_swap(T& x,T& y) { #if !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) using std::swap; swap(x,y); #else std::swap(x,y); #endif } } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[i�b detail/bidir_node_iterator.hppnu �[��� /* Copyright 2003-2018 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP #define BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/operators.hpp> #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include <boost/serialization/nvp.hpp> #include <boost/serialization/split_member.hpp> #endif namespace boost{ namespace multi_index{ namespace detail{ /* Iterator class for node-based indices with bidirectional * iterators (ordered and sequenced indices.) */ template<typename Node> class bidir_node_iterator: public bidirectional_iterator_helper< bidir_node_iterator<Node>, typename Node::value_type, typename Node::difference_type, const typename Node::value_type*, const typename Node::value_type&> { public: /* coverity[uninit_ctor]: suppress warning */ bidir_node_iterator(){} explicit bidir_node_iterator(Node* node_):node(node_){} const typename Node::value_type& operator*()const { return node->value(); } bidir_node_iterator& operator++() { Node::increment(node); return *this; } bidir_node_iterator& operator--() { Node::decrement(node); return *this; } #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) /* Serialization. As for why the following is public, * see explanation in safe_mode_iterator notes in safe_mode.hpp. */ BOOST_SERIALIZATION_SPLIT_MEMBER() typedef typename Node::base_type node_base_type; template<class Archive> void save(Archive& ar,const unsigned int)const { node_base_type* bnode=node; ar<<serialization::make_nvp("pointer",bnode); } template<class Archive> void load(Archive& ar,const unsigned int) { node_base_type* bnode; ar>>serialization::make_nvp("pointer",bnode); node=static_cast<Node*>(bnode); } #endif /* get_node is not to be used by the user */ typedef Node node_type; Node* get_node()const{return node;} private: Node* node; }; template<typename Node> bool operator==( const bidir_node_iterator<Node>& x, const bidir_node_iterator<Node>& y) { return x.get_node()==y.get_node(); } } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[0�&!� � detail/is_index_list.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP #define BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/mpl/empty.hpp> #include <boost/mpl/is_sequence.hpp> namespace boost{ namespace multi_index{ namespace detail{ template<typename T> struct is_index_list { BOOST_STATIC_CONSTANT(bool,mpl_sequence=mpl::is_sequence<T>::value); BOOST_STATIC_CONSTANT(bool,non_empty=!mpl::empty<T>::value); BOOST_STATIC_CONSTANT(bool,value=mpl_sequence&&non_empty); }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[ӭ�ؓ � detail/has_tag.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP #define BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/mpl/contains.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* determines whether an index type has a given tag in its tag list */ template<typename Tag> struct has_tag { template<typename Index> struct apply:mpl::contains<BOOST_DEDUCED_TYPENAME Index::tag_list,Tag> { }; }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[l�Y� detail/header_holder.hppnu �[��� /* Copyright 2003-2008 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP #define BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/noncopyable.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* A utility class used to hold a pointer to the header node. * The base from member idiom is used because index classes, which are * superclasses of multi_index_container, need this header in construction * time. The allocation is made by the allocator of the multi_index_container * class --hence, this allocator needs also be stored resorting * to the base from member trick. */ template<typename NodeTypePtr,typename Final> struct header_holder:private noncopyable { header_holder():member(final().allocate_node()){} ~header_holder(){final().deallocate_node(&*member);} NodeTypePtr member; private: Final& final(){return *static_cast<Final*>(this);} }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�a �i i detail/copy_map.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP #define BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/core/addressof.hpp> #include <boost/core/no_exceptions_support.hpp> #include <boost/move/core.hpp> #include <boost/move/utility_core.hpp> #include <boost/multi_index/detail/allocator_traits.hpp> #include <boost/multi_index/detail/auto_space.hpp> #include <boost/multi_index/detail/raw_ptr.hpp> #include <boost/noncopyable.hpp> #include <functional> namespace boost{ namespace multi_index{ namespace detail{ /* copy_map is used as an auxiliary structure during copy_() operations. * When a container with n nodes is replicated, node_map holds the pairings * between original and copied nodes, and provides a fast way to find a * copied node from an original one. * The semantics of the class are not simple, and no attempt has been made * to enforce it: multi_index_container handles it right. On the other hand, * the const interface, which is the one provided to index implementations, * only allows for: * - Enumeration of pairs of (original,copied) nodes (excluding the headers), * - fast retrieval of copied nodes (including the headers.) */ template <typename Node> struct copy_map_entry { copy_map_entry(Node* f,Node* s):first(f),second(s){} Node* first; Node* second; bool operator<(const copy_map_entry<Node>& x)const { return std::less<Node*>()(first,x.first); } }; struct copy_map_value_copier { template<typename Value> const Value& operator()(Value& x)const{return x;} }; struct copy_map_value_mover { template<typename Value> BOOST_RV_REF(Value) operator()(Value& x)const{return boost::move(x);} }; template <typename Node,typename Allocator> class copy_map:private noncopyable { typedef typename rebind_alloc_for< Allocator,Node >::type allocator_type; typedef allocator_traits<allocator_type> alloc_traits; typedef typename alloc_traits::pointer pointer; public: typedef const copy_map_entry<Node>* const_iterator; typedef typename alloc_traits::size_type size_type; copy_map( const Allocator& al,size_type size,Node* header_org,Node* header_cpy): al_(al),size_(size),spc(al_,size_),n(0), header_org_(header_org),header_cpy_(header_cpy),released(false) {} ~copy_map() { if(!released){ for(size_type i=0;i<n;++i){ alloc_traits::destroy( al_,boost::addressof((spc.data()+i)->second->value())); deallocate((spc.data()+i)->second); } } } const_iterator begin()const{return raw_ptr<const_iterator>(spc.data());} const_iterator end()const{return raw_ptr<const_iterator>(spc.data()+n);} void copy_clone(Node* node){clone(node,copy_map_value_copier());} void move_clone(Node* node){clone(node,copy_map_value_mover());} Node* find(Node* node)const { if(node==header_org_)return header_cpy_; return std::lower_bound( begin(),end(),copy_map_entry<Node>(node,0))->second; } void release() { released=true; } private: allocator_type al_; size_type size_; auto_space<copy_map_entry<Node>,Allocator> spc; size_type n; Node* header_org_; Node* header_cpy_; bool released; pointer allocate() { return alloc_traits::allocate(al_,1); } void deallocate(Node* node) { alloc_traits::deallocate(al_,static_cast<pointer>(node),1); } template<typename ValueAccess> void clone(Node* node,ValueAccess access) { (spc.data()+n)->first=node; (spc.data()+n)->second=raw_ptr<Node*>(allocate()); BOOST_TRY{ alloc_traits::construct( al_,boost::addressof((spc.data()+n)->second->value()), access(node->value())); } BOOST_CATCH(...){ deallocate((spc.data()+n)->second); BOOST_RETHROW; } BOOST_CATCH_END ++n; if(n==size_){ std::sort( raw_ptr<copy_map_entry<Node>*>(spc.data()), raw_ptr<copy_map_entry<Node>*>(spc.data())+size_); } } }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[ k�� � detail/rnd_index_ptr_array.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP #define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/multi_index/detail/allocator_traits.hpp> #include <boost/multi_index/detail/auto_space.hpp> #include <boost/multi_index/detail/rnd_index_node.hpp> #include <boost/noncopyable.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* pointer structure for use by random access indices */ template<typename Allocator> class random_access_index_ptr_array:private noncopyable { typedef random_access_index_node_impl< typename rebind_alloc_for< Allocator, char >::type > node_impl_type; public: typedef typename node_impl_type::pointer value_type; typedef typename rebind_alloc_for< Allocator,value_type >::type value_allocator; typedef allocator_traits<value_allocator> alloc_traits; typedef typename alloc_traits::pointer pointer; typedef typename alloc_traits::size_type size_type; random_access_index_ptr_array( const Allocator& al,value_type end_,size_type sz): size_(sz), capacity_(sz), spc(al,capacity_+1) { *end()=end_; end_->up()=end(); } size_type size()const{return size_;} size_type capacity()const{return capacity_;} void room_for_one() { if(size_==capacity_){ reserve(capacity_<=10?15:capacity_+capacity_/2); } } void reserve(size_type c) { if(c>capacity_)set_capacity(c); } void shrink_to_fit() { if(capacity_>size_)set_capacity(size_); } pointer begin()const{return ptrs();} pointer end()const{return ptrs()+size_;} pointer at(size_type n)const{return ptrs()+n;} void push_back(value_type x) { *(end()+1)=*end(); (*(end()+1))->up()=end()+1; *end()=x; (*end())->up()=end(); ++size_; } void erase(value_type x) { node_impl_type::extract(x->up(),end()+1); --size_; } void clear() { *begin()=*end(); (*begin())->up()=begin(); size_=0; } void swap(random_access_index_ptr_array& x) { std::swap(size_,x.size_); std::swap(capacity_,x.capacity_); spc.swap(x.spc); } template<typename BoolConstant> void swap(random_access_index_ptr_array& x,BoolConstant swap_allocators) { std::swap(size_,x.size_); std::swap(capacity_,x.capacity_); spc.swap(x.spc,swap_allocators); } private: size_type size_; size_type capacity_; auto_space<value_type,Allocator> spc; pointer ptrs()const { return spc.data(); } void set_capacity(size_type c) { auto_space<value_type,Allocator> spc1(spc.get_allocator(),c+1); node_impl_type::transfer(begin(),end()+1,spc1.data()); spc.swap(spc1); capacity_=c; } }; template<typename Allocator> void swap( random_access_index_ptr_array<Allocator>& x, random_access_index_ptr_array<Allocator>& y) { x.swap(y); } } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�ĢT detail/unbounded.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_UNBOUNDED_HPP #define BOOST_MULTI_INDEX_DETAIL_UNBOUNDED_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/detail/workaround.hpp> namespace boost{ namespace multi_index{ /* dummy type and variable for use in ordered_index::range() */ /* ODR-abiding technique shown at the example attached to * http://lists.boost.org/Archives/boost/2006/07/108355.php */ namespace detail{class unbounded_helper;} detail::unbounded_helper unbounded(detail::unbounded_helper); namespace detail{ class unbounded_helper { unbounded_helper(){} unbounded_helper(const unbounded_helper&){} friend unbounded_helper multi_index::unbounded(unbounded_helper); }; typedef unbounded_helper (*unbounded_type)(unbounded_helper); } /* namespace multi_index::detail */ inline detail::unbounded_helper unbounded(detail::unbounded_helper) { return detail::unbounded_helper(); } /* tags used in the implementation of range */ namespace detail{ struct none_unbounded_tag{}; struct lower_unbounded_tag{}; struct upper_unbounded_tag{}; struct both_unbounded_tag{}; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[o� ÷F �F detail/safe_mode.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_SAFE_MODE_HPP #define BOOST_MULTI_INDEX_DETAIL_SAFE_MODE_HPP #if defined(_MSC_VER) #pragma once #endif /* Safe mode machinery, in the spirit of Cay Hortmann's "Safe STL" * (http://www.horstmann.com/safestl.html). * In this mode, containers of type Container are derived from * safe_container<Container>, and their corresponding iterators * are wrapped with safe_iterator. These classes provide * an internal record of which iterators are at a given moment associated * to a given container, and properly mark the iterators as invalid * when the container gets destroyed. * Iterators are chained in a single attached list, whose header is * kept by the container. More elaborate data structures would yield better * performance, but I decided to keep complexity to a minimum since * speed is not an issue here. * Safe mode iterators automatically check that only proper operations * are performed on them: for instance, an invalid iterator cannot be * dereferenced. Additionally, a set of utilty macros and functions are * provided that serve to implement preconditions and cooperate with * the framework within the container. * Iterators can also be unchecked, i.e. they do not have info about * which container they belong in. This situation arises when the iterator * is restored from a serialization archive: only information on the node * is available, and it is not possible to determine to which container * the iterator is associated to. The only sensible policy is to assume * unchecked iterators are valid, though this can certainly generate false * positive safe mode checks. * This is not a full-fledged safe mode framework, and is only intended * for use within the limits of Boost.MultiIndex. */ /* Assertion macros. These resolve to no-ops if * !defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE). */ #if !defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) #undef BOOST_MULTI_INDEX_SAFE_MODE_ASSERT #define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) ((void)0) #else #if !defined(BOOST_MULTI_INDEX_SAFE_MODE_ASSERT) #include <boost/assert.hpp> #define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) BOOST_ASSERT(expr) #endif #endif #define BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it) \ BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ safe_mode::check_valid_iterator(it), \ safe_mode::invalid_iterator); #define BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(it) \ BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ safe_mode::check_dereferenceable_iterator(it), \ safe_mode::not_dereferenceable_iterator); #define BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(it) \ BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ safe_mode::check_incrementable_iterator(it), \ safe_mode::not_incrementable_iterator); #define BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(it) \ BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ safe_mode::check_decrementable_iterator(it), \ safe_mode::not_decrementable_iterator); #define BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,cont) \ BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ safe_mode::check_is_owner(it,cont), \ safe_mode::not_owner); #define BOOST_MULTI_INDEX_CHECK_SAME_OWNER(it0,it1) \ BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ safe_mode::check_same_owner(it0,it1), \ safe_mode::not_same_owner); #define BOOST_MULTI_INDEX_CHECK_VALID_RANGE(it0,it1) \ BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ safe_mode::check_valid_range(it0,it1), \ safe_mode::invalid_range); #define BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(it,it0,it1) \ BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ safe_mode::check_outside_range(it,it0,it1), \ safe_mode::inside_range); #define BOOST_MULTI_INDEX_CHECK_IN_BOUNDS(it,n) \ BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ safe_mode::check_in_bounds(it,n), \ safe_mode::out_of_bounds); #define BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(cont0,cont1) \ BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ safe_mode::check_different_container(cont0,cont1), \ safe_mode::same_container); #define BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(cont0,cont1) \ BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ safe_mode::check_equal_allocators(cont0,cont1), \ safe_mode::unequal_allocators); #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/multi_index/detail/access_specifier.hpp> #include <boost/multi_index/detail/iter_adaptor.hpp> #include <boost/multi_index/safe_mode_errors.hpp> #include <boost/noncopyable.hpp> #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include <boost/serialization/split_member.hpp> #include <boost/serialization/version.hpp> #endif #if defined(BOOST_HAS_THREADS) #include <boost/detail/lightweight_mutex.hpp> #endif namespace boost{ namespace multi_index{ namespace safe_mode{ /* Checking routines. Assume the best for unchecked iterators * (i.e. they pass the checking when there is not enough info * to know.) */ template<typename Iterator> inline bool check_valid_iterator(const Iterator& it) { return it.valid()||it.unchecked(); } template<typename Iterator> inline bool check_dereferenceable_iterator(const Iterator& it) { return (it.valid()&&it!=it.owner()->end())||it.unchecked(); } template<typename Iterator> inline bool check_incrementable_iterator(const Iterator& it) { return (it.valid()&&it!=it.owner()->end())||it.unchecked(); } template<typename Iterator> inline bool check_decrementable_iterator(const Iterator& it) { return (it.valid()&&it!=it.owner()->begin())||it.unchecked(); } template<typename Iterator> inline bool check_is_owner( const Iterator& it,const typename Iterator::container_type& cont) { return (it.valid()&&it.owner()==&cont)||it.unchecked(); } template<typename Iterator> inline bool check_same_owner(const Iterator& it0,const Iterator& it1) { return (it0.valid()&&it1.valid()&&it0.owner()==it1.owner())|| it0.unchecked()||it1.unchecked(); } template<typename Iterator> inline bool check_valid_range(const Iterator& it0,const Iterator& it1) { if(!check_same_owner(it0,it1))return false; if(it0.valid()){ Iterator last=it0.owner()->end(); if(it1==last)return true; for(Iterator first=it0;first!=last;++first){ if(first==it1)return true; } return false; } return true; } template<typename Iterator> inline bool check_outside_range( const Iterator& it,const Iterator& it0,const Iterator& it1) { if(!check_same_owner(it0,it1))return false; if(it0.valid()){ Iterator last=it0.owner()->end(); bool found=false; Iterator first=it0; for(;first!=last;++first){ if(first==it1)break; /* crucial that this check goes after previous break */ if(first==it)found=true; } if(first!=it1)return false; return !found; } return true; } template<typename Iterator,typename Difference> inline bool check_in_bounds(const Iterator& it,Difference n) { if(it.unchecked())return true; if(!it.valid()) return false; if(n>0) return it.owner()->end()-it>=n; else return it.owner()->begin()-it<=n; } template<typename Container> inline bool check_different_container( const Container& cont0,const Container& cont1) { return &cont0!=&cont1; } template<typename Container0,typename Container1> inline bool check_equal_allocators( const Container0& cont0,const Container1& cont1) { return cont0.get_allocator()==cont1.get_allocator(); } /* Invalidates all iterators equivalent to that given. Safe containers * must call this when deleting elements: the safe mode framework cannot * perform this operation automatically without outside help. */ template<typename Iterator> inline void detach_equivalent_iterators(Iterator& it) { if(it.valid()){ { #if defined(BOOST_HAS_THREADS) boost::detail::lightweight_mutex::scoped_lock lock(it.cont->mutex); #endif Iterator *prev_,*next_; for( prev_=static_cast<Iterator*>(&it.cont->header); (next_=static_cast<Iterator*>(prev_->next))!=0;){ if(next_!=&it&&*next_==it){ prev_->next=next_->next; next_->cont=0; } else prev_=next_; } } it.detach(); } } template<typename Container> class safe_container; /* fwd decl. */ } /* namespace multi_index::safe_mode */ namespace detail{ class safe_container_base; /* fwd decl. */ class safe_iterator_base { public: bool valid()const{return cont!=0;} bool unchecked()const{return unchecked_;} inline void detach(); void uncheck() { detach(); unchecked_=true; } protected: safe_iterator_base():cont(0),next(0),unchecked_(false){} explicit safe_iterator_base(safe_container_base* cont_): unchecked_(false) { attach(cont_); } safe_iterator_base(const safe_iterator_base& it): unchecked_(it.unchecked_) { attach(it.cont); } safe_iterator_base& operator=(const safe_iterator_base& it) { unchecked_=it.unchecked_; safe_container_base* new_cont=it.cont; if(cont!=new_cont){ detach(); attach(new_cont); } return *this; } ~safe_iterator_base() { detach(); } const safe_container_base* owner()const{return cont;} BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS: friend class safe_container_base; #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) template<typename> friend class safe_mode::safe_container; template<typename Iterator> friend void safe_mode::detach_equivalent_iterators(Iterator&); #endif inline void attach(safe_container_base* cont_); safe_container_base* cont; safe_iterator_base* next; bool unchecked_; }; class safe_container_base:private noncopyable { public: safe_container_base(){} BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: friend class safe_iterator_base; #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) template<typename Iterator> friend void safe_mode::detach_equivalent_iterators(Iterator&); #endif ~safe_container_base() { /* Detaches all remaining iterators, which by now will * be those pointing to the end of the container. */ for(safe_iterator_base* it=header.next;it;it=it->next)it->cont=0; header.next=0; } void swap(safe_container_base& x) { for(safe_iterator_base* it0=header.next;it0;it0=it0->next)it0->cont=&x; for(safe_iterator_base* it1=x.header.next;it1;it1=it1->next)it1->cont=this; std::swap(header.cont,x.header.cont); std::swap(header.next,x.header.next); } safe_iterator_base header; #if defined(BOOST_HAS_THREADS) boost::detail::lightweight_mutex mutex; #endif }; void safe_iterator_base::attach(safe_container_base* cont_) { cont=cont_; if(cont){ #if defined(BOOST_HAS_THREADS) boost::detail::lightweight_mutex::scoped_lock lock(cont->mutex); #endif next=cont->header.next; cont->header.next=this; } } void safe_iterator_base::detach() { if(cont){ #if defined(BOOST_HAS_THREADS) boost::detail::lightweight_mutex::scoped_lock lock(cont->mutex); #endif safe_iterator_base *prev_,*next_; for(prev_=&cont->header;(next_=prev_->next)!=this;prev_=next_){} prev_->next=next; cont=0; } } } /* namespace multi_index::detail */ namespace safe_mode{ /* In order to enable safe mode on a container: * - The container must derive from safe_container<container_type>, * - iterators must be generated via safe_iterator, which adapts a * preexistent unsafe iterator class. */ template<typename Container> class safe_container; template<typename Iterator,typename Container> class safe_iterator: public detail::iter_adaptor<safe_iterator<Iterator,Container>,Iterator>, public detail::safe_iterator_base { typedef detail::iter_adaptor<safe_iterator,Iterator> super; typedef detail::safe_iterator_base safe_super; public: typedef Container container_type; typedef typename Iterator::reference reference; typedef typename Iterator::difference_type difference_type; safe_iterator(){} explicit safe_iterator(safe_container<container_type>* cont_): safe_super(cont_){} template<typename T0> safe_iterator(const T0& t0,safe_container<container_type>* cont_): super(Iterator(t0)),safe_super(cont_){} template<typename T0,typename T1> safe_iterator( const T0& t0,const T1& t1,safe_container<container_type>* cont_): super(Iterator(t0,t1)),safe_super(cont_){} safe_iterator(const safe_iterator& x):super(x),safe_super(x){} safe_iterator& operator=(const safe_iterator& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); this->base_reference()=x.base_reference(); safe_super::operator=(x); return *this; } const container_type* owner()const { return static_cast<const container_type*>( static_cast<const safe_container<container_type>*>( this->safe_super::owner())); } /* get_node is not to be used by the user */ typedef typename Iterator::node_type node_type; node_type* get_node()const{return this->base_reference().get_node();} private: friend class boost::multi_index::detail::iter_adaptor_access; reference dereference()const { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(*this); return *(this->base_reference()); } bool equal(const safe_iterator& x)const { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); BOOST_MULTI_INDEX_CHECK_SAME_OWNER(*this,x); return this->base_reference()==x.base_reference(); } void increment() { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(*this); ++(this->base_reference()); } void decrement() { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(*this); --(this->base_reference()); } void advance(difference_type n) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); BOOST_MULTI_INDEX_CHECK_IN_BOUNDS(*this,n); this->base_reference()+=n; } difference_type distance_to(const safe_iterator& x)const { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); BOOST_MULTI_INDEX_CHECK_SAME_OWNER(*this,x); return x.base_reference()-this->base_reference(); } #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) /* Serialization. Note that Iterator::save and Iterator:load * are assumed to be defined and public: at first sight it seems * like we could have resorted to the public serialization interface * for doing the forwarding to the adapted iterator class: * ar<<base_reference(); * ar>>base_reference(); * but this would cause incompatibilities if a saving * program is in safe mode and the loading program is not, or * viceversa --in safe mode, the archived iterator data is one layer * deeper, this is especially relevant with XML archives. * It'd be nice if Boost.Serialization provided some forwarding * facility for use by adaptor classes. */ friend class boost::serialization::access; BOOST_SERIALIZATION_SPLIT_MEMBER() template<class Archive> void save(Archive& ar,const unsigned int version)const { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); this->base_reference().save(ar,version); } template<class Archive> void load(Archive& ar,const unsigned int version) { this->base_reference().load(ar,version); safe_super::uncheck(); } #endif }; template<typename Container> class safe_container:public detail::safe_container_base { typedef detail::safe_container_base super; public: void detach_dereferenceable_iterators() { typedef typename Container::iterator iterator; iterator end_=static_cast<Container*>(this)->end(); iterator *prev_,*next_; for( prev_=static_cast<iterator*>(&this->header); (next_=static_cast<iterator*>(prev_->next))!=0;){ if(*next_!=end_){ prev_->next=next_->next; next_->cont=0; } else prev_=next_; } } void swap(safe_container<Container>& x) { super::swap(x); } }; } /* namespace multi_index::safe_mode */ } /* namespace multi_index */ #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) namespace serialization{ template<typename Iterator,typename Container> struct version< boost::multi_index::safe_mode::safe_iterator<Iterator,Container> > { BOOST_STATIC_CONSTANT( int,value=boost::serialization::version<Iterator>::value); }; } /* namespace serialization */ #endif } /* namespace boost */ #endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */ #endif PK 3L�[�|?�� � detail/value_compare.hppnu �[��� /* Copyright 2003-2015 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_VALUE_COMPARE_HPP #define BOOST_MULTI_INDEX_DETAIL_VALUE_COMPARE_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/call_traits.hpp> namespace boost{ namespace multi_index{ namespace detail{ template<typename Value,typename KeyFromValue,typename Compare> struct value_comparison { typedef Value first_argument_type; typedef Value second_argument_type; typedef bool result_type; value_comparison( const KeyFromValue& key_=KeyFromValue(),const Compare& comp_=Compare()): key(key_),comp(comp_) { } bool operator()( typename call_traits<Value>::param_type x, typename call_traits<Value>::param_type y)const { return comp(key(x),key(y)); } private: KeyFromValue key; Compare comp; }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[mi��� � detail/archive_constructed.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP #define BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/core/no_exceptions_support.hpp> #include <boost/noncopyable.hpp> #include <boost/serialization/serialization.hpp> #include <boost/type_traits/aligned_storage.hpp> #include <boost/type_traits/alignment_of.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* constructs a stack-based object from a serialization archive */ template<typename T> struct archive_constructed:private noncopyable { template<class Archive> archive_constructed(Archive& ar,const unsigned int version) { serialization::load_construct_data_adl(ar,&get(),version); BOOST_TRY{ ar>>get(); } BOOST_CATCH(...){ (&get())->~T(); BOOST_RETHROW; } BOOST_CATCH_END } template<class Archive> archive_constructed(const char* name,Archive& ar,const unsigned int version) { serialization::load_construct_data_adl(ar,&get(),version); BOOST_TRY{ ar>>serialization::make_nvp(name,get()); } BOOST_CATCH(...){ (&get())->~T(); BOOST_RETHROW; } BOOST_CATCH_END } ~archive_constructed() { (&get())->~T(); } #include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp> T& get(){return *reinterpret_cast<T*>(&space);} #include <boost/multi_index/detail/restore_wstrict_aliasing.hpp> private: typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space; }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[��Xs s detail/rnd_index_ops.hppnu �[��� /* Copyright 2003-2015 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_OPS_HPP #define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_OPS_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/multi_index/detail/rnd_index_ptr_array.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* Common code for random_access_index memfuns having templatized and * non-templatized versions. */ template<typename Node,typename Allocator,typename Predicate> Node* random_access_index_remove( random_access_index_ptr_array<Allocator>& ptrs,Predicate pred) { typedef typename Node::value_type value_type; typedef typename Node::impl_ptr_pointer impl_ptr_pointer; impl_ptr_pointer first=ptrs.begin(), res=first, last=ptrs.end(); for(;first!=last;++first){ if(!pred( const_cast<const value_type&>(Node::from_impl(*first)->value()))){ if(first!=res){ std::swap(*first,*res); (*first)->up()=first; (*res)->up()=res; } ++res; } } return Node::from_impl(*res); } template<typename Node,typename Allocator,class BinaryPredicate> Node* random_access_index_unique( random_access_index_ptr_array<Allocator>& ptrs,BinaryPredicate binary_pred) { typedef typename Node::value_type value_type; typedef typename Node::impl_ptr_pointer impl_ptr_pointer; impl_ptr_pointer first=ptrs.begin(), res=first, last=ptrs.end(); if(first!=last){ for(;++first!=last;){ if(!binary_pred( const_cast<const value_type&>(Node::from_impl(*res)->value()), const_cast<const value_type&>(Node::from_impl(*first)->value()))){ ++res; if(first!=res){ std::swap(*first,*res); (*first)->up()=first; (*res)->up()=res; } } } ++res; } return Node::from_impl(*res); } template<typename Node,typename Allocator,typename Compare> void random_access_index_inplace_merge( const Allocator& al, random_access_index_ptr_array<Allocator>& ptrs, BOOST_DEDUCED_TYPENAME Node::impl_ptr_pointer first1,Compare comp) { typedef typename Node::value_type value_type; typedef typename Node::impl_pointer impl_pointer; typedef typename Node::impl_ptr_pointer impl_ptr_pointer; auto_space<impl_pointer,Allocator> spc(al,ptrs.size()); impl_ptr_pointer first0=ptrs.begin(), last0=first1, last1=ptrs.end(), out=spc.data(); while(first0!=last0&&first1!=last1){ if(comp( const_cast<const value_type&>(Node::from_impl(*first1)->value()), const_cast<const value_type&>(Node::from_impl(*first0)->value()))){ *out++=*first1++; } else{ *out++=*first0++; } } std::copy(&*first0,&*last0,&*out); std::copy(&*first1,&*last1,&*out); first1=ptrs.begin(); out=spc.data(); while(first1!=last1){ *first1=*out++; (*first1)->up()=first1; ++first1; } } /* sorting */ /* auxiliary stuff */ template<typename Node,typename Compare> struct random_access_index_sort_compare { typedef typename Node::impl_pointer first_argument_type; typedef typename Node::impl_pointer second_argument_type; typedef bool result_type; random_access_index_sort_compare(Compare comp_=Compare()):comp(comp_){} bool operator()( typename Node::impl_pointer x,typename Node::impl_pointer y)const { typedef typename Node::value_type value_type; return comp( const_cast<const value_type&>(Node::from_impl(x)->value()), const_cast<const value_type&>(Node::from_impl(y)->value())); } private: Compare comp; }; template<typename Node,typename Allocator,class Compare> void random_access_index_sort( const Allocator& al, random_access_index_ptr_array<Allocator>& ptrs, Compare comp) { /* The implementation is extremely simple: an auxiliary * array of pointers is sorted using stdlib facilities and * then used to rearrange the index. This is suboptimal * in space and time, but has some advantages over other * possible approaches: * - Use std::stable_sort() directly on ptrs using some * special iterator in charge of maintaining pointers * and up() pointers in sync: we cannot guarantee * preservation of the container invariants in the face of * exceptions, if, for instance, std::stable_sort throws * when ptrs transitorily contains duplicate elements. * - Rewrite the internal algorithms of std::stable_sort * adapted for this case: besides being a fair amount of * work, making a stable sort compatible with Boost.MultiIndex * invariants (basically, no duplicates or missing elements * even if an exception is thrown) is complicated, error-prone * and possibly won't perform much better than the * solution adopted. */ if(ptrs.size()<=1)return; typedef typename Node::impl_pointer impl_pointer; typedef typename Node::impl_ptr_pointer impl_ptr_pointer; typedef random_access_index_sort_compare< Node,Compare> ptr_compare; impl_ptr_pointer first=ptrs.begin(); impl_ptr_pointer last=ptrs.end(); auto_space< impl_pointer, Allocator> spc(al,ptrs.size()); impl_ptr_pointer buf=spc.data(); std::copy(&*first,&*last,&*buf); std::stable_sort(&*buf,&*buf+ptrs.size(),ptr_compare(comp)); while(first!=last){ *first=*buf++; (*first)->up()=first; ++first; } } } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[��8� � detail/raw_ptr.hppnu �[��� /* Copyright 2003-2015 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP #define BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/mpl/bool.hpp> #include <boost/type_traits/is_same.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* gets the underlying pointer of a pointer-like value */ template<typename RawPointer> inline RawPointer raw_ptr(RawPointer const& p,mpl::true_) { return p; } template<typename RawPointer,typename Pointer> inline RawPointer raw_ptr(Pointer const& p,mpl::false_) { return p==Pointer(0)?0:&*p; } template<typename RawPointer,typename Pointer> inline RawPointer raw_ptr(Pointer const& p) { return raw_ptr<RawPointer>(p,is_same<RawPointer,Pointer>()); } } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[h ( detail/rnd_index_loader.hppnu �[��� /* Copyright 2003-2018 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_LOADER_HPP #define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_LOADER_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/multi_index/detail/allocator_traits.hpp> #include <boost/multi_index/detail/auto_space.hpp> #include <boost/multi_index/detail/rnd_index_ptr_array.hpp> #include <boost/noncopyable.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* This class implements a serialization rearranger for random access * indices. In order to achieve O(n) performance, the following strategy * is followed: the nodes of the index are handled as if in a bidirectional * list, where the next pointers are stored in the original * random_access_index_ptr_array and the prev pointers are stored in * an auxiliary array. Rearranging of nodes in such a bidirectional list * is constant time. Once all the arrangements are performed (on destruction * time) the list is traversed in reverse order and * pointers are swapped and set accordingly so that they recover its * original semantics ( *(node->up())==node ) while retaining the * new order. */ template<typename Allocator> class random_access_index_loader_base:private noncopyable { protected: typedef random_access_index_node_impl< typename rebind_alloc_for< Allocator, char >::type > node_impl_type; typedef typename node_impl_type::pointer node_impl_pointer; typedef random_access_index_ptr_array<Allocator> ptr_array; random_access_index_loader_base(const Allocator& al_,ptr_array& ptrs_): al(al_), ptrs(ptrs_), header(*ptrs.end()), prev_spc(al,0), preprocessed(false) {} ~random_access_index_loader_base() { if(preprocessed) { node_impl_pointer n=header; next(n)=n; for(size_type i=ptrs.size();i--;){ n=prev(n); size_type d=position(n); if(d!=i){ node_impl_pointer m=prev(next_at(i)); std::swap(m->up(),n->up()); next_at(d)=next_at(i); std::swap(prev_at(d),prev_at(i)); } next(n)=n; } } } void rearrange(node_impl_pointer position_,node_impl_pointer x) { preprocess(); /* only incur this penalty if rearrange() is ever called */ if(position_==node_impl_pointer(0))position_=header; next(prev(x))=next(x); prev(next(x))=prev(x); prev(x)=position_; next(x)=next(position_); next(prev(x))=prev(next(x))=x; } private: typedef allocator_traits<Allocator> alloc_traits; typedef typename alloc_traits::size_type size_type; void preprocess() { if(!preprocessed){ /* get space for the auxiliary prev array */ auto_space<node_impl_pointer,Allocator> tmp(al,ptrs.size()+1); prev_spc.swap(tmp); /* prev_spc elements point to the prev nodes */ std::rotate_copy( &*ptrs.begin(),&*ptrs.end(),&*ptrs.end()+1,&*prev_spc.data()); /* ptrs elements point to the next nodes */ std::rotate(&*ptrs.begin(),&*ptrs.begin()+1,&*ptrs.end()+1); preprocessed=true; } } size_type position(node_impl_pointer x)const { return (size_type)(x->up()-ptrs.begin()); } node_impl_pointer& next_at(size_type n)const { return *ptrs.at(n); } node_impl_pointer& prev_at(size_type n)const { return *(prev_spc.data()+n); } node_impl_pointer& next(node_impl_pointer x)const { return *(x->up()); } node_impl_pointer& prev(node_impl_pointer x)const { return prev_at(position(x)); } Allocator al; ptr_array& ptrs; node_impl_pointer header; auto_space<node_impl_pointer,Allocator> prev_spc; bool preprocessed; }; template<typename Node,typename Allocator> class random_access_index_loader: private random_access_index_loader_base<Allocator> { typedef random_access_index_loader_base<Allocator> super; typedef typename super::node_impl_pointer node_impl_pointer; typedef typename super::ptr_array ptr_array; public: random_access_index_loader(const Allocator& al_,ptr_array& ptrs_): super(al_,ptrs_) {} void rearrange(Node* position_,Node *x) { super::rearrange( position_?position_->impl():node_impl_pointer(0),x->impl()); } }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[���� � detail/ord_index_ops.hppnu �[��� /* Copyright 2003-2014 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. * * The internal implementation of red-black trees is based on that of SGI STL * stl_tree.h file: * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ #ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP #define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/mpl/and.hpp> #include <boost/multi_index/detail/promotes_arg.hpp> #include <utility> namespace boost{ namespace multi_index{ namespace detail{ /* Common code for index memfuns having templatized and * non-templatized versions. * Implementation note: When CompatibleKey is consistently promoted to * KeyFromValue::result_type for comparison, the promotion is made once in * advance to increase efficiency. */ template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline Node* ordered_index_find( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp) { typedef typename KeyFromValue::result_type key_type; return ordered_index_find( top,y,key,x,comp, mpl::and_< promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>, promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >()); } template< typename Node,typename KeyFromValue, typename CompatibleCompare > inline Node* ordered_index_find( Node* top,Node* y,const KeyFromValue& key, const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, const CompatibleCompare& comp,mpl::true_) { return ordered_index_find(top,y,key,x,comp,mpl::false_()); } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline Node* ordered_index_find( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp,mpl::false_) { Node* y0=y; while (top){ if(!comp(key(top->value()),x)){ y=top; top=Node::from_impl(top->left()); } else top=Node::from_impl(top->right()); } return (y==y0||comp(x,key(y->value())))?y0:y; } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline Node* ordered_index_lower_bound( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp) { typedef typename KeyFromValue::result_type key_type; return ordered_index_lower_bound( top,y,key,x,comp, promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey>()); } template< typename Node,typename KeyFromValue, typename CompatibleCompare > inline Node* ordered_index_lower_bound( Node* top,Node* y,const KeyFromValue& key, const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, const CompatibleCompare& comp,mpl::true_) { return ordered_index_lower_bound(top,y,key,x,comp,mpl::false_()); } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline Node* ordered_index_lower_bound( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp,mpl::false_) { while(top){ if(!comp(key(top->value()),x)){ y=top; top=Node::from_impl(top->left()); } else top=Node::from_impl(top->right()); } return y; } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline Node* ordered_index_upper_bound( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp) { typedef typename KeyFromValue::result_type key_type; return ordered_index_upper_bound( top,y,key,x,comp, promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>()); } template< typename Node,typename KeyFromValue, typename CompatibleCompare > inline Node* ordered_index_upper_bound( Node* top,Node* y,const KeyFromValue& key, const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, const CompatibleCompare& comp,mpl::true_) { return ordered_index_upper_bound(top,y,key,x,comp,mpl::false_()); } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline Node* ordered_index_upper_bound( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp,mpl::false_) { while(top){ if(comp(x,key(top->value()))){ y=top; top=Node::from_impl(top->left()); } else top=Node::from_impl(top->right()); } return y; } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline std::pair<Node*,Node*> ordered_index_equal_range( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp) { typedef typename KeyFromValue::result_type key_type; return ordered_index_equal_range( top,y,key,x,comp, mpl::and_< promotes_1st_arg<CompatibleCompare,CompatibleKey,key_type>, promotes_2nd_arg<CompatibleCompare,key_type,CompatibleKey> >()); } template< typename Node,typename KeyFromValue, typename CompatibleCompare > inline std::pair<Node*,Node*> ordered_index_equal_range( Node* top,Node* y,const KeyFromValue& key, const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, const CompatibleCompare& comp,mpl::true_) { return ordered_index_equal_range(top,y,key,x,comp,mpl::false_()); } template< typename Node,typename KeyFromValue, typename CompatibleKey,typename CompatibleCompare > inline std::pair<Node*,Node*> ordered_index_equal_range( Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, const CompatibleCompare& comp,mpl::false_) { while(top){ if(comp(key(top->value()),x)){ top=Node::from_impl(top->right()); } else if(comp(x,key(top->value()))){ y=top; top=Node::from_impl(top->left()); } else{ return std::pair<Node*,Node*>( ordered_index_lower_bound( Node::from_impl(top->left()),top,key,x,comp,mpl::false_()), ordered_index_upper_bound( Node::from_impl(top->right()),y,key,x,comp,mpl::false_())); } } return std::pair<Node*,Node*>(y,y); } } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�u�� � detail/is_function.hppnu �[��� /* Copyright 2003-2019 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_IS_FUNCTION_HPP #define BOOST_MULTI_INDEX_DETAIL_IS_FUNCTION_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/detail/workaround.hpp> #if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)||\ BOOST_WORKAROUND(_LIBCPP_VERSION,<30700)||\ BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<40802) /* libc++: std::is_function<void() const> fails, * https://bugs.llvm.org/show_bug.cgi?id=20084 * * libstdc++-v3: std::is_function does not support ref-qualified function types, * https://github.com/gcc-mirror/gcc/commit/ * 2fa630fb50ba29d8e891c52a75aaec261b07874e# * diff-6547f965a8d66bf35a6388fcf404aaa3 */ #include <boost/type_traits/is_function.hpp> namespace boost{namespace multi_index{namespace detail{ template<typename T> struct is_function:boost::is_function<T>{}; }}} /* namespace boost::multi_index::detail */ #else #include <type_traits> namespace boost{namespace multi_index{namespace detail{ template<typename T> struct is_function:std::is_function<T>{}; }}} /* namespace boost::multi_index::detail */ #endif #endif PK 3L�[v˚q�5 �5 detail/scope_guard.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP #define BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/core/no_exceptions_support.hpp> #include <boost/mpl/if.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* Until some official version of the ScopeGuard idiom makes it into Boost, * we locally define our own. This is a merely reformated version of * ScopeGuard.h as defined in: * Alexandrescu, A., Marginean, P.:"Generic<Programming>: Change the Way You * Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000, * http://www.drdobbs.com/184403758 * with the following modifications: * - General pretty formatting (pretty to my taste at least.) * - Naming style changed to standard C++ library requirements. * - Added scope_guard_impl4 and obj_scope_guard_impl3, (Boost.MultiIndex * needs them). A better design would provide guards for many more * arguments through the Boost Preprocessor Library. * - Added scope_guard_impl_base::touch (see below.) * - Removed RefHolder and ByRef, whose functionality is provided * already by Boost.Ref. * - Removed static make_guard's and make_obj_guard's, so that the code * will work even if BOOST_NO_MEMBER_TEMPLATES is defined. This forces * us to move some private ctors to public, though. * * NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute * without an explicit qualification. * * We also define the following variants of the idiom: * * - make_guard_if_c<bool>( ... ) * - make_guard_if<IntegralConstant>( ... ) * - make_obj_guard_if_c<bool>( ... ) * - make_obj_guard_if<IntegralConstant>( ... ) * which may be used with a compile-time constant to yield * a "null_guard" if the boolean compile-time parameter is false, * or conversely, the guard is only constructed if the constant is true. * This is useful to avoid extra tagging, because the returned * null_guard can be optimzed comlpetely away by the compiler. */ class scope_guard_impl_base { public: scope_guard_impl_base():dismissed_(false){} void dismiss()const{dismissed_=true;} /* This helps prevent some "unused variable" warnings under, for instance, * GCC 3.2. */ void touch()const{} protected: ~scope_guard_impl_base(){} scope_guard_impl_base(const scope_guard_impl_base& other): dismissed_(other.dismissed_) { other.dismiss(); } template<typename J> static void safe_execute(J& j){ BOOST_TRY{ if(!j.dismissed_)j.execute(); } BOOST_CATCH(...){} BOOST_CATCH_END } mutable bool dismissed_; private: scope_guard_impl_base& operator=(const scope_guard_impl_base&); }; typedef const scope_guard_impl_base& scope_guard; struct null_guard : public scope_guard_impl_base { template< class T1 > null_guard( const T1& ) { } template< class T1, class T2 > null_guard( const T1&, const T2& ) { } template< class T1, class T2, class T3 > null_guard( const T1&, const T2&, const T3& ) { } template< class T1, class T2, class T3, class T4 > null_guard( const T1&, const T2&, const T3&, const T4& ) { } template< class T1, class T2, class T3, class T4, class T5 > null_guard( const T1&, const T2&, const T3&, const T4&, const T5& ) { } }; template< bool cond, class T > struct null_guard_return { typedef typename boost::mpl::if_c<cond,T,null_guard>::type type; }; template<typename F> class scope_guard_impl0:public scope_guard_impl_base { public: scope_guard_impl0(F fun):fun_(fun){} ~scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} void execute(){fun_();} protected: F fun_; }; template<typename F> inline scope_guard_impl0<F> make_guard(F fun) { return scope_guard_impl0<F>(fun); } template<bool cond, typename F> inline typename null_guard_return<cond,scope_guard_impl0<F> >::type make_guard_if_c(F fun) { return typename null_guard_return<cond,scope_guard_impl0<F> >::type(fun); } template<typename C, typename F> inline typename null_guard_return<C::value,scope_guard_impl0<F> >::type make_guard_if(F fun) { return make_guard_if<C::value>(fun); } template<typename F,typename P1> class scope_guard_impl1:public scope_guard_impl_base { public: scope_guard_impl1(F fun,P1 p1):fun_(fun),p1_(p1){} ~scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} void execute(){fun_(p1_);} protected: F fun_; const P1 p1_; }; template<typename F,typename P1> inline scope_guard_impl1<F,P1> make_guard(F fun,P1 p1) { return scope_guard_impl1<F,P1>(fun,p1); } template<bool cond, typename F,typename P1> inline typename null_guard_return<cond,scope_guard_impl1<F,P1> >::type make_guard_if_c(F fun,P1 p1) { return typename null_guard_return<cond,scope_guard_impl1<F,P1> >::type(fun,p1); } template<typename C, typename F,typename P1> inline typename null_guard_return<C::value,scope_guard_impl1<F,P1> >::type make_guard_if(F fun,P1 p1) { return make_guard_if_c<C::value>(fun,p1); } template<typename F,typename P1,typename P2> class scope_guard_impl2:public scope_guard_impl_base { public: scope_guard_impl2(F fun,P1 p1,P2 p2):fun_(fun),p1_(p1),p2_(p2){} ~scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} void execute(){fun_(p1_,p2_);} protected: F fun_; const P1 p1_; const P2 p2_; }; template<typename F,typename P1,typename P2> inline scope_guard_impl2<F,P1,P2> make_guard(F fun,P1 p1,P2 p2) { return scope_guard_impl2<F,P1,P2>(fun,p1,p2); } template<bool cond, typename F,typename P1,typename P2> inline typename null_guard_return<cond,scope_guard_impl2<F,P1,P2> >::type make_guard_if_c(F fun,P1 p1,P2 p2) { return typename null_guard_return<cond,scope_guard_impl2<F,P1,P2> >::type(fun,p1,p2); } template<typename C, typename F,typename P1,typename P2> inline typename null_guard_return<C::value,scope_guard_impl2<F,P1,P2> >::type make_guard_if(F fun,P1 p1,P2 p2) { return make_guard_if_c<C::value>(fun,p1,p2); } template<typename F,typename P1,typename P2,typename P3> class scope_guard_impl3:public scope_guard_impl_base { public: scope_guard_impl3(F fun,P1 p1,P2 p2,P3 p3):fun_(fun),p1_(p1),p2_(p2),p3_(p3){} ~scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} void execute(){fun_(p1_,p2_,p3_);} protected: F fun_; const P1 p1_; const P2 p2_; const P3 p3_; }; template<typename F,typename P1,typename P2,typename P3> inline scope_guard_impl3<F,P1,P2,P3> make_guard(F fun,P1 p1,P2 p2,P3 p3) { return scope_guard_impl3<F,P1,P2,P3>(fun,p1,p2,p3); } template<bool cond,typename F,typename P1,typename P2,typename P3> inline typename null_guard_return<cond,scope_guard_impl3<F,P1,P2,P3> >::type make_guard_if_c(F fun,P1 p1,P2 p2,P3 p3) { return typename null_guard_return<cond,scope_guard_impl3<F,P1,P2,P3> >::type(fun,p1,p2,p3); } template<typename C,typename F,typename P1,typename P2,typename P3> inline typename null_guard_return< C::value,scope_guard_impl3<F,P1,P2,P3> >::type make_guard_if(F fun,P1 p1,P2 p2,P3 p3) { return make_guard_if_c<C::value>(fun,p1,p2,p3); } template<typename F,typename P1,typename P2,typename P3,typename P4> class scope_guard_impl4:public scope_guard_impl_base { public: scope_guard_impl4(F fun,P1 p1,P2 p2,P3 p3,P4 p4): fun_(fun),p1_(p1),p2_(p2),p3_(p3),p4_(p4){} ~scope_guard_impl4(){scope_guard_impl_base::safe_execute(*this);} void execute(){fun_(p1_,p2_,p3_,p4_);} protected: F fun_; const P1 p1_; const P2 p2_; const P3 p3_; const P4 p4_; }; template<typename F,typename P1,typename P2,typename P3,typename P4> inline scope_guard_impl4<F,P1,P2,P3,P4> make_guard( F fun,P1 p1,P2 p2,P3 p3,P4 p4) { return scope_guard_impl4<F,P1,P2,P3,P4>(fun,p1,p2,p3,p4); } template<bool cond, typename F,typename P1,typename P2,typename P3,typename P4> inline typename null_guard_return<cond,scope_guard_impl4<F,P1,P2,P3,P4> >::type make_guard_if_c( F fun,P1 p1,P2 p2,P3 p3,P4 p4) { return typename null_guard_return<cond,scope_guard_impl4<F,P1,P2,P3,P4> >::type(fun,p1,p2,p3,p4); } template<typename C, typename F,typename P1,typename P2,typename P3,typename P4> inline typename null_guard_return<C::value,scope_guard_impl4<F,P1,P2,P3,P4> >::type make_guard_if( F fun,P1 p1,P2 p2,P3 p3,P4 p4) { return make_guard_if_c<C::value>(fun,p1,p2,p3,p4); } template<class Obj,typename MemFun> class obj_scope_guard_impl0:public scope_guard_impl_base { public: obj_scope_guard_impl0(Obj& obj,MemFun mem_fun):obj_(obj),mem_fun_(mem_fun){} ~obj_scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} void execute(){(obj_.*mem_fun_)();} protected: Obj& obj_; MemFun mem_fun_; }; template<class Obj,typename MemFun> inline obj_scope_guard_impl0<Obj,MemFun> make_obj_guard(Obj& obj,MemFun mem_fun) { return obj_scope_guard_impl0<Obj,MemFun>(obj,mem_fun); } template<bool cond, class Obj,typename MemFun> inline typename null_guard_return<cond,obj_scope_guard_impl0<Obj,MemFun> >::type make_obj_guard_if_c(Obj& obj,MemFun mem_fun) { return typename null_guard_return<cond,obj_scope_guard_impl0<Obj,MemFun> >::type(obj,mem_fun); } template<typename C, class Obj,typename MemFun> inline typename null_guard_return<C::value,obj_scope_guard_impl0<Obj,MemFun> >::type make_obj_guard_if(Obj& obj,MemFun mem_fun) { return make_obj_guard_if_c<C::value>(obj,mem_fun); } template<class Obj,typename MemFun,typename P1> class obj_scope_guard_impl1:public scope_guard_impl_base { public: obj_scope_guard_impl1(Obj& obj,MemFun mem_fun,P1 p1): obj_(obj),mem_fun_(mem_fun),p1_(p1){} ~obj_scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} void execute(){(obj_.*mem_fun_)(p1_);} protected: Obj& obj_; MemFun mem_fun_; const P1 p1_; }; template<class Obj,typename MemFun,typename P1> inline obj_scope_guard_impl1<Obj,MemFun,P1> make_obj_guard( Obj& obj,MemFun mem_fun,P1 p1) { return obj_scope_guard_impl1<Obj,MemFun,P1>(obj,mem_fun,p1); } template<bool cond, class Obj,typename MemFun,typename P1> inline typename null_guard_return<cond,obj_scope_guard_impl1<Obj,MemFun,P1> >::type make_obj_guard_if_c( Obj& obj,MemFun mem_fun,P1 p1) { return typename null_guard_return<cond,obj_scope_guard_impl1<Obj,MemFun,P1> >::type(obj,mem_fun,p1); } template<typename C, class Obj,typename MemFun,typename P1> inline typename null_guard_return<C::value,obj_scope_guard_impl1<Obj,MemFun,P1> >::type make_obj_guard_if( Obj& obj,MemFun mem_fun,P1 p1) { return make_obj_guard_if_c<C::value>(obj,mem_fun,p1); } template<class Obj,typename MemFun,typename P1,typename P2> class obj_scope_guard_impl2:public scope_guard_impl_base { public: obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2): obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2) {} ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} void execute(){(obj_.*mem_fun_)(p1_,p2_);} protected: Obj& obj_; MemFun mem_fun_; const P1 p1_; const P2 p2_; }; template<class Obj,typename MemFun,typename P1,typename P2> inline obj_scope_guard_impl2<Obj,MemFun,P1,P2> make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) { return obj_scope_guard_impl2<Obj,MemFun,P1,P2>(obj,mem_fun,p1,p2); } template<bool cond, class Obj,typename MemFun,typename P1,typename P2> inline typename null_guard_return<cond,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) { return typename null_guard_return<cond,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type(obj,mem_fun,p1,p2); } template<typename C, class Obj,typename MemFun,typename P1,typename P2> inline typename null_guard_return<C::value,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) { return make_obj_guard_if_c<C::value>(obj,mem_fun,p1,p2); } template<class Obj,typename MemFun,typename P1,typename P2,typename P3> class obj_scope_guard_impl3:public scope_guard_impl_base { public: obj_scope_guard_impl3(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3): obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2),p3_(p3) {} ~obj_scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} void execute(){(obj_.*mem_fun_)(p1_,p2_,p3_);} protected: Obj& obj_; MemFun mem_fun_; const P1 p1_; const P2 p2_; const P3 p3_; }; template<class Obj,typename MemFun,typename P1,typename P2,typename P3> inline obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) { return obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3>(obj,mem_fun,p1,p2,p3); } template<bool cond, class Obj,typename MemFun,typename P1,typename P2,typename P3> inline typename null_guard_return<cond,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) { return typename null_guard_return<cond,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type(obj,mem_fun,p1,p2,p3); } template<typename C, class Obj,typename MemFun,typename P1,typename P2,typename P3> inline typename null_guard_return<C::value,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) { return make_obj_guard_if_c<C::value>(obj,mem_fun,p1,p2,p3); } } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[IE2��* �* detail/vartempl_support.hppnu �[��� /* Copyright 2003-2013 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP #define BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP #if defined(_MSC_VER) #pragma once #endif /* Utilities for emulation of variadic template functions. Variadic packs are * replaced by lists of BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS parameters: * * - typename... Args --> BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK * - Args&&... args --> BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK * - std::forward<Args>(args)... --> BOOST_MULTI_INDEX_FORWARD_PARAM_PACK * * Forwarding emulated with Boost.Move. A template functions foo_imp * defined in such way accepts *exactly* BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS * arguments: variable number of arguments is emulated by providing a set of * overloads foo forwarding to foo_impl with * * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG (initial extra arg) * * which fill the extra args with boost::multi_index::detail::noarg's. * boost::multi_index::detail::vartempl_placement_new works the opposite * way: it acceps a full a pointer x to Value and a * BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK and forwards to * new(x) Value(args) where args is the argument pack after discarding * noarg's. * * Emulation decays to the real thing when the compiler supports variadic * templates and move semantics natively. */ #include <boost/config.hpp> #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)||\ defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #include <boost/move/core.hpp> #include <boost/move/utility.hpp> #include <boost/preprocessor/arithmetic/add.hpp> #include <boost/preprocessor/arithmetic/sub.hpp> #include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/control/if.hpp> #include <boost/preprocessor/facilities/empty.hpp> #include <boost/preprocessor/facilities/intercept.hpp> #include <boost/preprocessor/logical/and.hpp> #include <boost/preprocessor/punctuation/comma.hpp> #include <boost/preprocessor/punctuation/comma_if.hpp> #include <boost/preprocessor/repetition/enum.hpp> #include <boost/preprocessor/repetition/enum_params.hpp> #include <boost/preprocessor/repetition/repeat_from_to.hpp> #include <boost/preprocessor/seq/elem.hpp> #if !defined(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS) #define BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 5 #endif #define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK \ BOOST_PP_ENUM_PARAMS( \ BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,typename T) #define BOOST_MULTI_INDEX_VARTEMPL_ARG(z,n,_) \ BOOST_FWD_REF(BOOST_PP_CAT(T,n)) BOOST_PP_CAT(t,n) #define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK \ BOOST_PP_ENUM( \ BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ BOOST_MULTI_INDEX_VARTEMPL_ARG,~) #define BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG(z,n,_) \ boost::forward<BOOST_PP_CAT(T,n)>(BOOST_PP_CAT(t,n)) #define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK \ BOOST_PP_ENUM( \ BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) namespace boost{namespace multi_index{namespace detail{ struct noarg{}; }}} /* call vartempl function without args */ #define BOOST_MULTI_INDEX_NULL_PARAM_PACK \ BOOST_PP_ENUM_PARAMS( \ BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) #define BOOST_MULTI_INDEX_TEMPLATE_N(n) \ template<BOOST_PP_ENUM_PARAMS(n,typename T)> #define BOOST_MULTI_INDEX_TEMPLATE_0(n) #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX(z,n,data) \ BOOST_PP_IF(n, \ BOOST_MULTI_INDEX_TEMPLATE_N, \ BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ { \ return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ BOOST_PP_COMMA_IF( \ BOOST_PP_AND( \ n,BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))) \ BOOST_PP_ENUM_PARAMS( \ BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ ); \ } #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ ret,name_from,name_to) \ BOOST_PP_REPEAT_FROM_TO( \ 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX, \ (ret)(name_from)(name_to)) #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX( \ z,n,data) \ BOOST_PP_IF(n, \ BOOST_MULTI_INDEX_TEMPLATE_N, \ BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ BOOST_PP_SEQ_ELEM(3,data) BOOST_PP_SEQ_ELEM(4,data) /* extra arg */\ BOOST_PP_COMMA_IF(n) \ BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ { \ return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ BOOST_PP_SEQ_ELEM(4,data) /* extra_arg_name */ \ BOOST_PP_COMMA_IF(n) \ BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ BOOST_PP_COMMA_IF( \ BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ BOOST_PP_ENUM_PARAMS( \ BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ ); \ } #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ ret,name_from,name_to,extra_arg_type,extra_arg_name) \ BOOST_PP_REPEAT_FROM_TO( \ 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX, \ (ret)(name_from)(name_to)(extra_arg_type)(extra_arg_name)) namespace boost{ namespace multi_index{ namespace detail{ #define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX(z,n,name) \ template< \ typename Value \ BOOST_PP_COMMA_IF(n) \ BOOST_PP_ENUM_PARAMS(n,typename T) \ > \ Value* name( \ Value* x \ BOOST_PP_COMMA_IF(n) \ BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~) \ BOOST_PP_COMMA_IF( \ BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ BOOST_PP_ENUM_PARAMS( \ BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ BOOST_FWD_REF(noarg) BOOST_PP_INTERCEPT)) \ { \ return new(x) Value( \ BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)); \ } #define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(name) \ BOOST_PP_REPEAT_FROM_TO( \ 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX, \ name) BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(vartempl_placement_new) #undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX #undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #else /* native variadic templates support */ #include <utility> #define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK typename... Args #define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK Args&&... args #define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK std::forward<Args>(args)... #define BOOST_MULTI_INDEX_NULL_PARAM_PACK #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ ret,name_from,name_to) \ template<typename... Args> ret name_from(Args&&... args) \ { \ return name_to(std::forward<Args>(args)...); \ } #define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ ret,name_from,name_to,extra_arg_type,extra_arg_name) \ template<typename... Args> ret name_from( \ extra_arg_type extra_arg_name,Args&&... args) \ { \ return name_to(extra_arg_name,std::forward<Args>(args)...); \ } namespace boost{ namespace multi_index{ namespace detail{ template<typename Value,typename... Args> Value* vartempl_placement_new(Value*x,Args&&... args) { return new(x) Value(std::forward<Args>(args)...); } } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif #endif PK 3L�['Y�EO O detail/seq_index_node.hppnu �[��� /* Copyright 2003-2019 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP #define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/multi_index/detail/allocator_traits.hpp> #include <boost/multi_index/detail/raw_ptr.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* doubly-linked node for use by sequenced_index */ template<typename Allocator> struct sequenced_index_node_impl { typedef typename rebind_alloc_for< Allocator,sequenced_index_node_impl >::type node_allocator; typedef allocator_traits<node_allocator> alloc_traits; typedef typename alloc_traits::pointer pointer; typedef typename alloc_traits::const_pointer const_pointer; typedef typename alloc_traits::difference_type difference_type; pointer& prior(){return prior_;} pointer prior()const{return prior_;} pointer& next(){return next_;} pointer next()const{return next_;} /* interoperability with bidir_node_iterator */ static void increment(pointer& x){x=x->next();} static void decrement(pointer& x){x=x->prior();} /* algorithmic stuff */ static void link(pointer x,pointer header) { x->prior()=header->prior(); x->next()=header; x->prior()->next()=x->next()->prior()=x; } static void unlink(pointer x) { x->prior()->next()=x->next(); x->next()->prior()=x->prior(); } static void relink(pointer position,pointer x) { unlink(x); x->prior()=position->prior(); x->next()=position; x->prior()->next()=x->next()->prior()=x; } static void relink(pointer position,pointer x,pointer y) { /* position is assumed not to be in [x,y) */ if(x!=y){ pointer z=y->prior(); x->prior()->next()=y; y->prior()=x->prior(); x->prior()=position->prior(); z->next()=position; x->prior()->next()=x; z->next()->prior()=z; } } static void reverse(pointer header) { pointer x=header; do{ pointer y=x->next(); std::swap(x->prior(),x->next()); x=y; }while(x!=header); } static void swap(pointer x,pointer y) { /* This swap function does not exchange the header nodes, * but rather their pointers. This is *not* used for implementing * sequenced_index::swap. */ if(x->next()!=x){ if(y->next()!=y){ std::swap(x->next(),y->next()); std::swap(x->prior(),y->prior()); x->next()->prior()=x->prior()->next()=x; y->next()->prior()=y->prior()->next()=y; } else{ y->next()=x->next(); y->prior()=x->prior(); x->next()=x->prior()=x; y->next()->prior()=y->prior()->next()=y; } } else if(y->next()!=y){ x->next()=y->next(); x->prior()=y->prior(); y->next()=y->prior()=y; x->next()->prior()=x->prior()->next()=x; } } private: pointer prior_; pointer next_; }; template<typename Super> struct sequenced_index_node_trampoline: sequenced_index_node_impl< typename rebind_alloc_for< typename Super::allocator_type, char >::type > { typedef sequenced_index_node_impl< typename rebind_alloc_for< typename Super::allocator_type, char >::type > impl_type; }; template<typename Super> struct sequenced_index_node:Super,sequenced_index_node_trampoline<Super> { private: typedef sequenced_index_node_trampoline<Super> trampoline; public: typedef typename trampoline::impl_type impl_type; typedef typename trampoline::pointer impl_pointer; typedef typename trampoline::const_pointer const_impl_pointer; typedef typename trampoline::difference_type difference_type; impl_pointer& prior(){return trampoline::prior();} impl_pointer prior()const{return trampoline::prior();} impl_pointer& next(){return trampoline::next();} impl_pointer next()const{return trampoline::next();} impl_pointer impl() { return static_cast<impl_pointer>( static_cast<impl_type*>(static_cast<trampoline*>(this))); } const_impl_pointer impl()const { return static_cast<const_impl_pointer>( static_cast<const impl_type*>(static_cast<const trampoline*>(this))); } static sequenced_index_node* from_impl(impl_pointer x) { return static_cast<sequenced_index_node*>( static_cast<trampoline*>( raw_ptr<impl_type*>(x))); } static const sequenced_index_node* from_impl(const_impl_pointer x) { return static_cast<const sequenced_index_node*>( static_cast<const trampoline*>( raw_ptr<const impl_type*>(x))); } /* interoperability with bidir_node_iterator */ static void increment(sequenced_index_node*& x) { impl_pointer xi=x->impl(); trampoline::increment(xi); x=from_impl(xi); } static void decrement(sequenced_index_node*& x) { impl_pointer xi=x->impl(); trampoline::decrement(xi); x=from_impl(xi); } }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�^N�� � # detail/restore_wstrict_aliasing.hppnu �[��� /* Copyright 2003-2016 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #define BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING #include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp> #undef BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING PK 3L�[���"7 7 detail/hash_index_iterator.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP #define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/operators.hpp> #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include <boost/serialization/nvp.hpp> #include <boost/serialization/split_member.hpp> #include <boost/serialization/version.hpp> #endif namespace boost{ namespace multi_index{ namespace detail{ /* Iterator class for hashed indices. */ struct hashed_index_global_iterator_tag{}; struct hashed_index_local_iterator_tag{}; template< typename Node,typename BucketArray, typename IndexCategory,typename IteratorCategory > class hashed_index_iterator: public forward_iterator_helper< hashed_index_iterator<Node,BucketArray,IndexCategory,IteratorCategory>, typename Node::value_type, typename Node::difference_type, const typename Node::value_type*, const typename Node::value_type&> { public: /* coverity[uninit_ctor]: suppress warning */ hashed_index_iterator(){} hashed_index_iterator(Node* node_):node(node_){} const typename Node::value_type& operator*()const { return node->value(); } hashed_index_iterator& operator++() { this->increment(IteratorCategory()); return *this; } #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) /* Serialization. As for why the following is public, * see explanation in safe_mode_iterator notes in safe_mode.hpp. */ BOOST_SERIALIZATION_SPLIT_MEMBER() typedef typename Node::base_type node_base_type; template<class Archive> void save(Archive& ar,const unsigned int)const { node_base_type* bnode=node; ar<<serialization::make_nvp("pointer",bnode); } template<class Archive> void load(Archive& ar,const unsigned int version) { load(ar,version,IteratorCategory()); } template<class Archive> void load( Archive& ar,const unsigned int version,hashed_index_global_iterator_tag) { node_base_type* bnode; ar>>serialization::make_nvp("pointer",bnode); node=static_cast<Node*>(bnode); if(version<1){ BucketArray* throw_away; /* consume unused ptr */ ar>>serialization::make_nvp("pointer",throw_away); } } template<class Archive> void load( Archive& ar,const unsigned int version,hashed_index_local_iterator_tag) { node_base_type* bnode; ar>>serialization::make_nvp("pointer",bnode); node=static_cast<Node*>(bnode); if(version<1){ BucketArray* buckets; ar>>serialization::make_nvp("pointer",buckets); if(buckets&&node&&node->impl()==buckets->end()->prior()){ /* end local_iterators used to point to end node, now they are null */ node=0; } } } #endif /* get_node is not to be used by the user */ typedef Node node_type; Node* get_node()const{return node;} private: void increment(hashed_index_global_iterator_tag) { Node::template increment<IndexCategory>(node); } void increment(hashed_index_local_iterator_tag) { Node::template increment_local<IndexCategory>(node); } Node* node; }; template< typename Node,typename BucketArray, typename IndexCategory,typename IteratorCategory > bool operator==( const hashed_index_iterator< Node,BucketArray,IndexCategory,IteratorCategory>& x, const hashed_index_iterator< Node,BucketArray,IndexCategory,IteratorCategory>& y) { return x.get_node()==y.get_node(); } } /* namespace multi_index::detail */ } /* namespace multi_index */ #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) /* class version = 1 : hashed_index_iterator does no longer serialize a bucket * array pointer. */ namespace serialization { template< typename Node,typename BucketArray, typename IndexCategory,typename IteratorCategory > struct version< boost::multi_index::detail::hashed_index_iterator< Node,BucketArray,IndexCategory,IteratorCategory > > { BOOST_STATIC_CONSTANT(int,value=1); }; } /* namespace serialization */ #endif } /* namespace boost */ #endif PK 3L�[�AǶ] ] detail/allocator_traits.hppnu �[��� /* Copyright 2003-2020 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_ALLOCATOR_TRAITS_HPP #define BOOST_MULTI_INDEX_DETAIL_ALLOCATOR_TRAITS_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #if !defined(BOOST_NO_CXX11_ALLOCATOR) #include <boost/type_traits/is_empty.hpp> #include <memory> #else #include <boost/detail/workaround.hpp> #include <boost/move/core.hpp> #include <boost/move/utility_core.hpp> #include <boost/multi_index/detail/vartempl_support.hpp> #include <boost/type_traits/integral_constant.hpp> #include <boost/type_traits/is_empty.hpp> #include <new> #endif namespace boost{ namespace multi_index{ namespace detail{ /* poor man's replacement of std::allocator_traits */ #if !defined(BOOST_NO_CXX11_ALLOCATOR) template<typename T> struct void_helper{typedef void type;}; template<typename Allocator,typename=void> struct allocator_is_always_equal:boost::is_empty<Allocator>{}; template<typename Allocator> struct allocator_is_always_equal< Allocator, typename void_helper< typename std::allocator_traits<Allocator>::is_always_equal >::type >:std::allocator_traits<Allocator>::is_always_equal{}; template<typename Allocator> struct allocator_traits:std::allocator_traits<Allocator> { /* wrap std::allocator_traits alias templates for use in C++03 codebase */ typedef std::allocator_traits<Allocator> super; /* pre-C++17 compatibilty */ typedef allocator_is_always_equal<Allocator> is_always_equal; template<typename T> struct rebind_alloc { typedef typename super::template rebind_alloc<T> type; }; template<typename T> struct rebind_traits { typedef typename super::template rebind_traits<T> type; }; }; #else /* not a full std::allocator_traits rewrite (not needed) */ template<typename Allocator> struct allocator_traits { typedef Allocator allocator_type; typedef typename Allocator::value_type value_type; typedef typename Allocator::pointer pointer; typedef typename Allocator::const_pointer const_pointer; /* [const_]void_pointer not provided as boost::pointer_traits's * rebind_to has been seen to fail with things like * boost::interprocess::offset_ptr in relatively old environments. */ typedef typename Allocator::difference_type difference_type; typedef typename Allocator::size_type size_type; typedef boost::false_type propagate_on_container_copy_assignment; typedef boost::false_type propagate_on_container_move_assignment; typedef boost::false_type propagate_on_container_swap; typedef boost::is_empty<Allocator> is_always_equal; template<typename T> struct rebind_alloc { typedef typename Allocator::template rebind<T>::other type; }; template<typename T> struct rebind_traits { typedef allocator_traits<typename rebind_alloc<T>::type> type; }; static pointer allocate(Allocator& a,size_type n){return a.allocate(n);} static pointer allocate(Allocator& a,size_type n,const_pointer p) /* should've been const_void_pointer p */ {return a.allocate(n,p);} static void deallocate(Allocator& a,pointer p,size_type n) {a.deallocate(p,n);} template<typename T> static void construct(Allocator&,T* p,const T& x) {::new (static_cast<void*>(p)) T(x);} template<typename T> static void construct(Allocator&,T* p,BOOST_RV_REF(T) x) {::new (static_cast<void*>(p)) T(boost::move(x));} template<typename T,BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK> static void construct(Allocator&,T* p,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) { vartempl_placement_new(p,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); } #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) /* MSVC issues spurious warnings about unreferencend formal parameters in * destroy<T> when T is a class with trivial dtor. */ #pragma warning(push) #pragma warning(disable:4100) #endif template<typename T> static void destroy(Allocator&,T* p){p->~T();} #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) #pragma warning(pop) #endif static size_type max_size(Allocator& a)BOOST_NOEXCEPT{return a.max_size();} static Allocator select_on_container_copy_construction(const Allocator& a) { return a; } }; #endif template<typename Allocator,typename T> struct rebind_alloc_for { typedef typename allocator_traits<Allocator>:: template rebind_alloc<T>::type type; }; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[1"i � detail/ord_index_impl_fwd.hppnu �[��� /* Copyright 2003-2015 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP #define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP #if defined(_MSC_VER) #pragma once #endif namespace boost{ namespace multi_index{ namespace detail{ template< typename KeyFromValue,typename Compare, typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy > class ordered_index; template< typename KeyFromValue1,typename Compare1, typename SuperMeta1,typename TagList1,typename Category1, typename AugmentPolicy1, typename KeyFromValue2,typename Compare2, typename SuperMeta2,typename TagList2,typename Category2, typename AugmentPolicy2 > bool operator==( const ordered_index< KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, const ordered_index< KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); template< typename KeyFromValue1,typename Compare1, typename SuperMeta1,typename TagList1,typename Category1, typename AugmentPolicy1, typename KeyFromValue2,typename Compare2, typename SuperMeta2,typename TagList2,typename Category2, typename AugmentPolicy2 > bool operator<( const ordered_index< KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, const ordered_index< KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); template< typename KeyFromValue1,typename Compare1, typename SuperMeta1,typename TagList1,typename Category1, typename AugmentPolicy1, typename KeyFromValue2,typename Compare2, typename SuperMeta2,typename TagList2,typename Category2, typename AugmentPolicy2 > bool operator!=( const ordered_index< KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, const ordered_index< KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); template< typename KeyFromValue1,typename Compare1, typename SuperMeta1,typename TagList1,typename Category1, typename AugmentPolicy1, typename KeyFromValue2,typename Compare2, typename SuperMeta2,typename TagList2,typename Category2, typename AugmentPolicy2 > bool operator>( const ordered_index< KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, const ordered_index< KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); template< typename KeyFromValue1,typename Compare1, typename SuperMeta1,typename TagList1,typename Category1, typename AugmentPolicy1, typename KeyFromValue2,typename Compare2, typename SuperMeta2,typename TagList2,typename Category2, typename AugmentPolicy2 > bool operator>=( const ordered_index< KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, const ordered_index< KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); template< typename KeyFromValue1,typename Compare1, typename SuperMeta1,typename TagList1,typename Category1, typename AugmentPolicy1, typename KeyFromValue2,typename Compare2, typename SuperMeta2,typename TagList2,typename Category2, typename AugmentPolicy2 > bool operator<=( const ordered_index< KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, const ordered_index< KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); template< typename KeyFromValue,typename Compare, typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy > void swap( ordered_index< KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, ordered_index< KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y); } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�k� detail/duplicates_iterator.hppnu �[��� /* Copyright 2003-2018 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP #define BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <iterator> namespace boost{ namespace multi_index{ namespace detail{ /* duplicates_operator is given a range of ordered elements and * passes only over those which are duplicated. */ template<typename Node,typename Predicate> class duplicates_iterator { public: typedef typename Node::value_type value_type; typedef typename Node::difference_type difference_type; typedef const typename Node::value_type* pointer; typedef const typename Node::value_type& reference; typedef std::forward_iterator_tag iterator_category; duplicates_iterator(Node* node_,Node* end_,Predicate pred_): node(node_),begin_chunk(0),end(end_),pred(pred_) { advance(); } duplicates_iterator(Node* end_,Predicate pred_): node(end_),begin_chunk(end_),end(end_),pred(pred_) { } reference operator*()const { return node->value(); } pointer operator->()const { return &node->value(); } duplicates_iterator& operator++() { Node::increment(node); sync(); return *this; } duplicates_iterator operator++(int) { duplicates_iterator tmp(*this); ++(*this); return tmp; } Node* get_node()const{return node;} private: void sync() { if(node!=end&&pred(begin_chunk->value(),node->value()))advance(); } void advance() { for(Node* node2=node;node!=end;node=node2){ Node::increment(node2); if(node2!=end&&!pred(node->value(),node2->value()))break; } begin_chunk=node; } Node* node; Node* begin_chunk; Node* end; Predicate pred; }; template<typename Node,typename Predicate> bool operator==( const duplicates_iterator<Node,Predicate>& x, const duplicates_iterator<Node,Predicate>& y) { return x.get_node()==y.get_node(); } template<typename Node,typename Predicate> bool operator!=( const duplicates_iterator<Node,Predicate>& x, const duplicates_iterator<Node,Predicate>& y) { return !(x==y); } } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif PK 3L�[�՜� � detail/index_node_base.hppnu �[��� /* Copyright 2003-2016 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP #define BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/type_traits/aligned_storage.hpp> #include <boost/type_traits/alignment_of.hpp> #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include <boost/archive/archive_exception.hpp> #include <boost/serialization/access.hpp> #include <boost/throw_exception.hpp> #endif namespace boost{ namespace multi_index{ namespace detail{ /* index_node_base tops the node hierarchy of multi_index_container. It holds * the value of the element contained. */ template<typename Value> struct pod_value_holder { typename aligned_storage< sizeof(Value), alignment_of<Value>::value >::type space; }; template<typename Value,typename Allocator> struct index_node_base:private pod_value_holder<Value> { typedef index_node_base base_type; /* used for serialization purposes */ typedef Value value_type; typedef Allocator allocator_type; #include <boost/multi_index/detail/ignore_wstrict_aliasing.hpp> value_type& value() { return *reinterpret_cast<value_type*>(&this->space); } const value_type& value()const { return *reinterpret_cast<const value_type*>(&this->space); } #include <boost/multi_index/detail/restore_wstrict_aliasing.hpp> static index_node_base* from_value(const value_type* p) { return static_cast<index_node_base *>( reinterpret_cast<pod_value_holder<Value>*>( /* std 9.2.17 */ const_cast<value_type*>(p))); } private: #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) friend class boost::serialization::access; /* nodes do not emit any kind of serialization info. They are * fed to Boost.Serialization so that pointers to nodes are * tracked correctly. */ template<class Archive> void serialize(Archive&,const unsigned int) { } #endif }; template<typename Node,typename Value> Node* node_from_value(const Value* p) { typedef typename Node::allocator_type allocator_type; return static_cast<Node*>( index_node_base<Value,allocator_type>::from_value(p)); } } /* namespace multi_index::detail */ } /* namespace multi_index */ #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) /* Index nodes never get constructed directly by Boost.Serialization, * as archives are always fed pointers to previously existent * nodes. So, if this is called it means we are dealing with a * somehow invalid archive. */ #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) namespace serialization{ #else namespace multi_index{ namespace detail{ #endif template<class Archive,typename Value,typename Allocator> inline void load_construct_data( Archive&,boost::multi_index::detail::index_node_base<Value,Allocator>*, const unsigned int) { throw_exception( archive::archive_exception(archive::archive_exception::other_exception)); } #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) } /* namespace serialization */ #else } /* namespace multi_index::detail */ } /* namespace multi_index */ #endif #endif } /* namespace boost */ #endif PK 3L�[7f�s$ $ "