File indexing completed on 2025-07-15 08:29:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
0012 #define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
0013
0014 #ifndef BOOST_CONFIG_HPP
0015 # include <boost/config.hpp>
0016 #endif
0017
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 # pragma once
0020 #endif
0021
0022 #include <boost/container/detail/config_begin.hpp>
0023 #include <boost/container/detail/workaround.hpp>
0024
0025 #include <boost/container/container_fwd.hpp>
0026
0027 #include <boost/move/detail/to_raw_pointer.hpp>
0028 #include <boost/container/detail/type_traits.hpp>
0029 #include <boost/container/detail/placement_new.hpp>
0030 #include <boost/container/detail/iterator.hpp>
0031
0032 #include <boost/intrusive/slist.hpp>
0033 #include <boost/intrusive/pointer_traits.hpp>
0034 #include <boost/intrusive/detail/twin.hpp>
0035
0036 #include <boost/move/utility_core.hpp>
0037 #include <boost/move/detail/iterator_to_raw_pointer.hpp>
0038
0039
0040 namespace boost {
0041 namespace container {
0042 namespace dtl {
0043
0044 template<class VoidPointer>
0045 class basic_multiallocation_chain
0046 {
0047 private:
0048 typedef bi::slist_base_hook<bi::void_pointer<VoidPointer>
0049 ,bi::link_mode<bi::normal_link>
0050 > node;
0051
0052 typedef typename boost::intrusive::pointer_traits
0053 <VoidPointer>::template rebind_pointer<char>::type char_ptr;
0054 typedef typename boost::intrusive::
0055 pointer_traits<char_ptr>::difference_type difference_type;
0056
0057 typedef bi::slist< node
0058 , bi::linear<true>
0059 , bi::cache_last<true>
0060 , bi::size_type<typename boost::container::dtl::make_unsigned<difference_type>::type>
0061 > slist_impl_t;
0062 slist_impl_t slist_impl_;
0063
0064 typedef typename boost::intrusive::pointer_traits
0065 <VoidPointer>::template rebind_pointer<node>::type node_ptr;
0066 typedef typename boost::intrusive::
0067 pointer_traits<node_ptr> node_ptr_traits;
0068
0069 static node & to_node(const VoidPointer &p)
0070 { return *static_cast<node*>(static_cast<void*>(boost::movelib::to_raw_pointer(p))); }
0071
0072 static VoidPointer from_node(node &n)
0073 { return node_ptr_traits::pointer_to(n); }
0074
0075 static node_ptr to_node_ptr(const VoidPointer &p)
0076 { return node_ptr_traits::static_cast_from(p); }
0077
0078 BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
0079
0080 public:
0081
0082 typedef VoidPointer void_pointer;
0083 typedef typename slist_impl_t::iterator iterator;
0084 typedef typename slist_impl_t::size_type size_type;
0085 typedef boost::intrusive::twin<void_pointer> pointer_pair;
0086
0087 basic_multiallocation_chain()
0088 : slist_impl_()
0089 {}
0090
0091 basic_multiallocation_chain(const void_pointer &b, const void_pointer &before_e, size_type n)
0092 : slist_impl_(to_node_ptr(b), to_node_ptr(before_e), n)
0093 {}
0094
0095 basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other)
0096 : slist_impl_(::boost::move(other.slist_impl_))
0097 {}
0098
0099 basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other)
0100 {
0101 slist_impl_ = ::boost::move(other.slist_impl_);
0102 return *this;
0103 }
0104
0105 bool empty() const
0106 { return slist_impl_.empty(); }
0107
0108 size_type size() const
0109 { return slist_impl_.size(); }
0110
0111 iterator before_begin()
0112 { return slist_impl_.before_begin(); }
0113
0114 iterator begin()
0115 { return slist_impl_.begin(); }
0116
0117 iterator end()
0118 { return slist_impl_.end(); }
0119
0120 iterator last()
0121 { return slist_impl_.last(); }
0122
0123 void clear()
0124 { slist_impl_.clear(); }
0125
0126 iterator insert_after(iterator it, void_pointer m)
0127 { return slist_impl_.insert_after(it, to_node(m)); }
0128
0129 void push_front(const void_pointer &m)
0130 { return slist_impl_.push_front(to_node(m)); }
0131
0132 void push_back(const void_pointer &m)
0133 { return slist_impl_.push_back(to_node(m)); }
0134
0135 void_pointer pop_front()
0136 {
0137 node & n = slist_impl_.front();
0138 void_pointer ret = from_node(n);
0139 slist_impl_.pop_front();
0140 return ret;
0141 }
0142
0143 void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
0144 { slist_impl_.splice_after(after_this, x.slist_impl_, before_b, before_e, n); }
0145
0146 void splice_after(iterator after_this, basic_multiallocation_chain &x)
0147 { slist_impl_.splice_after(after_this, x.slist_impl_); }
0148
0149 void erase_after(iterator before_b, iterator e, size_type n)
0150 { slist_impl_.erase_after(before_b, e, n); }
0151
0152 void_pointer incorporate_after(iterator after_this, const void_pointer &b, size_type unit_bytes, size_type num_units)
0153 {
0154 typedef typename boost::intrusive::pointer_traits<char_ptr> char_pointer_traits;
0155 char_ptr elem = char_pointer_traits::static_cast_from(b);
0156 if(num_units){
0157 char_ptr prev_elem = elem;
0158 elem += difference_type(unit_bytes);
0159 for(size_type i = 0; i != num_units-1u; ++i, elem += difference_type(unit_bytes)){
0160 ::new (boost::movelib::to_raw_pointer(prev_elem), boost_container_new_t()) void_pointer(elem);
0161 prev_elem = elem;
0162 }
0163 slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units);
0164 }
0165 return elem;
0166 }
0167
0168 void incorporate_after(iterator after_this, void_pointer b, void_pointer before_e, size_type n)
0169 { slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(before_e), n); }
0170
0171 void swap(basic_multiallocation_chain &x)
0172 { slist_impl_.swap(x.slist_impl_); }
0173
0174 static iterator iterator_to(const void_pointer &p)
0175 { return slist_impl_t::s_iterator_to(to_node(p)); }
0176
0177 pointer_pair extract_data()
0178 {
0179 if(BOOST_LIKELY(!slist_impl_.empty())){
0180 pointer_pair ret
0181 (slist_impl_.begin().operator->()
0182 ,slist_impl_.last().operator->());
0183 slist_impl_.clear();
0184 return ret;
0185 }
0186 else {
0187 return pointer_pair();
0188 }
0189 }
0190 };
0191
0192 template <class Iterator, class T>
0193 class multialloc_iterator
0194 : public boost::container::iterator
0195 < typename Iterator::iterator_category
0196 , T
0197 , typename Iterator::difference_type
0198 , T*
0199 , T&
0200 >
0201 {
0202 public:
0203 inline explicit multialloc_iterator(const Iterator &it)
0204 : m_it(it)
0205 {}
0206
0207 inline explicit multialloc_iterator()
0208 : m_it()
0209 {}
0210
0211
0212 inline multialloc_iterator& operator++()
0213 { increment(); return *this; }
0214
0215 inline multialloc_iterator operator++(int)
0216 {
0217 multialloc_iterator result (*this);
0218 increment();
0219 return result;
0220 }
0221
0222 inline friend bool operator== (const multialloc_iterator& i, const multialloc_iterator& i2)
0223 { return i.equal(i2); }
0224
0225 inline friend bool operator!= (const multialloc_iterator& i, const multialloc_iterator& i2)
0226 { return !(i == i2); }
0227
0228 inline friend typename Iterator::difference_type operator- (const multialloc_iterator& i, const multialloc_iterator& i2)
0229 { return i2.distance_to(i); }
0230
0231
0232 inline multialloc_iterator& operator+=(typename Iterator::difference_type off)
0233 { this->advance(off); return *this; }
0234
0235 inline multialloc_iterator operator+(typename Iterator::difference_type off) const
0236 {
0237 multialloc_iterator other(*this);
0238 other.advance(off);
0239 return other;
0240 }
0241
0242 inline friend multialloc_iterator operator+(typename Iterator::difference_type off, const multialloc_iterator& right)
0243 { return right + off; }
0244
0245 inline multialloc_iterator& operator-=(typename Iterator::difference_type off)
0246 { this->advance(-off); return *this; }
0247
0248 inline multialloc_iterator operator-(typename Iterator::difference_type off) const
0249 { return *this + (-off); }
0250
0251 inline T& operator*() const
0252 { return *this->operator->(); }
0253
0254 inline T* operator->() const
0255 { return static_cast<T*>(static_cast<void*>(boost::movelib::iterator_to_raw_pointer(m_it))); }
0256
0257 inline Iterator & base()
0258 { return m_it; }
0259
0260 inline const Iterator & base() const
0261 { return m_it; }
0262
0263 private:
0264 Iterator m_it;
0265
0266 inline void increment()
0267 { ++m_it; }
0268
0269 inline void decrement()
0270 { --m_it; }
0271
0272 inline bool equal(const multialloc_iterator &other) const
0273 { return m_it == other.m_it; }
0274
0275 inline bool less(const multialloc_iterator &other) const
0276 { return other.m_it < m_it; }
0277
0278 inline void advance(typename Iterator::difference_type n)
0279 { boost::container::iterator_advance(m_it, n); }
0280
0281 inline typename Iterator::difference_type distance_to(const multialloc_iterator &other)const
0282 { return boost::container::iterator_distance(other.m_it, m_it); }
0283 };
0284
0285
0286 template<class MultiallocationChain, class T>
0287 class transform_multiallocation_chain
0288 : public MultiallocationChain
0289 {
0290 private:
0291 BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain)
0292
0293
0294
0295 typedef typename MultiallocationChain::void_pointer void_pointer;
0296 typedef typename boost::intrusive::pointer_traits
0297 <void_pointer> void_pointer_traits;
0298 typedef typename void_pointer_traits::template
0299 rebind_pointer<T>::type pointer;
0300 typedef typename boost::intrusive::pointer_traits
0301 <pointer> pointer_traits;
0302
0303 static pointer cast(const void_pointer &p)
0304 { return pointer_traits::static_cast_from(p); }
0305
0306 public:
0307 typedef multialloc_iterator
0308 <typename MultiallocationChain::iterator, T> iterator;
0309 typedef typename MultiallocationChain::size_type size_type;
0310 typedef boost::intrusive::twin<pointer> pointer_pair;
0311
0312 transform_multiallocation_chain()
0313 : MultiallocationChain()
0314 {}
0315
0316 transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other)
0317 : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
0318 {}
0319
0320 transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other)
0321 : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
0322 {}
0323
0324 transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other)
0325 {
0326 return static_cast<MultiallocationChain&>
0327 (this->MultiallocationChain::operator=(::boost::move(static_cast<MultiallocationChain&>(other))));
0328 }
0329
0330 void push_front(const pointer &mem)
0331 { this->MultiallocationChain::push_front(mem); }
0332
0333 void push_back(const pointer &mem)
0334 { return this->MultiallocationChain::push_back(mem); }
0335
0336 void swap(transform_multiallocation_chain &other_chain)
0337 { this->MultiallocationChain::swap(other_chain); }
0338
0339 void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
0340 { this->MultiallocationChain::splice_after(after_this.base(), x, before_b.base(), before_e.base(), n); }
0341
0342 void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n)
0343 { this->MultiallocationChain::incorporate_after(after_this.base(), b, before_e, n); }
0344
0345 pointer pop_front()
0346 { return cast(this->MultiallocationChain::pop_front()); }
0347
0348 bool empty() const
0349 { return this->MultiallocationChain::empty(); }
0350
0351 iterator before_begin()
0352 { return iterator(this->MultiallocationChain::before_begin()); }
0353
0354 iterator begin()
0355 { return iterator(this->MultiallocationChain::begin()); }
0356
0357 iterator last()
0358 { return iterator(this->MultiallocationChain::last()); }
0359
0360 iterator end()
0361 { return iterator(this->MultiallocationChain::end()); }
0362
0363 size_type size() const
0364 { return this->MultiallocationChain::size(); }
0365
0366 void clear()
0367 { this->MultiallocationChain::clear(); }
0368
0369 iterator insert_after(iterator it, pointer m)
0370 { return iterator(this->MultiallocationChain::insert_after(it.base(), m)); }
0371
0372 static iterator iterator_to(const pointer &p)
0373 { return iterator(MultiallocationChain::iterator_to(p)); }
0374
0375 pointer_pair extract_data()
0376 {
0377 typename MultiallocationChain::pointer_pair data(this->MultiallocationChain::extract_data());
0378 return pointer_pair(cast(data.first), cast(data.second));
0379 }
0380
0381
0382
0383 };
0384
0385 }}}
0386
0387
0388
0389
0390
0391 #include <boost/container/detail/config_end.hpp>
0392
0393 #endif