LWG 3039 changed the spec to use remove_cvref_t instead of decay_t, and this patch makes that change to our std::packaged_task. I'm not sure why I created a custom type at namespace scope to constrain packaged_task. This patch replaces it with an alias for enable_if.
std::thread already had the change, so this just adds a comment noting the issue number. * include/std/future (__constrain_pkgdtask): Replace with ... (packaged_task::__not_same): New alias template, using __remove_cvref_t instead of decay. * include/std/thread (thread::__not_same): Add comment. Tested powerpc64le-linux, committed to trunk.
commit df8c05879aa008a993cbd5f0762f9ef8557f2bb7 Author: Jonathan Wakely <jwak...@redhat.com> Date: Thu Jun 14 23:36:09 2018 +0100 LWG 3039 Unnecessary decay in thread and packaged_task * include/std/future (__constrain_pkgdtask): Replace with ... (packaged_task::__not_same): New alias template, using __remove_cvref_t instead of decay. * include/std/thread (thread::__not_same): Add comment. diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index c17a253d26e..937c05ef2b2 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -1462,15 +1462,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_cast<_Alloc&>(_M_impl)); } - template<typename _Task, typename _Fn, bool - = is_same<_Task, typename decay<_Fn>::type>::value> - struct __constrain_pkgdtask - { typedef void __type; }; - - template<typename _Task, typename _Fn> - struct __constrain_pkgdtask<_Task, _Fn, true> - { }; - /// packaged_task template<typename _Res, typename... _ArgTypes> class packaged_task<_Res(_ArgTypes...)> @@ -1478,6 +1469,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type; shared_ptr<_State_type> _M_state; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3039. Unnecessary decay in thread and packaged_task + template<typename _Fn, typename _Fn2 = __remove_cvref_t<_Fn>> + using __not_same + = typename enable_if<!is_same<packaged_task, _Fn2>::value>::type; + public: // Construction and destruction packaged_task() noexcept { } @@ -1488,8 +1485,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION packaged_task(allocator_arg_t, const _Allocator& __a) noexcept { } - template<typename _Fn, typename = typename - __constrain_pkgdtask<packaged_task, _Fn>::__type> + template<typename _Fn, typename = __not_same<_Fn>> explicit packaged_task(_Fn&& __fn) : packaged_task(allocator_arg, std::allocator<int>(), @@ -1499,11 +1495,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2097. packaged_task constructors should be constrained // 2407. [this constructor should not be] explicit - template<typename _Fn, typename _Alloc, typename = typename - __constrain_pkgdtask<packaged_task, _Fn>::__type> + template<typename _Fn, typename _Alloc, typename = __not_same<_Fn>> packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn) : _M_state(__create_task_state<_Res(_ArgTypes...)>( - std::forward<_Fn>(__fn), __a)) + std::forward<_Fn>(__fn), __a)) { } ~packaged_task() diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index 61861b58520..13acd6a3091 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -104,6 +104,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2097. packaged_task constructors should be constrained + // 3039. Unnecessary decay in thread and packaged_task template<typename _Tp> using __not_same = __not_<is_same<__remove_cvref_t<_Tp>, thread>>;