safe_mode.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 569 行 · 第 1/2 页
HPP
569 行
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& 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 */} /* namespace boost */#endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?