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 + -
显示快捷键?