/usr/include/boost/container
Edit: /usr/include/boost/container/list.hpp (58593B)
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2015. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_LIST_HPP
#define BOOST_CONTAINER_LIST_HPP
#ifndef BOOST_CONFIG_HPP
# include
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include
#include
// container
#include
#include //new_allocator
#include
// container/detail
#include
#include
#include
#include
#include
#include
#include
#include
// move
#include
#include
#include
// move/detail
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
# include
#endif
#include
// intrusive
#include
#include
// other
#include
// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include
#endif
namespace boost {
namespace container {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace dtl {
template
struct list_hook
{
typedef typename dtl::bi::make_list_base_hook
, dtl::bi::link_mode >::type type;
};
template
struct list_node
: public list_hook::type
{
public:
typedef T value_type;
typedef T internal_type;
typedef typename list_hook::type hook_type;
typedef typename dtl::aligned_storage::value>::type storage_t;
storage_t m_storage;
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600) && (BOOST_GCC < 80000)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#define BOOST_CONTAINER_DISABLE_ALIASING_WARNING
# endif
BOOST_CONTAINER_FORCEINLINE T &get_data()
{ return *reinterpret_cast(this->m_storage.data); }
BOOST_CONTAINER_FORCEINLINE const T &get_data() const
{ return *reinterpret_cast(this->m_storage.data); }
BOOST_CONTAINER_FORCEINLINE T *get_data_ptr()
{ return reinterpret_cast(this->m_storage.data); }
BOOST_CONTAINER_FORCEINLINE const T *get_data_ptr() const
{ return reinterpret_cast(this->m_storage.data); }
BOOST_CONTAINER_FORCEINLINE internal_type &get_real_data()
{ return *reinterpret_cast(this->m_storage.data); }
BOOST_CONTAINER_FORCEINLINE const internal_type &get_real_data() const
{ return *reinterpret_cast(this->m_storage.data); }
BOOST_CONTAINER_FORCEINLINE internal_type *get_real_data_ptr()
{ return reinterpret_cast(this->m_storage.data); }
BOOST_CONTAINER_FORCEINLINE const internal_type *get_real_data_ptr() const
{ return reinterpret_cast(this->m_storage.data); }
BOOST_CONTAINER_FORCEINLINE ~list_node()
{ reinterpret_cast(this->m_storage.data)->~T(); }
#if defined(BOOST_CONTAINER_DISABLE_ALIASING_WARNING)
#pragma GCC diagnostic pop
#undef BOOST_CONTAINER_DISABLE_ALIASING_WARNING
# endif
BOOST_CONTAINER_FORCEINLINE void destroy_header()
{ static_cast(this)->~hook_type(); }
};
template
struct iiterator_node_value_type< list_node > {
typedef T type;
};
template
struct intrusive_list_type
{
typedef boost::container::allocator_traits allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename boost::intrusive::pointer_traits
::template
rebind_pointer::type
void_pointer;
typedef typename dtl::list_node
node_type;
typedef typename dtl::bi::make_list
< node_type
, dtl::bi::base_hook::type>
, dtl::bi::constant_time_size
, dtl::bi::size_type
>::type container_type;
typedef container_type type ;
};
} //namespace dtl {
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! A list is a doubly linked list. That is, it is a Sequence that supports both
//! forward and backward traversal, and (amortized) constant time insertion and
//! removal of elements at the beginning or the end, or in the middle. Lists have
//! the important property that insertion and splicing do not invalidate iterators
//! to list elements, and that even removal invalidates only the iterators that point
//! to the elements that are removed. The ordering of iterators may be changed
//! (that is, list::iterator might have a different predecessor or successor
//! after a list operation than it did before), but the iterators themselves will
//! not be invalidated or made to point to different elements unless that invalidation
//! or mutation is explicit.
//!
//! \tparam T The type of object that is stored in the list
//! \tparam Allocator The allocator used for all internal memory management, use void
//! for the default allocator
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template
#else
template
#endif
class list
: protected dtl::node_alloc_holder
< typename real_allocator::type
, typename dtl::intrusive_list_type::type>::type>
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef typename real_allocator::type ValueAllocator;
typedef typename
dtl::intrusive_list_type::type Icont;
typedef dtl::node_alloc_holder AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
typedef typename AllocHolder::NodeAlloc NodeAlloc;
typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node;
typedef dtl::allocator_destroyer Destroyer;
typedef typename AllocHolder::alloc_version alloc_version;
typedef boost::container::allocator_traits allocator_traits_type;
typedef boost::container::equal_to_value
equal_to_value_type;
BOOST_COPYABLE_AND_MOVABLE(list)
typedef dtl::iterator_from_iiterator iterator_impl;
typedef dtl::iterator_from_iiterator const_iterator_impl;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
//
// types
//
//////////////////////////////////////////////
typedef T value_type;
typedef typename ::boost::container::allocator_traits::pointer pointer;
typedef typename ::boost::container::allocator_traits::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits::reference reference;
typedef typename ::boost::container::allocator_traits::const_reference const_reference;
typedef typename ::boost::container::allocator_traits::size_type size_type;
typedef typename ::boost::container::allocator_traits::difference_type difference_type;
typedef ValueAllocator allocator_type;
typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator;
//////////////////////////////////////////////
//
// construct/copy/destroy
//
//////////////////////////////////////////////
//! Effects: Default constructs a list.
//!
//! Throws: If allocator_type's default constructor throws.
//!
//! Complexity: Constant.
list() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value)
: AllocHolder()
{}
//! Effects: Constructs a list taking the allocator as parameter.
//!
//! Throws: Nothing
//!
//! Complexity: Constant.
explicit list(const allocator_type &a) BOOST_NOEXCEPT_OR_NOTHROW
: AllocHolder(a)
{}
//! Effects: Constructs a list
//! and inserts n value-initialized value_types.
//!
//! Throws: If allocator_type's default constructor
//! throws or T's default or copy constructor throws.
//!
//! Complexity: Linear to n.
explicit list(size_type n)
: AllocHolder(ValueAllocator())
{ this->resize(n); }
//! Effects: Constructs a list that will use a copy of allocator a
//! and inserts n copies of value.
//!
//! Throws: If allocator_type's default constructor
//! throws or T's default or copy constructor throws.
//!
//! Complexity: Linear to n.
list(size_type n, const allocator_type &a)
: AllocHolder(a)
{ this->resize(n); }
//! Effects: Constructs a list that will use a copy of allocator a
//! and inserts n copies of value.
//!
//! Throws: If allocator_type's default constructor
//! throws or T's default or copy constructor throws.
//!
//! Complexity: Linear to n.
list(size_type n, const T& value, const ValueAllocator& a = ValueAllocator())
: AllocHolder(a)
{ this->insert(this->cbegin(), n, value); }
//! Effects: Copy constructs a list.
//!
//! Postcondition: x == *this.
//!
//! Throws: If allocator_type's default constructor throws.
//!
//! Complexity: Linear to the elements x contains.
list(const list& x)
: AllocHolder(x)
{ this->insert(this->cbegin(), x.begin(), x.end()); }
//! Effects: Move constructor. Moves x's resources to *this.
//!
//! Throws: If allocator_type's copy constructor throws.
//!
//! Complexity: Constant.
list(BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW
: AllocHolder(BOOST_MOVE_BASE(AllocHolder, x))
{}
//! Effects: Copy constructs a list using the specified allocator.
//!
//! Postcondition: x == *this.
//!
//! Throws: If allocator_type's default constructor or copy constructor throws.
//!
//! Complexity: Linear to the elements x contains.
list(const list& x, const allocator_type &a)
: AllocHolder(a)
{ this->insert(this->cbegin(), x.begin(), x.end()); }
//! Effects: Move constructor sing the specified allocator.
//! Moves x's resources to *this.
//!
//! Throws: If allocation or value_type's copy constructor throws.
//!
//! Complexity: Constant if a == x.get_allocator(), linear otherwise.
list(BOOST_RV_REF(list) x, const allocator_type &a)
: AllocHolder(a)
{
if(this->node_alloc() == x.node_alloc()){
this->icont().swap(x.icont());
}
else{
this->insert(this->cbegin(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
}
}
//! Effects: Constructs a list that will use a copy of allocator a
//! and inserts a copy of the range [first, last) in the list.
//!
//! Throws: If allocator_type's default constructor
//! throws or T's constructor taking a dereferenced InIt throws.
//!
//! Complexity: Linear to the range [first, last).
template
list(InpIt first, InpIt last, const ValueAllocator &a = ValueAllocator())
: AllocHolder(a)
{ this->insert(this->cbegin(), first, last); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! Effects: Constructs a list that will use a copy of allocator a
//! and inserts a copy of the range [il.begin(), il.end()) in the list.
//!
//! Throws: If allocator_type's default constructor
//! throws or T's constructor taking a dereferenced
//! std::initializer_list iterator throws.
//!
//! Complexity: Linear to the range [il.begin(), il.end()).
list(std::initializer_list il, const ValueAllocator &a = ValueAllocator())
: AllocHolder(a)
{ this->insert(this->cbegin(), il.begin(), il.end()); }
#endif
//! Effects: Destroys the list. All stored values are destroyed
//! and used memory is deallocated.
//!
//! Throws: Nothing.
//!
//! Complexity: Linear to the number of elements.
BOOST_CONTAINER_FORCEINLINE ~list() BOOST_NOEXCEPT_OR_NOTHROW
{} //AllocHolder clears the list
//! Effects: Makes *this contain the same elements as x.
//!
//! Postcondition: this->size() == x.size(). *this contains a copy
//! of each of x's elements.
//!
//! Throws: If memory allocation throws or T's copy constructor throws.
//!
//! Complexity: Linear to the number of elements in x.
list& operator=(BOOST_COPY_ASSIGN_REF(list) x)
{
if (BOOST_LIKELY(this != &x)) {
NodeAlloc &this_alloc = this->node_alloc();
const NodeAlloc &x_alloc = x.node_alloc();
dtl::bool_ flag;
if(flag && this_alloc != x_alloc){
this->clear();
}
this->AllocHolder::copy_assign_alloc(x);
this->assign(x.begin(), x.end());
}
return *this;
}
//! Effects: Move assignment. All x's values are transferred to *this.
//!
//! Postcondition: x.empty(). *this contains a the elements x had
//! before the function.
//!
//! Throws: If allocator_traits_type::propagate_on_container_move_assignment
//! is false and (allocation throws or value_type's move constructor throws)
//!
//! Complexity: Constant if allocator_traits_type::
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
list& operator=(BOOST_RV_REF(list) x)
BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
|| allocator_traits_type::is_always_equal::value)
{
if (BOOST_LIKELY(this != &x)) {
NodeAlloc &this_alloc = this->node_alloc();
NodeAlloc &x_alloc = x.node_alloc();
const bool propagate_alloc = allocator_traits_type::
propagate_on_container_move_assignment::value;
const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
//Resources can be transferred if both allocators are
//going to be equal after this function (either propagated or already equal)
if(propagate_alloc || allocators_equal){
//Destroy
this->clear();
//Move allocator if needed
this->AllocHolder::move_assign_alloc(x);
//Obtain resources
this->icont() = boost::move(x.icont());
}
//Else do a one by one move
else{
this->assign( boost::make_move_iterator(x.begin())
, boost::make_move_iterator(x.end()));
}
}
return *this;
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! Effects: Makes *this contain the same elements as il.
//!
//! Postcondition: this->size() == il.size(). *this contains a copy
//! of each of x's elements.
//!
//! Throws: If memory allocation throws or T's copy constructor throws.
//!
//! Complexity: Linear to the number of elements in x.
BOOST_CONTAINER_FORCEINLINE list& operator=(std::initializer_list il)
{
this->assign(il.begin(), il.end());
return *this;
}
#endif
//! Effects: Assigns the n copies of val to *this.
//!
//! Throws: If memory allocation throws or T's copy constructor throws.
//!
//! Complexity: Linear to n.
BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& val)
{
typedef constant_iterator cvalue_iterator;
return this->assign(cvalue_iterator(val, n), cvalue_iterator());
}
//! Effects: Assigns the range [first, last) to *this.
//!
//! Throws: If memory allocation throws or
//! T's constructor from dereferencing InpIt throws.
//!
//! Complexity: Linear to n.
template
void assign(InpIt first, InpIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename dtl::disable_if_convertible::type * = 0
#endif
)
{
iterator first1 = this->begin();
const iterator last1 = this->end();
for ( ; first1 != last1 && first != last; ++first1, ++first)
*first1 = *first;
if (first == last)
this->erase(first1, last1);
else{
this->insert(last1, first, last);
}
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! Effects: Assigns the range [il.begin(), il.end()) to *this.
//!
//! Throws: If memory allocation throws or
//! T's constructor from dereferencing std::initializer_list iterator throws.
//!
//! Complexity: Linear to n.
BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list il)
{ this->assign(il.begin(), il.end()); }
#endif
//! Effects: Returns a copy of the internal allocator.
//!
//! Throws: If allocator's copy constructor throws.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return allocator_type(this->node_alloc()); }
//! Effects: Returns a reference to the internal allocator.
//!
//! Throws: Nothing
//!
//! Complexity: Constant.
//!
//! Note: Non-standard extension.
BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return this->node_alloc(); }
//! Effects: Returns a reference to the internal allocator.
//!
//! Throws: Nothing
//!
//! Complexity: Constant.
//!
//! Note: Non-standard extension.
BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->node_alloc(); }
//////////////////////////////////////////////
//
// iterators
//
//////////////////////////////////////////////
//! Effects: Returns an iterator to the first element contained in the list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->icont().begin()); }
//! Effects: Returns a const_iterator to the first element contained in the list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->cbegin(); }
//! Effects: Returns an iterator to the end of the list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->icont().end()); }
//! Effects: Returns a const_iterator to the end of the list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->cend(); }
//! Effects: Returns a reverse_iterator pointing to the beginning
//! of the reversed list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(end()); }
//! Effects: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->crbegin(); }
//! Effects: Returns a reverse_iterator pointing to the end
//! of the reversed list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(begin()); }
//! Effects: Returns a const_reverse_iterator pointing to the end
//! of the reversed list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->crend(); }
//! Effects: Returns a const_iterator to the first element contained in the list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_iterator(this->non_const_icont().begin()); }
//! Effects: Returns a const_iterator to the end of the list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_iterator(this->non_const_icont().end()); }
//! Effects: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->cend()); }
//! Effects: Returns a const_reverse_iterator pointing to the end
//! of the reversed list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->cbegin()); }
//////////////////////////////////////////////
//
// capacity
//
//////////////////////////////////////////////
//! Effects: Returns true if the list contains no elements.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
{ return !this->size(); }
//! Effects: Returns the number of the elements contained in the list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->icont().size(); }
//! Effects: Returns the largest possible size of the list.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return AllocHolder::max_size(); }
//! Effects: Inserts or erases elements at the end such that
//! the size becomes n. New elements are value initialized.
//!
//! Throws: If memory allocation throws, or T's copy constructor throws.
//!
//! Complexity: Linear to the difference between size() and new_size.
void resize(size_type new_size)
{
if(!priv_try_shrink(new_size)){
typedef value_init_construct_iterator value_init_iterator;
this->insert(this->cend(), value_init_iterator(new_size - this->size()), value_init_iterator());
}
}
//! Effects: Inserts or erases elements at the end such that
//! the size becomes n. New elements are copy constructed from x.
//!
//! Throws: If memory allocation throws, or T's copy constructor throws.
//!
//! Complexity: Linear to the difference between size() and new_size.
void resize(size_type new_size, const T& x)
{
if(!priv_try_shrink(new_size)){
this->insert(this->cend(), new_size - this->size(), x);
}
}
//////////////////////////////////////////////
//
// element access
//
//////////////////////////////////////////////
//! Requires: !empty()
//!
//! Effects: Returns a reference to the first element
//! from the beginning of the container.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
reference front() BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(!this->empty());
return *this->begin();
}
//! Requires: !empty()
//!
//! Effects: Returns a const reference to the first element
//! from the beginning of the container.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(!this->empty());
return *this->begin();
}
//! Requires: !empty()
//!
//! Effects: Returns a reference to the first element
//! from the beginning of the container.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
reference back() BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(!this->empty());
return *(--this->end());
}
//! Requires: !empty()
//!
//! Effects: Returns a const reference to the first element
//! from the beginning of the container.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(!this->empty());
return *(--this->end());
}
//////////////////////////////////////////////
//
// modifiers
//
//////////////////////////////////////////////
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! Effects: Inserts an object of type T constructed with
//! std::forward(args)... in the end of the list.
//!
//! Returns: A reference to the created object.
//!
//! Throws: If memory allocation throws or
//! T's in-place constructor throws.
//!
//! Complexity: Constant
template
reference emplace_back(BOOST_FWD_REF(Args)... args)
{ return *this->emplace(this->cend(), boost::forward(args)...); }
//! Effects: Inserts an object of type T constructed with
//! std::forward(args)... in the beginning of the list.
//!
//! Returns: A reference to the created object.
//!
//! Throws: If memory allocation throws or
//! T's in-place constructor throws.
//!
//! Complexity: Constant
template
reference emplace_front(BOOST_FWD_REF(Args)... args)
{ return *this->emplace(this->cbegin(), boost::forward(args)...); }
//! Effects: Inserts an object of type T constructed with
//! std::forward(args)... before p.
//!
//! Throws: If memory allocation throws or
//! T's in-place constructor throws.
//!
//! Complexity: Constant
template
iterator emplace(const_iterator position, BOOST_FWD_REF(Args)... args)
{
BOOST_ASSERT((priv_is_linked)(position));
NodePtr pnode(AllocHolder::create_node(boost::forward(args)...));
return iterator(this->icont().insert(position.get(), *pnode));
}
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_CONTAINER_LIST_EMPLACE_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
reference emplace_back(BOOST_MOVE_UREF##N)\
{ return *this->emplace(this->cend() BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
reference emplace_front(BOOST_MOVE_UREF##N)\
{ return *this->emplace(this->cbegin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(const_iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
BOOST_ASSERT(position == this->cend() || (--(++position) == position) );\
NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\
return iterator(this->icont().insert(position.get(), *pnode));\
}\
//
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_LIST_EMPLACE_CODE)
#undef BOOST_CONTAINER_LIST_EMPLACE_CODE
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! Effects: Inserts a copy of x at the beginning of the list.
//!
//! Throws: If memory allocation throws or
//! T's copy constructor throws.
//!
//! Complexity: Amortized constant time.
void push_front(const T &x);
//! Effects: Constructs a new element in the beginning of the list
//! and moves the resources of x to this new element.
//!
//! Throws: If memory allocation throws.
//!
//! Complexity: Amortized constant time.
void push_front(T &&x);
#else
BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
#endif
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! Effects: Inserts a copy of x at the end of the list.
//!
//! Throws: If memory allocation throws or
//! T's copy constructor throws.
//!
//! Complexity: Amortized constant time.
void push_back(const T &x);
//! Effects: Constructs a new element in the end of the list
//! and moves the resources of x to this new element.
//!
//! Throws: If memory allocation throws.
//!
//! Complexity: Amortized constant time.
void push_back(T &&x);
#else
BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
#endif
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! Requires: p must be a valid iterator of *this.
//!
//! Effects: Insert a copy of x before p.
//!
//! Returns: an iterator to the inserted element.
//!
//! Throws: If memory allocation throws or x's copy constructor throws.
//!
//! Complexity: Amortized constant time.
iterator insert(const_iterator p, const T &x);
//! Requires: p must be a valid iterator of *this.
//!
//! Effects: Insert a new element before p with x's resources.
//!
//! Returns: an iterator to the inserted element.
//!
//! Throws: If memory allocation throws.
//!
//! Complexity: Amortized constant time.
iterator insert(const_iterator p, T &&x);
#else
BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
#endif
//! Requires: p must be a valid iterator of *this.
//!
//! Effects: Inserts n copies of x before p.
//!
//! Returns: an iterator to the first inserted element or p if n is 0.
//!
//! Throws: If memory allocation throws or T's copy constructor throws.
//!
//! Complexity: Linear to n.
iterator insert(const_iterator position, size_type n, const T& x)
{
//range check is done by insert
typedef constant_iterator cvalue_iterator;
return this->insert(position, cvalue_iterator(x, n), cvalue_iterator());
}
//! Requires: p must be a valid iterator of *this.
//!
//! Effects: Insert a copy of the [first, last) range before p.
//!
//! Returns: an iterator to the first inserted element or p if first == last.
//!
//! Throws: If memory allocation throws, T's constructor from a
//! dereferenced InpIt throws.
//!
//! Complexity: Linear to distance [first, last).
template
iterator insert(const_iterator p, InpIt first, InpIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename dtl::enable_if_c
< !dtl::is_convertible::value
&& (dtl::is_input_iterator::value
|| dtl::is_same::value
)
>::type * = 0
#endif
)
{
BOOST_ASSERT((priv_is_linked)(p));
const typename Icont::iterator ipos(p.get());
iterator ret_it(ipos);
if(first != last){
ret_it = iterator(this->icont().insert(ipos, *this->create_node_from_it(first)));
++first;
}
for (; first != last; ++first){
this->icont().insert(ipos, *this->create_node_from_it(first));
}
return ret_it;
}
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template
iterator insert(const_iterator position, FwdIt first, FwdIt last
, typename dtl::enable_if_c
< !dtl::is_convertible::value
&& !(dtl::is_input_iterator::value
|| dtl::is_same::value
)
>::type * = 0
)
{
BOOST_ASSERT((priv_is_linked)(position));
//Optimized allocation and construction
insertion_functor func(this->icont(), position.get());
iterator before_p(position.get());
--before_p;
this->allocate_many_and_construct(first, boost::container::iterator_distance(first, last), func);
return ++before_p;
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! Requires: p must be a valid iterator of *this.
//!
//! Effects: Insert a copy of the [il.begin(), il.end()) range before p.
//!
//! Returns: an iterator to the first inserted element or p if if.begin() == il.end().
//!
//! Throws: If memory allocation throws, T's constructor from a
//! dereferenced std::initializer_list iterator throws.
//!
//! Complexity: Linear to distance [il.begin(), il.end()).
iterator insert(const_iterator p, std::initializer_list il)
{
//position range check is done by insert()
return insert(p, il.begin(), il.end());
}
#endif
//! Effects: Removes the first element from the list.
//!
//! Throws: Nothing.
//!
//! Complexity: Amortized constant time.
void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(!this->empty());
this->erase(this->cbegin());
}
//! Effects: Removes the last element from the list.
//!
//! Throws: Nothing.
//!
//! Complexity: Amortized constant time.
void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(!this->empty());
const_iterator tmp = this->cend();
this->erase(--tmp);
}
//! Requires: p must be a valid iterator of *this.
//!
//! Effects: Erases the element at p.
//!
//! Throws: Nothing.
//!
//! Complexity: Amortized constant time.
iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(p != this->cend() && (priv_is_linked)(p));
return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc())));
}
//! Requires: first and last must be valid iterator to elements in *this.
//!
//! Effects: Erases the elements pointed by [first, last).
//!
//! Throws: Nothing.
//!
//! Complexity: Linear to the distance between first and last.
iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(first == last || (first != this->cend() && (priv_is_linked)(first)));
BOOST_ASSERT(first == last || (priv_is_linked)(last));
return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version()));
}
//! Effects: Swaps the contents of *this and x.
//!
//! Throws: Nothing.
//!
//! Complexity: Constant.
void swap(list& x)
BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
|| allocator_traits_type::is_always_equal::value)
{
BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
allocator_traits_type::is_always_equal::value ||
this->get_stored_allocator() == x.get_stored_allocator());
AllocHolder::swap(x);
}
//! Effects: Erases all the elements of the list.
//!
//! Throws: Nothing.
//!
//! Complexity: Linear to the number of elements in the list.
void clear() BOOST_NOEXCEPT_OR_NOTHROW
{ AllocHolder::clear(alloc_version()); }
//////////////////////////////////////////////
//
// slist operations
//
//////////////////////////////////////////////
//! Requires: p must point to an element contained
//! by the list. x != *this. this' allocator and x's allocator shall compare equal
//!
//! Effects: Transfers all the elements of list x to this list, before the
//! the element pointed by p. No destructors or copy constructors are called.
//!
//! Throws: Nothing
//!
//! Complexity: Constant.
//!
//! Note: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, list& x) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT((priv_is_linked)(p));
BOOST_ASSERT(this != &x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont());
}
//! Requires: p must point to an element contained
//! by the list. x != *this. this' allocator and x's allocator shall compare equal
//!
//! Effects: Transfers all the elements of list x to this list, before the
//! the element pointed by p. No destructors or copy constructors are called.
//!
//! Throws: Nothing
//!
//! Complexity: Constant.
//!
//! Note: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW
{
//Checks done in splice
this->splice(p, static_cast(x));
}
//! Requires: p must point to an element contained
//! by this list. i must point to an element contained in list x.
//! this' allocator and x's allocator shall compare equal
//!
//! Effects: Transfers the value pointed by i, from list x to this list,
//! before the element pointed by p. No destructors or copy constructors are called.
//! If p == i or p == ++i, this function is a null operation.
//!
//! Throws: Nothing
//!
//! Complexity: Constant.
//!
//! Note: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, list &x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT((priv_is_linked)(p));
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), i.get());
}
//! Requires: p must point to an element contained
//! by this list. i must point to an element contained in list x.
//! this' allocator and x's allocator shall compare equal.
//!
//! Effects: Transfers the value pointed by i, from list x to this list,
//! before the element pointed by p. No destructors or copy constructors are called.
//! If p == i or p == ++i, this function is a null operation.
//!
//! Throws: Nothing
//!
//! Complexity: Constant.
//!
//! Note: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(this != &x);
//Additional checks done in splice()
this->splice(p, static_cast(x), i);
}
//! Requires: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
//! this' allocator and x's allocator shall compare equal
//!
//! Effects: Transfers the range pointed by first and last from list x to this list,
//! before the element pointed by p. No destructors or copy constructors are called.
//!
//! Throws: Nothing
//!
//! Complexity: Linear to the number of elements transferred.
//!
//! Note: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT((priv_is_linked)(p));
BOOST_ASSERT(first == last || (first != x.cend() && x.priv_is_linked(first)));
BOOST_ASSERT(first == last || x.priv_is_linked(last));
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), first.get(), last.get());
}
//! Requires: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
//! this' allocator and x's allocator shall compare equal.
//!
//! Effects: Transfers the range pointed by first and last from list x to this list,
//! before the element pointed by p. No destructors or copy constructors are called.
//!
//! Throws: Nothing
//!
//! Complexity: Linear to the number of elements transferred.
//!
//! Note: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(this != &x);
//Additional checks done in splice()
this->splice(p, static_cast(x), first, last);
}
//! Requires: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
//! n == distance(first, last). this' allocator and x's allocator shall compare equal
//!
//! Effects: Transfers the range pointed by first and last from list x to this list,
//! before the element pointed by p. No destructors or copy constructors are called.
//!
//! Throws: Nothing
//!
//! Complexity: Constant.
//!
//! Note: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
//!
//! Note: Non-standard extension
void splice(const_iterator p, list &x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
}
//! Requires: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
//! n == distance(first, last). this' allocator and x's allocator shall compare equal
//!
//! Effects: Transfers the range pointed by first and last from list x to this list,
//! before the element pointed by p. No destructors or copy constructors are called.
//!
//! Throws: Nothing
//!
//! Complexity: Constant.
//!
//! Note: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
//!
//! Note: Non-standard extension
void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice(p, static_cast(x), first, last, n); }
//! Effects: Removes all the elements that compare equal to value.
//!
//! Throws: If comparison throws.
//!
//! Complexity: Linear time. It performs exactly size() comparisons for equality.
//!
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
void remove(const T& value)
{ this->remove_if(equal_to_value_type(value)); }
//! Effects: Removes all the elements for which a specified
//! predicate is satisfied.
//!
//! Throws: If pred throws.
//!
//! Complexity: Linear time. It performs exactly size() calls to the predicate.
//!
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
template
void remove_if(Pred pred)
{
typedef value_to_node_compare value_to_node_compare_type;
this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
}
//! Effects: Removes adjacent duplicate elements or adjacent
//! elements that are equal from the list.
//!
//! Throws: If comparison throws.
//!
//! Complexity: Linear time (size()-1 comparisons equality comparisons).
//!
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
void unique()
{ this->unique(value_equal_t()); }
//! Effects: Removes adjacent duplicate elements or adjacent
//! elements that satisfy some binary predicate from the list.
//!
//! Throws: If pred throws.
//!
//! Complexity: Linear time (size()-1 comparisons calls to pred()).
//!
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
template
void unique(BinaryPredicate binary_pred)
{
typedef value_to_node_compare value_to_node_compare_type;
this->icont().unique_and_dispose(value_to_node_compare_type(binary_pred), Destroyer(this->node_alloc()));
}
//! Requires: The lists x and *this must be distinct.
//!
//! Effects: This function removes all of x's elements and inserts them
//! in order into *this according to std::less. The merge is stable;
//! that is, if an element from *this is equivalent to one from x, then the element
//! from *this will precede the one from x.
//!
//! Throws: If comparison throws.
//!
//! Complexity: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
void merge(list &x)
{ this->merge(x, value_less_t()); }
//! Requires: The lists x and *this must be distinct.
//!
//! Effects: This function removes all of x's elements and inserts them
//! in order into *this according to std::less. The merge is stable;
//! that is, if an element from *this is equivalent to one from x, then the element
//! from *this will precede the one from x.
//!
//! Throws: If comparison throws.
//!
//! Complexity: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
void merge(BOOST_RV_REF(list) x)
{ this->merge(static_cast(x)); }
//! Requires: p must be a comparison function that induces a strict weak
//! ordering and both *this and x must be sorted according to that ordering
//! The lists x and *this must be distinct.
//!
//! Effects: This function removes all of x's elements and inserts them
//! in order into *this. The merge is stable; that is, if an element from *this is
//! equivalent to one from x, then the element from *this will precede the one from x.
//!
//! Throws: If comp throws.
//!
//! Complexity: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
//!
//! Note: Iterators and references to *this are not invalidated.
template
void merge(list &x, const StrictWeakOrdering &comp)
{
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
typedef value_to_node_compare value_to_node_compare_type;
this->icont().merge(x.icont(), value_to_node_compare_type(comp));
}
//! Requires: p must be a comparison function that induces a strict weak
//! ordering and both *this and x must be sorted according to that ordering
//! The lists x and *this must be distinct.
//!
//! Effects: This function removes all of x's elements and inserts them
//! in order into *this. The merge is stable; that is, if an element from *this is
//! equivalent to one from x, then the element from *this will precede the one from x.
//!
//! Throws: If comp throws.
//!
//! Complexity: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
//!
//! Note: Iterators and references to *this are not invalidated.
template
void merge(BOOST_RV_REF(list) x, StrictWeakOrdering comp)
{ this->merge(static_cast(x), comp); }
//! Effects: This function sorts the list *this according to std::less.
//! The sort is stable, that is, the relative order of equivalent elements is preserved.
//!
//! Throws: If comparison throws.
//!
//! Notes: Iterators and references are not invalidated.
//!
//! Complexity: The number of comparisons is approximately N log N, where N
//! is the list's size.
void sort()
{ this->sort(value_less_t()); }
//! Effects: This function sorts the list *this according to std::less.
//! The sort is stable, that is, the relative order of equivalent elements is preserved.
//!
//! Throws: If comp throws.
//!
//! Notes: Iterators and references are not invalidated.
//!
//! Complexity: The number of comparisons is approximately N log N, where N
//! is the list's size.
template
void sort(StrictWeakOrdering comp)
{
// nothing if the list has length 0 or 1.
if (this->size() < 2)
return;
typedef value_to_node_compare value_to_node_compare_type;
this->icont().sort(value_to_node_compare_type(comp));
}
//! Effects: Reverses the order of elements in the list.
//!
//! Throws: Nothing.
//!
//! Complexity: This function is linear time.
//!
//! Note: Iterators and references are not invalidated
void reverse() BOOST_NOEXCEPT_OR_NOTHROW
{ this->icont().reverse(); }
//! Effects: Returns true if x and y are equal
//!
//! Complexity: Linear to the number of elements in the container.
friend bool operator==(const list& x, const list& y)
{ return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
//! Effects: Returns true if x and y are unequal
//!
//! Complexity: Linear to the number of elements in the container.
friend bool operator!=(const list& x, const list& y)
{ return !(x == y); }
//! Effects: Returns true if x is less than y
//!
//! Complexity: Linear to the number of elements in the container.
friend bool operator<(const list& x, const list& y)
{ return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
//! Effects: Returns true if x is greater than y
//!
//! Complexity: Linear to the number of elements in the container.
friend bool operator>(const list& x, const list& y)
{ return y < x; }
//! Effects: Returns true if x is equal or less than y
//!
//! Complexity: Linear to the number of elements in the container.
friend bool operator<=(const list& x, const list& y)
{ return !(y < x); }
//! Effects: Returns true if x is equal or greater than y
//!
//! Complexity: Linear to the number of elements in the container.
friend bool operator>=(const list& x, const list& y)
{ return !(x < y); }
//! Effects: x.swap(y)
//!
//! Complexity: Constant.
friend void swap(list& x, list& y)
{ x.swap(y); }
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
static bool priv_is_linked(const_iterator const position)
{
const_iterator cur(position);
//This list is circular including end nodes
return (--(++cur)) == position && (++(--cur)) == position;
}
bool priv_try_shrink(size_type new_size)
{
const size_type len = this->size();
if(len > new_size){
const const_iterator iend = this->cend();
size_type to_erase = len - new_size;
const_iterator ifirst;
if(to_erase < len/2u){
ifirst = iend;
while(to_erase--){
--ifirst;
}
}
else{
ifirst = this->cbegin();
size_type to_skip = len - to_erase;
while(to_skip--){
++ifirst;
}
}
this->erase(ifirst, iend);
return true;
}
else{
return false;
}
}
iterator priv_insert(const_iterator p, const T &x)
{
BOOST_ASSERT((priv_is_linked)(p));
NodePtr tmp = AllocHolder::create_node(x);
return iterator(this->icont().insert(p.get(), *tmp));
}
iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x)
{
BOOST_ASSERT((priv_is_linked)(p));
NodePtr tmp = AllocHolder::create_node(boost::move(x));
return iterator(this->icont().insert(p.get(), *tmp));
}
void priv_push_back (const T &x)
{ this->insert(this->cend(), x); }
void priv_push_back (BOOST_RV_REF(T) x)
{ this->insert(this->cend(), boost::move(x)); }
void priv_push_front (const T &x)
{ this->insert(this->cbegin(), x); }
void priv_push_front (BOOST_RV_REF(T) x)
{ this->insert(this->cbegin(), boost::move(x)); }
class insertion_functor;
friend class insertion_functor;
class insertion_functor
{
Icont &icont_;
typedef typename Icont::const_iterator iconst_iterator;
const iconst_iterator pos_;
public:
insertion_functor(Icont &icont, typename Icont::const_iterator pos)
: icont_(icont), pos_(pos)
{}
void operator()(Node &n)
{
this->icont_.insert(pos_, n);
}
};
typedef value_less value_less_t;
typedef value_equal value_equal_t;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
template
list(InputIterator, InputIterator) ->
list::value_type>;
template
list(InputIterator, InputIterator, ValueAllocator const&) ->
list::value_type, ValueAllocator>;
#endif
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
} //namespace container {
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template
struct has_trivial_destructor_after_move >
{
typedef typename boost::container::list::allocator_type allocator_type;
typedef typename ::boost::container::allocator_traits::pointer pointer;
static const bool value = ::boost::has_trivial_destructor_after_move::value &&
::boost::has_trivial_destructor_after_move::value;
};
namespace container {
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}}
#include
#endif // BOOST_CONTAINER_LIST_HPP