📄 sequenced_index.hpp
字号:
/* Copyright 2003-2004 Joaqu韓 M L髉ez Mu駉z. * 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#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */#include <boost/call_traits.hpp>#include <boost/detail/no_exceptions_support.hpp>#include <boost/detail/workaround.hpp>#include <boost/iterator/reverse_iterator.hpp>#include <boost/mpl/push_front.hpp>#include <boost/multi_index/detail/access_specifier.hpp>#include <boost/multi_index/detail/index_iterator.hpp>#include <boost/multi_index/detail/seq_index_node.hpp>#include <boost/multi_index/detail/seq_index_ops.hpp>#include <boost/multi_index/detail/safe_mode.hpp>#include <boost/multi_index/detail/scope_guard.hpp>#include <boost/multi_index/sequenced_index_fwd.hpp>#include <boost/tuple/tuple.hpp>#include <cstddef>#include <functional>#include <utility>#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ detail::make_obj_guard(*this,&sequenced_index::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch();#else#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT#endifnamespace boost{namespace multi_index{namespace detail{/* sequenced_index adds a layer of sequenced indexing to a given Super */template<typename Super,typename TagList>#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)#if BOOST_WORKAROUND(BOOST_MSVC,<1300)class sequenced_index: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS Super, public index_proxy<sequenced_index_node<typename Super::node_type> >#elseclass sequenced_index: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS Super, public safe_container<sequenced_index<Super,TagList> >#endif#elseclass sequenced_index: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS Super#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#endifprotected: typedef sequenced_index_node<typename Super::node_type> node_type;public: /* types */ typedef typename node_type::value_type value_type; typedef tuples::null_type ctor_args; typedef typename Super::final_allocator_type allocator_type; typedef typename allocator_type::reference reference; typedef typename allocator_type::const_reference const_reference;#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)#if BOOST_WORKAROUND(BOOST_MSVC,<1300) typedef index_iterator<node_type> iterator; typedef index_iterator<node_type> const_iterator;#else typedef index_iterator<node_type,sequenced_index> iterator; typedef index_iterator<node_type,sequenced_index> const_iterator;#endif#else typedef index_iterator<node_type> iterator; typedef index_iterator<node_type> const_iterator;#endif typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef typename allocator_type::pointer pointer; typedef typename allocator_type::const_pointer const_pointer; typedef typename boost::reverse_iterator<iterator> reverse_iterator; typedef typename boost::reverse_iterator<const_iterator> const_reverse_iterator; typedef typename TagList::type 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;private:#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)#if BOOST_WORKAROUND(BOOST_MSVC,<1300) typedef index_proxy<sequenced_index_node< typename Super::node_type> > safe_super;#else typedef safe_container<sequenced_index> safe_super;#endif#endif typedef typename call_traits<value_type>::param_type value_param_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<Super,TagList>& operator=( const sequenced_index<Super,TagList>& x) { this->final()=x.final(); return *this; } template <class InputIterator> void assign(InputIterator first,InputIterator last) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; clear(); for(;first!=last;++first)push_back(*first); } 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 { return this->final().get_allocator(); } /* iterators */ iterator begin() {return make_iterator(node_type::from_impl(header()->next()));} const_iterator begin()const {return make_iterator(node_type::from_impl(header()->next()));} iterator end(){return make_iterator(header());} const_iterator end()const{return make_iterator(header());} reverse_iterator rbegin(){return make_reverse_iterator(end());} const_reverse_iterator rbegin()const{return make_reverse_iterator(end());} reverse_iterator rend(){return make_reverse_iterator(begin());} const_reverse_iterator rend()const{return make_reverse_iterator(begin());} /* capacity */ bool empty()const{return this->final_empty_();} size_type size()const{return this->final_size_();} size_type max_size()const{return this->final_max_size_();} void resize(size_type n,value_param_type x=value_type()) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; if(n>size())insert(end(),n-size(),x); else if(n<size()){ iterator it=begin(); std::advance(it,n); erase(it,end()); } } /* 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 */ std::pair<iterator,bool> push_front(value_param_type x) {return insert(begin(),x);} void pop_front(){erase(begin());} std::pair<iterator,bool> push_back(value_param_type x) {return insert(end(),x);} void pop_back(){erase(--end());} std::pair<iterator,bool> insert(iterator position,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; std::pair<final_node_type*,bool> p=this->final_insert_(x); if(p.second)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) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; for(;first!=last;++first)insert(position,*first); } 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,value_param_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())); } 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())); } void swap(sequenced_index<Super,TagList>& x) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; this->final_swap_(x.final()); } void clear() { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; erase(begin(),end()); } /* list operations */ void splice(iterator position,sequenced_index<Super,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)x.erase(first++); else ++first; } } void splice(iterator position,sequenced_index<Super,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<Super,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)x.erase(first++); else ++first; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -