From e73d6fe8285466b1eb8c6cd58277400c394d6dd6 Mon Sep 17 00:00:00 2001 From: Edward Smith-Rowland <3dw4rd@verizon.net> Date: Fri, 17 Oct 2008 08:08:03 +0000 Subject: [PATCH] forward_list.h: Factor list construction to dispatch routines. 2008-10-16 Edward Smith-Rowland <3dw4rd@verizon.net> * include/bits/forward_list.h: Factor list construction to dispatch routines. * include/bits/forward_list.tcc: Likewise. * testsuite/23_containers/forward_list/modifiers/2.cc: From-SVN: r141189 --- libstdc++-v3/ChangeLog | 7 + libstdc++-v3/include/bits/forward_list.h | 63 +++++++-- libstdc++-v3/include/bits/forward_list.tcc | 141 ++------------------- .../23_containers/forward_list/modifiers/2.cc | 2 +- 4 files changed, 75 insertions(+), 138 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4b7151e..1364419 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2008-10-16 Edward Smith-Rowland <3dw4rd@verizon.net> + + * include/bits/forward_list.h: Factor list construction to dispatch + routines. + * include/bits/forward_list.tcc: Likewise. + * testsuite/23_containers/forward_list/modifiers/2.cc: + 2008-10-16 Paolo Carlini * include/bits/forward_list.tcc (operator==): Use auto. diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index 88a6017..cce8f3d 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -469,7 +469,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * the default value. */ explicit - forward_list(size_type __n); + forward_list(size_type __n) + : _Base(_Alloc()) + { _M_fill_initialize(__n, value_type()); } /** * @brief Creates a %forward_list with copies of an exemplar element. @@ -481,7 +483,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * value. */ forward_list(size_type __n, const _Tp& __value, - const _Alloc& __al = _Alloc()); + const _Alloc& __al = _Alloc()) + : _Base(__al) + { _M_fill_initialize(__n, __value); } /** * @brief Builds a %forward_list from a range. @@ -495,7 +499,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ template forward_list(_InputIterator __first, _InputIterator __last, - const _Alloc& __al = _Alloc()); + const _Alloc& __al = _Alloc()) + : _Base(__al) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } /** * @brief The %forward_list copy constructor. @@ -505,7 +515,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * The newly-created %forward_list uses a copy of the allocation * object used by @a list. */ - forward_list(const forward_list& __list); + forward_list(const forward_list& __list) + : _Base(__list.get_allocator()) + { _M_initialize_dispatch(__list.begin(), __list.end(), + __false_type()); } /** * @brief The %forward_list move constructor. @@ -528,7 +541,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * in the initializer_list @a il. This is linear in il.size(). */ forward_list(std::initializer_list<_Tp> __il, - const _Alloc& __al = _Alloc()); + const _Alloc& __al = _Alloc()) + : _Base(__al) + { _M_initialize_dispatch(__il.begin(), __il.end(), __false_type()); } /** * @brief The forward_list dtor. @@ -871,7 +886,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * does not invalidate iterators and references. */ void - insert_after(const_iterator __pos, size_type __n, const _Tp& __val); + insert_after(const_iterator __pos, size_type __n, const _Tp& __val) + { + forward_list<_Tp, _Alloc> __tmp(__n, __val, this->get_allocator()); + this->splice_after(__pos, std::move(__tmp)); + } /** * @brief Inserts a range into the %forward_list. @@ -889,7 +908,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template void insert_after(const_iterator __pos, - _InputIterator __first, _InputIterator __last); + _InputIterator __first, _InputIterator __last) + { + forward_list<_Tp, _Alloc> __tmp(__first, __last, this->get_allocator()); + this->splice_after(__pos, std::move(__tmp)); + } /** * @brief Inserts the contents of an initializer_list into @@ -905,7 +928,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * does not invalidate iterators and references. */ void - insert_after(const_iterator __pos, std::initializer_list<_Tp> __il); + insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) + { + forward_list<_Tp, _Alloc> __tmp(__il, this->get_allocator()); + this->splice_after(__pos, std::move(__tmp)); + } /** * @brief Removes the element pointed to by the iterator following @@ -1106,7 +1133,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * the pointer is the user's responsibility. */ void - unique(); + unique() + { this->unique(std::equal_to<_Tp>()); } /** * @brief Remove consecutive elements satisfying a predicate. @@ -1186,6 +1214,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ void reverse(); + + private: + template + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { _M_fill_initialize(static_cast(__n), __x); } + + // Called by the range constructor to implement [23.1.1]/9 + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + + // Called by forward_list(n,v,a), and the range constructor when it turns out + // to be the same thing. + void + _M_fill_initialize(size_type __n, const value_type& __value); }; /** diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc index 46b97d5..f222f70 100644 --- a/libstdc++-v3/include/bits/forward_list.tcc +++ b/libstdc++-v3/include/bits/forward_list.tcc @@ -206,38 +206,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return __pos; } - template - forward_list<_Tp, _Alloc>:: - forward_list(size_type __n) - : _Base() - { - _Fwd_list_node_base* __to = &this->_M_impl._M_head; - for (size_type __i = 0; __i < __n; ++__i) - { - __to->_M_next = this->_M_create_node(_Tp()); - __to = __to->_M_next; - } - } - - template - forward_list<_Tp, _Alloc>:: - forward_list(size_type __n, const _Tp& __value, const _Alloc& __al) - : _Base(__al) - { - _Fwd_list_node_base* __to = &this->_M_impl._M_head; - for (size_type __i = 0; __i < __n; ++__i) - { - __to->_M_next = this->_M_create_node(__value); - __to = __to->_M_next; - } - } - + // Called by the range constructor to implement [23.1.1]/9 template template + void forward_list<_Tp, _Alloc>:: - forward_list(_InputIterator __first, _InputIterator __last, - const _Alloc& __al) - : _Base(__al) + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { _Fwd_list_node_base* __to = &this->_M_impl._M_head; _InputIterator __curr = __first; @@ -249,34 +224,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } } + // Called by forward_list(n,v,a), and the range constructor + // when it turns out to be the same thing. template + void forward_list<_Tp, _Alloc>:: - forward_list(const forward_list& __list) - : _Base(__list._M_get_Node_allocator()) - { - const _Fwd_list_node_base* __from = &__list._M_impl._M_head; - _Fwd_list_node_base* __to = &this->_M_impl._M_head; - while (__from->_M_next != 0) - { - const _Node* __temp = static_cast<_Node*>(__from->_M_next); - __to->_M_next = this->_M_create_node(__temp->_M_value); - __from = __from->_M_next; - __to = __to->_M_next; - } - } - - template - forward_list<_Tp, _Alloc>:: - forward_list(std::initializer_list<_Tp> __il, const _Alloc& __al) - : _Base(__al) + _M_fill_initialize(size_type __n, const value_type& __value) { _Fwd_list_node_base* __to = &this->_M_impl._M_head; - for (const _Tp* __item = __il.begin(); - __item != __il.end(); ++__item) - { - __to->_M_next = this->_M_create_node(*__item); - __to = __to->_M_next; - } + for (; __n > 0; --__n) + { + __to->_M_next = this->_M_create_node(__value); + __to = __to->_M_next; + } } template @@ -309,61 +269,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template void forward_list<_Tp, _Alloc>:: - insert_after(const_iterator __pos, - size_type __n, const _Tp& __val) - { - _Fwd_list_node_base* __to - = const_cast<_Fwd_list_node_base*>(__pos._M_node); - _Fwd_list_node_base* __keep = __to->_M_next; - for (size_type __i = 0; __i < __n; ++__i) - { - __to->_M_next = this->_M_create_node(__val); - __to = __to->_M_next; - } - __to->_M_next = __keep; - } - - template - template - void - forward_list<_Tp, _Alloc>:: - insert_after(const_iterator __pos, - _InputIterator __first, _InputIterator __last) - { - _Fwd_list_node_base* __to - = const_cast<_Fwd_list_node_base*>(__pos._M_node); - _Fwd_list_node_base* __keep = __to->_M_next; - _InputIterator __curr = __first; - while (__curr != __last) - { - __to->_M_next = this->_M_create_node(*__curr); - __to = __to->_M_next; - ++__curr; - } - __to->_M_next = __keep; - } - - template - void - forward_list<_Tp, _Alloc>:: - insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) - { - _Fwd_list_node_base* __to - = const_cast<_Fwd_list_node_base*>(__pos._M_node); - _Fwd_list_node_base* __keep = __to->_M_next; - const _Tp* __item = __il.begin(); - while (__item != __il.end()) - { - __to->_M_next = this->_M_create_node(*__item); - __to = __to->_M_next; - ++__item; - } - __to->_M_next = __keep; - } - - template - void - forward_list<_Tp, _Alloc>:: resize(size_type __sz, value_type __val) { iterator __k = before_begin(); @@ -441,26 +346,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } template - void - forward_list<_Tp, _Alloc>:: - unique() - { - iterator __first = begin(); - iterator __last = end(); - if (__first == __last) - return; - iterator __next = __first; - while (++__next != __last) - { - if (*__first == *__next) - erase_after(__first); - else - __first = __next; - __next = __first; - } - } - - template template void forward_list<_Tp, _Alloc>:: diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc index 9d79b22..a628358 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc @@ -51,7 +51,7 @@ test02() // Note: Calling l.insert_after(pos, 5, 42); without the long five // gets resolved to the iterator range version and fails to compile! - fl.insert_after(pos, 5L, 42); + fl.insert_after(pos, 5, 42); VERIFY(*pos == 1); ++pos; -- 2.7.4