299 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			299 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | ////////////////////////////////////////////////////////////////////////////// | ||
|  | // | ||
|  | // (C) Copyright Ion Gaztanaga 2005-2013. 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/container for documentation. | ||
|  | // | ||
|  | ////////////////////////////////////////////////////////////////////////////// | ||
|  | 
 | ||
|  | #ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP | ||
|  | #define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP | ||
|  | 
 | ||
|  | #ifndef BOOST_CONFIG_HPP | ||
|  | #  include <boost/config.hpp> | ||
|  | #endif | ||
|  | 
 | ||
|  | #if defined(BOOST_HAS_PRAGMA_ONCE) | ||
|  | #  pragma once | ||
|  | #endif | ||
|  | 
 | ||
|  | #include <boost/container/detail/config_begin.hpp> | ||
|  | #include <boost/container/detail/workaround.hpp> | ||
|  | // container | ||
|  | #include <boost/container/container_fwd.hpp> | ||
|  | // container/detail | ||
|  | #include <boost/container/detail/to_raw_pointer.hpp> | ||
|  | #include <boost/container/detail/transform_iterator.hpp> | ||
|  | #include <boost/container/detail/type_traits.hpp> | ||
|  | // intrusive | ||
|  | #include <boost/intrusive/slist.hpp> | ||
|  | #include <boost/intrusive/pointer_traits.hpp> | ||
|  | // move | ||
|  | #include <boost/move/utility_core.hpp> | ||
|  | 
 | ||
|  | namespace boost { | ||
|  | namespace container { | ||
|  | namespace container_detail { | ||
|  | 
 | ||
|  | template<class VoidPointer> | ||
|  | class basic_multiallocation_chain | ||
|  | { | ||
|  |    private: | ||
|  |    typedef bi::slist_base_hook<bi::void_pointer<VoidPointer> | ||
|  |                         ,bi::link_mode<bi::normal_link> | ||
|  |                         > node; | ||
|  | 
 | ||
|  |    typedef typename boost::intrusive::pointer_traits | ||
|  |       <VoidPointer>::template rebind_pointer<char>::type    char_ptr; | ||
|  |    typedef typename boost::intrusive:: | ||
|  |       pointer_traits<char_ptr>::difference_type             difference_type; | ||
|  | 
 | ||
|  |    typedef bi::slist< node | ||
|  |                     , bi::linear<true> | ||
|  |                     , bi::cache_last<true> | ||
|  |                     , bi::size_type<typename boost::container::container_detail::make_unsigned<difference_type>::type> | ||
|  |                     > slist_impl_t; | ||
|  |    slist_impl_t slist_impl_; | ||
|  | 
 | ||
|  |    typedef typename boost::intrusive::pointer_traits | ||
|  |       <VoidPointer>::template rebind_pointer<node>::type    node_ptr; | ||
|  |    typedef typename boost::intrusive:: | ||
|  |       pointer_traits<node_ptr>                              node_ptr_traits; | ||
|  | 
 | ||
|  |    static node & to_node(const VoidPointer &p) | ||
|  |    {  return *static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p)));  } | ||
|  | 
 | ||
|  |    static VoidPointer from_node(node &n) | ||
|  |    {  return node_ptr_traits::pointer_to(n);  } | ||
|  | 
 | ||
|  |    static node_ptr to_node_ptr(const VoidPointer &p) | ||
|  |    {  return node_ptr_traits::static_cast_from(p);   } | ||
|  | 
 | ||
|  |    BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain) | ||
|  | 
 | ||
|  |    public: | ||
|  | 
 | ||
|  |    typedef VoidPointer                       void_pointer; | ||
|  |    typedef typename slist_impl_t::iterator   iterator; | ||
|  |    typedef typename slist_impl_t::size_type  size_type; | ||
|  | 
 | ||
|  |    basic_multiallocation_chain() | ||
|  |       :  slist_impl_() | ||
|  |    {} | ||
|  | 
 | ||
|  |    basic_multiallocation_chain(const void_pointer &b, const void_pointer &before_e, size_type n) | ||
|  |       :  slist_impl_(to_node_ptr(b), to_node_ptr(before_e), n) | ||
|  |    {} | ||
|  | 
 | ||
|  |    basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other) | ||
|  |       :  slist_impl_(::boost::move(other.slist_impl_)) | ||
|  |    {} | ||
|  | 
 | ||
|  |    basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other) | ||
|  |    { | ||
|  |       slist_impl_ = ::boost::move(other.slist_impl_); | ||
|  |       return *this; | ||
|  |    } | ||
|  | 
 | ||
