fix doc example typo
[boost.git] / boost / interprocess / containers / container / slist.hpp
blob9b6a4db65f2ca926bfea7dc2e34bb1b210a41fa8
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2004-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 // This file comes from SGI's stl_slist.h file. Modified by Ion Gaztanaga 2004-2008
12 // Renaming, isolating and porting to generic algorithms. Pointer typedef
13 // set to allocator::pointer to allow placing it in shared memory.
15 ///////////////////////////////////////////////////////////////////////////////
18 * Copyright (c) 1994
19 * Hewlett-Packard Company
21 * Permission to use, copy, modify, distribute and sell this software
22 * and its documentation for any purpose is hereby granted without fee,
23 * provided that the above copyright notice appear in all copies and
24 * that both that copyright notice and this permission notice appear
25 * in supporting documentation. Hewlett-Packard Company makes no
26 * representations about the suitability of this software for any
27 * purpose. It is provided "as is" without express or implied warranty.
30 * Copyright (c) 1996
31 * Silicon Graphics Computer Systems, Inc.
33 * Permission to use, copy, modify, distribute and sell this software
34 * and its documentation for any purpose is hereby granted without fee,
35 * provided that the above copyright notice appear in all copies and
36 * that both that copyright notice and this permission notice appear
37 * in supporting documentation. Silicon Graphics makes no
38 * representations about the suitability of this software for any
39 * purpose. It is provided "as is" without express or implied warranty.
43 #ifndef BOOST_CONTAINERS_SLIST_HPP
44 #define BOOST_CONTAINERS_SLIST_HPP
46 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
47 # pragma once
48 #endif
50 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
51 #include <boost/interprocess/containers/container/detail/workaround.hpp>
53 #include <boost/interprocess/containers/container/containers_fwd.hpp>
54 #include <boost/interprocess/detail/move.hpp>
55 #include <boost/pointer_to_other.hpp>
56 #include <boost/interprocess/containers/container/detail/utilities.hpp>
57 #include <boost/interprocess/containers/container/detail/mpl.hpp>
58 #include <boost/type_traits/has_trivial_destructor.hpp>
59 #include <boost/detail/no_exceptions_support.hpp>
60 #include <boost/interprocess/containers/container/detail/node_alloc_holder.hpp>
61 #include <boost/intrusive/slist.hpp>
64 #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
65 //Preprocessor library to emulate perfect forwarding
66 #include <boost/interprocess/containers/container/detail/preprocessor.hpp>
67 #endif
69 #include <iterator>
70 #include <utility>
71 #include <memory>
72 #include <functional>
73 #include <algorithm>
75 #ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
76 namespace boost {
77 namespace interprocess {
78 #else
79 namespace boost {
80 namespace interprocess_container {
81 #endif
83 /// @cond
85 namespace containers_detail {
87 template<class VoidPointer>
88 struct slist_hook
90 typedef typename containers_detail::bi::make_slist_base_hook
91 <containers_detail::bi::void_pointer<VoidPointer>, containers_detail::bi::link_mode<containers_detail::bi::normal_link> >::type type;
94 template <class T, class VoidPointer>
95 struct slist_node
96 : public slist_hook<VoidPointer>::type
98 #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
100 slist_node()
101 : m_data()
104 #define BOOST_PP_LOCAL_MACRO(n) \
105 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
106 slist_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
107 : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
108 {} \
110 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
111 #include BOOST_PP_LOCAL_ITERATE()
113 #else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
115 slist_node()
116 : m_data()
119 template<class ...Args>
120 slist_node(Args &&...args)
121 : m_data(boost::interprocess::forward<Args>(args)...)
123 #endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
125 T m_data;
128 template<class A>
129 struct intrusive_slist_type
131 typedef typename A::value_type value_type;
132 typedef typename boost::pointer_to_other
133 <typename A::pointer, void>::type void_pointer;
134 typedef typename containers_detail::slist_node
135 <value_type, void_pointer> node_type;
137 typedef typename containers_detail::bi::make_slist
138 <node_type
139 ,containers_detail::bi::base_hook<typename slist_hook<void_pointer>::type>
140 ,containers_detail::bi::constant_time_size<true>
141 ,containers_detail::bi::size_type<typename A::size_type>
142 >::type container_type;
143 typedef container_type type ;
146 } //namespace containers_detail {
148 /// @endcond
150 //! An slist is a singly linked list: a list where each element is linked to the next
151 //! element, but not to the previous element. That is, it is a Sequence that
152 //! supports forward but not backward traversal, and (amortized) constant time
153 //! insertion and removal of elements. Slists, like lists, have the important
154 //! property that insertion and splicing do not invalidate iterators to list elements,
155 //! and that even removal invalidates only the iterators that point to the elements
156 //! that are removed. The ordering of iterators may be changed (that is,
157 //! slist<T>::iterator might have a different predecessor or successor after a list
158 //! operation than it did before), but the iterators themselves will not be invalidated
159 //! or made to point to different elements unless that invalidation or mutation is explicit.
161 //! The main difference between slist and list is that list's iterators are bidirectional
162 //! iterators, while slist's iterators are forward iterators. This means that slist is
163 //! less versatile than list; frequently, however, bidirectional iterators are
164 //! unnecessary. You should usually use slist unless you actually need the extra
165 //! functionality of list, because singly linked lists are smaller and faster than double
166 //! linked lists.
167 //!
168 //! Important performance note: like every other Sequence, slist defines the member
169 //! functions insert and erase. Using these member functions carelessly, however, can
170 //! result in disastrously slow programs. The problem is that insert's first argument is
171 //! an iterator p, and that it inserts the new element(s) before p. This means that
172 //! insert must find the iterator just before p; this is a constant-time operation
173 //! for list, since list has bidirectional iterators, but for slist it must find that
174 //! iterator by traversing the list from the beginning up to p. In other words:
175 //! insert and erase are slow operations anywhere but near the beginning of the slist.
176 //!
177 //! Slist provides the member functions insert_after and erase_after, which are constant
178 //! time operations: you should always use insert_after and erase_after whenever
179 //! possible. If you find that insert_after and erase_after aren't adequate for your
180 //! needs, and that you often need to use insert and erase in the middle of the list,
181 //! then you should probably use list instead of slist.
182 template <class T, class A>
183 class slist
184 : protected containers_detail::node_alloc_holder
185 <A, typename containers_detail::intrusive_slist_type<A>::type>
187 /// @cond
188 typedef typename
189 containers_detail::intrusive_slist_type<A>::type Icont;
190 typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
191 typedef typename AllocHolder::NodePtr NodePtr;
192 typedef slist <T, A> ThisType;
193 typedef typename AllocHolder::NodeAlloc NodeAlloc;
194 typedef typename AllocHolder::ValAlloc ValAlloc;
195 typedef typename AllocHolder::Node Node;
196 typedef containers_detail::allocator_destroyer<NodeAlloc> Destroyer;
197 typedef typename AllocHolder::allocator_v1 allocator_v1;
198 typedef typename AllocHolder::allocator_v2 allocator_v2;
199 typedef typename AllocHolder::alloc_version alloc_version;
201 class equal_to_value
203 typedef typename AllocHolder::value_type value_type;
204 const value_type &t_;
206 public:
207 equal_to_value(const value_type &t)
208 : t_(t)
211 bool operator()(const value_type &t)const
212 { return t_ == t; }
215 template<class Pred>
216 struct ValueCompareToNodeCompare
217 : Pred
219 ValueCompareToNodeCompare(Pred pred)
220 : Pred(pred)
223 bool operator()(const Node &a, const Node &b) const
224 { return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
226 bool operator()(const Node &a) const
227 { return static_cast<const Pred&>(*this)(a.m_data); }
229 /// @endcond
230 public:
231 //! The type of object, T, stored in the list
232 typedef T value_type;
233 //! Pointer to T
234 typedef typename A::pointer pointer;
235 //! Const pointer to T
236 typedef typename A::const_pointer const_pointer;
237 //! Reference to T
238 typedef typename A::reference reference;
239 //! Const reference to T
240 typedef typename A::const_reference const_reference;
241 //! An unsigned integral type
242 typedef typename A::size_type size_type;
243 //! A signed integral type
244 typedef typename A::difference_type difference_type;
245 //! The allocator type
246 typedef A allocator_type;
247 //! The stored allocator type
248 typedef NodeAlloc stored_allocator_type;
250 /// @cond
251 private:
252 typedef difference_type list_difference_type;
253 typedef pointer list_pointer;
254 typedef const_pointer list_const_pointer;
255 typedef reference list_reference;
256 typedef const_reference list_const_reference;
257 /// @endcond
259 public:
260 BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(slist)
262 //! Const iterator used to iterate through a list.
263 class const_iterator
264 /// @cond
265 : public std::iterator<std::forward_iterator_tag,
266 value_type, list_difference_type,
267 list_const_pointer, list_const_reference>
270 protected:
271 typename Icont::iterator m_it;
272 explicit const_iterator(typename Icont::iterator it) : m_it(it){}
273 void prot_incr(){ ++m_it; }
275 private:
276 typename Icont::iterator get()
277 { return this->m_it; }
279 public:
280 friend class slist<T, A>;
281 typedef list_difference_type difference_type;
283 //Constructors
284 const_iterator()
285 : m_it()
288 //Pointer like operators
289 const_reference operator*() const
290 { return m_it->m_data; }
292 const_pointer operator->() const
293 { return const_pointer(&m_it->m_data); }
295 //Increment / Decrement
296 const_iterator& operator++()
297 { prot_incr(); return *this; }
299 const_iterator operator++(int)
300 { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp); }
302 //Comparison operators
303 bool operator== (const const_iterator& r) const
304 { return m_it == r.m_it; }
306 bool operator!= (const const_iterator& r) const
307 { return m_it != r.m_it; }
309 /// @endcond
312 //! Iterator used to iterate through a list
313 class iterator
314 /// @cond
315 : public const_iterator
318 private:
319 explicit iterator(typename Icont::iterator it)
320 : const_iterator(it)
323 typename Icont::iterator get()
324 { return this->m_it; }
326 public:
327 friend class slist<T, A>;
328 typedef list_pointer pointer;
329 typedef list_reference reference;
331 //Constructors
332 iterator(){}
334 //Pointer like operators
335 reference operator*() const { return this->m_it->m_data; }
336 pointer operator->() const { return pointer(&this->m_it->m_data); }
338 //Increment / Decrement
339 iterator& operator++()
340 { this->prot_incr(); return *this; }
342 iterator operator++(int)
343 { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
345 /// @endcond
348 public:
349 //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
350 //!
351 //! <b>Throws</b>: If allocator_type's copy constructor throws.
352 //!
353 //! <b>Complexity</b>: Constant.
354 explicit slist(const allocator_type& a = allocator_type())
355 : AllocHolder(a)
358 explicit slist(size_type n)
359 : AllocHolder(allocator_type())
360 { this->resize(n); }
362 //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
363 //! and inserts n copies of value.
365 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
366 //! throws or T's default or copy constructor throws.
367 //!
368 //! <b>Complexity</b>: Linear to n.
369 explicit slist(size_type n, const value_type& x, const allocator_type& a = allocator_type())
370 : AllocHolder(a)
371 { this->priv_create_and_insert_nodes(this->before_begin(), n, x); }
373 //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
374 //! and inserts a copy of the range [first, last) in the list.
376 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
377 //! throws or T's constructor taking an dereferenced InIt throws.
379 //! <b>Complexity</b>: Linear to the range [first, last).
380 template <class InpIt>
381 slist(InpIt first, InpIt last,
382 const allocator_type& a = allocator_type())
383 : AllocHolder(a)
384 { this->insert_after(this->before_begin(), first, last); }
386 //! <b>Effects</b>: Copy constructs a list.
388 //! <b>Postcondition</b>: x == *this.
389 //!
390 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
391 //!
392 //! <b>Complexity</b>: Linear to the elements x contains.
393 slist(const slist& x)
394 : AllocHolder(x)
395 { this->insert_after(this->before_begin(), x.begin(), x.end()); }
397 //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
399 //! <b>Throws</b>: If allocator_type's copy constructor throws.
400 //!
401 //! <b>Complexity</b>: Constant.
402 slist(BOOST_INTERPROCESS_RV_REF(slist) x)
403 : AllocHolder(boost::interprocess::move((AllocHolder&)x))
406 //! <b>Effects</b>: Makes *this contain the same elements as x.
408 //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
409 //! of each of x's elements.
411 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
413 //! <b>Complexity</b>: Linear to the number of elements in x.
414 slist& operator= (const slist& x)
416 if (&x != this){
417 this->assign(x.begin(), x.end());
419 return *this;
422 //! <b>Effects</b>: Makes *this contain the same elements as x.
424 //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
425 //! of each of x's elements.
427 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
429 //! <b>Complexity</b>: Linear to the number of elements in x.
430 slist& operator= (BOOST_INTERPROCESS_RV_REF(slist) mx)
432 if (&mx != this){
433 this->clear();
434 this->swap(mx);
436 return *this;
439 //! <b>Effects</b>: Destroys the list. All stored values are destroyed
440 //! and used memory is deallocated.
442 //! <b>Throws</b>: Nothing.
444 //! <b>Complexity</b>: Linear to the number of elements.
445 ~slist()
446 {} //AllocHolder clears the slist
448 //! <b>Effects</b>: Returns a copy of the internal allocator.
449 //!
450 //! <b>Throws</b>: If allocator's copy constructor throws.
451 //!
452 //! <b>Complexity</b>: Constant.
453 allocator_type get_allocator() const
454 { return allocator_type(this->node_alloc()); }
456 const stored_allocator_type &get_stored_allocator() const
457 { return this->node_alloc(); }
459 stored_allocator_type &get_stored_allocator()
460 { return this->node_alloc(); }
462 public:
464 //! <b>Effects</b>: Assigns the n copies of val to *this.
466 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
468 //! <b>Complexity</b>: Linear to n.
469 void assign(size_type n, const T& val)
470 { this->priv_fill_assign(n, val); }
472 //! <b>Effects</b>: Assigns the range [first, last) to *this.
474 //! <b>Throws</b>: If memory allocation throws or
475 //! T's constructor from dereferencing InpIt throws.
477 //! <b>Complexity</b>: Linear to n.
478 template <class InpIt>
479 void assign(InpIt first, InpIt last)
481 const bool aux_boolean = containers_detail::is_convertible<InpIt, std::size_t>::value;
482 typedef containers_detail::bool_<aux_boolean> Result;
483 this->priv_assign_dispatch(first, last, Result());
486 //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
487 //!
488 //! <b>Throws</b>: Nothing.
489 //!
490 //! <b>Complexity</b>: Constant.
491 iterator begin()
492 { return iterator(this->icont().begin()); }
494 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
495 //!
496 //! <b>Throws</b>: Nothing.
497 //!
498 //! <b>Complexity</b>: Constant.
499 const_iterator begin() const
500 { return this->cbegin(); }
502 //! <b>Effects</b>: Returns an iterator to the end of the list.
503 //!
504 //! <b>Throws</b>: Nothing.
505 //!
506 //! <b>Complexity</b>: Constant.
507 iterator end()
508 { return iterator(this->icont().end()); }
510 //! <b>Effects</b>: Returns a const_iterator to the end of the list.
511 //!
512 //! <b>Throws</b>: Nothing.
513 //!
514 //! <b>Complexity</b>: Constant.
515 const_iterator end() const
516 { return this->cend(); }
518 //! <b>Effects</b>: Returns a non-dereferenceable iterator that,
519 //! when incremented, yields begin(). This iterator may be used
520 //! as the argument toinsert_after, erase_after, etc.
521 //!
522 //! <b>Throws</b>: Nothing.
523 //!
524 //! <b>Complexity</b>: Constant.
525 iterator before_begin()
526 { return iterator(end()); }
528 //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
529 //! that, when incremented, yields begin(). This iterator may be used
530 //! as the argument toinsert_after, erase_after, etc.
531 //!
532 //! <b>Throws</b>: Nothing.
533 //!
534 //! <b>Complexity</b>: Constant.
535 const_iterator before_begin() const
536 { return this->cbefore_begin(); }
538 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
539 //!
540 //! <b>Throws</b>: Nothing.
541 //!
542 //! <b>Complexity</b>: Constant.
543 const_iterator cbegin() const
544 { return const_iterator(this->non_const_icont().begin()); }
546 //! <b>Effects</b>: Returns a const_iterator to the end of the list.
547 //!
548 //! <b>Throws</b>: Nothing.
549 //!
550 //! <b>Complexity</b>: Constant.
551 const_iterator cend() const
552 { return const_iterator(this->non_const_icont().end()); }
554 //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
555 //! that, when incremented, yields begin(). This iterator may be used
556 //! as the argument toinsert_after, erase_after, etc.
557 //!
558 //! <b>Throws</b>: Nothing.
559 //!
560 //! <b>Complexity</b>: Constant.
561 const_iterator cbefore_begin() const
562 { return const_iterator(end()); }
564 //! <b>Effects</b>: Returns the number of the elements contained in the list.
565 //!
566 //! <b>Throws</b>: Nothing.
567 //!
568 //! <b>Complexity</b>: Constant.
569 size_type size() const
570 { return this->icont().size(); }
572 //! <b>Effects</b>: Returns the largest possible size of the list.
573 //!
574 //! <b>Throws</b>: Nothing.
575 //!
576 //! <b>Complexity</b>: Constant.
577 size_type max_size() const
578 { return AllocHolder::max_size(); }
580 //! <b>Effects</b>: Returns true if the list contains no elements.
581 //!
582 //! <b>Throws</b>: Nothing.
583 //!
584 //! <b>Complexity</b>: Constant.
585 bool empty() const
586 { return !this->size(); }
588 //! <b>Effects</b>: Swaps the contents of *this and x.
589 //! If this->allocator_type() != x.allocator_type()
590 //! allocators are also swapped.
592 //! <b>Throws</b>: Nothing.
594 //! <b>Complexity</b>: Linear to the number of elements on *this and x.
595 void swap(slist& x)
596 { AllocHolder::swap(x); }
598 //! <b>Requires</b>: !empty()
600 //! <b>Effects</b>: Returns a reference to the first element
601 //! from the beginning of the container.
602 //!
603 //! <b>Throws</b>: Nothing.
604 //!
605 //! <b>Complexity</b>: Constant.
606 reference front()
607 { return *this->begin(); }
609 //! <b>Requires</b>: !empty()
611 //! <b>Effects</b>: Returns a const reference to the first element
612 //! from the beginning of the container.
613 //!
614 //! <b>Throws</b>: Nothing.
615 //!
616 //! <b>Complexity</b>: Constant.
617 const_reference front() const
618 { return *this->begin(); }
620 //! <b>Effects</b>: Inserts a copy of t in the beginning of the list.
622 //! <b>Throws</b>: If memory allocation throws or
623 //! T's copy constructor throws.
625 //! <b>Complexity</b>: Amortized constant time.
626 void push_front(const value_type& x)
627 { this->icont().push_front(*this->create_node(x)); }
629 //! <b>Effects</b>: Constructs a new element in the beginning of the list
630 //! and moves the resources of t to this new element.
632 //! <b>Throws</b>: If memory allocation throws.
634 //! <b>Complexity</b>: Amortized constant time.
635 void push_front(BOOST_INTERPROCESS_RV_REF(T) x)
636 { this->icont().push_front(*this->create_node(boost::interprocess::move(x))); }
638 //! <b>Effects</b>: Removes the first element from the list.
640 //! <b>Throws</b>: Nothing.
642 //! <b>Complexity</b>: Amortized constant time.
643 void pop_front()
644 { this->icont().pop_front_and_dispose(Destroyer(this->node_alloc())); }
646 //! <b>Returns</b>: The iterator to the element before i in the sequence.
647 //! Returns the end-iterator, if either i is the begin-iterator or the
648 //! sequence is empty.
649 //!
650 //! <b>Throws</b>: Nothing.
651 //!
652 //! <b>Complexity</b>: Linear to the number of elements before i.
653 iterator previous(iterator p)
654 { return iterator(this->icont().previous(p.get())); }
656 //! <b>Returns</b>: The const_iterator to the element before i in the sequence.
657 //! Returns the end-const_iterator, if either i is the begin-const_iterator or
658 //! the sequence is empty.
659 //!
660 //! <b>Throws</b>: Nothing.
661 //!
662 //! <b>Complexity</b>: Linear to the number of elements before i.
663 const_iterator previous(const_iterator p)
664 { return const_iterator(this->icont().previous(p.get())); }
666 //! <b>Requires</b>: p must be a valid iterator of *this.
668 //! <b>Effects</b>: Inserts a copy of the value after the p pointed
669 //! by prev_p.
671 //! <b>Returns</b>: An iterator to the inserted element.
672 //!
673 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
674 //!
675 //! <b>Complexity</b>: Amortized constant time.
677 //! <b>Note</b>: Does not affect the validity of iterators and references of
678 //! previous values.
679 iterator insert_after(const_iterator prev_pos, const value_type& x)
680 { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
682 //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
684 //! <b>Effects</b>: Inserts a move constructed copy object from the value after the
685 //! p pointed by prev_pos.
687 //! <b>Returns</b>: An iterator to the inserted element.
688 //!
689 //! <b>Throws</b>: If memory allocation throws.
690 //!
691 //! <b>Complexity</b>: Amortized constant time.
693 //! <b>Note</b>: Does not affect the validity of iterators and references of
694 //! previous values.
695 iterator insert_after(const_iterator prev_pos, BOOST_INTERPROCESS_RV_REF(value_type) x)
696 { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(boost::interprocess::move(x)))); }
698 //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
700 //! <b>Effects</b>: Inserts n copies of x after prev_pos.
702 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
704 //! <b>Complexity</b>: Linear to n.
706 //! <b>Note</b>: Does not affect the validity of iterators and references of
707 //! previous values.
708 void insert_after(const_iterator prev_pos, size_type n, const value_type& x)
709 { this->priv_create_and_insert_nodes(prev_pos, n, x); }
711 //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
712 //!
713 //! <b>Effects</b>: Inserts the range pointed by [first, last)
714 //! after the p prev_pos.
715 //!
716 //! <b>Throws</b>: If memory allocation throws, T's constructor from a
717 //! dereferenced InpIt throws.
718 //!
719 //! <b>Complexity</b>: Linear to the number of elements inserted.
720 //!
721 //! <b>Note</b>: Does not affect the validity of iterators and references of
722 //! previous values.
723 template <class InIter>
724 void insert_after(const_iterator prev_pos, InIter first, InIter last)
726 const bool aux_boolean = containers_detail::is_convertible<InIter, std::size_t>::value;
727 typedef containers_detail::bool_<aux_boolean> Result;
728 this->priv_insert_after_range_dispatch(prev_pos, first, last, Result());
731 //! <b>Requires</b>: p must be a valid iterator of *this.
733 //! <b>Effects</b>: Insert a copy of x before p.
735 //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
737 //! <b>Complexity</b>: Linear to the elements before p.
738 iterator insert(const_iterator p, const value_type& x)
739 { return this->insert_after(previous(p), x); }
741 //! <b>Requires</b>: p must be a valid iterator of *this.
743 //! <b>Effects</b>: Insert a new element before p with mx's resources.
745 //! <b>Throws</b>: If memory allocation throws.
747 //! <b>Complexity</b>: Linear to the elements before p.
748 iterator insert(const_iterator p, BOOST_INTERPROCESS_RV_REF(value_type) x)
749 { return this->insert_after(previous(p), boost::interprocess::move(x)); }
751 //! <b>Requires</b>: p must be a valid iterator of *this.
753 //! <b>Effects</b>: Inserts n copies of x before p.
755 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
757 //! <b>Complexity</b>: Linear to n plus linear to the elements before p.
758 void insert(const_iterator p, size_type n, const value_type& x)
759 { return this->insert_after(previous(p), n, x); }
761 //! <b>Requires</b>: p must be a valid iterator of *this.
763 //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
765 //! <b>Throws</b>: If memory allocation throws, T's constructor from a
766 //! dereferenced InpIt throws.
768 //! <b>Complexity</b>: Linear to std::distance [first, last) plus
769 //! linear to the elements before p.
770 template <class InIter>
771 void insert(const_iterator p, InIter first, InIter last)
772 { return this->insert_after(previous(p), first, last); }
774 #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
776 //! <b>Effects</b>: Inserts an object of type T constructed with
777 //! std::forward<Args>(args)... in the front of the list
779 //! <b>Throws</b>: If memory allocation throws or
780 //! T's copy constructor throws.
782 //! <b>Complexity</b>: Amortized constant time.
783 template <class... Args>
784 void emplace_front(Args&&... args)
785 { this->emplace_after(this->cbefore_begin(), boost::interprocess::forward<Args>(args)...); }
787 //! <b>Effects</b>: Inserts an object of type T constructed with
788 //! std::forward<Args>(args)... before p
790 //! <b>Throws</b>: If memory allocation throws or
791 //! T's in-place constructor throws.
793 //! <b>Complexity</b>: Linear to the elements before p
794 template <class... Args>
795 iterator emplace(const_iterator p, Args&&... args)
796 { return this->emplace_after(this->previous(p), boost::interprocess::forward<Args>(args)...); }
798 //! <b>Effects</b>: Inserts an object of type T constructed with
799 //! std::forward<Args>(args)... after prev
801 //! <b>Throws</b>: If memory allocation throws or
802 //! T's in-place constructor throws.
804 //! <b>Complexity</b>: Constant
805 template <class... Args>
806 iterator emplace_after(const_iterator prev, Args&&... args)
808 typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
809 new ((void*)containers_detail::get_pointer(d.get())) Node(boost::interprocess::forward<Args>(args)...);
810 NodePtr node = d.get();
811 d.release();
812 return iterator(this->icont().insert_after(prev.get(), *node));
815 #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
817 //0 args
818 void emplace_front()
819 { this->emplace_after(this->cbefore_begin()); }
821 iterator emplace(const_iterator p)
822 { return this->emplace_after(this->previous(p)); }
824 iterator emplace_after(const_iterator prev)
826 typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
827 new ((void*)containers_detail::get_pointer(d.get())) Node();
828 NodePtr node = d.get();
829 d.release();
830 return iterator(this->icont().insert_after(prev.get(), *node));
833 #define BOOST_PP_LOCAL_MACRO(n) \
834 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
835 void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
837 this->emplace \
838 (this->cbegin(), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
841 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
842 iterator emplace \
843 (const_iterator p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
845 return this->emplace_after \
846 (this->previous(p), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
849 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
850 iterator emplace_after \
851 (const_iterator prev, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
853 typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator()); \
854 new ((void*)containers_detail::get_pointer(d.get())) \
855 Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
856 NodePtr node = d.get(); \
857 d.release(); \
858 return iterator(this->icont().insert_after(prev.get(), *node)); \
861 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
862 #include BOOST_PP_LOCAL_ITERATE()
864 #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
866 //! <b>Effects</b>: Erases the element after the element pointed by prev_pos
867 //! of the list.
869 //! <b>Returns</b>: the first element remaining beyond the removed elements,
870 //! or end() if no such element exists.
871 //!
872 //! <b>Throws</b>: Nothing.
873 //!
874 //! <b>Complexity</b>: Constant.
875 //!
876 //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
877 iterator erase_after(const_iterator prev_pos)
879 return iterator(this->icont().erase_after_and_dispose(prev_pos.get(), Destroyer(this->node_alloc())));
882 //! <b>Effects</b>: Erases the range (before_first, last) from
883 //! the list.
885 //! <b>Returns</b>: the first element remaining beyond the removed elements,
886 //! or end() if no such element exists.
887 //!
888 //! <b>Throws</b>: Nothing.
889 //!
890 //! <b>Complexity</b>: Linear to the number of erased elements.
891 //!
892 //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
893 iterator erase_after(const_iterator before_first, const_iterator last)
895 return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc())));
898 //! <b>Requires</b>: p must be a valid iterator of *this.
900 //! <b>Effects</b>: Erases the element at p p.
902 //! <b>Throws</b>: Nothing.
904 //! <b>Complexity</b>: Linear to the number of elements before p.
905 iterator erase(const_iterator p)
906 { return iterator(this->erase_after(previous(p))); }
908 //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
910 //! <b>Effects</b>: Erases the elements pointed by [first, last).
912 //! <b>Throws</b>: Nothing.
914 //! <b>Complexity</b>: Linear to the distance between first and last plus
915 //! linear to the elements before first.
916 iterator erase(const_iterator first, const_iterator last)
917 { return iterator(this->erase_after(previous(first), last)); }
919 //! <b>Effects</b>: Inserts or erases elements at the end such that
920 //! the size becomes n. New elements are copy constructed from x.
922 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
924 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
925 void resize(size_type new_size, const T& x)
927 typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
928 while (++(cur_next = cur) != end_n && new_size > 0){
929 --new_size;
930 cur = cur_next;
932 if (cur_next != end_n)
933 this->erase_after(const_iterator(cur), const_iterator(end_n));
934 else
935 this->insert_after(const_iterator(cur), new_size, x);
938 //! <b>Effects</b>: Inserts or erases elements at the end such that
939 //! the size becomes n. New elements are default constructed.
941 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
943 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
944 void resize(size_type new_size)
946 typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
947 size_type len = this->size();
948 size_type left = new_size;
950 while (++(cur_next = cur) != end_n && left > 0){
951 --left;
952 cur = cur_next;
954 if (cur_next != end_n){
955 this->erase_after(const_iterator(cur), const_iterator(end_n));
957 else{
958 this->priv_create_and_insert_nodes(const_iterator(cur), new_size - len);
962 //! <b>Effects</b>: Erases all the elements of the list.
964 //! <b>Throws</b>: Nothing.
966 //! <b>Complexity</b>: Linear to the number of elements in the list.
967 void clear()
968 { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
970 //! <b>Requires</b>: p must point to an element contained
971 //! by the list. x != *this
973 //! <b>Effects</b>: Transfers all the elements of list x to this list, after the
974 //! the element pointed by p. No destructors or copy constructors are called.
976 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
977 //! are not equal.
979 //! <b>Complexity</b>: Linear to the elements in x.
980 //!
981 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
982 //! this list. Iterators of this list and all the references are not invalidated.
983 void splice_after(const_iterator prev_pos, slist& x)
985 if((NodeAlloc&)*this == (NodeAlloc&)x){
986 this->icont().splice_after(prev_pos.get(), x.icont());
988 else{
989 throw std::runtime_error("slist::splice called with unequal allocators");
993 //! <b>Requires</b>: prev_pos must be a valid iterator of this.
994 //! i must point to an element contained in list x.
995 //!
996 //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
997 //! after the element pointed by prev_pos.
998 //! If prev_pos == prev or prev_pos == ++prev, this function is a null operation.
999 //!
1000 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
1001 //! are not equal.
1002 //!
1003 //! <b>Complexity</b>: Constant.
1004 //!
1005 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1006 //! list. Iterators of this list and all the references are not invalidated.
1007 void splice_after(const_iterator prev_pos, slist& x, const_iterator prev)
1009 if((NodeAlloc&)*this == (NodeAlloc&)x){
1010 this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
1012 else{
1013 throw std::runtime_error("slist::splice called with unequal allocators");
1017 //! <b>Requires</b>: prev_pos must be a valid iterator of this.
1018 //! before_first and before_last must be valid iterators of x.
1019 //! prev_pos must not be contained in [before_first, before_last) range.
1020 //!
1021 //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
1022 //! from list x to this list, after the element pointed by prev_pos.
1023 //!
1024 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
1025 //! are not equal.
1026 //!
1027 //! <b>Complexity</b>: Linear to the number of transferred elements.
1028 //!
1029 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1030 //! list. Iterators of this list and all the references are not invalidated.
1031 void splice_after(const_iterator prev_pos, slist& x,
1032 const_iterator before_first, const_iterator before_last)
1034 if((NodeAlloc&)*this == (NodeAlloc&)x){
1035 this->icont().splice_after
1036 (prev_pos.get(), x.icont(), before_first.get(), before_last.get());
1038 else{
1039 throw std::runtime_error("slist::splice called with unequal allocators");
1043 //! <b>Requires</b>: prev_pos must be a valid iterator of this.
1044 //! before_first and before_last must be valid iterators of x.
1045 //! prev_pos must not be contained in [before_first, before_last) range.
1046 //! n == std::distance(before_first, before_last)
1047 //!
1048 //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
1049 //! from list x to this list, after the element pointed by prev_pos.
1050 //!
1051 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
1052 //! are not equal.
1053 //!
1054 //! <b>Complexity</b>: Constant.
1055 //!
1056 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1057 //! list. Iterators of this list and all the references are not invalidated.
1058 void splice_after(const_iterator prev_pos, slist& x,
1059 const_iterator before_first, const_iterator before_last,
1060 size_type n)
1062 if((NodeAlloc&)*this == (NodeAlloc&)x){
1063 this->icont().splice_after
1064 (prev_pos.get(), x.icont(), before_first.get(), before_last.get(), n);
1066 else{
1067 throw std::runtime_error("slist::splice called with unequal allocators");
1071 //! <b>Requires</b>: p must point to an element contained
1072 //! by the list. x != *this
1074 //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
1075 //! the element pointed by p. No destructors or copy constructors are called.
1077 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
1078 //! are not equal.
1080 //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
1081 //!
1082 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
1083 //! this list. Iterators of this list and all the references are not invalidated.
1084 void splice(const_iterator p, ThisType& x)
1085 { this->splice_after(this->previous(p), x); }
1087 //! <b>Requires</b>: p must point to an element contained
1088 //! by this list. i must point to an element contained in list x.
1089 //!
1090 //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
1091 //! before the the element pointed by p. No destructors or copy constructors are called.
1092 //! If p == i or p == ++i, this function is a null operation.
1093 //!
1094 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
1095 //! are not equal.
1096 //!
1097 //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
1098 //!
1099 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1100 //! list. Iterators of this list and all the references are not invalidated.
1101 void splice(const_iterator p, slist& x, const_iterator i)
1102 { this->splice_after(previous(p), x, i); }
1104 //! <b>Requires</b>: p must point to an element contained
1105 //! by this list. first and last must point to elements contained in list x.
1106 //!
1107 //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
1108 //! before the the element pointed by p. No destructors or copy constructors are called.
1109 //!
1110 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
1111 //! are not equal.
1112 //!
1113 //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
1114 //! and in distance(first, last).
1115 //!
1116 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1117 //! list. Iterators of this list and all the references are not invalidated.
1118 void splice(const_iterator p, slist& x, const_iterator first, const_iterator last)
1119 { this->splice_after(previous(p), x, previous(first), previous(last)); }
1121 //! <b>Effects</b>: Reverses the order of elements in the list.
1122 //!
1123 //! <b>Throws</b>: Nothing.
1124 //!
1125 //! <b>Complexity</b>: This function is linear time.
1126 //!
1127 //! <b>Note</b>: Iterators and references are not invalidated
1128 void reverse()
1129 { this->icont().reverse(); }
1131 //! <b>Effects</b>: Removes all the elements that compare equal to value.
1132 //!
1133 //! <b>Throws</b>: Nothing.
1134 //!
1135 //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
1136 //!
1137 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1138 //! and iterators to elements that are not removed remain valid.
1139 void remove(const T& value)
1140 { remove_if(equal_to_value(value)); }
1142 //! <b>Effects</b>: Removes all the elements for which a specified
1143 //! predicate is satisfied.
1144 //!
1145 //! <b>Throws</b>: If pred throws.
1146 //!
1147 //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
1148 //!
1149 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1150 //! and iterators to elements that are not removed remain valid.
1151 template <class Pred>
1152 void remove_if(Pred pred)
1154 typedef ValueCompareToNodeCompare<Pred> Predicate;
1155 this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
1158 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
1159 //! elements that are equal from the list.
1160 //!
1161 //! <b>Throws</b>: Nothing.
1162 //!
1163 //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
1164 //!
1165 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1166 //! and iterators to elements that are not removed remain valid.
1167 void unique()
1168 { this->unique(value_equal()); }
1170 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
1171 //! elements that satisfy some binary predicate from the list.
1172 //!
1173 //! <b>Throws</b>: If pred throws.
1174 //!
1175 //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
1176 //!
1177 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1178 //! and iterators to elements that are not removed remain valid.
1179 template <class Pred>
1180 void unique(Pred pred)
1182 typedef ValueCompareToNodeCompare<Pred> Predicate;
1183 this->icont().unique_and_dispose(Predicate(pred), Destroyer(this->node_alloc()));
1186 //! <b>Requires</b>: The lists x and *this must be distinct.
1188 //! <b>Effects</b>: This function removes all of x's elements and inserts them
1189 //! in order into *this according to std::less<value_type>. The merge is stable;
1190 //! that is, if an element from *this is equivalent to one from x, then the element
1191 //! from *this will precede the one from x.
1192 //!
1193 //! <b>Throws</b>: Nothing.
1194 //!
1195 //! <b>Complexity</b>: This function is linear time: it performs at most
1196 //! size() + x.size() - 1 comparisons.
1197 void merge(slist & x)
1198 { this->merge(x, value_less()); }
1200 //! <b>Requires</b>: p must be a comparison function that induces a strict weak
1201 //! ordering and both *this and x must be sorted according to that ordering
1202 //! The lists x and *this must be distinct.
1203 //!
1204 //! <b>Effects</b>: This function removes all of x's elements and inserts them
1205 //! in order into *this. The merge is stable; that is, if an element from *this is
1206 //! equivalent to one from x, then the element from *this will precede the one from x.
1207 //!
1208 //! <b>Throws</b>: Nothing.
1209 //!
1210 //! <b>Complexity</b>: This function is linear time: it performs at most
1211 //! size() + x.size() - 1 comparisons.
1212 //!
1213 //! <b>Note</b>: Iterators and references to *this are not invalidated.
1214 template <class StrictWeakOrdering>
1215 void merge(slist& x, StrictWeakOrdering comp)
1217 if((NodeAlloc&)*this == (NodeAlloc&)x){
1218 this->icont().merge(x.icont(),
1219 ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
1221 else{
1222 throw std::runtime_error("list::merge called with unequal allocators");
1226 //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
1227 //! The sort is stable, that is, the relative order of equivalent elements is preserved.
1228 //!
1229 //! <b>Throws</b>: Nothing.
1231 //! <b>Notes</b>: Iterators and references are not invalidated.
1232 //!
1233 //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
1234 //! is the list's size.
1235 void sort()
1236 { this->sort(value_less()); }
1238 //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
1239 //! The sort is stable, that is, the relative order of equivalent elements is preserved.
1240 //!
1241 //! <b>Throws</b>: Nothing.
1243 //! <b>Notes</b>: Iterators and references are not invalidated.
1244 //!
1245 //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
1246 //! is the list's size.
1247 template <class StrictWeakOrdering>
1248 void sort(StrictWeakOrdering comp)
1250 // nothing if the slist has length 0 or 1.
1251 if (this->size() < 2)
1252 return;
1253 this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
1256 /// @cond
1257 private:
1259 //Iterator range version
1260 template<class InpIterator>
1261 void priv_create_and_insert_nodes
1262 (const_iterator prev, InpIterator beg, InpIterator end)
1264 typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
1265 priv_create_and_insert_nodes(prev, beg, end, alloc_version(), ItCat());
1268 template<class InpIterator>
1269 void priv_create_and_insert_nodes
1270 (const_iterator prev, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
1272 for (; beg != end; ++beg){
1273 this->icont().insert_after(prev.get(), *this->create_node_from_it(beg));
1274 ++prev;
1278 template<class InpIterator>
1279 void priv_create_and_insert_nodes
1280 (const_iterator prev, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
1281 { //Just forward to the default one
1282 priv_create_and_insert_nodes(prev, beg, end, allocator_v1(), std::input_iterator_tag());
1285 class insertion_functor;
1286 friend class insertion_functor;
1288 class insertion_functor
1290 Icont &icont_;
1291 typename Icont::const_iterator prev_;
1293 public:
1294 insertion_functor(Icont &icont, typename Icont::const_iterator prev)
1295 : icont_(icont), prev_(prev)
1298 void operator()(Node &n)
1299 { prev_ = this->icont_.insert_after(prev_, n); }
1302 template<class FwdIterator>
1303 void priv_create_and_insert_nodes
1304 (const_iterator prev, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
1306 //Optimized allocation and construction
1307 this->allocate_many_and_construct
1308 (beg, std::distance(beg, end), insertion_functor(this->icont(), prev.get()));
1311 //Default constructed version
1312 void priv_create_and_insert_nodes(const_iterator prev, size_type n)
1314 typedef default_construct_iterator<value_type, difference_type> default_iterator;
1315 this->priv_create_and_insert_nodes(prev, default_iterator(n), default_iterator());
1318 //Copy constructed version
1319 void priv_create_and_insert_nodes(const_iterator prev, size_type n, const T& x)
1321 typedef constant_iterator<value_type, difference_type> cvalue_iterator;
1322 this->priv_create_and_insert_nodes(prev, cvalue_iterator(x, n), cvalue_iterator());
1325 //Dispatch to detect iterator range or integer overloads
1326 template <class InputIter>
1327 void priv_insert_dispatch(const_iterator prev,
1328 InputIter first, InputIter last,
1329 containers_detail::false_)
1330 { this->priv_create_and_insert_nodes(prev, first, last); }
1332 template<class Integer>
1333 void priv_insert_dispatch(const_iterator prev, Integer n, Integer x, containers_detail::true_)
1334 { this->priv_create_and_insert_nodes(prev, n, x); }
1336 void priv_fill_assign(size_type n, const T& val)
1338 iterator end_n(this->end());
1339 iterator prev(this->before_begin());
1340 iterator node(this->begin());
1341 for ( ; node != end_n && n > 0 ; --n){
1342 *node = val;
1343 prev = node;
1344 ++node;
1346 if (n > 0)
1347 this->priv_create_and_insert_nodes(prev, n, val);
1348 else
1349 this->erase_after(prev, end_n);
1352 template <class Int>
1353 void priv_assign_dispatch(Int n, Int val, containers_detail::true_)
1354 { this->priv_fill_assign((size_type) n, (T)val); }
1356 template <class InpIt>
1357 void priv_assign_dispatch(InpIt first, InpIt last, containers_detail::false_)
1359 iterator end_n(this->end());
1360 iterator prev(this->before_begin());
1361 iterator node(this->begin());
1362 while (node != end_n && first != last){
1363 *node = *first;
1364 prev = node;
1365 ++node;
1366 ++first;
1368 if (first != last)
1369 this->priv_create_and_insert_nodes(prev, first, last);
1370 else
1371 this->erase_after(prev, end_n);
1374 template <class Int>
1375 void priv_insert_after_range_dispatch(const_iterator prev_pos, Int n, Int x, containers_detail::true_)
1376 { this->priv_create_and_insert_nodes(prev_pos, n, x); }
1378 template <class InIter>
1379 void priv_insert_after_range_dispatch(const_iterator prev_pos, InIter first, InIter last, containers_detail::false_)
1380 { this->priv_create_and_insert_nodes(prev_pos, first, last); }
1382 //Functors for member algorithm defaults
1383 struct value_less
1385 bool operator()(const value_type &a, const value_type &b) const
1386 { return a < b; }
1389 struct value_equal
1391 bool operator()(const value_type &a, const value_type &b) const
1392 { return a == b; }
1395 struct value_equal_to_this
1397 explicit value_equal_to_this(const value_type &ref)
1398 : m_ref(ref){}
1400 bool operator()(const value_type &val) const
1401 { return m_ref == val; }
1403 const value_type &m_ref;
1405 /// @endcond
1408 template <class T, class A>
1409 inline bool
1410 operator==(const slist<T,A>& x, const slist<T,A>& y)
1412 if(x.size() != y.size()){
1413 return false;
1415 typedef typename slist<T,A>::const_iterator const_iterator;
1416 const_iterator end1 = x.end();
1418 const_iterator i1 = x.begin();
1419 const_iterator i2 = y.begin();
1420 while (i1 != end1 && *i1 == *i2){
1421 ++i1;
1422 ++i2;
1424 return i1 == end1;
1427 template <class T, class A>
1428 inline bool
1429 operator<(const slist<T,A>& sL1, const slist<T,A>& sL2)
1431 return std::lexicographical_compare
1432 (sL1.begin(), sL1.end(), sL2.begin(), sL2.end());
1435 template <class T, class A>
1436 inline bool
1437 operator!=(const slist<T,A>& sL1, const slist<T,A>& sL2)
1438 { return !(sL1 == sL2); }
1440 template <class T, class A>
1441 inline bool
1442 operator>(const slist<T,A>& sL1, const slist<T,A>& sL2)
1443 { return sL2 < sL1; }
1445 template <class T, class A>
1446 inline bool
1447 operator<=(const slist<T,A>& sL1, const slist<T,A>& sL2)
1448 { return !(sL2 < sL1); }
1450 template <class T, class A>
1451 inline bool
1452 operator>=(const slist<T,A>& sL1, const slist<T,A>& sL2)
1453 { return !(sL1 < sL2); }
1455 template <class T, class A>
1456 inline void swap(slist<T,A>& x, slist<T,A>& y)
1457 { x.swap(y); }
1461 /// @cond
1463 namespace boost {
1464 namespace interprocess {
1466 //!has_trivial_destructor_after_move<> == true_type
1467 //!specialization for optimizations
1468 template <class T, class A>
1469 struct has_trivial_destructor_after_move<boost::interprocess_container::slist<T, A> >
1471 static const bool value = has_trivial_destructor<A>::value;
1474 } //namespace interprocess {
1476 namespace interprocess_container {
1478 /// @endcond
1480 }} //namespace boost{ namespace interprocess_container {
1482 // Specialization of insert_iterator so that insertions will be constant
1483 // time rather than linear time.
1485 ///@cond
1487 //Ummm, I don't like to define things in namespace std, but
1488 //there is no other way
1489 namespace std {
1491 template <class T, class A>
1492 class insert_iterator<boost::interprocess_container::slist<T, A> >
1494 protected:
1495 typedef boost::interprocess_container::slist<T, A> Container;
1496 Container* container;
1497 typename Container::iterator iter;
1498 public:
1499 typedef Container container_type;
1500 typedef output_iterator_tag iterator_category;
1501 typedef void value_type;
1502 typedef void difference_type;
1503 typedef void pointer;
1504 typedef void reference;
1506 insert_iterator(Container& x,
1507 typename Container::iterator i,
1508 bool is_previous = false)
1509 : container(&x), iter(is_previous ? i : x.previous(i)){ }
1511 insert_iterator<Container>&
1512 operator=(const typename Container::value_type& value)
1514 iter = container->insert_after(iter, value);
1515 return *this;
1517 insert_iterator<Container>& operator*(){ return *this; }
1518 insert_iterator<Container>& operator++(){ return *this; }
1519 insert_iterator<Container>& operator++(int){ return *this; }
1522 } //namespace std;
1524 ///@endcond
1526 #include <boost/interprocess/containers/container/detail/config_end.hpp>
1528 #endif /* BOOST_CONTAINERS_SLIST_HPP */