Message ID | 20240620153304.2023285-1-jwakely@redhat.com |
---|---|
State | New |
Headers | show |
Series | libstdc++: Simplify std::valarray initialization helpers | expand |
Pushed to trunk. On Thu, 20 Jun 2024 at 16:34, Jonathan Wakely <jwakely@redhat.com> wrote: > > Tested x86_64-linux. > > -- >8 -- > > Dispatching to partial specializations doesn't really seem to offer much > benefit here. The __is_trivial(T) condition is a compile-time constant > so the untaken branches are dead code and don't cost us anything. > > libstdc++-v3/ChangeLog: > > * include/bits/valarray_array.h (_Array_default_ctor): Remove. > (__valarray_default_construct): Inline it into here. > (_Array_init_ctor): Remove. > (__valarray_fill_construct): Inline it into here. > (_Array_copy_ctor): Remove. > (__valarray_copy_construct(const T*, const T*, T*)): Inline it > into here. > (__valarray_copy_construct(const T*, size_t, size_t, T*)): > Use _GLIBCXX17_CONSTEXPR for constant condition. > --- > libstdc++-v3/include/bits/valarray_array.h | 97 ++++------------------ > 1 file changed, 18 insertions(+), 79 deletions(-) > > diff --git a/libstdc++-v3/include/bits/valarray_array.h b/libstdc++-v3/include/bits/valarray_array.h > index 07c49ce1057..0dc28333f33 100644 > --- a/libstdc++-v3/include/bits/valarray_array.h > +++ b/libstdc++-v3/include/bits/valarray_array.h > @@ -62,105 +62,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > __valarray_release_memory(void* __p) > { operator delete(__p); } > > - // Turn a raw-memory into an array of _Tp filled with _Tp() > - // This is required in 'valarray<T> v(n);' > - template<typename _Tp, bool> > - struct _Array_default_ctor > - { > - // Please note that this isn't exception safe. But > - // valarrays aren't required to be exception safe. > - inline static void > - _S_do_it(_Tp* __b, _Tp* __e) > - { > - while (__b != __e) > - new(__b++) _Tp(); > - } > - }; > - > - template<typename _Tp> > - struct _Array_default_ctor<_Tp, true> > - { > - // For trivial types, it suffices to say 'memset()' > - inline static void > - _S_do_it(_Tp* __b, _Tp* __e) > - { __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); } > - }; > - > + // Turn raw-memory into an array of _Tp filled with _Tp(). > + // This is used in `valarray<T> v(n);` and in `valarray<T>::shift(n)`. > template<typename _Tp> > inline void > __valarray_default_construct(_Tp* __b, _Tp* __e) > { > - _Array_default_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e); > + if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) > + __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); > + else > + while (__b != __e) > + ::new(static_cast<void*>(__b++)) _Tp(); > } > > // Turn a raw-memory into an array of _Tp filled with __t > // This is the required in valarray<T> v(n, t). Also > // used in valarray<>::resize(). > - template<typename _Tp, bool> > - struct _Array_init_ctor > - { > - // Please note that this isn't exception safe. But > - // valarrays aren't required to be exception safe. > - inline static void > - _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t) > - { > - while (__b != __e) > - new(__b++) _Tp(__t); > - } > - }; > - > - template<typename _Tp> > - struct _Array_init_ctor<_Tp, true> > - { > - inline static void > - _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t) > - { > - while (__b != __e) > - *__b++ = __t; > - } > - }; > - > template<typename _Tp> > inline void > __valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t) > { > - _Array_init_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __t); > + while (__b != __e) > + ::new(static_cast<void*>(__b++)) _Tp(__t); > } > > - // > // copy-construct raw array [__o, *) from plain array [__b, __e) > - // We can't just say 'memcpy()' > - // > - template<typename _Tp, bool> > - struct _Array_copy_ctor > - { > - // Please note that this isn't exception safe. But > - // valarrays aren't required to be exception safe. > - inline static void > - _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) > - { > - while (__b != __e) > - new(__o++) _Tp(*__b++); > - } > - }; > - > - template<typename _Tp> > - struct _Array_copy_ctor<_Tp, true> > - { > - inline static void > - _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) > - { > - if (__b) > - __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); > - } > - }; > - > template<typename _Tp> > inline void > __valarray_copy_construct(const _Tp* __b, const _Tp* __e, > _Tp* __restrict__ __o) > { > - _Array_copy_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __o); > + if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) > + { > + if (__b) > + __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); > + } > + else > + while (__b != __e) > + ::new(static_cast<void*>(__o++)) _Tp(*__b++); > } > > // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] > @@ -169,7 +108,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, > size_t __s, _Tp* __restrict__ __o) > { > - if (__is_trivial(_Tp)) > + if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) > while (__n--) > { > *__o++ = *__a; > -- > 2.45.2 >
diff --git a/libstdc++-v3/include/bits/valarray_array.h b/libstdc++-v3/include/bits/valarray_array.h index 07c49ce1057..0dc28333f33 100644 --- a/libstdc++-v3/include/bits/valarray_array.h +++ b/libstdc++-v3/include/bits/valarray_array.h @@ -62,105 +62,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __valarray_release_memory(void* __p) { operator delete(__p); } - // Turn a raw-memory into an array of _Tp filled with _Tp() - // This is required in 'valarray<T> v(n);' - template<typename _Tp, bool> - struct _Array_default_ctor - { - // Please note that this isn't exception safe. But - // valarrays aren't required to be exception safe. - inline static void - _S_do_it(_Tp* __b, _Tp* __e) - { - while (__b != __e) - new(__b++) _Tp(); - } - }; - - template<typename _Tp> - struct _Array_default_ctor<_Tp, true> - { - // For trivial types, it suffices to say 'memset()' - inline static void - _S_do_it(_Tp* __b, _Tp* __e) - { __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); } - }; - + // Turn raw-memory into an array of _Tp filled with _Tp(). + // This is used in `valarray<T> v(n);` and in `valarray<T>::shift(n)`. template<typename _Tp> inline void __valarray_default_construct(_Tp* __b, _Tp* __e) { - _Array_default_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e); + if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) + __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); + else + while (__b != __e) + ::new(static_cast<void*>(__b++)) _Tp(); } // Turn a raw-memory into an array of _Tp filled with __t // This is the required in valarray<T> v(n, t). Also // used in valarray<>::resize(). - template<typename _Tp, bool> - struct _Array_init_ctor - { - // Please note that this isn't exception safe. But - // valarrays aren't required to be exception safe. - inline static void - _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t) - { - while (__b != __e) - new(__b++) _Tp(__t); - } - }; - - template<typename _Tp> - struct _Array_init_ctor<_Tp, true> - { - inline static void - _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t) - { - while (__b != __e) - *__b++ = __t; - } - }; - template<typename _Tp> inline void __valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t) { - _Array_init_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __t); + while (__b != __e) + ::new(static_cast<void*>(__b++)) _Tp(__t); } - // // copy-construct raw array [__o, *) from plain array [__b, __e) - // We can't just say 'memcpy()' - // - template<typename _Tp, bool> - struct _Array_copy_ctor - { - // Please note that this isn't exception safe. But - // valarrays aren't required to be exception safe. - inline static void - _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) - { - while (__b != __e) - new(__o++) _Tp(*__b++); - } - }; - - template<typename _Tp> - struct _Array_copy_ctor<_Tp, true> - { - inline static void - _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) - { - if (__b) - __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); - } - }; - template<typename _Tp> inline void __valarray_copy_construct(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) { - _Array_copy_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __o); + if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) + { + if (__b) + __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); + } + else + while (__b != __e) + ::new(static_cast<void*>(__o++)) _Tp(*__b++); } // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] @@ -169,7 +108,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, size_t __s, _Tp* __restrict__ __o) { - if (__is_trivial(_Tp)) + if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) while (__n--) { *__o++ = *__a;