diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-22 07:18:37 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-22 07:18:37 +0000 |
commit | 47d30ca026ee42d0d6429de6482a6adc8c8333e6 (patch) | |
tree | 5307a01039deafd8a3fdd8686b0742e7996335d9 /libstdc++-v3/include/bits | |
parent | 29a84dc1fb3448b24d959158b796c0dcb95bf602 (diff) | |
download | gcc-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.h | 91 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/forward_list.tcc | 40 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/move.h | 5 |
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); } |