From f15d7a588228842f558b14c0f23ba76d9b5e8d80 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Thu, 22 Jan 2015 18:33:29 +0000 Subject: [PATCH] Fix PR#22284. Add a new overload to deque::insert to handle forward iterators. Update tests to exercise this case. llvm-svn: 226847 --- libcxx/include/deque | 28 ++++++++++++--- .../deque.modifiers/insert_iter_iter.pass.cpp | 41 +++++++++++++++++++++- 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/libcxx/include/deque b/libcxx/include/deque index 5602d4a..2ac7bf3 100644 --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -117,7 +117,7 @@ public: iterator insert(const_iterator p, value_type&& v); iterator insert(const_iterator p, size_type n, const value_type& v); template - iterator insert (const_iterator p, InputIterator f, InputIterator l); + iterator insert(const_iterator p, InputIterator f, InputIterator l); iterator insert(const_iterator p, initializer_list il); void pop_front(); void pop_back(); @@ -1332,11 +1332,15 @@ public: iterator insert(const_iterator __p, const value_type& __v); iterator insert(const_iterator __p, size_type __n, const value_type& __v); template - iterator insert (const_iterator __p, _InputIter __f, _InputIter __l, + iterator insert(const_iterator __p, _InputIter __f, _InputIter __l, typename enable_if<__is_input_iterator<_InputIter>::value - &&!__is_bidirectional_iterator<_InputIter>::value>::type* = 0); + &&!__is_forward_iterator<_InputIter>::value>::type* = 0); + template + iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, + typename enable_if<__is_forward_iterator<_ForwardIterator>::value + &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type* = 0); template - iterator insert (const_iterator __p, _BiIter __f, _BiIter __l, + iterator insert(const_iterator __p, _BiIter __f, _BiIter __l, typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type* = 0); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY @@ -2098,7 +2102,7 @@ template typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l, typename enable_if<__is_input_iterator<_InputIter>::value - &&!__is_bidirectional_iterator<_InputIter>::value>::type*) + &&!__is_forward_iterator<_InputIter>::value>::type*) { __split_buffer __buf(__base::__alloc()); __buf.__construct_at_end(__f, __l); @@ -2107,6 +2111,20 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __ } template +template +typename deque<_Tp, _Allocator>::iterator +deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, + typename enable_if<__is_forward_iterator<_ForwardIterator>::value + &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type*) +{ + size_type __n = _VSTD::distance(__f, __l); + __split_buffer __buf(__n, 0, __base::__alloc()); + __buf.__construct_at_end(__f, __l); + typedef typename __split_buffer::iterator __fwd; + return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end())); +} + +template template typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l, diff --git a/libcxx/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp index 2bc37c3..909390f 100644 --- a/libcxx/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp @@ -46,11 +46,49 @@ make(int size, int start = 0 ) template void -test(int P, C& c1, const C& c2) +test(int P, const C& c0, const C& c2) { + { + typedef typename C::iterator I; + typedef typename C::const_iterator CI; + typedef input_iterator BCI; + C c1 = c0; + std::size_t c1_osize = c1.size(); + CI i = c1.insert(c1.begin() + P, BCI(c2.begin()), BCI(c2.end())); + assert(i == c1.begin() + P); + assert(c1.size() == c1_osize + c2.size()); + assert(distance(c1.begin(), c1.end()) == c1.size()); + i = c1.begin(); + for (int j = 0; j < P; ++j, ++i) + assert(*i == j); + for (int j = 0; j < c2.size(); ++j, ++i) + assert(*i == j); + for (int j = P; j < c1_osize; ++j, ++i) + assert(*i == j); + } + { + typedef typename C::iterator I; + typedef typename C::const_iterator CI; + typedef forward_iterator BCI; + C c1 = c0; + std::size_t c1_osize = c1.size(); + CI i = c1.insert(c1.begin() + P, BCI(c2.begin()), BCI(c2.end())); + assert(i == c1.begin() + P); + assert(c1.size() == c1_osize + c2.size()); + assert(distance(c1.begin(), c1.end()) == c1.size()); + i = c1.begin(); + for (int j = 0; j < P; ++j, ++i) + assert(*i == j); + for (int j = 0; j < c2.size(); ++j, ++i) + assert(*i == j); + for (int j = P; j < c1_osize; ++j, ++i) + assert(*i == j); + } + { typedef typename C::iterator I; typedef typename C::const_iterator CI; typedef bidirectional_iterator BCI; + C c1 = c0; std::size_t c1_osize = c1.size(); CI i = c1.insert(c1.begin() + P, BCI(c2.begin()), BCI(c2.end())); assert(i == c1.begin() + P); @@ -63,6 +101,7 @@ test(int P, C& c1, const C& c2) assert(*i == j); for (int j = P; j < c1_osize; ++j, ++i) assert(*i == j); + } } template -- 2.7.4