[committed] libstdc++: Optimize std::decay
Commit Message
Tested powerpc64le-linux, pushed to trunk.
-- >8 --
Define partial specializations of std::decay and its __decay_selector
helper so that remove_reference, is_array and is_function are not
instantiated for every type, and remove_extent is not instantiated for
arrays.
libstdc++-v3/ChangeLog:
* include/std/type_traits (__decay_selector): Add partial
specializations for array types. Only check for function types
when not dealing with an array.
(decay): Add partial specializations for reference types.
---
libstdc++-v3/include/std/type_traits | 39 ++++++++++++++--------------
1 file changed, 20 insertions(+), 19 deletions(-)
@@ -2203,34 +2203,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Decay trait for arrays and functions, used for perfect forwarding
// in make_pair, make_tuple, etc.
- template<typename _Up,
- bool _IsArray = is_array<_Up>::value,
- bool _IsFunction = is_function<_Up>::value>
- struct __decay_selector;
-
- // NB: DR 705.
template<typename _Up>
- struct __decay_selector<_Up, false, false>
- { typedef __remove_cv_t<_Up> __type; };
+ struct __decay_selector
+ : __conditional_t<is_const<const _Up>::value, // false for functions
+ remove_cv<_Up>, // N.B. DR 705.
+ add_pointer<_Up>> // function decays to pointer
+ { };
+
+ template<typename _Up, size_t _Nm>
+ struct __decay_selector<_Up[_Nm]>
+ { using type = _Up*; };
template<typename _Up>
- struct __decay_selector<_Up, true, false>
- { typedef typename remove_extent<_Up>::type* __type; };
+ struct __decay_selector<_Up[]>
+ { using type = _Up*; };
- template<typename _Up>
- struct __decay_selector<_Up, false, true>
- { typedef typename add_pointer<_Up>::type __type; };
/// @endcond
/// decay
template<typename _Tp>
- class decay
- {
- typedef typename remove_reference<_Tp>::type __remove_type;
+ struct decay
+ { using type = typename __decay_selector<_Tp>::type; };
- public:
- typedef typename __decay_selector<__remove_type>::__type type;
- };
+ template<typename _Tp>
+ struct decay<_Tp&>
+ { using type = typename __decay_selector<_Tp>::type; };
+
+ template<typename _Tp>
+ struct decay<_Tp&&>
+ { using type = typename __decay_selector<_Tp>::type; };
/// @cond undocumented