diff options
Diffstat (limited to 'boost/multi_index/sequenced_index.hpp')
-rw-r--r-- | boost/multi_index/sequenced_index.hpp | 279 |
1 files changed, 203 insertions, 76 deletions
diff --git a/boost/multi_index/sequenced_index.hpp b/boost/multi_index/sequenced_index.hpp index e8832eee58..d56edddd17 100644 --- a/boost/multi_index/sequenced_index.hpp +++ b/boost/multi_index/sequenced_index.hpp @@ -1,4 +1,4 @@ -/* Copyright 2003-2011 Joaquin M Lopez Munoz. +/* 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) @@ -9,7 +9,7 @@ #ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP #define BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP -#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#if defined(_MSC_VER) #pragma once #endif @@ -20,17 +20,20 @@ #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.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/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/safe_ctr_proxy.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> @@ -38,16 +41,23 @@ #include <functional> #include <utility> +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include<initializer_list> +#endif + #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include <boost/bind.hpp> #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(*this,&sequenced_index::check_invariant_); \ + 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 @@ -64,16 +74,9 @@ class sequenced_index: BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) -#if BOOST_WORKAROUND(BOOST_MSVC,<1300) - ,public safe_ctr_proxy_impl< - bidir_node_iterator< - sequenced_index_node<typename SuperMeta::type::node_type> >, - sequenced_index<SuperMeta,TagList> > -#else ,public safe_mode::safe_container< sequenced_index<SuperMeta,TagList> > #endif -#endif { #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ @@ -105,16 +108,9 @@ public: typedef typename allocator_type::const_reference const_reference; #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) -#if BOOST_WORKAROUND(BOOST_MSVC,<1300) - typedef safe_mode::safe_iterator< - bidir_node_iterator<node_type>, - safe_ctr_proxy< - bidir_node_iterator<node_type> > > iterator; -#else typedef safe_mode::safe_iterator< bidir_node_iterator<node_type>, sequenced_index> iterator; -#endif #else typedef bidir_node_iterator<node_type> iterator; #endif @@ -154,18 +150,18 @@ protected: private: #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) -#if BOOST_WORKAROUND(BOOST_MSVC,<1300) - typedef safe_ctr_proxy_impl< - bidir_node_iterator<node_type>, - sequenced_index> safe_super; -#else typedef safe_mode::safe_container< sequenced_index> safe_super; #endif -#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 @@ -180,12 +176,28 @@ public: 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; @@ -193,27 +205,37 @@ public: for(size_type i=0;i<n;++i)push_back(value); } - allocator_type get_allocator()const + allocator_type get_allocator()const BOOST_NOEXCEPT { return this->final().get_allocator(); } /* iterators */ - iterator begin() + iterator begin()BOOST_NOEXCEPT {return make_iterator(node_type::from_impl(header()->next()));} - const_iterator begin()const + const_iterator begin()const BOOST_NOEXCEPT {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());} - const_iterator cbegin()const{return begin();} - const_iterator cend()const{return end();} - const_reverse_iterator crbegin()const{return rbegin();} - const_reverse_iterator crend()const{return rend();} + 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) { @@ -227,26 +249,25 @@ public: /* 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_();} + 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=value_type()) + void resize(size_type n,value_param_type x) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; if(n>size())insert(end(),n-size(),x); - else if(n<size()){ - iterator it; - if(n<=size()/2){ - it=begin(); - std::advance(it,n); - } - else{ - it=end(); - for(size_type m=size()-n;m--;--it){} - } - erase(it,end()); - } + else if(n<size())for(size_type m=size()-n;m--;)pop_back(); } /* access: no non-const versions provided as sequenced_index @@ -258,14 +279,28 @@ public: /* modifiers */ - std::pair<iterator,bool> push_front(value_param_type x) + 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());} - std::pair<iterator,bool> push_back(value_param_type x) + + 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());} - std::pair<iterator,bool> insert(iterator position,value_param_type x) + 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); @@ -277,6 +312,18 @@ public: 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); @@ -291,6 +338,13 @@ public: 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 + iterator erase(iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); @@ -315,7 +369,7 @@ public: return first; } - bool replace(iterator position,value_param_type x) + bool replace(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); @@ -325,6 +379,16 @@ public: 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) { @@ -347,7 +411,7 @@ public: } template<typename Modifier,typename Rollback> - bool modify(iterator position,Modifier mod,Rollback back) + bool modify(iterator position,Modifier mod,Rollback back_) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); @@ -364,16 +428,17 @@ public: #endif return this->final_modify_( - mod,back,static_cast<final_node_type*>(position.get_node())); + 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() + void clear()BOOST_NOEXCEPT { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; this->final_clear_(); @@ -495,7 +560,7 @@ public: sequenced_index_sort(header(),comp); } - void reverse() + void reverse()BOOST_NOEXCEPT { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; node_impl_type::reverse(header()->impl()); @@ -555,8 +620,19 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: #endif { - /* The actual copying takes place in subsequent call to copy_(). - */ + /* 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() @@ -591,17 +667,21 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::copy_(x,map); } - node_type* insert_(value_param_type v,node_type* x) + template<typename Variant> + final_node_type* insert_( + value_param_type v,final_node_type*& x,Variant variant) { - node_type* res=static_cast<node_type*>(super::insert_(v,x)); - if(res==x)link(x); + final_node_type* res=super::insert_(v,x,variant); + if(res==x)link(static_cast<node_type*>(x)); return res; } - node_type* insert_(value_param_type v,node_type* position,node_type* x) + template<typename Variant> + final_node_type* insert_( + value_param_type v,node_type* position,final_node_type*& x,Variant variant) { - node_type* res=static_cast<node_type*>(super::insert_(v,position,x)); - if(res==x)link(x); + final_node_type* res=super::insert_(v,position,x,variant); + if(res==x)link(static_cast<node_type*>(x)); return res; } @@ -643,9 +723,19 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::swap_(x); } - bool replace_(value_param_type v,node_type* x) + void swap_elements_(sequenced_index<SuperMeta,TagList>& x) { - return super::replace_(v,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,node_type* x,Variant variant) + { + return super::replace_(v,x,variant); } bool modify_(node_type* x) @@ -695,7 +785,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: Archive& ar,const unsigned int version,const index_loader_type& lm) { lm.load( - ::boost::bind(&sequenced_index::rearranger,this,_1,_2), + ::boost::bind( + &sequenced_index::rearranger,this,::boost::arg<1>(),::boost::arg<2>()), ar,version); super::load_(ar,version,lm); } @@ -781,7 +872,7 @@ private: { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; clear(); - for(;first!=last;++first)push_back(*first); + for(;first!=last;++first)this->final_insert_ref_(*first); } void assign_iter(size_type n,value_param_type value,mpl::false_) @@ -796,7 +887,13 @@ private: iterator position,InputIterator first,InputIterator last,mpl::true_) { BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - for(;first!=last;++first)insert(position,*first); + 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( @@ -807,7 +904,36 @@ private: 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 @@ -929,5 +1055,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable( } #undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF #endif |