|  |    bool empty() const | ||
|  |    {  return slist_impl_.empty(); } | ||
|  | 
 | ||
|  |    size_type size() const | ||
|  |    {  return slist_impl_.size();  } | ||
|  | 
 | ||
|  |    iterator before_begin() | ||
|  |    {  return slist_impl_.before_begin(); } | ||
|  | 
 | ||
|  |    iterator begin() | ||
|  |    {  return slist_impl_.begin(); } | ||
|  | 
 | ||
|  |    iterator end() | ||
|  |    {  return slist_impl_.end(); } | ||
|  | 
 | ||
|  |    iterator last() | ||
|  |    {  return slist_impl_.last(); } | ||
|  | 
 | ||
|  |    void clear() | ||
|  |    {  slist_impl_.clear(); } | ||
|  | 
 | ||
|  |    iterator insert_after(iterator it, void_pointer m) | ||
|  |    {  return slist_impl_.insert_after(it, to_node(m));   } | ||
|  | 
 | ||
|  |    void push_front(const void_pointer &m) | ||
|  |    {  return slist_impl_.push_front(to_node(m));  } | ||
|  | 
 | ||
|  |    void push_back(const void_pointer &m) | ||
|  |    {  return slist_impl_.push_back(to_node(m));   } | ||
|  | 
 | ||
|  |    void_pointer pop_front() | ||
|  |    { | ||
|  |       node & n = slist_impl_.front(); | ||
|  |       void_pointer ret = from_node(n); | ||
|  |       slist_impl_.pop_front(); | ||
|  |       return ret; | ||
|  |    } | ||
|  | 
 | ||
|  |    void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n) | ||
|  |    {  slist_impl_.splice_after(after_this, x.slist_impl_, before_b, before_e, n);   } | ||
|  | 
 | ||
|  |    void splice_after(iterator after_this, basic_multiallocation_chain &x) | ||
|  |    {  slist_impl_.splice_after(after_this, x.slist_impl_);   } | ||
|  | 
 | ||
|  |    void erase_after(iterator before_b, iterator e, size_type n) | ||
|  |    {  slist_impl_.erase_after(before_b, e, n);   } | ||
|  | 
 | ||
|  |    void_pointer incorporate_after(iterator after_this, const void_pointer &b, size_type unit_bytes, size_type num_units) | ||
|  |    { | ||
|  |       typedef typename boost::intrusive::pointer_traits<char_ptr> char_pointer_traits; | ||
|  |       char_ptr elem = char_pointer_traits::static_cast_from(b); | ||
|  |       if(num_units){ | ||
|  |          char_ptr prev_elem = elem; | ||
|  |          elem += unit_bytes; | ||
|  |          for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){ | ||
|  |             ::new (container_detail::to_raw_pointer(prev_elem)) void_pointer(elem); | ||
|  |             prev_elem = elem; | ||
|  |          } | ||
|  |          slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units); | ||
|  |       } | ||
|  |       return elem; | ||
|  |    } | ||
|  | 
 | ||
|  |    void incorporate_after(iterator after_this, void_pointer b, void_pointer before_e, size_type n) | ||
|  |    {  slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(before_e), n);   } | ||
|  | 
 | ||
|  |    void swap(basic_multiallocation_chain &x) | ||
|  |    {  slist_impl_.swap(x.slist_impl_);   } | ||
|  | 
 | ||
|  |    static iterator iterator_to(const void_pointer &p) | ||
|  |    {  return slist_impl_t::s_iterator_to(to_node(p));   } | ||
|  | 
 | ||
|  |    std::pair<void_pointer, void_pointer> extract_data() | ||
|  |    { | ||
|  |       std::pair<void_pointer, void_pointer> ret | ||
|  |          (slist_impl_.begin().operator->() | ||
|  |          ,slist_impl_.last().operator->()); | ||
|  |       slist_impl_.clear(); | ||
|  |       return ret; | ||
|  |    } | ||
|  | }; | ||
|  | 
 | ||
|  | template<class T> | ||
|  | struct cast_functor | ||
|  | { | ||
|  |    typedef typename container_detail::add_reference<T>::type result_type; | ||
|  |    template<class U> | ||
|  |    result_type operator()(U &ptr) const | ||
|  |    {  return *static_cast<T*>(static_cast<void*>(&ptr));  } | ||
|  | }; | ||
|  | 
 | ||
|  | template<class MultiallocationChain, class T> | ||
|  | class transform_multiallocation_chain | ||
|  |    : public MultiallocationChain | ||
|  | { | ||
|  |    private: | ||
|  |    BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain) | ||
|  |    //transform_multiallocation_chain(const transform_multiallocation_chain &); | ||
|  |    //transform_multiallocation_chain & operator=(const transform_multiallocation_chain &); | ||
|  | 
 | ||
