// List implementation -*- C++ -*-
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-// 2011 Free Software Foundation, Inc.
+// Copyright (C) 2001-2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
#define _STL_LIST_H 1
#include <bits/concept_check.h>
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
#include <initializer_list>
#endif
///< User's data.
_Tp _M_data;
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
template<typename... _Args>
_List_node(_Args&&... __args)
: __detail::_List_node_base(), _M_data(std::forward<_Args>(__args)...)
typedef _Tp* pointer;
typedef _Tp& reference;
- _List_iterator()
+ _List_iterator() _GLIBCXX_NOEXCEPT
: _M_node() { }
explicit
- _List_iterator(__detail::_List_node_base* __x)
+ _List_iterator(__detail::_List_node_base* __x) _GLIBCXX_NOEXCEPT
: _M_node(__x) { }
+ _Self
+ _M_const_cast() const _GLIBCXX_NOEXCEPT
+ { return *this; }
+
// Must downcast from _List_node_base to _List_node to get to _M_data.
reference
- operator*() const
+ operator*() const _GLIBCXX_NOEXCEPT
{ return static_cast<_Node*>(_M_node)->_M_data; }
pointer
- operator->() const
+ operator->() const _GLIBCXX_NOEXCEPT
{ return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); }
_Self&
- operator++()
+ operator++() _GLIBCXX_NOEXCEPT
{
_M_node = _M_node->_M_next;
return *this;
}
_Self
- operator++(int)
+ operator++(int) _GLIBCXX_NOEXCEPT
{
_Self __tmp = *this;
_M_node = _M_node->_M_next;
}
_Self&
- operator--()
+ operator--() _GLIBCXX_NOEXCEPT
{
_M_node = _M_node->_M_prev;
return *this;
}
_Self
- operator--(int)
+ operator--(int) _GLIBCXX_NOEXCEPT
{
_Self __tmp = *this;
_M_node = _M_node->_M_prev;
}
bool
- operator==(const _Self& __x) const
+ operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT
{ return _M_node == __x._M_node; }
bool
- operator!=(const _Self& __x) const
+ operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT
{ return _M_node != __x._M_node; }
// The only member points to the %list element.
typedef const _Tp* pointer;
typedef const _Tp& reference;
- _List_const_iterator()
+ _List_const_iterator() _GLIBCXX_NOEXCEPT
: _M_node() { }
explicit
_List_const_iterator(const __detail::_List_node_base* __x)
+ _GLIBCXX_NOEXCEPT
: _M_node(__x) { }
- _List_const_iterator(const iterator& __x)
+ _List_const_iterator(const iterator& __x) _GLIBCXX_NOEXCEPT
: _M_node(__x._M_node) { }
+ iterator
+ _M_const_cast() const _GLIBCXX_NOEXCEPT
+ { return iterator(const_cast<__detail::_List_node_base*>(_M_node)); }
+
// Must downcast from List_node_base to _List_node to get to
// _M_data.
reference
- operator*() const
+ operator*() const _GLIBCXX_NOEXCEPT
{ return static_cast<_Node*>(_M_node)->_M_data; }
pointer
- operator->() const
+ operator->() const _GLIBCXX_NOEXCEPT
{ return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); }
_Self&
- operator++()
+ operator++() _GLIBCXX_NOEXCEPT
{
_M_node = _M_node->_M_next;
return *this;
}
_Self
- operator++(int)
+ operator++(int) _GLIBCXX_NOEXCEPT
{
_Self __tmp = *this;
_M_node = _M_node->_M_next;
}
_Self&
- operator--()
+ operator--() _GLIBCXX_NOEXCEPT
{
_M_node = _M_node->_M_prev;
return *this;
}
_Self
- operator--(int)
+ operator--(int) _GLIBCXX_NOEXCEPT
{
_Self __tmp = *this;
_M_node = _M_node->_M_prev;
}
bool
- operator==(const _Self& __x) const
+ operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT
{ return _M_node == __x._M_node; }
bool
- operator!=(const _Self& __x) const
+ operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT
{ return _M_node != __x._M_node; }
// The only member points to the %list element.
template<typename _Val>
inline bool
operator==(const _List_iterator<_Val>& __x,
- const _List_const_iterator<_Val>& __y)
+ const _List_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
{ return __x._M_node == __y._M_node; }
template<typename _Val>
inline bool
operator!=(const _List_iterator<_Val>& __x,
- const _List_const_iterator<_Val>& __y)
+ const _List_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
{ return __x._M_node != __y._M_node; }
/// See bits/stl_deque.h's _Deque_base for an explanation.
template<typename _Tp, typename _Alloc>
- class _List_base
+ class _GLIBCXX_DEFAULT_ABI_TAG _List_base
{
protected:
// NOTA BENE
typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
+ static size_t
+ _S_distance(const __detail::_List_node_base* __first,
+ const __detail::_List_node_base* __last)
+ {
+ size_t __n = 0;
+ while (__first != __last)
+ {
+ __first = __first->_M_next;
+ ++__n;
+ }
+ return __n;
+ }
+
struct _List_impl
: public _Node_alloc_type
{
+#if _GLIBCXX_USE_CXX11_ABI
+ _List_node<size_t> _M_node;
+#else
__detail::_List_node_base _M_node;
-
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- size_t _M_size;
#endif
_List_impl()
: _Node_alloc_type(), _M_node()
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- , _M_size(0)
-#endif
{ }
- _List_impl(const _Node_alloc_type& __a)
+ _List_impl(const _Node_alloc_type& __a) _GLIBCXX_NOEXCEPT
: _Node_alloc_type(__a), _M_node()
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- , _M_size(0)
-#endif
{ }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- _List_impl(_Node_alloc_type&& __a)
- : _Node_alloc_type(std::move(__a)), _M_node(), _M_size(0)
+#if __cplusplus >= 201103L
+ _List_impl(_Node_alloc_type&& __a) _GLIBCXX_NOEXCEPT
+ : _Node_alloc_type(std::move(__a)), _M_node()
{ }
#endif
};
_List_impl _M_impl;
- _List_node<_Tp>*
- _M_get_node()
+#if _GLIBCXX_USE_CXX11_ABI
+ size_t _M_get_size() const { return _M_impl._M_node._M_data; }
+
+ void _M_set_size(size_t __n) { _M_impl._M_node._M_data = __n; }
+
+ void _M_inc_size(size_t __n) { _M_impl._M_node._M_data += __n; }
+
+ void _M_dec_size(size_t __n) { _M_impl._M_node._M_data -= __n; }
+
+ size_t
+ _M_distance(const __detail::_List_node_base* __first,
+ const __detail::_List_node_base* __last) const
+ { return _S_distance(__first, __last); }
+
+ // return the stored size
+ size_t _M_node_count() const { return _M_impl._M_node._M_data; }
+#else
+ // dummy implementations used when the size is not stored
+ size_t _M_get_size() const { return 0; }
+ void _M_set_size(size_t) { }
+ void _M_inc_size(size_t) { }
+ void _M_dec_size(size_t) { }
+ size_t _M_distance(const void*, const void*) const { return 0; }
+
+ // count the number of nodes
+ size_t _M_node_count() const
{
- _List_node<_Tp>* __tmp = _M_impl._Node_alloc_type::allocate(1);
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- ++_M_impl._M_size;
-#endif
- return __tmp;
+ return _S_distance(_M_impl._M_node._M_next,
+ std::__addressof(_M_impl._M_node));
}
+#endif
+
+ _List_node<_Tp>*
+ _M_get_node()
+ { return _M_impl._Node_alloc_type::allocate(1); }
void
- _M_put_node(_List_node<_Tp>* __p)
- {
- _M_impl._Node_alloc_type::deallocate(__p, 1);
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- --_M_impl._M_size;
-#endif
- }
-
+ _M_put_node(_List_node<_Tp>* __p) _GLIBCXX_NOEXCEPT
+ { _M_impl._Node_alloc_type::deallocate(__p, 1); }
+
public:
typedef _Alloc allocator_type;
: _M_impl()
{ _M_init(); }
- _List_base(const _Node_alloc_type& __a)
+ _List_base(const _Node_alloc_type& __a) _GLIBCXX_NOEXCEPT
: _M_impl(__a)
{ _M_init(); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- _List_base(_List_base&& __x)
+#if __cplusplus >= 201103L
+ _List_base(_List_base&& __x) noexcept
: _M_impl(std::move(__x._M_get_Node_allocator()))
{
- _M_init();
- __detail::_List_node_base::swap(_M_impl._M_node, __x._M_impl._M_node);
- std::swap(_M_impl._M_size, __x._M_impl._M_size);
+ auto* const __xnode = std::__addressof(__x._M_impl._M_node);
+ if (__xnode->_M_next == __xnode)
+ _M_init();
+ else
+ {
+ auto* const __node = std::__addressof(_M_impl._M_node);
+ __node->_M_next = __xnode->_M_next;
+ __node->_M_prev = __xnode->_M_prev;
+ __node->_M_next->_M_prev = __node->_M_prev->_M_next = __node;
+ _M_set_size(__x._M_get_size());
+ __x._M_init();
+ }
}
#endif
{ _M_clear(); }
void
- _M_clear();
+ _M_clear() _GLIBCXX_NOEXCEPT;
void
- _M_init()
+ _M_init() _GLIBCXX_NOEXCEPT
{
this->_M_impl._M_node._M_next = &this->_M_impl._M_node;
this->_M_impl._M_node._M_prev = &this->_M_impl._M_node;
+ _M_set_size(0);
}
};
*
* @ingroup sequences
*
+ * @tparam _Tp Type of element.
+ * @tparam _Alloc Allocator type, defaults to allocator<_Tp>.
+ *
* Meets the requirements of a <a href="tables.html#65">container</a>, a
* <a href="tables.html#66">reversible container</a>, and a
* <a href="tables.html#67">sequence</a>, including the
* %empty.
*/
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
- class list : protected _List_base<_Tp, _Alloc>
+ class _GLIBCXX_DEFAULT_ABI_TAG list : protected _List_base<_Tp, _Alloc>
{
// concept requirements
typedef typename _Alloc::value_type _Alloc_value_type;
* Allocates space for a new node and constructs a copy of
* @a __args in it.
*/
-#ifndef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus < 201103L
_Node*
_M_create_node(const value_type& __x)
{
public:
// [23.2.2.1] construct/copy/destroy
// (assign() and get_allocator() are also listed in this section)
+
/**
- * @brief Default constructor creates no elements.
+ * @brief Creates a %list with no elements.
*/
list()
+#if __cplusplus >= 201103L
+ noexcept(is_nothrow_default_constructible<_Node_alloc_type>::value)
+#endif
: _Base() { }
/**
* @param __a An allocator object.
*/
explicit
- list(const allocator_type& __a)
+ list(const allocator_type& __a) _GLIBCXX_NOEXCEPT
: _Base(_Node_alloc_type(__a)) { }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
/**
* @brief Creates a %list with default constructed elements.
* @param __n The number of elements to initially create.
: _Base(__x._M_get_Node_allocator())
{ _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
/**
* @brief %List move constructor.
* @param __x A %list of identical element and allocator types.
* [@a __first,@a __last). This is linear in N (where N is
* distance(@a __first,@a __last)).
*/
+#if __cplusplus >= 201103L
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+ list(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a = allocator_type())
+ : _Base(_Node_alloc_type(__a))
+ { _M_initialize_dispatch(__first, __last, __false_type()); }
+#else
template<typename _InputIterator>
list(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_initialize_dispatch(__first, __last, _Integral());
}
+#endif
/**
* No explicit dtor needed as the _Base dtor takes care of
list&
operator=(const list& __x);
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
/**
* @brief %List move assignment operator.
* @param __x A %list of identical element and allocator types.
* that the resulting %list's size is the same as the number of
* elements assigned. Old data may be lost.
*/
+#if __cplusplus >= 201103L
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+ void
+ assign(_InputIterator __first, _InputIterator __last)
+ { _M_assign_dispatch(__first, __last, __false_type()); }
+#else
template<typename _InputIterator>
void
assign(_InputIterator __first, _InputIterator __last)
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_assign_dispatch(__first, __last, _Integral());
}
+#endif
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
/**
* @brief Assigns an initializer_list to a %list.
* @param __l An initializer_list of value_type.
rend() const _GLIBCXX_NOEXCEPT
{ return const_reverse_iterator(begin()); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
/**
* Returns a read-only (constant) iterator that points to the
* first element in the %list. Iteration is done in ordinary
/** Returns the number of elements in the %list. */
size_type
size() const _GLIBCXX_NOEXCEPT
- {
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- return this->_M_impl._M_size;
-#else
- return std::distance(begin(), end());
-#endif
- }
+ { return this->_M_node_count(); }
/** Returns the size() of the largest possible %list. */
size_type
max_size() const _GLIBCXX_NOEXCEPT
{ return _M_get_Node_allocator().max_size(); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
/**
* @brief Resizes the %list to the specified number of elements.
* @param __new_size Number of elements the %list should contain.
* element of the %list.
*/
reference
- front()
+ front() _GLIBCXX_NOEXCEPT
{ return *begin(); }
/**
* element of the %list.
*/
const_reference
- front() const
+ front() const _GLIBCXX_NOEXCEPT
{ return *begin(); }
/**
* of the %list.
*/
reference
- back()
+ back() _GLIBCXX_NOEXCEPT
{
iterator __tmp = end();
--__tmp;
* element of the %list.
*/
const_reference
- back() const
+ back() const _GLIBCXX_NOEXCEPT
{
const_iterator __tmp = end();
--__tmp;
push_front(const value_type& __x)
{ this->_M_insert(begin(), __x); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
void
push_front(value_type&& __x)
{ this->_M_insert(begin(), std::move(__x)); }
* called.
*/
void
- pop_front()
+ pop_front() _GLIBCXX_NOEXCEPT
{ this->_M_erase(begin()); }
/**
push_back(const value_type& __x)
{ this->_M_insert(end(), __x); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
void
push_back(value_type&& __x)
{ this->_M_insert(end(), std::move(__x)); }
* is needed, it should be retrieved before pop_back() is called.
*/
void
- pop_back()
+ pop_back() _GLIBCXX_NOEXCEPT
{ this->_M_erase(iterator(this->_M_impl._M_node._M_prev)); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
/**
* @brief Constructs object in %list before specified iterator.
* @param __position A const_iterator into the %list.
*/
template<typename... _Args>
iterator
- emplace(iterator __position, _Args&&... __args);
-#endif
+ emplace(const_iterator __position, _Args&&... __args);
+ /**
+ * @brief Inserts given value into %list before specified iterator.
+ * @param __position A const_iterator into the %list.
+ * @param __x Data to be inserted.
+ * @return An iterator that points to the inserted data.
+ *
+ * This function will insert a copy of the given value before
+ * the specified location. Due to the nature of a %list this
+ * operation can be done in constant time, and does not
+ * invalidate iterators and references.
+ */
+ iterator
+ insert(const_iterator __position, const value_type& __x);
+#else
/**
* @brief Inserts given value into %list before specified iterator.
* @param __position An iterator into the %list.
*/
iterator
insert(iterator __position, const value_type& __x);
+#endif
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
/**
* @brief Inserts given rvalue into %list before specified iterator.
- * @param __position An iterator into the %list.
+ * @param __position A const_iterator into the %list.
* @param __x Data to be inserted.
* @return An iterator that points to the inserted data.
*
* invalidate iterators and references.
*/
iterator
- insert(iterator __position, value_type&& __x)
+ insert(const_iterator __position, value_type&& __x)
{ return emplace(__position, std::move(__x)); }
/**
* @brief Inserts the contents of an initializer_list into %list
- * before specified iterator.
- * @param __p An iterator into the %list.
+ * before specified const_iterator.
+ * @param __p A const_iterator into the %list.
* @param __l An initializer_list of value_type.
+ * @return An iterator pointing to the first element inserted
+ * (or __position).
*
* This function will insert copies of the data in the
* initializer_list @a l into the %list before the location
* This operation is linear in the number of elements inserted and
* does not invalidate iterators and references.
*/
- void
- insert(iterator __p, initializer_list<value_type> __l)
- { this->insert(__p, __l.begin(), __l.end()); }
+ iterator
+ insert(const_iterator __p, initializer_list<value_type> __l)
+ { return this->insert(__p, __l.begin(), __l.end()); }
#endif
+#if __cplusplus >= 201103L
+ /**
+ * @brief Inserts a number of copies of given data into the %list.
+ * @param __position A const_iterator into the %list.
+ * @param __n Number of elements to be inserted.
+ * @param __x Data to be inserted.
+ * @return An iterator pointing to the first element inserted
+ * (or __position).
+ *
+ * This function will insert a specified number of copies of the
+ * given data before the location specified by @a position.
+ *
+ * This operation is linear in the number of elements inserted and
+ * does not invalidate iterators and references.
+ */
+ iterator
+ insert(const_iterator __position, size_type __n, const value_type& __x);
+#else
/**
* @brief Inserts a number of copies of given data into the %list.
* @param __position An iterator into the %list.
list __tmp(__n, __x, get_allocator());
splice(__position, __tmp);
}
+#endif
+#if __cplusplus >= 201103L
+ /**
+ * @brief Inserts a range into the %list.
+ * @param __position A const_iterator into the %list.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @return An iterator pointing to the first element inserted
+ * (or __position).
+ *
+ * This function will insert copies of the data in the range [@a
+ * first,@a last) into the %list before the location specified by
+ * @a position.
+ *
+ * This operation is linear in the number of elements inserted and
+ * does not invalidate iterators and references.
+ */
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+ iterator
+ insert(const_iterator __position, _InputIterator __first,
+ _InputIterator __last);
+#else
/**
* @brief Inserts a range into the %list.
* @param __position An iterator into the %list.
list __tmp(__first, __last, get_allocator());
splice(__position, __tmp);
}
+#endif
/**
* @brief Remove element at given position.
* any way. Managing the pointer is the user's responsibility.
*/
iterator
+#if __cplusplus >= 201103L
+ erase(const_iterator __position) noexcept;
+#else
erase(iterator __position);
+#endif
/**
* @brief Remove a range of elements.
* is the user's responsibility.
*/
iterator
+#if __cplusplus >= 201103L
+ erase(const_iterator __first, const_iterator __last) noexcept
+#else
erase(iterator __first, iterator __last)
+#endif
{
while (__first != __last)
__first = erase(__first);
- return __last;
+ return __last._M_const_cast();
}
/**
{
__detail::_List_node_base::swap(this->_M_impl._M_node,
__x._M_impl._M_node);
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- std::swap(this->_M_impl._M_size, __x._M_impl._M_size);
-#endif
+
+ size_t __xsize = __x._M_get_size();
+ __x._M_set_size(this->_M_get_size());
+ this->_M_set_size(__xsize);
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 431. Swapping containers with unequal allocators.
* Requires this != @a __x.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- splice(iterator __position, list&& __x)
+#if __cplusplus >= 201103L
+ splice(const_iterator __position, list&& __x) noexcept
#else
splice(iterator __position, list& __x)
#endif
{
_M_check_equal_allocators(__x);
- this->_M_transfer(__position, __x.begin(), __x.end());
+ this->_M_transfer(__position._M_const_cast(),
+ __x.begin(), __x.end());
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- this->_M_impl._M_size += __x.size();
- __x._M_impl._M_size = 0;
-#endif
+ this->_M_inc_size(__x._M_get_size());
+ __x._M_set_size(0);
}
}
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
void
- splice(iterator __position, list& __x)
+ splice(const_iterator __position, list& __x) noexcept
{ splice(__position, std::move(__x)); }
#endif
+#if __cplusplus >= 201103L
+ /**
+ * @brief Insert element from another %list.
+ * @param __position Const_iterator referencing the element to
+ * insert before.
+ * @param __x Source list.
+ * @param __i Const_iterator referencing the element to move.
+ *
+ * Removes the element in list @a __x referenced by @a __i and
+ * inserts it into the current list before @a __position.
+ */
+ void
+ splice(const_iterator __position, list&& __x, const_iterator __i) noexcept
+#else
/**
* @brief Insert element from another %list.
* @param __position Iterator referencing the element to insert before.
* inserts it into the current list before @a __position.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- splice(iterator __position, list&& __x, iterator __i)
-#else
splice(iterator __position, list& __x, iterator __i)
#endif
{
- iterator __j = __i;
+ iterator __j = __i._M_const_cast();
++__j;
if (__position == __i || __position == __j)
return;
if (this != &__x)
- {
- _M_check_equal_allocators(__x);
+ _M_check_equal_allocators(__x);
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- ++this->_M_impl._M_size;
- --__x._M_impl._M_size;
-#endif
- }
+ this->_M_transfer(__position._M_const_cast(),
+ __i._M_const_cast(), __j);
- this->_M_transfer(__position, __i, __j);
+ this->_M_inc_size(1);
+ __x._M_dec_size(1);
}
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
+ /**
+ * @brief Insert element from another %list.
+ * @param __position Const_iterator referencing the element to
+ * insert before.
+ * @param __x Source list.
+ * @param __i Const_iterator referencing the element to move.
+ *
+ * Removes the element in list @a __x referenced by @a __i and
+ * inserts it into the current list before @a __position.
+ */
void
- splice(iterator __position, list& __x, iterator __i)
+ splice(const_iterator __position, list& __x, const_iterator __i) noexcept
{ splice(__position, std::move(__x), __i); }
#endif
+#if __cplusplus >= 201103L
+ /**
+ * @brief Insert range from another %list.
+ * @param __position Const_iterator referencing the element to
+ * insert before.
+ * @param __x Source list.
+ * @param __first Const_iterator referencing the start of range in x.
+ * @param __last Const_iterator referencing the end of range in x.
+ *
+ * Removes elements in the range [__first,__last) and inserts them
+ * before @a __position in constant time.
+ *
+ * Undefined if @a __position is in [__first,__last).
+ */
+ void
+ splice(const_iterator __position, list&& __x, const_iterator __first,
+ const_iterator __last) noexcept
+#else
/**
* @brief Insert range from another %list.
* @param __position Iterator referencing the element to insert before.
* Undefined if @a __position is in [__first,__last).
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- splice(iterator __position, list&& __x, iterator __first,
- iterator __last)
-#else
splice(iterator __position, list& __x, iterator __first,
iterator __last)
#endif
if (__first != __last)
{
if (this != &__x)
- {
- _M_check_equal_allocators(__x);
+ _M_check_equal_allocators(__x);
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- const size_type __size = std::distance(__first, __last);
- this->_M_impl._M_size += __size;
- __x._M_impl._M_size -= __size;
-#endif
- }
+ size_t __n = this->_M_distance(__first._M_node, __last._M_node);
+ this->_M_inc_size(__n);
+ __x._M_dec_size(__n);
- this->_M_transfer(__position, __first, __last);
+ this->_M_transfer(__position._M_const_cast(),
+ __first._M_const_cast(),
+ __last._M_const_cast());
}
}
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
+ /**
+ * @brief Insert range from another %list.
+ * @param __position Const_iterator referencing the element to
+ * insert before.
+ * @param __x Source list.
+ * @param __first Const_iterator referencing the start of range in x.
+ * @param __last Const_iterator referencing the end of range in x.
+ *
+ * Removes elements in the range [__first,__last) and inserts them
+ * before @a __position in constant time.
+ *
+ * Undefined if @a __position is in [__first,__last).
+ */
void
- splice(iterator __position, list& __x, iterator __first, iterator __last)
+ splice(const_iterator __position, list& __x, const_iterator __first,
+ const_iterator __last) noexcept
{ splice(__position, std::move(__x), __first, __last); }
#endif
* sorted order, leaving @a __x empty when complete. Elements in
* this list precede elements in @a __x that are equal.
*/
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
void
merge(list&& __x);
* in this list precede elements in @a __x that are equivalent
* according to StrictWeakOrdering().
*/
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
template<typename _StrictWeakOrdering>
void
merge(list&& __x, _StrictWeakOrdering __comp);
__false_type)
{
for (; __first != __last; ++__first)
+#if __cplusplus >= 201103L
+ emplace_back(*__first);
+#else
push_back(*__first);
+#endif
}
// Called by list(n,v,a), and the range constructor when it turns out
push_back(__x);
}
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
// Called by list(n).
void
_M_default_initialize(size_type __n)
{ __position._M_node->_M_transfer(__first._M_node, __last._M_node); }
// Inserts new element at position given and with value given.
-#ifndef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus < 201103L
void
_M_insert(iterator __position, const value_type& __x)
{
_Node* __tmp = _M_create_node(__x);
__tmp->_M_hook(__position._M_node);
+ this->_M_inc_size(1);
}
#else
template<typename... _Args>
{
_Node* __tmp = _M_create_node(std::forward<_Args>(__args)...);
__tmp->_M_hook(__position._M_node);
+ this->_M_inc_size(1);
}
#endif
// Erases element at position given.
void
- _M_erase(iterator __position)
+ _M_erase(iterator __position) _GLIBCXX_NOEXCEPT
{
+ this->_M_dec_size(1);
__position._M_node->_M_unhook();
_Node* __n = static_cast<_Node*>(__position._M_node);
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
_M_get_Node_allocator().destroy(__n);
#else
_M_get_Tp_allocator().destroy(std::__addressof(__n->_M_data));
// To implement the splice (and merge) bits of N1599.
void
- _M_check_equal_allocators(list& __x)
+ _M_check_equal_allocators(list& __x) _GLIBCXX_NOEXCEPT
{
if (std::__alloc_neq<typename _Base::_Node_alloc_type>::
_S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator()))
- __throw_runtime_error(__N("list::_M_check_equal_allocators"));
+ __builtin_abort();
}
};
inline bool
operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
{
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- return (__x.size() == __y.size()
- && std::equal(__x.begin(), __x.end(), __y.begin()));
-#else
typedef typename list<_Tp, _Alloc>::const_iterator const_iterator;
const_iterator __end1 = __x.end();
const_iterator __end2 = __y.end();
++__i2;
}
return __i1 == __end1 && __i2 == __end2;
-#endif
}
/**