1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/container for documentation.
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 ///////////////////////////////////////////////////////////////////////////////
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.
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)
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>
75 #ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
77 namespace interprocess
{
80 namespace interprocess_container
{
85 namespace containers_detail
{
87 template<class VoidPointer
>
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
>
96 : public slist_hook
<VoidPointer
>::type
98 #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
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, _)) \
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
119 template<class ...Args
>
120 slist_node(Args
&&...args
)
121 : m_data(boost::interprocess::forward
<Args
>(args
)...)
123 #endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
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
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 {
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
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.
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
>
184 : protected containers_detail::node_alloc_holder
185 <A
, typename
containers_detail::intrusive_slist_type
<A
>::type
>
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
;
203 typedef typename
AllocHolder::value_type value_type
;
204 const value_type
&t_
;
207 equal_to_value(const value_type
&t
)
211 bool operator()(const value_type
&t
)const
216 struct ValueCompareToNodeCompare
219 ValueCompareToNodeCompare(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
); }
231 //! The type of object, T, stored in the list
232 typedef T value_type
;
234 typedef typename
A::pointer pointer
;
235 //! Const pointer to T
236 typedef typename
A::const_pointer const_pointer
;
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
;
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
;
260 BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(slist
)
262 //! Const iterator used to iterate through a list.
265 : public std::iterator
<std::forward_iterator_tag
,
266 value_type
, list_difference_type
,
267 list_const_pointer
, list_const_reference
>
271 typename
Icont::iterator m_it
;
272 explicit const_iterator(typename
Icont::iterator it
) : m_it(it
){}
273 void prot_incr(){ ++m_it
; }
276 typename
Icont::iterator
get()
277 { return this->m_it
; }
280 friend class slist
<T
, A
>;
281 typedef list_difference_type difference_type
;
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
; }
312 //! Iterator used to iterate through a list
315 : public const_iterator
319 explicit iterator(typename
Icont::iterator it
)
323 typename
Icont::iterator
get()
324 { return this->m_it
; }
327 friend class slist
<T
, A
>;
328 typedef list_pointer pointer
;
329 typedef list_reference reference
;
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
); }
349 //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
351 //! <b>Throws</b>: If allocator_type's copy constructor throws.
353 //! <b>Complexity</b>: Constant.
354 explicit slist(const allocator_type
& a
= allocator_type())
358 explicit slist(size_type n
)
359 : AllocHolder(allocator_type())
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.
368 //! <b>Complexity</b>: Linear to n.
369 explicit slist(size_type n
, const value_type
& x
, const allocator_type
& a
= allocator_type())
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())
384 { this->insert_after(this->before_begin(), first
, last
); }
386 //! <b>Effects</b>: Copy constructs a list.
388 //! <b>Postcondition</b>: x == *this.
390 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
392 //! <b>Complexity</b>: Linear to the elements x contains.
393 slist(const slist
& 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.
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
)
417 this->assign(x
.begin(), x
.end());
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
)
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.
446 {} //AllocHolder clears the slist
448 //! <b>Effects</b>: Returns a copy of the internal allocator.
450 //! <b>Throws</b>: If allocator's copy constructor throws.
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(); }
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.
488 //! <b>Throws</b>: Nothing.
490 //! <b>Complexity</b>: Constant.
492 { return iterator(this->icont().begin()); }
494 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
496 //! <b>Throws</b>: Nothing.
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.
504 //! <b>Throws</b>: Nothing.
506 //! <b>Complexity</b>: Constant.
508 { return iterator(this->icont().end()); }
510 //! <b>Effects</b>: Returns a const_iterator to the end of the list.
512 //! <b>Throws</b>: Nothing.
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.
522 //! <b>Throws</b>: Nothing.
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.
532 //! <b>Throws</b>: Nothing.
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.
540 //! <b>Throws</b>: Nothing.
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.
548 //! <b>Throws</b>: Nothing.
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.
558 //! <b>Throws</b>: Nothing.
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.
566 //! <b>Throws</b>: Nothing.
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.
574 //! <b>Throws</b>: Nothing.
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.
582 //! <b>Throws</b>: Nothing.
584 //! <b>Complexity</b>: Constant.
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.
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.
603 //! <b>Throws</b>: Nothing.
605 //! <b>Complexity</b>: Constant.
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.
614 //! <b>Throws</b>: Nothing.
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.
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.
650 //! <b>Throws</b>: Nothing.
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.
660 //! <b>Throws</b>: Nothing.
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
671 //! <b>Returns</b>: An iterator to the inserted element.
673 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
675 //! <b>Complexity</b>: Amortized constant time.
677 //! <b>Note</b>: Does not affect the validity of iterators and references of
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.
689 //! <b>Throws</b>: If memory allocation throws.
691 //! <b>Complexity</b>: Amortized constant time.
693 //! <b>Note</b>: Does not affect the validity of iterators and references of
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
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.
713 //! <b>Effects</b>: Inserts the range pointed by [first, last)
714 //! after the p prev_pos.
716 //! <b>Throws</b>: If memory allocation throws, T's constructor from a
717 //! dereferenced InpIt throws.
719 //! <b>Complexity</b>: Linear to the number of elements inserted.
721 //! <b>Note</b>: Does not affect the validity of iterators and references of
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();
812 return iterator(this->icont().insert_after(prev
.get(), *node
));
815 #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
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();
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, _)) \
838 (this->cbegin(), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
841 template<BOOST_PP_ENUM_PARAMS(n, class P)> \
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(); \
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
869 //! <b>Returns</b>: the first element remaining beyond the removed elements,
870 //! or end() if no such element exists.
872 //! <b>Throws</b>: Nothing.
874 //! <b>Complexity</b>: Constant.
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
885 //! <b>Returns</b>: the first element remaining beyond the removed elements,
886 //! or end() if no such element exists.
888 //! <b>Throws</b>: Nothing.
890 //! <b>Complexity</b>: Linear to the number of erased elements.
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){
932 if (cur_next
!= end_n
)
933 this->erase_after(const_iterator(cur
), const_iterator(end_n
));
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){
954 if (cur_next
!= end_n
){
955 this->erase_after(const_iterator(cur
), const_iterator(end_n
));
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.
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
979 //! <b>Complexity</b>: Linear to the elements in x.
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());
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.
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.
1000 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
1003 //! <b>Complexity</b>: Constant.
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());
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.
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.
1024 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
1027 //! <b>Complexity</b>: Linear to the number of transferred elements.
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());
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)
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.
1051 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
1054 //! <b>Complexity</b>: Constant.
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
,
1062 if((NodeAlloc
&)*this == (NodeAlloc
&)x
){
1063 this->icont().splice_after
1064 (prev_pos
.get(), x
.icont(), before_first
.get(), before_last
.get(), n
);
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
1080 //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
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.
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.
1094 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
1097 //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
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.
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.
1110 //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
1113 //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
1114 //! and in distance(first, last).
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.
1123 //! <b>Throws</b>: Nothing.
1125 //! <b>Complexity</b>: This function is linear time.
1127 //! <b>Note</b>: Iterators and references are not invalidated
1129 { this->icont().reverse(); }
1131 //! <b>Effects</b>: Removes all the elements that compare equal to value.
1133 //! <b>Throws</b>: Nothing.
1135 //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
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.
1145 //! <b>Throws</b>: If pred throws.
1147 //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
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.
1161 //! <b>Throws</b>: Nothing.
1163 //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
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.
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.
1173 //! <b>Throws</b>: If pred throws.
1175 //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
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.
1193 //! <b>Throws</b>: Nothing.
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.
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.
1208 //! <b>Throws</b>: Nothing.
1210 //! <b>Complexity</b>: This function is linear time: it performs at most
1211 //! size() + x.size() - 1 comparisons.
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
));
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.
1229 //! <b>Throws</b>: Nothing.
1231 //! <b>Notes</b>: Iterators and references are not invalidated.
1233 //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
1234 //! is the list's size.
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.
1241 //! <b>Throws</b>: Nothing.
1243 //! <b>Notes</b>: Iterators and references are not invalidated.
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)
1253 this->icont().sort(ValueCompareToNodeCompare
<StrictWeakOrdering
>(comp
));
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
));
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
1291 typename
Icont::const_iterator prev_
;
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
){
1347 this->priv_create_and_insert_nodes(prev
, n
, val
);
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
){
1369 this->priv_create_and_insert_nodes(prev
, first
, last
);
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
1385 bool operator()(const value_type
&a
, const value_type
&b
) const
1391 bool operator()(const value_type
&a
, const value_type
&b
) const
1395 struct value_equal_to_this
1397 explicit value_equal_to_this(const value_type
&ref
)
1400 bool operator()(const value_type
&val
) const
1401 { return m_ref
== val
; }
1403 const value_type
&m_ref
;
1408 template <class T
, class A
>
1410 operator==(const slist
<T
,A
>& x
, const slist
<T
,A
>& y
)
1412 if(x
.size() != y
.size()){
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
){
1427 template <class T
, class A
>
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
>
1437 operator!=(const slist
<T
,A
>& sL1
, const slist
<T
,A
>& sL2
)
1438 { return !(sL1
== sL2
); }
1440 template <class T
, class A
>
1442 operator>(const slist
<T
,A
>& sL1
, const slist
<T
,A
>& sL2
)
1443 { return sL2
< sL1
; }
1445 template <class T
, class A
>
1447 operator<=(const slist
<T
,A
>& sL1
, const slist
<T
,A
>& sL2
)
1448 { return !(sL2
< sL1
); }
1450 template <class T
, class A
>
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
)
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
{
1480 }} //namespace boost{ namespace interprocess_container {
1482 // Specialization of insert_iterator so that insertions will be constant
1483 // time rather than linear time.
1487 //Ummm, I don't like to define things in namespace std, but
1488 //there is no other way
1491 template <class T
, class A
>
1492 class insert_iterator
<boost::interprocess_container::slist
<T
, A
> >
1495 typedef boost::interprocess_container::slist
<T
, A
> Container
;
1496 Container
* container
;
1497 typename
Container::iterator iter
;
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
);
1517 insert_iterator
<Container
>& operator*(){ return *this; }
1518 insert_iterator
<Container
>& operator++(){ return *this; }
1519 insert_iterator
<Container
>& operator++(int){ return *this; }
1526 #include <boost/interprocess/containers/container/detail/config_end.hpp>
1528 #endif /* BOOST_CONTAINERS_SLIST_HPP */