|  |    typedef typename MultiallocationChain::void_pointer   void_pointer; | ||
|  |    typedef typename boost::intrusive::pointer_traits | ||
|  |       <void_pointer>                                     void_pointer_traits; | ||
|  |    typedef typename void_pointer_traits::template | ||
|  |       rebind_pointer<T>::type                            pointer; | ||
|  |    typedef typename boost::intrusive::pointer_traits | ||
|  |       <pointer>                                          pointer_traits; | ||
|  | 
 | ||
|  |    static pointer cast(const void_pointer &p) | ||
|  |    {  return pointer_traits::static_cast_from(p);  } | ||
|  | 
 | ||
|  |    public: | ||
|  |    typedef transform_iterator | ||
|  |       < typename MultiallocationChain::iterator | ||
|  |       , container_detail::cast_functor <T> >             iterator; | ||
|  |    typedef typename MultiallocationChain::size_type      size_type; | ||
|  | 
 | ||
|  |    transform_multiallocation_chain() | ||
|  |       : MultiallocationChain() | ||
|  |    {} | ||
|  | 
 | ||
|  |    transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other) | ||
|  |       : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other))) | ||
|  |    {} | ||
|  | 
 | ||
|  |    transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other) | ||
|  |       : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other))) | ||
|  |    {} | ||
|  | 
 | ||
|  |    transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other) | ||
|  |    { | ||
|  |       return static_cast<MultiallocationChain&> | ||
|  |          (this->MultiallocationChain::operator=(::boost::move(static_cast<MultiallocationChain&>(other)))); | ||
|  |    } | ||
|  | /* | ||
|  |    void push_front(const pointer &mem) | ||
|  |    {  holder_.push_front(mem);  } | ||
|  | 
 | ||
|  |    void push_back(const pointer &mem) | ||
|  |    {  return holder_.push_back(mem);   } | ||
|  | 
 | ||
|  |    void swap(transform_multiallocation_chain &other_chain) | ||
|  |    {  holder_.swap(other_chain.holder_); } | ||
|  | 
 | ||
|  |    void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n) | ||
|  |    {  holder_.splice_after(after_this.base(), x.holder_, before_b.base(), before_e.base(), n);  } | ||
|  | 
 | ||
|  |    void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n) | ||
|  |    {  holder_.incorporate_after(after_this.base(), b, before_e, n);  } | ||
|  | */ | ||
|  |    pointer pop_front() | ||
|  |    {  return cast(this->MultiallocationChain::pop_front());  } | ||
|  | /* | ||
|  |    bool empty() const | ||
|  |    {  return holder_.empty(); } | ||
|  | 
 | ||
|  |    iterator before_begin() | ||
|  |    {  return iterator(holder_.before_begin());   } | ||
|  | */ | ||
|  |    iterator begin() | ||
|  |    {  return iterator(this->MultiallocationChain::begin());   } | ||
|  | /* | ||
|  |    iterator end() | ||
|  |    {  return iterator(holder_.end());   } | ||
|  | 
 | ||
|  |    iterator last() | ||
|  |    {  return iterator(holder_.last());   } | ||
|  | 
 | ||
|  |    size_type size() const | ||
|  |    {  return holder_.size();  } | ||
|  | 
 | ||
|  |    void clear() | ||
|  |    {  holder_.clear(); } | ||
|  | */ | ||
|  |    iterator insert_after(iterator it, pointer m) | ||
|  |    {  return iterator(this->MultiallocationChain::insert_after(it.base(), m)); } | ||
|  | 
 | ||
|  |    static iterator iterator_to(const pointer &p) | ||
|  |    {  return iterator(MultiallocationChain::iterator_to(p));  } | ||
|  | 
 | ||
|  |    std::pair<pointer, pointer> extract_data() | ||
|  |    { | ||
|  |       std::pair<void_pointer, void_pointer> data(this->MultiallocationChain::extract_data()); | ||
|  |       return std::pair<pointer, pointer>(cast(data.first), cast(data.second)); | ||
|  |    } | ||
|  | /* | ||
|  |    MultiallocationChain &extract_multiallocation_chain() | ||
|  |    {  return holder_;  }*/ | ||
|  | }; | ||
|  | 
 | ||
|  | }}} | ||
|  | 
 | ||
|  | // namespace container_detail { | ||
|  | // namespace container { | ||
|  | // namespace boost { | ||
|  | 
 | ||
|  | #include <boost/container/detail/config_end.hpp> | ||
|  | 
 | ||
|  | #endif   //BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP |