Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@101: // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // See http://www.boost.org/libs/container for documentation. Chris@16: // Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP Chris@16: #define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP Chris@16: Chris@101: #ifndef BOOST_CONFIG_HPP Chris@101: # include Chris@101: #endif Chris@101: Chris@101: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@101: # pragma once Chris@101: #endif Chris@101: Chris@101: #include Chris@101: #include Chris@101: // container Chris@16: #include Chris@101: // container/detail Chris@101: #include Chris@101: #include Chris@16: #include Chris@101: // intrusive Chris@16: #include Chris@16: #include Chris@101: // move Chris@101: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace container { Chris@16: namespace container_detail { Chris@16: Chris@16: template Chris@16: class basic_multiallocation_chain Chris@16: { Chris@16: private: Chris@16: typedef bi::slist_base_hook Chris@16: ,bi::link_mode Chris@16: > node; Chris@16: Chris@16: typedef typename boost::intrusive::pointer_traits Chris@16: ::template rebind_pointer::type char_ptr; Chris@16: typedef typename boost::intrusive:: Chris@16: pointer_traits::difference_type difference_type; Chris@16: Chris@16: typedef bi::slist< node Chris@16: , bi::linear Chris@16: , bi::cache_last Chris@101: , bi::size_type::type> Chris@16: > slist_impl_t; Chris@16: slist_impl_t slist_impl_; Chris@16: Chris@16: typedef typename boost::intrusive::pointer_traits Chris@16: ::template rebind_pointer::type node_ptr; Chris@16: typedef typename boost::intrusive:: Chris@16: pointer_traits node_ptr_traits; Chris@16: Chris@16: static node & to_node(const VoidPointer &p) Chris@16: { return *static_cast(static_cast(container_detail::to_raw_pointer(p))); } Chris@16: Chris@16: static VoidPointer from_node(node &n) Chris@16: { return node_ptr_traits::pointer_to(n); } Chris@16: Chris@16: static node_ptr to_node_ptr(const VoidPointer &p) Chris@16: { return node_ptr_traits::static_cast_from(p); } Chris@16: Chris@16: BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain) Chris@16: Chris@16: public: Chris@16: Chris@16: typedef VoidPointer void_pointer; Chris@16: typedef typename slist_impl_t::iterator iterator; Chris@16: typedef typename slist_impl_t::size_type size_type; Chris@16: Chris@16: basic_multiallocation_chain() Chris@16: : slist_impl_() Chris@16: {} Chris@16: Chris@16: basic_multiallocation_chain(const void_pointer &b, const void_pointer &before_e, size_type n) Chris@16: : slist_impl_(to_node_ptr(b), to_node_ptr(before_e), n) Chris@16: {} Chris@16: Chris@16: basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other) Chris@16: : slist_impl_(::boost::move(other.slist_impl_)) Chris@16: {} Chris@16: Chris@16: basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other) Chris@16: { Chris@16: slist_impl_ = ::boost::move(other.slist_impl_); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: bool empty() const Chris@16: { return slist_impl_.empty(); } Chris@16: Chris@16: size_type size() const Chris@16: { return slist_impl_.size(); } Chris@16: Chris@16: iterator before_begin() Chris@16: { return slist_impl_.before_begin(); } Chris@16: Chris@16: iterator begin() Chris@16: { return slist_impl_.begin(); } Chris@16: Chris@16: iterator end() Chris@16: { return slist_impl_.end(); } Chris@16: Chris@16: iterator last() Chris@16: { return slist_impl_.last(); } Chris@16: Chris@16: void clear() Chris@16: { slist_impl_.clear(); } Chris@16: Chris@16: iterator insert_after(iterator it, void_pointer m) Chris@16: { return slist_impl_.insert_after(it, to_node(m)); } Chris@16: Chris@16: void push_front(const void_pointer &m) Chris@16: { return slist_impl_.push_front(to_node(m)); } Chris@16: Chris@16: void push_back(const void_pointer &m) Chris@16: { return slist_impl_.push_back(to_node(m)); } Chris@16: Chris@16: void_pointer pop_front() Chris@16: { Chris@16: node & n = slist_impl_.front(); Chris@16: void_pointer ret = from_node(n); Chris@16: slist_impl_.pop_front(); Chris@16: return ret; Chris@16: } Chris@16: Chris@16: void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n) Chris@16: { slist_impl_.splice_after(after_this, x.slist_impl_, before_b, before_e, n); } Chris@16: Chris@16: void splice_after(iterator after_this, basic_multiallocation_chain &x) Chris@16: { slist_impl_.splice_after(after_this, x.slist_impl_); } Chris@16: Chris@16: void erase_after(iterator before_b, iterator e, size_type n) Chris@16: { slist_impl_.erase_after(before_b, e, n); } Chris@16: Chris@16: void_pointer incorporate_after(iterator after_this, const void_pointer &b, size_type unit_bytes, size_type num_units) Chris@16: { Chris@16: typedef typename boost::intrusive::pointer_traits char_pointer_traits; Chris@16: char_ptr elem = char_pointer_traits::static_cast_from(b); Chris@16: if(num_units){ Chris@16: char_ptr prev_elem = elem; Chris@16: elem += unit_bytes; Chris@16: for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){ Chris@16: ::new (container_detail::to_raw_pointer(prev_elem)) void_pointer(elem); Chris@16: prev_elem = elem; Chris@16: } Chris@16: slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units); Chris@16: } Chris@16: return elem; Chris@16: } Chris@16: Chris@16: void incorporate_after(iterator after_this, void_pointer b, void_pointer before_e, size_type n) Chris@16: { slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(before_e), n); } Chris@16: Chris@16: void swap(basic_multiallocation_chain &x) Chris@16: { slist_impl_.swap(x.slist_impl_); } Chris@16: Chris@16: static iterator iterator_to(const void_pointer &p) Chris@16: { return slist_impl_t::s_iterator_to(to_node(p)); } Chris@16: Chris@16: std::pair extract_data() Chris@16: { Chris@16: std::pair ret Chris@16: (slist_impl_.begin().operator->() Chris@16: ,slist_impl_.last().operator->()); Chris@16: slist_impl_.clear(); Chris@16: return ret; Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct cast_functor Chris@16: { Chris@16: typedef typename container_detail::add_reference::type result_type; Chris@16: template Chris@16: result_type operator()(U &ptr) const Chris@16: { return *static_cast(static_cast(&ptr)); } Chris@16: }; Chris@16: Chris@16: template Chris@16: class transform_multiallocation_chain Chris@16: : public MultiallocationChain Chris@16: { Chris@16: private: Chris@16: BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain) Chris@16: //transform_multiallocation_chain(const transform_multiallocation_chain &); Chris@16: //transform_multiallocation_chain & operator=(const transform_multiallocation_chain &); Chris@16: Chris@16: typedef typename MultiallocationChain::void_pointer void_pointer; Chris@16: typedef typename boost::intrusive::pointer_traits Chris@16: void_pointer_traits; Chris@16: typedef typename void_pointer_traits::template Chris@16: rebind_pointer::type pointer; Chris@16: typedef typename boost::intrusive::pointer_traits Chris@16: pointer_traits; Chris@16: Chris@16: static pointer cast(const void_pointer &p) Chris@16: { return pointer_traits::static_cast_from(p); } Chris@16: Chris@16: public: Chris@16: typedef transform_iterator Chris@16: < typename MultiallocationChain::iterator Chris@16: , container_detail::cast_functor > iterator; Chris@16: typedef typename MultiallocationChain::size_type size_type; Chris@16: Chris@16: transform_multiallocation_chain() Chris@16: : MultiallocationChain() Chris@16: {} Chris@16: Chris@16: transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other) Chris@16: : MultiallocationChain(::boost::move(static_cast(other))) Chris@16: {} Chris@16: Chris@16: transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other) Chris@16: : MultiallocationChain(::boost::move(static_cast(other))) Chris@16: {} Chris@16: Chris@16: transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other) Chris@16: { Chris@16: return static_cast Chris@16: (this->MultiallocationChain::operator=(::boost::move(static_cast(other)))); Chris@16: } Chris@16: /* Chris@16: void push_front(const pointer &mem) Chris@16: { holder_.push_front(mem); } Chris@16: Chris@16: void push_back(const pointer &mem) Chris@16: { return holder_.push_back(mem); } Chris@16: Chris@16: void swap(transform_multiallocation_chain &other_chain) Chris@16: { holder_.swap(other_chain.holder_); } Chris@16: Chris@16: void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n) Chris@16: { holder_.splice_after(after_this.base(), x.holder_, before_b.base(), before_e.base(), n); } Chris@16: Chris@16: void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n) Chris@16: { holder_.incorporate_after(after_this.base(), b, before_e, n); } Chris@16: */ Chris@16: pointer pop_front() Chris@16: { return cast(this->MultiallocationChain::pop_front()); } Chris@16: /* Chris@16: bool empty() const Chris@16: { return holder_.empty(); } Chris@16: Chris@16: iterator before_begin() Chris@16: { return iterator(holder_.before_begin()); } Chris@16: */ Chris@16: iterator begin() Chris@16: { return iterator(this->MultiallocationChain::begin()); } Chris@16: /* Chris@16: iterator end() Chris@16: { return iterator(holder_.end()); } Chris@16: Chris@16: iterator last() Chris@16: { return iterator(holder_.last()); } Chris@16: Chris@16: size_type size() const Chris@16: { return holder_.size(); } Chris@16: Chris@16: void clear() Chris@16: { holder_.clear(); } Chris@16: */ Chris@16: iterator insert_after(iterator it, pointer m) Chris@16: { return iterator(this->MultiallocationChain::insert_after(it.base(), m)); } Chris@16: Chris@16: static iterator iterator_to(const pointer &p) Chris@16: { return iterator(MultiallocationChain::iterator_to(p)); } Chris@16: Chris@16: std::pair extract_data() Chris@16: { Chris@16: std::pair data(this->MultiallocationChain::extract_data()); Chris@16: return std::pair(cast(data.first), cast(data.second)); Chris@16: } Chris@16: /* Chris@16: MultiallocationChain &extract_multiallocation_chain() Chris@16: { return holder_; }*/ Chris@16: }; Chris@16: Chris@16: }}} Chris@16: Chris@16: // namespace container_detail { Chris@16: // namespace container { Chris@16: // namespace boost { Chris@16: Chris@16: #include Chris@16: Chris@16: #endif //BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP