fix doc example typo
[boost.git] / boost / interprocess / containers / container / detail / multiallocation_chain.hpp
blob1f3f2c565e61580f99a624b1be8beeb7833156e7
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2008. 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 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
12 #define BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
14 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
15 #include <boost/interprocess/containers/container/detail/utilities.hpp>
16 #include <boost/interprocess/containers/container/detail/type_traits.hpp>
17 #include <boost/interprocess/containers/container/detail/transform_iterator.hpp>
19 namespace boost {
20 namespace interprocess_container {
21 namespace containers_detail {
23 template<class VoidPointer>
24 class basic_multiallocation_slist
26 public:
27 typedef VoidPointer void_pointer;
29 private:
30 static VoidPointer &priv_get_ref(const VoidPointer &p)
31 { return *static_cast<void_pointer*>(containers_detail::get_pointer(p)); }
33 basic_multiallocation_slist(basic_multiallocation_slist &);
34 basic_multiallocation_slist &operator=(basic_multiallocation_slist &);
36 public:
37 BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_slist)
39 //!This iterator is returned by "allocate_many" functions so that
40 //!the user can access the multiple buffers allocated in a single call
41 class iterator
42 : public std::iterator<std::input_iterator_tag, char>
44 friend class basic_multiallocation_slist<void_pointer>;
45 void unspecified_bool_type_func() const {}
46 typedef void (iterator::*unspecified_bool_type)() const;
48 iterator(void_pointer node_range)
49 : next_node_(node_range)
52 public:
53 typedef char value_type;
54 typedef value_type & reference;
55 typedef value_type * pointer;
57 iterator()
58 : next_node_(0)
61 iterator &operator=(const iterator &other)
62 { next_node_ = other.next_node_; return *this; }
64 public:
65 iterator& operator++()
67 next_node_ = *static_cast<void_pointer*>(containers_detail::get_pointer(next_node_));
68 return *this;
71 iterator operator++(int)
73 iterator result(*this);
74 ++*this;
75 return result;
78 bool operator== (const iterator& other) const
79 { return next_node_ == other.next_node_; }
81 bool operator!= (const iterator& other) const
82 { return !operator== (other); }
84 reference operator*() const
85 { return *static_cast<char*>(containers_detail::get_pointer(next_node_)); }
87 operator unspecified_bool_type() const
88 { return next_node_? &iterator::unspecified_bool_type_func : 0; }
90 pointer operator->() const
91 { return &(*(*this)); }
93 private:
94 void_pointer next_node_;
97 private:
98 iterator it_;
100 public:
101 basic_multiallocation_slist()
102 : it_(iterator())
105 basic_multiallocation_slist(void_pointer p)
106 : it_(p ? iterator_to(p) : iterator())
109 basic_multiallocation_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
110 : it_(iterator())
111 { this->swap(other); }
113 basic_multiallocation_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
115 basic_multiallocation_slist tmp(boost::interprocess::move(other));
116 this->swap(tmp);
117 return *this;
120 bool empty() const
121 { return !it_; }
123 iterator before_begin() const
124 { return iterator(void_pointer(const_cast<void*>(static_cast<const void*>(&it_.next_node_)))); }
126 iterator begin() const
127 { return it_; }
129 iterator end() const
130 { return iterator(); }
132 void clear()
133 { this->it_.next_node_ = void_pointer(0); }
135 iterator insert_after(iterator it, void_pointer m)
137 priv_get_ref(m) = priv_get_ref(it.next_node_);
138 priv_get_ref(it.next_node_) = m;
139 return iterator(m);
142 void push_front(void_pointer m)
144 priv_get_ref(m) = this->it_.next_node_;
145 this->it_.next_node_ = m;
148 void pop_front()
149 { ++it_; }
151 void *front() const
152 { return containers_detail::get_pointer(it_.next_node_); }
154 void splice_after(iterator after_this, iterator before_begin, iterator before_end)
156 if (after_this != before_begin && after_this != before_end && before_begin != before_end) {
157 void_pointer next_b = priv_get_ref(before_begin.next_node_);
158 void_pointer next_e = priv_get_ref(before_end.next_node_);
159 void_pointer next_p = priv_get_ref(after_this.next_node_);
160 priv_get_ref(before_begin.next_node_) = next_e;
161 priv_get_ref(before_end.next_node_) = next_p;
162 priv_get_ref(after_this.next_node_) = next_b;
166 void swap(basic_multiallocation_slist &other_chain)
168 std::swap(this->it_, other_chain.it_);
171 static iterator iterator_to(void_pointer p)
172 { return iterator(p); }
174 void_pointer extract_data()
176 void_pointer ret = empty() ? void_pointer(0) : void_pointer(&*it_);
177 it_ = iterator();
178 return ret;
182 template<class VoidPointer>
183 class basic_multiallocation_cached_slist
185 private:
186 basic_multiallocation_slist<VoidPointer> slist_;
187 typename basic_multiallocation_slist<VoidPointer>::iterator last_;
189 basic_multiallocation_cached_slist(basic_multiallocation_cached_slist &);
190 basic_multiallocation_cached_slist &operator=(basic_multiallocation_cached_slist &);
192 public:
193 BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_slist)
195 typedef typename basic_multiallocation_slist<VoidPointer>::void_pointer void_pointer;
196 typedef typename basic_multiallocation_slist<VoidPointer>::iterator iterator;
198 basic_multiallocation_cached_slist()
199 : slist_(), last_(slist_.before_begin())
202 basic_multiallocation_cached_slist(iterator first_node)
203 : slist_(first_node), last_(slist_.before_begin())
205 iterator end;
206 while(first_node != end){
207 ++last_;
211 basic_multiallocation_cached_slist(void_pointer p1, void_pointer p2)
212 : slist_(p1), last_(p2 ? iterator_to(p2) : slist_.before_begin())
215 basic_multiallocation_cached_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
216 : slist_(), last_(slist_.before_begin())
217 { this->swap(other); }
219 basic_multiallocation_cached_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
221 basic_multiallocation_cached_slist tmp(boost::interprocess::move(other));
222 this->swap(tmp);
223 return *this;
226 bool empty() const
227 { return slist_.empty(); }
229 iterator before_begin() const
230 { return slist_.before_begin(); }
232 iterator begin() const
233 { return slist_.begin(); }
235 iterator end() const
236 { return slist_.end(); }
238 iterator last() const
239 { return last_; }
241 void clear()
243 slist_.clear();
244 last_ = slist_.before_begin();
247 iterator insert_after(iterator it, void_pointer m)
249 slist_.insert_after(it, m);
250 if(it == last_){
251 last_ = slist_.iterator_to(m);
253 return iterator_to(m);
256 void push_front(void_pointer m)
257 { this->insert_after(this->before_begin(), m); }
259 void push_back(void_pointer m)
260 { this->insert_after(last_, m); }
262 void pop_front()
264 if(last_ == slist_.begin()){
265 last_ = slist_.before_begin();
267 slist_.pop_front();
270 void *front() const
271 { return slist_.front(); }
273 void splice_after(iterator after_this, iterator before_begin, iterator before_end)
275 if(before_begin == before_end)
276 return;
277 if(after_this == last_){
278 last_ = before_end;
280 slist_.splice_after(after_this, before_begin, before_end);
283 void swap(basic_multiallocation_cached_slist &x)
285 slist_.swap(x.slist_);
286 using std::swap;
287 swap(last_, x.last_);
288 if(last_ == x.before_begin()){
289 last_ = this->before_begin();
291 if(x.last_ == this->before_begin()){
292 x.last_ = x.before_begin();
296 static iterator iterator_to(void_pointer p)
297 { return basic_multiallocation_slist<VoidPointer>::iterator_to(p); }
299 std::pair<void_pointer, void_pointer> extract_data()
301 if(this->empty()){
302 return std::pair<void_pointer, void_pointer>(void_pointer(0), void_pointer(0));
304 else{
305 void_pointer p1 = slist_.extract_data();
306 void_pointer p2 = void_pointer(&*last_);
307 last_ = iterator();
308 return std::pair<void_pointer, void_pointer>(p1, p2);
313 template<class MultiallocatorCachedSlist>
314 class basic_multiallocation_cached_counted_slist
316 private:
317 MultiallocatorCachedSlist cached_slist_;
318 std::size_t size_;
320 basic_multiallocation_cached_counted_slist(basic_multiallocation_cached_counted_slist &);
321 basic_multiallocation_cached_counted_slist &operator=(basic_multiallocation_cached_counted_slist &);
323 public:
324 BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_counted_slist)
326 typedef typename MultiallocatorCachedSlist::void_pointer void_pointer;
327 typedef typename MultiallocatorCachedSlist::iterator iterator;
329 basic_multiallocation_cached_counted_slist()
330 : cached_slist_(), size_(0)
333 basic_multiallocation_cached_counted_slist(void_pointer p1, void_pointer p2, std::size_t n)
334 : cached_slist_(p1, p2), size_(n)
337 basic_multiallocation_cached_counted_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
338 : cached_slist_(), size_(0)
339 { this->swap(other); }
341 basic_multiallocation_cached_counted_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
343 basic_multiallocation_cached_counted_slist tmp(boost::interprocess::move(other));
344 this->swap(tmp);
345 return *this;
348 basic_multiallocation_cached_counted_slist (MultiallocatorCachedSlist mem, std::size_t n)
349 : cached_slist_(boost::interprocess::move(mem)), size_(n)
352 bool empty() const
353 { return cached_slist_.empty(); }
355 std::size_t size() const
356 { return size_; }
358 iterator before_begin() const
359 { return cached_slist_.before_begin(); }
361 iterator begin() const
362 { return cached_slist_.begin(); }
364 iterator end() const
365 { return cached_slist_.end(); }
367 iterator last() const
368 { return cached_slist_.last(); }
370 void clear()
372 cached_slist_.clear();
373 size_ = 0;
376 iterator insert_after(iterator it, void_pointer m)
378 iterator ret = cached_slist_.insert_after(it, m);
379 ++size_;
380 return ret;
383 void push_front(void_pointer m)
384 { this->insert_after(this->before_begin(), m); }
386 void push_back(void_pointer m)
387 { this->insert_after(this->before_begin(), m); }
389 void pop_front()
391 cached_slist_.pop_front();
392 --size_;
395 void *front() const
396 { return cached_slist_.front(); }
398 void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end)
400 std::size_t n = static_cast<std::size_t>(std::distance(before_begin, before_end));
401 this->splice_after(after_this, x, before_begin, before_end, n);
404 void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end, std::size_t n)
406 cached_slist_.splice_after(after_this, before_begin, before_end);
407 size_ += n;
408 x.size_ -= n;
411 void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x)
413 cached_slist_.splice_after(after_this, x.before_begin(), x.last());
414 size_ += x.size_;
415 x.size_ = 0;
418 void swap(basic_multiallocation_cached_counted_slist &x)
420 cached_slist_.swap(x.cached_slist_);
421 using std::swap;
422 swap(size_, x.size_);
425 static iterator iterator_to(void_pointer p)
426 { return MultiallocatorCachedSlist::iterator_to(p); }
428 std::pair<void_pointer, void_pointer> extract_data()
430 size_ = 0;
431 return cached_slist_.extract_data();
435 template<class T>
436 struct cast_functor
438 typedef typename containers_detail::add_reference<T>::type result_type;
439 result_type operator()(char &ptr) const
440 { return *static_cast<T*>(static_cast<void*>(&ptr)); }
444 template<class MultiallocationChain, class T>
445 class transform_multiallocation_chain
447 private:
449 MultiallocationChain holder_;
450 typedef typename MultiallocationChain::void_pointer void_pointer;
451 typedef typename boost::pointer_to_other
452 <void_pointer, T>::type pointer;
454 transform_multiallocation_chain(transform_multiallocation_chain &);
455 transform_multiallocation_chain &operator=(transform_multiallocation_chain &);
457 static pointer cast(void_pointer p)
459 return pointer(static_cast<T*>(containers_detail::get_pointer(p)));
462 public:
463 BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(transform_multiallocation_chain)
465 typedef transform_iterator
466 < typename MultiallocationChain::iterator
467 , containers_detail::cast_functor <T> > iterator;
469 transform_multiallocation_chain(void_pointer p1, void_pointer p2, std::size_t n)
470 : holder_(p1, p2, n)
473 transform_multiallocation_chain()
474 : holder_()
477 transform_multiallocation_chain(BOOST_INTERPROCESS_RV_REF(transform_multiallocation_chain) other)
478 : holder_()
479 { this->swap(other); }
481 transform_multiallocation_chain(BOOST_INTERPROCESS_RV_REF(MultiallocationChain) other)
482 : holder_(boost::interprocess::move(other))
485 transform_multiallocation_chain& operator=(BOOST_INTERPROCESS_RV_REF(transform_multiallocation_chain) other)
487 transform_multiallocation_chain tmp(boost::interprocess::move(other));
488 this->swap(tmp);
489 return *this;
492 void push_front(pointer mem)
493 { holder_.push_front(mem); }
495 void swap(transform_multiallocation_chain &other_chain)
496 { holder_.swap(other_chain.holder_); }
498 void splice_after(iterator after_this, iterator before_begin, iterator before_end)
499 { holder_.splice_after(after_this.base(), before_begin.base(), before_end.base()); }
501 void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, std::size_t n)
502 { holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n); }
504 void pop_front()
505 { holder_.pop_front(); }
507 pointer front() const
508 { return cast(holder_.front()); }
510 bool empty() const
511 { return holder_.empty(); }
513 iterator before_begin() const
514 { return iterator(holder_.before_begin()); }
516 iterator begin() const
517 { return iterator(holder_.begin()); }
519 iterator end() const
520 { return iterator(holder_.end()); }
522 iterator last() const
523 { return iterator(holder_.last()); }
525 std::size_t size() const
526 { return holder_.size(); }
528 void clear()
529 { holder_.clear(); }
531 iterator insert_after(iterator it, pointer m)
532 { return iterator(holder_.insert_after(it.base(), m)); }
534 static iterator iterator_to(pointer p)
535 { return iterator(MultiallocationChain::iterator_to(p)); }
537 std::pair<void_pointer, void_pointer> extract_data()
538 { return holder_.extract_data(); }
540 MultiallocationChain extract_multiallocation_chain()
542 return MultiallocationChain(boost::interprocess::move(holder_));
548 // namespace containers_detail {
549 // namespace interprocess_container {
550 // namespace boost {
552 #include <boost/interprocess/containers/container/detail/config_end.hpp>
554 #endif //BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP