summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/bits
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-22 07:18:37 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-22 07:18:37 +0000
commit47d30ca026ee42d0d6429de6482a6adc8c8333e6 (patch)
tree5307a01039deafd8a3fdd8686b0742e7996335d9 /libstdc++-v3/include/bits
parent29a84dc1fb3448b24d959158b796c0dcb95bf602 (diff)
downloadgcc-47d30ca026ee42d0d6429de6482a6adc8c8333e6.tar.gz
2012-10-22 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 192664 using svnmerge.py git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@192665 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/bits')
-rw-r--r--libstdc++-v3/include/bits/forward_list.h91
-rw-r--r--libstdc++-v3/include/bits/forward_list.tcc40
-rw-r--r--libstdc++-v3/include/bits/move.h5
3 files changed, 102 insertions, 34 deletions
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index ce355048a86..a5c9f434b35 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -266,11 +266,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
struct _Fwd_list_base
{
protected:
- typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits;
+ typedef typename _Alloc_traits::template rebind<_Tp>::other
+ _Tp_alloc_type;
- typedef typename _Alloc::template
+ typedef typename _Alloc_traits::template
rebind<_Fwd_list_node<_Tp>>::other _Node_alloc_type;
+ typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
+
struct _Fwd_list_impl
: public _Node_alloc_type
{
@@ -312,12 +316,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Fwd_list_base(const _Fwd_list_base& __lst, const _Node_alloc_type& __a);
- _Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a)
- : _M_impl(__a)
- {
- this->_M_impl._M_head._M_next = __lst._M_impl._M_head._M_next;
- __lst._M_impl._M_head._M_next = 0;
- }
+ _Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a);
_Fwd_list_base(_Fwd_list_base&& __lst)
: _M_impl(std::move(__lst._M_get_Node_allocator()))
@@ -333,7 +332,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Node*
_M_get_node()
- { return _M_get_Node_allocator().allocate(1); }
+ { return _Node_alloc_traits::allocate(_M_get_Node_allocator(), 1); }
template<typename... _Args>
_Node*
@@ -342,8 +341,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Node* __node = this->_M_get_node();
__try
{
- _M_get_Node_allocator().construct(__node,
- std::forward<_Args>(__args)...);
+ _Node_alloc_traits::construct(_M_get_Node_allocator(), __node,
+ std::forward<_Args>(__args)...);
__node->_M_next = 0;
}
__catch(...)
@@ -360,7 +359,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
_M_put_node(_Node* __p)
- { _M_get_Node_allocator().deallocate(__p, 1); }
+ { _Node_alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
_Fwd_list_node_base*
_M_erase_after(_Fwd_list_node_base* __pos);
@@ -413,14 +412,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef _Fwd_list_node_base _Node_base;
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
typedef typename _Base::_Node_alloc_type _Node_alloc_type;
+ typedef typename _Base::_Node_alloc_traits _Node_alloc_traits;
+ typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
public:
// types:
typedef _Tp value_type;
- typedef typename _Tp_alloc_type::pointer pointer;
- typedef typename _Tp_alloc_type::const_pointer const_pointer;
- typedef typename _Tp_alloc_type::reference reference;
- typedef typename _Tp_alloc_type::const_reference const_reference;
+ typedef typename _Alloc_traits::pointer pointer;
+ typedef typename _Alloc_traits::const_pointer const_pointer;
+ typedef typename _Alloc_traits::reference reference;
+ typedef typename _Alloc_traits::const_reference const_reference;
typedef _Fwd_list_iterator<_Tp> iterator;
typedef _Fwd_list_const_iterator<_Tp> const_iterator;
@@ -504,12 +505,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief The %forward_list copy constructor.
* @param __list A %forward_list of identical element and allocator
* types.
- *
- * The newly-created %forward_list uses a copy of the allocation
- * object used by @a __list.
*/
forward_list(const forward_list& __list)
- : _Base(__list._M_get_Node_allocator())
+ : _Base(_Node_alloc_traits::_S_select_on_copy(
+ __list._M_get_Node_allocator()))
{ _M_range_initialize(__list.begin(), __list.end()); }
/**
@@ -560,16 +559,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* types.
*
* The contents of @a __list are moved into this %forward_list
- * (without copying). @a __list is a valid, but unspecified
- * %forward_list
+ * (without copying, if the allocators permit it).
+ * @a __list is a valid, but unspecified %forward_list
*/
forward_list&
operator=(forward_list&& __list)
+ noexcept(_Node_alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__list);
+ constexpr bool __move_storage =
+ _Node_alloc_traits::_S_propagate_on_move_assign()
+ || _Node_alloc_traits::_S_always_equal();
+ _M_move_assign(std::move(__list),
+ integral_constant<bool, __move_storage>());
return *this;
}
@@ -740,7 +741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
size_type
max_size() const noexcept
- { return this->_M_get_Node_allocator().max_size(); }
+ { return _Node_alloc_traits::max_size(this->_M_get_Node_allocator()); }
// 23.2.3.3 element access:
@@ -981,8 +982,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
void
swap(forward_list& __list)
- { std::swap(this->_M_impl._M_head._M_next,
- __list._M_impl._M_head._M_next); }
+ noexcept(_Node_alloc_traits::_S_nothrow_swap())
+ {
+ std::swap(this->_M_impl._M_head._M_next,
+ __list._M_impl._M_head._M_next);
+ _Node_alloc_traits::_S_on_swap(this->_M_get_Node_allocator(),
+ __list._M_get_Node_allocator());
+ }
/**
* @brief Resizes the %forward_list to the specified number of
@@ -1239,6 +1245,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// Called by resize(sz).
void
_M_default_insert_after(const_iterator __pos, size_type __n);
+
+ // Called by operator=(forward_list&&)
+ void
+ _M_move_assign(forward_list&& __list, std::true_type) noexcept
+ {
+ clear();
+ std::swap(this->_M_impl._M_head._M_next,
+ __list._M_impl._M_head._M_next);
+ std::__alloc_on_move(this->_M_get_Node_allocator(),
+ __list._M_get_Node_allocator());
+ }
+
+ // Called by operator=(forward_list&&)
+ void
+ _M_move_assign(forward_list&& __list, std::false_type)
+ {
+ if (__list._M_get_Node_allocator() == this->_M_get_Node_allocator())
+ _M_move_assign(std::move(__list), std::true_type());
+ else
+ {
+ // The rvalue's allocator cannot be moved, or is not equal,
+ // so we need to individually move each element.
+ this->assign(std::__make_move_if_noexcept_iterator(__list.begin()),
+ std::__make_move_if_noexcept_iterator(__list.end()));
+ __list.clear();
+ }
+ }
};
/**
diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc
index 3c9f2380b27..5d18a6ebf44 100644
--- a/libstdc++-v3/include/bits/forward_list.tcc
+++ b/libstdc++-v3/include/bits/forward_list.tcc
@@ -52,6 +52,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
template<typename _Tp, typename _Alloc>
+ _Fwd_list_base<_Tp, _Alloc>::
+ _Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a)
+ : _M_impl(__a)
+ {
+ if (__lst._M_get_Node_allocator() == __a)
+ this->_M_impl._M_head._M_next = __lst._M_impl._M_head._M_next;
+ else
+ {
+ this->_M_impl._M_head._M_next = 0;
+ _Fwd_list_node_base* __to = &this->_M_impl._M_head;
+ _Node* __curr = static_cast<_Node*>(__lst._M_impl._M_head._M_next);
+
+ while (__curr)
+ {
+ __to->_M_next =
+ _M_create_node(std::move_if_noexcept(__curr->_M_value));
+ __to = __to->_M_next;
+ __curr = static_cast<_Node*>(__curr->_M_next);
+ }
+ }
+ __lst._M_impl._M_head._M_next = 0;
+ }
+
+ template<typename _Tp, typename _Alloc>
template<typename... _Args>
_Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>::
@@ -72,7 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
_Node* __curr = static_cast<_Node*>(__pos->_M_next);
__pos->_M_next = __curr->_M_next;
- _M_get_Node_allocator().destroy(__curr);
+ _Node_alloc_traits::destroy(_M_get_Node_allocator(), __curr);
_M_put_node(__curr);
return __pos->_M_next;
}
@@ -88,7 +112,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
_Node* __temp = __curr;
__curr = static_cast<_Node*>(__curr->_M_next);
- _M_get_Node_allocator().destroy(__temp);
+ _Node_alloc_traits::destroy(_M_get_Node_allocator(), __temp);
_M_put_node(__temp);
}
__pos->_M_next = __last;
@@ -144,6 +168,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
if (&__list != this)
{
+ if (_Node_alloc_traits::_S_propagate_on_copy_assign())
+ {
+ auto& __this_alloc = this->_M_get_Node_allocator();
+ auto& __that_alloc = __list._M_get_Node_allocator();
+ if (!_Node_alloc_traits::_S_always_equal()
+ && __this_alloc != __that_alloc)
+ {
+ // replacement allocator cannot free existing storage
+ clear();
+ }
+ std::__alloc_on_copy(__this_alloc, __that_alloc);
+ }
iterator __prev1 = before_begin();
iterator __curr1 = begin();
iterator __last1 = end();
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index 353c466d8fc..236f0de300a 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -1,6 +1,6 @@
// Move, forward and identity for C++0x + swap -*- C++ -*-
-// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2007-2012 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
@@ -65,7 +65,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @{
*/
- // forward (as per N3143)
/**
* @brief Forward an lvalue.
* @return The parameter cast to the specified type.
@@ -117,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* type is copyable, in which case an lvalue-reference is returned instead.
*/
template<typename _Tp>
- inline typename
+ inline constexpr typename
conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type
move_if_noexcept(_Tp& __x) noexcept
{ return std::move(__x); }