This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [v3 PATCH] PR libstdc++/77619
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: Ville Voutilainen <ville dot voutilainen at gmail dot com>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 20 Sep 2016 15:07:13 +0100
- Subject: Re: [v3 PATCH] PR libstdc++/77619
- Authentication-results: sourceware.org; auth=none
- References: <CAFk2RUaw=L0aB8WPyOM1TbR3bCTXqGKEDUVJd=zYkzTMCN1Q9Q@mail.gmail.com>
On 18/09/16 21:07 +0300, Ville Voutilainen wrote:
diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h
index 3d12628..c7ca1f8 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -83,6 +83,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
::new(static_cast<void*>(__p)) _T1(__value);
}
#endif
Blank line here please.
+ template<typename _T1>
+ inline void
+ _Construct_novalue(_T1* __p)
+ { ::new(static_cast<void*>(__p)) _T1; }
/**
* Destroy the object pointed to by a pointer type.
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index c5c81fb..b4213d5 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -640,6 +644,104 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
allocator<_Tp>&)
{ return std::__uninitialized_default_n(__first, __n); }
+ template<bool _TrivialValueType>
+ struct __uninitialized_default_novalue_1
+ {
+ template<typename _ForwardIterator>
+ static void
+ __uninit_default_novalue(_ForwardIterator __first,
+ _ForwardIterator __last)
+ {
...
+ }
The left brace is indented with spaces and the right one with a tab,
might as well make them the same.
+ };
+
+ template<>
+ struct __uninitialized_default_novalue_1<true>
+ {
+ template<typename _ForwardIterator>
+ static void
+ __uninit_default_novalue(_ForwardIterator __first,
+ _ForwardIterator __last)
+ {
+ }
Ditto.
+ };
+
+ template<bool _TrivialValueType>
+ struct __uninitialized_default_novalue_n_1
+ {
+ template<typename _ForwardIterator, typename _Size>
+ static _ForwardIterator
+ __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
+ {
+ _ForwardIterator __cur = __first;
+ __try
+ {
+ for (; __n > 0; --__n, ++__cur)
+ std::_Construct_novalue(std::__addressof(*__cur));
+ return __cur;
+ }
+ __catch(...)
+ {
+ std::_Destroy(__first, __cur);
+ __throw_exception_again;
+ }
+ }
Ditto.
+ };
+
+ template<>
+ struct __uninitialized_default_novalue_n_1<true>
+ {
+ template<typename _ForwardIterator, typename _Size>
+ static _ForwardIterator
+ __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
+ {
+ }
Ditto.
+ };
+
+ // __uninitialized_default_novalue
+ // Fills [first, last) with std::distance(first, last) default-initialized
+ // value_types(s).
+ template<typename _ForwardIterator>
+ inline void
+ __uninitialized_default_novalue(_ForwardIterator __first,
+ _ForwardIterator __last)
+ {
+ typedef typename iterator_traits<_ForwardIterator>::value_type
+ _ValueType;
+ // trivial types can have deleted assignment
+ const bool __assignable = is_copy_assignable<_ValueType>::value;
Aha! A non-whitespace comment ... __assignable isn't used. If it's not
needed it can be removed.
+ std::__uninitialized_default_novalue_1<
+ is_trivially_default_constructible<_ValueType>::value>::
+ __uninit_default_novalue(__first, __last);
+ }
+
+ // __uninitialized_default_n
+ // Fills [first, first + n) with n default-initialized value_type(s).
+ template<typename _ForwardIterator, typename _Size>
+ inline _ForwardIterator
+ __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
+ {
+ typedef typename iterator_traits<_ForwardIterator>::value_type
+ _ValueType;
+ // trivial types can have deleted assignment
+ const bool __assignable = is_copy_assignable<_ValueType>::value;
Ditto.
+ return __uninitialized_default_novalue_n_1<
+ is_trivially_default_constructible<_ValueType>::value>::
+ __uninit_default_novalue_n(__first, __n);
+ }
template<typename _InputIterator, typename _Size,
typename _ForwardIterator>
@@ -669,6 +771,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
random_access_iterator_tag)
{ return std::uninitialized_copy(__first, __first + __n, __result); }
+ template<typename _InputIterator, typename _Size,
+ typename _ForwardIterator>
+ pair<_InputIterator, _ForwardIterator>
+ __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
+ _ForwardIterator __result, input_iterator_tag)
+ {
+ _ForwardIterator __cur = __result;
+ __try
+ {
+ for (; __n > 0; --__n, ++__first, ++__cur)
+ std::_Construct(std::__addressof(*__cur), *__first);
+ return {__first, __cur};
+ }
+ __catch(...)
+ {
+ std::_Destroy(__result, __cur);
+ __throw_exception_again;
+ }
+ }
+
+ template<typename _RandomAccessIterator, typename _Size,
+ typename _ForwardIterator>
+ inline pair<_RandomAccessIterator, _ForwardIterator>
+ __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
+ _ForwardIterator __result,
+ random_access_iterator_tag)
+ {
+ auto second = uninitialized_copy(__first, __first + __n, __result);
+ auto first = std::next(__first, __n);
+ return {first, second};
I was going to say these names need to be uglified, but they can't be
macros due to std::pair. Carry on.
@@ -744,35 +877,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
uninitialized_move_n(_InputIterator __first, _Size __count,
_ForwardIterator __result)
{
- for (; __count > 0; ++__result, (void) ++__first, --__count)
- ::new (static_cast<void*>(std::__addressof(*__result)))
- typename
- iterator_traits<_ForwardIterator>::value_type(std::move(*__first));
- return {__first, __result};
+ auto res = std::__uninitialized_copy_n_pair
+ (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
+ __count, __result);
+ return {res.first.base(), res.second};
However, res isn't a reserved name AFAIK, so should be __res.
OK for trunk with that change, and the whitespace changes if you would
be so kind. Thanks.