multiallocation_chain.hpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
  11. #define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
  12. #include "config_begin.hpp"
  13. #include <boost/container/container_fwd.hpp>
  14. #include <boost/container/detail/utilities.hpp>
  15. #include <boost/container/detail/type_traits.hpp>
  16. #include <boost/container/detail/transform_iterator.hpp>
  17. #include <boost/intrusive/slist.hpp>
  18. #include <boost/intrusive/pointer_traits.hpp>
  19. #include <boost/type_traits/make_unsigned.hpp>
  20. #include <boost/move/utility.hpp>
  21. namespace boost {
  22. namespace container {
  23. namespace container_detail {
  24. template<class VoidPointer>
  25. class basic_multiallocation_chain
  26. {
  27. private:
  28. typedef bi::slist_base_hook<bi::void_pointer<VoidPointer>
  29. ,bi::link_mode<bi::normal_link>
  30. > node;
  31. typedef typename boost::intrusive::pointer_traits
  32. <VoidPointer>::template rebind_pointer<char>::type char_ptr;
  33. typedef typename boost::intrusive::
  34. pointer_traits<char_ptr>::difference_type difference_type;
  35. typedef bi::slist< node
  36. , bi::linear<true>
  37. , bi::cache_last<true>
  38. , bi::size_type<typename boost::make_unsigned<difference_type>::type>
  39. > slist_impl_t;
  40. slist_impl_t slist_impl_;
  41. typedef typename boost::intrusive::pointer_traits
  42. <VoidPointer>::template rebind_pointer<node>::type node_ptr;
  43. typedef typename boost::intrusive::
  44. pointer_traits<node_ptr> node_ptr_traits;
  45. static node & to_node(const VoidPointer &p)
  46. { return *static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p))); }
  47. static VoidPointer from_node(node &n)
  48. { return node_ptr_traits::pointer_to(n); }
  49. static node_ptr to_node_ptr(const VoidPointer &p)
  50. { return node_ptr_traits::static_cast_from(p); }
  51. BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
  52. public:
  53. typedef VoidPointer void_pointer;
  54. typedef typename slist_impl_t::iterator iterator;
  55. typedef typename slist_impl_t::size_type size_type;
  56. basic_multiallocation_chain()
  57. : slist_impl_()
  58. {}
  59. basic_multiallocation_chain(const void_pointer &b, const void_pointer &before_e, size_type n)
  60. : slist_impl_(to_node_ptr(b), to_node_ptr(before_e), n)
  61. {}
  62. basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other)
  63. : slist_impl_(::boost::move(other.slist_impl_))
  64. {}
  65. basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other)
  66. {
  67. slist_impl_ = ::boost::move(other.slist_impl_);
  68. return *this;
  69. }
  70. bool empty() const
  71. { return slist_impl_.empty(); }
  72. size_type size() const
  73. { return slist_impl_.size(); }
  74. iterator before_begin()
  75. { return slist_impl_.before_begin(); }
  76. iterator begin()
  77. { return slist_impl_.begin(); }
  78. iterator end()
  79. { return slist_impl_.end(); }
  80. iterator last()
  81. { return slist_impl_.last(); }
  82. void clear()
  83. { slist_impl_.clear(); }
  84. iterator insert_after(iterator it, void_pointer m)
  85. { return slist_impl_.insert_after(it, to_node(m)); }
  86. void push_front(const void_pointer &m)
  87. { return slist_impl_.push_front(to_node(m)); }
  88. void push_back(const void_pointer &m)
  89. { return slist_impl_.push_back(to_node(m)); }
  90. void_pointer pop_front()
  91. {
  92. node & n = slist_impl_.front();
  93. void_pointer ret = from_node(n);
  94. slist_impl_.pop_front();
  95. return ret;
  96. }
  97. void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
  98. { slist_impl_.splice_after(after_this, x.slist_impl_, before_b, before_e, n); }
  99. void splice_after(iterator after_this, basic_multiallocation_chain &x)
  100. { slist_impl_.splice_after(after_this, x.slist_impl_); }
  101. void erase_after(iterator before_b, iterator e, size_type n)
  102. { slist_impl_.erase_after(before_b, e, n); }
  103. void_pointer incorporate_after(iterator after_this, const void_pointer &b, size_type unit_bytes, size_type num_units)
  104. {
  105. typedef typename boost::intrusive::pointer_traits<char_ptr> char_pointer_traits;
  106. char_ptr elem = char_pointer_traits::static_cast_from(b);
  107. if(num_units){
  108. char_ptr prev_elem = elem;
  109. elem += unit_bytes;
  110. for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){
  111. ::new (container_detail::to_raw_pointer(prev_elem)) void_pointer(elem);
  112. prev_elem = elem;
  113. }
  114. slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units);
  115. }
  116. return elem;
  117. }
  118. void incorporate_after(iterator after_this, void_pointer b, void_pointer before_e, size_type n)
  119. { slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(before_e), n); }
  120. void swap(basic_multiallocation_chain &x)
  121. { slist_impl_.swap(x.slist_impl_); }
  122. static iterator iterator_to(const void_pointer &p)
  123. { return slist_impl_t::s_iterator_to(to_node(p)); }
  124. std::pair<void_pointer, void_pointer> extract_data()
  125. {
  126. std::pair<void_pointer, void_pointer> ret
  127. (slist_impl_.begin().operator->()
  128. ,slist_impl_.last().operator->());
  129. slist_impl_.clear();
  130. return ret;
  131. }
  132. };
  133. template<class T>
  134. struct cast_functor
  135. {
  136. typedef typename container_detail::add_reference<T>::type result_type;
  137. template<class U>
  138. result_type operator()(U &ptr) const
  139. { return *static_cast<T*>(static_cast<void*>(&ptr)); }
  140. };
  141. template<class MultiallocationChain, class T>
  142. class transform_multiallocation_chain
  143. : public MultiallocationChain
  144. {
  145. private:
  146. BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain)
  147. //transform_multiallocation_chain(const transform_multiallocation_chain &);
  148. //transform_multiallocation_chain & operator=(const transform_multiallocation_chain &);
  149. typedef typename MultiallocationChain::void_pointer void_pointer;
  150. typedef typename boost::intrusive::pointer_traits
  151. <void_pointer> void_pointer_traits;
  152. typedef typename void_pointer_traits::template
  153. rebind_pointer<T>::type pointer;
  154. typedef typename boost::intrusive::pointer_traits
  155. <pointer> pointer_traits;
  156. static pointer cast(const void_pointer &p)
  157. { return pointer_traits::static_cast_from(p); }
  158. public:
  159. typedef transform_iterator
  160. < typename MultiallocationChain::iterator
  161. , container_detail::cast_functor <T> > iterator;
  162. typedef typename MultiallocationChain::size_type size_type;
  163. transform_multiallocation_chain()
  164. : MultiallocationChain()
  165. {}
  166. transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other)
  167. : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
  168. {}
  169. transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other)
  170. : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
  171. {}
  172. transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other)
  173. {
  174. return static_cast<MultiallocationChain&>
  175. (this->MultiallocationChain::operator=(::boost::move(static_cast<MultiallocationChain&>(other))));
  176. }
  177. /*
  178. void push_front(const pointer &mem)
  179. { holder_.push_front(mem); }
  180. void push_back(const pointer &mem)
  181. { return holder_.push_back(mem); }
  182. void swap(transform_multiallocation_chain &other_chain)
  183. { holder_.swap(other_chain.holder_); }
  184. void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
  185. { holder_.splice_after(after_this.base(), x.holder_, before_b.base(), before_e.base(), n); }
  186. void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n)
  187. { holder_.incorporate_after(after_this.base(), b, before_e, n); }
  188. */
  189. pointer pop_front()
  190. { return cast(this->MultiallocationChain::pop_front()); }
  191. /*
  192. bool empty() const
  193. { return holder_.empty(); }
  194. iterator before_begin()
  195. { return iterator(holder_.before_begin()); }
  196. */
  197. iterator begin()
  198. { return iterator(this->MultiallocationChain::begin()); }
  199. /*
  200. iterator end()
  201. { return iterator(holder_.end()); }
  202. iterator last()
  203. { return iterator(holder_.last()); }
  204. size_type size() const
  205. { return holder_.size(); }
  206. void clear()
  207. { holder_.clear(); }
  208. */
  209. iterator insert_after(iterator it, pointer m)
  210. { return iterator(this->MultiallocationChain::insert_after(it.base(), m)); }
  211. static iterator iterator_to(const pointer &p)
  212. { return iterator(MultiallocationChain::iterator_to(p)); }
  213. std::pair<pointer, pointer> extract_data()
  214. {
  215. std::pair<void_pointer, void_pointer> data(this->MultiallocationChain::extract_data());
  216. return std::pair<pointer, pointer>(cast(data.first), cast(data.second));
  217. }
  218. /*
  219. MultiallocationChain &extract_multiallocation_chain()
  220. { return holder_; }*/
  221. };
  222. }}}
  223. // namespace container_detail {
  224. // namespace container {
  225. // namespace boost {
  226. #include <boost/container/detail/config_end.hpp>
  227. #endif //BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP