P0604R0 add invoke_result, is_invocable etc. for C++17
authorJonathan Wakely <jwakely@redhat.com>
Fri, 10 Mar 2017 15:29:38 +0000 (15:29 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 10 Mar 2017 15:29:38 +0000 (15:29 +0000)
* include/bits/invoke.h (__invoke): Use __invoke_result instead of
result_of, and __is_nothrow_invocable instead of
__is_nothrow_callable.
* include/bits/shared_ptr_base.h (__shared_ptr): Use __is_invocable
instead of __is_callable.
* include/std/functional (invoke): use invoke_result_t instead of
result_of_t and is_nothrow_invocable instead of is_nothrow_callable.
(_Not_fn): Use __invoke_result instead of result_of.
* include/std/type_traits (__result_of_memobj, __result_of_memfun):
Remove partial specializations for reference_wrapper types.
(__result_of_impl): Use __inv_unwrap to strip reference_wrapper.
(__invoke_result): Define replacement for result_of and then use it to
define result_of.
(__is_callable_impl, __is_callable, __is_nothrow_callable): Replace
with __is_invocable_impl, __is_invocable, and __is_nothrow_invocable
respectively.
(invoke_result, invoke_result_t): Define for C++17.
(is_callable, is_nothrow_callable): Replace with is_invocable,
is_invocable_r, is_nothrow_invocable, and is_nothrow_invocable_r.
(is_callable_v, is_nothrow_callable_v): Replace with is_invocable_v,
is_invocable_r_v, is_nothrow_invocable_v, and is_nothrow_invocable_r_v.
* include/std/variant (hash<variant<T...>>): Use is_nothrow_invocable_v
instead of is_nothrow_callable_v.
* testsuite/20_util/function_objects/invoke/59768.cc: Remove unused
main function.
* testsuite/20_util/function_objects/not_fn/1.cc: Use is_invocable
instead of is_callable.
* testsuite/20_util/is_callable/*: Rename directory and adjust tests
to use new traits.
* testsuite/20_util/is_notjrow_callable/*: Likewise.
* testsuite/20_util/optional/hash.cc: Use is_invocable_v instead of
is_callable.
* testsuite/20_util/variant/hash.cc: Likewise.

From-SVN: r246036

34 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/invoke.h
libstdc++-v3/include/bits/shared_ptr_base.h
libstdc++-v3/include/std/functional
libstdc++-v3/include/std/type_traits
libstdc++-v3/include/std/variant
libstdc++-v3/testsuite/20_util/function_objects/invoke/59768.cc
libstdc++-v3/testsuite/20_util/function_objects/not_fn/1.cc
libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation_ext.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs_ext.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_callable/value.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_callable/value_ext.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_invocable/requirements/explicit_instantiation.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_invocable/requirements/explicit_instantiation_ext.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_invocable/requirements/typedefs.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_invocable/requirements/typedefs_ext.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_invocable/value.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_invocable/value_ext.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation_ext.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs_ext.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_nothrow_callable/value.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_nothrow_callable/value_ext.cc [deleted file]
libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/explicit_instantiation.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/explicit_instantiation_ext.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/typedefs.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/typedefs_ext.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_nothrow_invocable/value.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_nothrow_invocable/value_ext.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/optional/hash.cc
libstdc++-v3/testsuite/20_util/variant/hash.cc

index d94f6d4831ecbc17fe90ff3e23f1b2549c74545c..a6ae03da06789b2ad996903e7e923a7a148bc585 100644 (file)
@@ -1,3 +1,39 @@
+2017-03-10  Jonathan Wakely  <jwakely@redhat.com>
+
+       * include/bits/invoke.h (__invoke): Use __invoke_result instead of
+       result_of, and __is_nothrow_invocable instead of
+       __is_nothrow_callable.
+       * include/bits/shared_ptr_base.h (__shared_ptr): Use __is_invocable
+       instead of __is_callable.
+       * include/std/functional (invoke): use invoke_result_t instead of
+       result_of_t and is_nothrow_invocable instead of is_nothrow_callable.
+       (_Not_fn): Use __invoke_result instead of result_of.
+       * include/std/type_traits (__result_of_memobj, __result_of_memfun):
+       Remove partial specializations for reference_wrapper types.
+       (__result_of_impl): Use __inv_unwrap to strip reference_wrapper.
+       (__invoke_result): Define replacement for result_of and then use it to
+       define result_of.
+       (__is_callable_impl, __is_callable, __is_nothrow_callable): Replace
+       with __is_invocable_impl, __is_invocable, and __is_nothrow_invocable
+       respectively.
+       (invoke_result, invoke_result_t): Define for C++17.
+       (is_callable, is_nothrow_callable): Replace with is_invocable,
+       is_invocable_r, is_nothrow_invocable, and is_nothrow_invocable_r.
+       (is_callable_v, is_nothrow_callable_v): Replace with is_invocable_v,
+       is_invocable_r_v, is_nothrow_invocable_v, and is_nothrow_invocable_r_v.
+       * include/std/variant (hash<variant<T...>>): Use is_nothrow_invocable_v
+       instead of is_nothrow_callable_v.
+       * testsuite/20_util/function_objects/invoke/59768.cc: Remove unused
+       main function.
+       * testsuite/20_util/function_objects/not_fn/1.cc: Use is_invocable
+       instead of is_callable.
+       * testsuite/20_util/is_callable/*: Rename directory and adjust tests
+       to use new traits.
+       * testsuite/20_util/is_notjrow_callable/*: Likewise.
+       * testsuite/20_util/optional/hash.cc: Use is_invocable_v instead of
+       is_callable.
+       * testsuite/20_util/variant/hash.cc: Likewise.
+
 2017-03-10  George Lander  <george.lander@arm.com>
 
        * acinclude.m4 (glibcxx_cv_obsolete_isnan): Define
index 56d9afbf3f405f9d1bf901dedc5166bfead0817a..eba8707435b06d80da1c54a2786a31d1ab88985d 100644 (file)
@@ -85,13 +85,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// Invoke a callable object.
   template<typename _Callable, typename... _Args>
-    constexpr typename result_of<_Callable&&(_Args&&...)>::type
+    constexpr typename __invoke_result<_Callable, _Args...>::type
     __invoke(_Callable&& __fn, _Args&&... __args)
-    noexcept(__is_nothrow_callable<_Callable&&(_Args&&...)>::value)
+    noexcept(__is_nothrow_invocable<_Callable, _Args...>::value)
     {
-      using __result_of = result_of<_Callable&&(_Args&&...)>;
-      using __type = typename __result_of::type;
-      using __tag = typename __result_of::__invoke_type;
+      using __result = __invoke_result<_Callable, _Args...>;
+      using __type = typename __result::type;
+      using __tag = typename __result::__invoke_type;
       return std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
                                        std::forward<_Args>(__args)...);
     }
index 770a0948d4036fec578c39b477d746eb6817c67b..a203f42c5151291b4be840b6a66cfeb8c82b76a3 100644 (file)
@@ -1085,7 +1085,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        __shared_ptr(_Yp* __p, _Deleter __d)
        : _M_ptr(__p), _M_refcount(__p, __d)
        {
-         static_assert(__is_callable<_Deleter&(_Yp*&)>::value,
+         static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
              "deleter expression d(p) is well-formed");
          _M_enable_shared_from_this_with(__p);
        }
@@ -1095,7 +1095,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
        : _M_ptr(__p), _M_refcount(__p, __d, std::move(__a))
        {
-         static_assert(__is_callable<_Deleter&(_Yp*&)>::value,
+         static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
              "deleter expression d(p) is well-formed");
          _M_enable_shared_from_this_with(__p);
        }
index 366a7fb346eedbe419898a3e253f9ba15f76416e..ae5bc0a3bf9388972f9a2301918d6aca13197d6d 100644 (file)
@@ -73,9 +73,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// Invoke a callable object.
   template<typename _Callable, typename... _Args>
-    inline result_of_t<_Callable&&(_Args&&...)>
+    inline invoke_result_t<_Callable, _Args...>
     invoke(_Callable&& __fn, _Args&&... __args)
-    noexcept(is_nothrow_callable_v<_Callable&&(_Args&&...)>)
+    noexcept(is_nothrow_invocable_v<_Callable, _Args...>)
     {
       return std::__invoke(std::forward<_Callable>(__fn),
                           std::forward<_Args>(__args)...);
@@ -903,7 +903,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
     class _Not_fn
     {
       template<typename _Fn2, typename... _Args>
-       using __inv_res_t = result_of_t<_Fn2(_Args&&...)>;
+       using __inv_res_t = typename __invoke_result<_Fn2, _Args...>::type;
 
       template<typename _Tp>
        static decltype(!std::declval<_Tp>())
index 76865f44541b7753888a301a582922fc6c352a11..7d067cabd72e5b9e6ed0e9e76314ca4de3449960 100644 (file)
@@ -2392,59 +2392,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // 2219.  INVOKE-ing a pointer to member with a reference_wrapper
   //        as the object expression
 
-  template<typename _Res, typename _Class, typename _Arg>
-    struct __result_of_memobj<_Res _Class::*, reference_wrapper<_Arg>>
-    : __result_of_memobj_ref<_Res _Class::*, _Arg&>
-    { };
-
-  template<typename _Res, typename _Class, typename _Arg>
-    struct __result_of_memobj<_Res _Class::*, reference_wrapper<_Arg>&>
-    : __result_of_memobj_ref<_Res _Class::*, _Arg&>
-    { };
-
-  template<typename _Res, typename _Class, typename _Arg>
-    struct __result_of_memobj<_Res _Class::*, const reference_wrapper<_Arg>&>
-    : __result_of_memobj_ref<_Res _Class::*, _Arg&>
-    { };
-
-  template<typename _Res, typename _Class, typename _Arg>
-    struct __result_of_memobj<_Res _Class::*, reference_wrapper<_Arg>&&>
-    : __result_of_memobj_ref<_Res _Class::*, _Arg&>
-    { };
-
-  template<typename _Res, typename _Class, typename _Arg>
-    struct __result_of_memobj<_Res _Class::*, const reference_wrapper<_Arg>&&>
-    : __result_of_memobj_ref<_Res _Class::*, _Arg&>
-    { };
-
-  template<typename _Res, typename _Class, typename _Arg, typename... _Args>
-    struct __result_of_memfun<_Res _Class::*, reference_wrapper<_Arg>, _Args...>
-    : __result_of_memfun_ref<_Res _Class::*, _Arg&, _Args...>
-    { };
-
-  template<typename _Res, typename _Class, typename _Arg, typename... _Args>
-    struct __result_of_memfun<_Res _Class::*, reference_wrapper<_Arg>&,
-                             _Args...>
-    : __result_of_memfun_ref<_Res _Class::*, _Arg&, _Args...>
-    { };
-
-  template<typename _Res, typename _Class, typename _Arg, typename... _Args>
-    struct __result_of_memfun<_Res _Class::*, const reference_wrapper<_Arg>&,
-                             _Args...>
-    : __result_of_memfun_ref<_Res _Class::*, _Arg&, _Args...>
-    { };
-
-  template<typename _Res, typename _Class, typename _Arg, typename... _Args>
-    struct __result_of_memfun<_Res _Class::*, reference_wrapper<_Arg>&&,
-                             _Args...>
-    : __result_of_memfun_ref<_Res _Class::*, _Arg&, _Args...>
-    { };
+  // Used by result_of, invoke etc. to unwrap a reference_wrapper.
+  template<typename _Tp, typename _Up = typename decay<_Tp>::type>
+    struct __inv_unwrap
+    {
+      using type = _Tp;
+    };
 
-  template<typename _Res, typename _Class, typename _Arg, typename... _Args>
-    struct __result_of_memfun<_Res _Class::*, const reference_wrapper<_Arg>&&,
-                             _Args...>
-    : __result_of_memfun_ref<_Res _Class::*, _Arg&, _Args...>
-    };
+  template<typename _Tp, typename _Up>
+    struct __inv_unwrap<_Tp, reference_wrapper<_Up>>
+    {
+      using type = _Up&;
+    };
 
   template<bool, bool, typename _Functor, typename... _ArgTypes>
     struct __result_of_impl
@@ -2454,12 +2413,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _MemPtr, typename _Arg>
     struct __result_of_impl<true, false, _MemPtr, _Arg>
-    : public __result_of_memobj<typename decay<_MemPtr>::type, _Arg>
+    : public __result_of_memobj<typename decay<_MemPtr>::type,
+                               typename __inv_unwrap<_Arg>::type>
     { };
 
   template<typename _MemPtr, typename _Arg, typename... _Args>
     struct __result_of_impl<false, true, _MemPtr, _Arg, _Args...>
-    : public __result_of_memfun<typename decay<_MemPtr>::type, _Arg, _Args...>
+    : public __result_of_memfun<typename decay<_MemPtr>::type,
+                               typename __inv_unwrap<_Arg>::type, _Args...>
     { };
 
   // [func.require] paragraph 1 bullet 5:
@@ -2481,8 +2442,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef decltype(_S_test<_Functor, _ArgTypes...>(0)) type;
     };
 
+  // __invoke_result (std::invoke_result for C++11)
   template<typename _Functor, typename... _ArgTypes>
-    struct result_of<_Functor(_ArgTypes...)>
+    struct __invoke_result
     : public __result_of_impl<
         is_member_object_pointer<
           typename remove_reference<_Functor>::type
@@ -2490,10 +2452,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         is_member_function_pointer<
           typename remove_reference<_Functor>::type
         >::value,
-           _Functor, _ArgTypes...
+       _Functor, _ArgTypes...
       >::type
     { };
 
+  template<typename _Functor, typename... _ArgTypes>
+    struct result_of<_Functor(_ArgTypes...)>
+    : public __invoke_result<_Functor, _ArgTypes...>
+    { };
+
 #if __cplusplus > 201103L
   /// Alias template for aligned_storage
   template<size_t _Len, size_t _Align =
@@ -2781,37 +2748,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #endif// c++1z or gnu++11
 
-  // __is_callable (std::is_callable for C++11)
+  // __is_invocable (std::is_invocable for C++11)
 
-  template<typename _Result, typename _Ret, typename = __void_t<>>
-    struct __is_callable_impl : false_type { };
+  template<typename _Result, typename _Ret, typename = void>
+    struct __is_invocable_impl : false_type { };
 
   template<typename _Result, typename _Ret>
-    struct __is_callable_impl<_Result, _Ret, __void_t<typename _Result::type>>
+    struct __is_invocable_impl<_Result, _Ret, __void_t<typename _Result::type>>
     : __or_<is_void<_Ret>, is_convertible<typename _Result::type, _Ret>>::type
     { };
 
-  template<typename, typename _Ret = void>
-    struct __is_callable; // not defined
-
-  template<typename _Fn, typename... _ArgTypes, typename _Ret>
-    struct __is_callable<_Fn(_ArgTypes...), _Ret>
-    : __is_callable_impl<result_of<_Fn(_ArgTypes...)>, _Ret>::type
+  template<typename _Fn, typename... _ArgTypes>
+    struct __is_invocable
+    : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
     { };
 
-  // Used by __invoke and __is_nothrow_callable to unwrap a reference_wrapper.
-  template<typename _Tp, typename _Up = typename decay<_Tp>::type>
-    struct __inv_unwrap
-    {
-      using type = _Tp;
-    };
-
-  template<typename _Tp, typename _Up>
-    struct __inv_unwrap<_Tp, reference_wrapper<_Up>>
-    {
-      using type = _Up&;
-    };
-
   template<typename _Fn, typename _Tp, typename... _Args>
     constexpr bool __call_is_nt(__invoke_memfun_ref)
     {
@@ -2846,21 +2797,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return noexcept(std::declval<_Fn>()(std::declval<_Args>()...));
     }
 
-  template<typename _ResultOf, typename _Fn, typename... _Args>
+  template<typename _Result, typename _Fn, typename... _Args>
     struct __call_is_nothrow
     : __bool_constant<
-      std::__call_is_nt<_Fn, _Args...>(typename _ResultOf::__invoke_type{})>
+       std::__call_is_nt<_Fn, _Args...>(typename _Result::__invoke_type{})
+      >
     { };
 
-  // __is_nothrow_callable (std::is_nothrow_callable for C++11)
-
-  template<typename, typename _Ret = void>
-    struct __is_nothrow_callable; // not defined
+  template<typename _Fn, typename... _Args>
+    using __call_is_nothrow_
+      = __call_is_nothrow<__invoke_result<_Fn, _Args...>, _Fn, _Args...>;
 
-  template<typename _Fn, typename... _Args, typename _Ret>
-    struct __is_nothrow_callable<_Fn(_Args...), _Ret>
-    : __and_<__is_callable<_Fn(_Args...), _Ret>,
-             __call_is_nothrow<result_of<_Fn(_Args...)>, _Fn, _Args...>>::type
+  // __is_nothrow_invocable (std::is_nothrow_invocable for C++11)
+  template<typename _Fn, typename... _Args>
+    struct __is_nothrow_invocable
+    : __and_<__is_invocable<_Fn, _Args...>,
+             __call_is_nothrow_<_Fn, _Args...>>::type
     { };
 
   struct __nonesuch {
@@ -2871,36 +2823,63 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   };
 
 #if __cplusplus > 201402L
-# define __cpp_lib_is_callable 201603
+# define __cpp_lib_is_invocable 201703
+
+  /// std::invoke_result
+  template<typename _Functor, typename... _ArgTypes>
+    struct invoke_result
+    : public __invoke_result<_Functor, _ArgTypes...>
+    { };
+
+  /// std::invoke_result_t
+  template<typename _Fn, typename... _Args>
+    using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
 
-  /// std::is_callable
-  template<typename, typename _Ret = void>
-    struct is_callable; // not defined
+  /// std::is_invocable
+  template<typename _Fn, typename... _ArgTypes>
+    struct is_invocable
+    : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
+    { };
 
-  template<typename _Fn, typename... _ArgTypes, typename _Ret>
-    struct is_callable<_Fn(_ArgTypes...), _Ret>
-    : __is_callable<_Fn(_ArgTypes...), _Ret>::type
+  /// std::is_invocable_r
+  template<typename _Ret, typename _Fn, typename... _ArgTypes>
+    struct is_invocable_r
+    : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>::type
     { };
 
-  /// std::is_nothrow_callable
-  template<typename, typename _Ret = void>
-    struct is_nothrow_callable; // not defined
+  /// std::is_nothrow_invocable
+  template<typename _Fn, typename... _ArgTypes>
+    struct is_nothrow_invocable
+    : __and_<__is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>,
+             __call_is_nothrow_<_Fn, _ArgTypes...>>::type
+    { };
 
-  template<typename _Fn, typename... _ArgTypes, typename _Ret>
-    struct is_nothrow_callable<_Fn(_ArgTypes...), _Ret>
-    : __is_nothrow_callable<_Fn(_ArgTypes...), _Ret>::type
+  /// std::is_nothrow_invocable_r
+  template<typename _Ret, typename _Fn, typename... _ArgTypes>
+    struct is_nothrow_invocable_r
+    : __and_<__is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>,
+             __call_is_nothrow_<_Fn, _ArgTypes...>>::type
     { };
 
-  /// std::is_callable_v
-  template<typename _Tp, typename _Ret = void>
-    constexpr bool is_callable_v = is_callable<_Tp, _Ret>::value;
+  /// std::is_invocable_v
+  template<typename _Fn, typename... _Args>
+    inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
 
-  /// std::is_nothrow_callable_v
-  template<typename _Tp, typename _Ret = void>
-    constexpr bool is_nothrow_callable_v
-      = is_nothrow_callable<_Tp, _Ret>::value;
-#endif // C++17
+  /// std::is_nothrow_invocable_v
+  template<typename _Fn, typename... _Args>
+    inline constexpr bool is_nothrow_invocable_v
+      = is_nothrow_invocable<_Fn, _Args...>::value;
 
+  /// std::is_invocable_r_v
+  template<typename _Fn, typename... _Args>
+    inline constexpr bool is_invocable_r_v
+      = is_invocable_r<_Fn, _Args...>::value;
+
+  /// std::is_nothrow_invocable_r_v
+  template<typename _Fn, typename... _Args>
+    inline constexpr bool is_nothrow_invocable_r_v
+      = is_nothrow_invocable_r<_Fn, _Args...>::value;
+#endif // C++17
 
 #if __cplusplus > 201402L
 # define __cpp_lib_type_trait_variable_templates 201510L
index 0cc50d03c4d0b5815e8c0de51438471e20b2a1a2..46d7b92adcfeb62decc12f38d9fd319e234f1b3e 100644 (file)
@@ -1236,7 +1236,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       size_t
       operator()(const variant<_Types...>& __t) const
-      noexcept((is_nothrow_callable_v<hash<decay_t<_Types>>(_Types)> && ...))
+      noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
       {
        if (!__t.valueless_by_exception())
          {
index 2536d229f64ef54073784685bbb11444b23782ac..823e9e0612c953a9621b149a278e1d964cc59b7e 100644 (file)
@@ -35,9 +35,3 @@ test01()
   std::invoke(&A::foo, refc, 100);             // const lvalue
   std::invoke(&A::foo, std::move(refc), 100);  // const rvalue
 }
-
-int
-main()
-{
-  test01();
-}
index 0311d013072673efbec0fe1fce8720d1ac868601..f3cae38ee9a34c917cf9dc9c759ce7329fd36c98 100644 (file)
@@ -103,7 +103,7 @@ test06()
   F f;
   auto notf = std::not_fn(f);
   using NotF = decltype(notf);
-  static_assert( std::is_callable<NotF()>::value, "cannot negate" );
+  static_assert( std::is_invocable<NotF>::value, "cannot negate" );
   static_assert( !noexcept(notf()), "conversion to bool affects noexcept" );
 }
 
@@ -117,7 +117,7 @@ test07()
   F f;
   auto notf = std::not_fn(f);
   using NotF = decltype(notf);
-  static_assert( !std::is_callable<NotF()>::value, "cannot negate" );
+  static_assert( !std::is_invocable<NotF>::value, "cannot negate" );
 }
 
 int
diff --git a/libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation.cc
deleted file mode 100644 (file)
index e1d6384..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// { dg-options "-std=gnu++17" }
-// { dg-do compile }
-
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// NB: This file is for testing type_traits with NO OTHER INCLUDES.
-
-#include <type_traits>
-
-namespace std
-{
-  struct test_type { };
-  template struct is_callable<test_type(), int>;
-}
diff --git a/libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation_ext.cc b/libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation_ext.cc
deleted file mode 100644 (file)
index b55ce7a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// { dg-do compile { target c++11 } }
-
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// NB: This file is for testing type_traits with NO OTHER INCLUDES.
-
-#include <type_traits>
-
-namespace std
-{
-  struct test_type { };
-  template struct __is_callable<test_type(), int>;
-}
diff --git a/libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs.cc
deleted file mode 100644 (file)
index c429f95..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// { dg-options "-std=gnu++17" }
-// { dg-do compile }
-
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// NB: This file is for testing type_traits with NO OTHER INCLUDES.
-
-#include <type_traits>
-
-void test01()
-{
-  // Check for required typedefs
-  typedef std::is_callable<int(), void>       test_type;
-  static_assert( std::is_base_of_v<std::false_type, test_type> );
-}
diff --git a/libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs_ext.cc b/libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs_ext.cc
deleted file mode 100644 (file)
index 09ba06e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// { dg-do compile { target c++11 } }
-
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// NB: This file is for testing type_traits with NO OTHER INCLUDES.
-
-#include <type_traits>
-
-void test01()
-{
-  // Check for required typedefs
-  typedef std::__is_callable<int(), void>     test_type;
-  static_assert( std::is_base_of<std::false_type, test_type>::value, "" );
-}
diff --git a/libstdc++-v3/testsuite/20_util/is_callable/value.cc b/libstdc++-v3/testsuite/20_util/is_callable/value.cc
deleted file mode 100644 (file)
index e0bb815..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// { dg-options "-std=gnu++17" }
-// { dg-do compile }
-
-#include <type_traits>
-
-#ifndef IS_CALLABLE_DEFINED
-template<typename T, typename R = void>
-  constexpr bool is_callable()
-  {
-    static_assert(std::is_callable<T, R>::value == std::is_callable_v<T, R>);
-    return std::is_callable_v<T, R>;
-  }
-#endif
-
-void test01()
-{
-  using func_type_v0 = void(*)();
-
-  static_assert(   is_callable< func_type_v0() >(),        "");
-  static_assert(   is_callable< func_type_v0(), void  >(),  "");
-  static_assert( ! is_callable< func_type_v0(), void* >(),  "");
-  static_assert( ! is_callable< func_type_v0(), int   >(),  "");
-
-  static_assert( ! is_callable< func_type_v0(int) >(),       "");
-  static_assert( ! is_callable< func_type_v0(int), void  >(), "");
-  static_assert( ! is_callable< func_type_v0(int), void* >(), "");
-  static_assert( ! is_callable< func_type_v0(int), int   >(), "");
-
-  using func_type_i0 = int(*)();
-
-  static_assert(   is_callable< func_type_i0() >(),      "");
-  static_assert(   is_callable< func_type_i0(), void >(), "");
-  static_assert(   is_callable< func_type_i0(), int  >(), "");
-  static_assert( ! is_callable< func_type_i0(), int& >(), "");
-  static_assert(   is_callable< func_type_i0(), long >(), "");
-
-  static_assert( ! is_callable< func_type_i0(int) >(),      "");
-  static_assert( ! is_callable< func_type_i0(int), void >(), "");
-  static_assert( ! is_callable< func_type_i0(int), int  >(), "");
-  static_assert( ! is_callable< func_type_i0(int), int& >(), "");
-  static_assert( ! is_callable< func_type_i0(int), long >(), "");
-
-  using func_type_l0 = int&(*)();
-
-  static_assert(   is_callable< func_type_l0() >(),        "");
-  static_assert(   is_callable< func_type_l0(), void >(),   "");
-  static_assert(   is_callable< func_type_l0(), int >(),    "");
-  static_assert(   is_callable< func_type_l0(), int& >(),   "");
-  static_assert( ! is_callable< func_type_l0(), int&& >(),  "");
-  static_assert(   is_callable< func_type_l0(), long >(),   "");
-  static_assert( ! is_callable< func_type_l0(), long& >(),  "");
-
-  static_assert( ! is_callable< func_type_l0(int) >(),       "");
-  static_assert( ! is_callable< func_type_l0(int), void >(),  "");
-  static_assert( ! is_callable< func_type_l0(int), int  >(),  "");
-  static_assert( ! is_callable< func_type_l0(int), int& >(),  "");
-  static_assert( ! is_callable< func_type_l0(int), long >(),  "");
-
-  using func_type_ii = int(*)(int);
-
-  static_assert( ! is_callable< func_type_ii() >(),      "");
-  static_assert( ! is_callable< func_type_ii(), int  >(), "");
-  static_assert( ! is_callable< func_type_ii(), int& >(), "");
-  static_assert( ! is_callable< func_type_ii(), long >(), "");
-
-  static_assert(   is_callable< func_type_ii(int) >(),       "");
-  static_assert(   is_callable< func_type_ii(int), int  >(),  "");
-  static_assert( ! is_callable< func_type_ii(int), int& >(),  "");
-  static_assert(   is_callable< func_type_ii(int), long >(),  "");
-
-  using func_type_il = int(*)(int&);
-
-  static_assert( ! is_callable< func_type_il() >(),      "");
-
-  static_assert( ! is_callable< func_type_il(int) >(),       "");
-  static_assert( ! is_callable< func_type_il(int), int  >(),  "");
-  static_assert( ! is_callable< func_type_il(int), int& >(),  "");
-  static_assert( ! is_callable< func_type_il(int), long >(),  "");
-
-  static_assert(   is_callable< func_type_il(int&) >(),              "");
-  static_assert(   is_callable< func_type_il(int&), int  >(), "");
-  static_assert( ! is_callable< func_type_il(int&), int& >(), "");
-  static_assert(   is_callable< func_type_il(int&), long >(), "");
-
-  using func_type_ir = int(*)(int&&);
-
-  static_assert( ! is_callable< func_type_ir() >(),      "");
-
-  static_assert(   is_callable< func_type_ir(int) >(),       "");
-  static_assert(   is_callable< func_type_ir(int), int  >(),  "");
-  static_assert( ! is_callable< func_type_ir(int), int& >(),  "");
-  static_assert(   is_callable< func_type_ir(int), long >(),  "");
-
-  static_assert( ! is_callable< func_type_ir(int&) >(),              "");
-  static_assert( ! is_callable< func_type_ir(int&), int  >(), "");
-  static_assert( ! is_callable< func_type_ir(int&), int& >(), "");
-  static_assert( ! is_callable< func_type_ir(int&), long >(), "");
-
-  struct X { };
-
-  using mem_type_i = int X::*;
-
-  static_assert( ! is_callable< mem_type_i() >(),        "");
-
-  static_assert( ! is_callable< mem_type_i(int) >(),       "");
-  static_assert( ! is_callable< mem_type_i(int), int  >(),  "");
-  static_assert( ! is_callable< mem_type_i(int), int& >(),  "");
-  static_assert( ! is_callable< mem_type_i(int), long >(),  "");
-
-  static_assert( ! is_callable< mem_type_i(int&) >(),      "");
-  static_assert( ! is_callable< mem_type_i(int&), int  >(), "");
-  static_assert( ! is_callable< mem_type_i(int&), int& >(), "");
-  static_assert( ! is_callable< mem_type_i(int&), long >(), "");
-
-  static_assert(   is_callable< mem_type_i(X&) >(),      "");
-  static_assert(   is_callable< mem_type_i(X&), int  >(), "");
-  static_assert(   is_callable< mem_type_i(X&), int& >(), "");
-  static_assert(   is_callable< mem_type_i(X&), long >(), "");
-
-  using memfun_type_i = int (X::*)();
-
-  static_assert( ! is_callable< memfun_type_i() >(),    "");
-
-  static_assert( ! is_callable< memfun_type_i(int) >(),         "");
-
-  static_assert( ! is_callable< memfun_type_i(int&) >(), "");
-
-  static_assert(   is_callable< memfun_type_i(X&) >(),       "");
-  static_assert(   is_callable< memfun_type_i(X&), int  >(),  "");
-  static_assert( ! is_callable< memfun_type_i(X&), int& >(),  "");
-  static_assert(   is_callable< memfun_type_i(X&), long >(),  "");
-  static_assert(   is_callable< memfun_type_i(X*) >(),       "");
-
-  static_assert( ! is_callable< memfun_type_i(const X&) >(),         "");
-  static_assert( ! is_callable< memfun_type_i(const X&), int  >(),  "");
-  static_assert( ! is_callable< memfun_type_i(X&, int) >(), "");
-
-  using memfun_type_iic = int& (X::*)(int&) const;
-
-  static_assert( ! is_callable< memfun_type_iic() >(),               "");
-  static_assert( ! is_callable< memfun_type_iic(int)  >(),           "");
-  static_assert( ! is_callable< memfun_type_iic(int&) >(),           "");
-  static_assert( ! is_callable< memfun_type_iic(X&, int) >(),        "");
-  static_assert( ! is_callable< memfun_type_iic(const X&, int) >(),  "");
-  static_assert( ! is_callable< memfun_type_iic(const X&, int&, int)  >(), "");
-
-  static_assert(   is_callable< memfun_type_iic(const X&, int&)  >(),     "");
-  static_assert(   is_callable< memfun_type_iic(const X&, int&), int  >(), "");
-  static_assert(   is_callable< memfun_type_iic(const X&, int&), int& >(), "");
-  static_assert(   is_callable< memfun_type_iic(const X&, int&), long >(), "");
-  static_assert( ! is_callable< memfun_type_iic(const X&, int&), long& >(),"");
-  static_assert(   is_callable< memfun_type_iic(const X*, int&)  >(),     "");
-
-  struct F {
-    int& operator()();
-    long& operator()() const;
-    short& operator()(int) &&;
-    char& operator()(int) const&;
-  private:
-    void operator()(int, int);
-  };
-  using CF = const F;
-
-  static_assert(   is_callable< F(),   int&   >(), "");
-  static_assert(   is_callable< F&(),  int&   >(), "");
-  static_assert(   is_callable< CF(),  long& >(), "");
-  static_assert(   is_callable< CF&(), long& >(), "");
-  static_assert(   is_callable< F(int),          short& >(), "");
-  static_assert(   is_callable< F&(int),  char& >(), "");
-  static_assert(   is_callable< CF(int),  char& >(), "");
-  static_assert(   is_callable< CF&(int), char& >(), "");
-
-  static_assert( ! is_callable< F(int, int) >(), "");
-}
diff --git a/libstdc++-v3/testsuite/20_util/is_callable/value_ext.cc b/libstdc++-v3/testsuite/20_util/is_callable/value_ext.cc
deleted file mode 100644 (file)
index f7c8be9..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// { dg-do compile { target c++11 } }
-
-#include <type_traits>
-
-template<typename T, typename R = void>
-  constexpr bool is_callable() { return std::__is_callable<T, R>::value; }
-
-#define IS_CALLABLE_DEFINED
-#include "value.cc"
diff --git a/libstdc++-v3/testsuite/20_util/is_invocable/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/is_invocable/requirements/explicit_instantiation.cc
new file mode 100644 (file)
index 0000000..da4d480
--- /dev/null
@@ -0,0 +1,30 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+namespace std
+{
+  struct test_type { };
+  template struct is_invocable<test_type>;
+  template struct is_invocable_r<int, test_type>;
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_invocable/requirements/explicit_instantiation_ext.cc b/libstdc++-v3/testsuite/20_util/is_invocable/requirements/explicit_instantiation_ext.cc
new file mode 100644 (file)
index 0000000..d91d765
--- /dev/null
@@ -0,0 +1,28 @@
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+namespace std
+{
+  struct test_type { };
+  template struct __is_invocable<test_type>;
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_invocable/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/is_invocable/requirements/typedefs.cc
new file mode 100644 (file)
index 0000000..9b42080
--- /dev/null
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+void test01()
+{
+  // Check for required typedefs
+  typedef std::is_invocable<int>       test_type;
+  static_assert( std::is_base_of_v<std::false_type, test_type> );
+}
+
+void test02()
+{
+  // Check for required typedefs
+  typedef std::is_invocable_r<void, int>       test_type;
+  static_assert( std::is_base_of_v<std::false_type, test_type> );
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_invocable/requirements/typedefs_ext.cc b/libstdc++-v3/testsuite/20_util/is_invocable/requirements/typedefs_ext.cc
new file mode 100644 (file)
index 0000000..10d4f9d
--- /dev/null
@@ -0,0 +1,29 @@
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+void test01()
+{
+  // Check for required typedefs
+  typedef std::__is_invocable<int>     test_type;
+  static_assert( std::is_base_of<std::false_type, test_type>::value, "" );
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_invocable/value.cc b/libstdc++-v3/testsuite/20_util/is_invocable/value.cc
new file mode 100644 (file)
index 0000000..adfa879
--- /dev/null
@@ -0,0 +1,200 @@
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+#include <type_traits>
+
+#ifndef IS_INVOCABLE_DEFINED
+template<typename... T>
+  constexpr bool is_invocable()
+  {
+    constexpr bool result = std::is_invocable_v<T...>;
+    static_assert(std::is_invocable<T...>::value == result);
+    return result;
+  }
+
+template<typename R, typename... T>
+  constexpr bool is_invocable_r()
+  {
+    constexpr bool result = std::is_invocable_r_v<R, T...>;
+    static_assert(std::is_invocable_r<R, T...>::value == result);
+    return result;
+  }
+#endif
+
+void test01()
+{
+  using func_type_v0 = void(*)();
+
+  static_assert(   is_invocable< func_type_v0 >(),         "");
+  static_assert(   is_invocable_r<void,  func_type_v0 >(),  "");
+  static_assert( ! is_invocable_r<void*, func_type_v0 >(),  "");
+  static_assert( ! is_invocable_r<int,   func_type_v0 >(),  "");
+
+  static_assert( ! is_invocable< func_type_v0, int >(),              "");
+  static_assert( ! is_invocable_r< void,  func_type_v0, int >(), "");
+  static_assert( ! is_invocable_r< void*, func_type_v0, int >(), "");
+  static_assert( ! is_invocable_r< int,   func_type_v0, int >(), "");
+
+  using func_type_i0 = int(*)();
+
+  static_assert(   is_invocable< func_type_i0 >(),       "");
+  static_assert(   is_invocable_r<void, func_type_i0 >(), "");
+  static_assert(   is_invocable_r<int,  func_type_i0 >(), "");
+  static_assert( ! is_invocable_r<int&, func_type_i0 >(), "");
+  static_assert(   is_invocable_r<long, func_type_i0 >(), "");
+
+  static_assert( ! is_invocable< func_type_i0, int >(),             "");
+  static_assert( ! is_invocable_r< void, func_type_i0, int >(), "");
+  static_assert( ! is_invocable_r< int,  func_type_i0, int >(), "");
+  static_assert( ! is_invocable_r< int&, func_type_i0, int >(), "");
+  static_assert( ! is_invocable_r< long, func_type_i0, int >(), "");
+
+  using func_type_l0 = int&(*)();
+
+  static_assert(   is_invocable< func_type_l0 >(),         "");
+  static_assert(   is_invocable_r< void,  func_type_l0 >(),   "");
+  static_assert(   is_invocable_r< int,   func_type_l0 >(),    "");
+  static_assert(   is_invocable_r< int&,  func_type_l0 >(),   "");
+  static_assert( ! is_invocable_r< int&&, func_type_l0 >(),  "");
+  static_assert(   is_invocable_r< long,  func_type_l0 >(),   "");
+  static_assert( ! is_invocable_r< long&, func_type_l0 >(),  "");
+
+  static_assert( ! is_invocable< func_type_l0(int) >(),              "");
+  static_assert( ! is_invocable_r< void, func_type_l0, int >(),  "");
+  static_assert( ! is_invocable_r< int,  func_type_l0, int >(),  "");
+  static_assert( ! is_invocable_r< int&, func_type_l0, int >(),  "");
+  static_assert( ! is_invocable_r< long, func_type_l0, int >(),  "");
+
+  using func_type_ii = int(*)(int);
+
+  static_assert( ! is_invocable< func_type_ii >(),       "");
+  static_assert( ! is_invocable_r< int,  func_type_ii >(), "");
+  static_assert( ! is_invocable_r< int&, func_type_ii >(), "");
+  static_assert( ! is_invocable_r< long, func_type_ii >(), "");
+
+  static_assert(   is_invocable< func_type_ii, int >(),              "");
+  static_assert(   is_invocable_r< int,  func_type_ii, int >(),  "");
+  static_assert( ! is_invocable_r< int&, func_type_ii, int >(),  "");
+  static_assert(   is_invocable_r< long, func_type_ii, int >(),  "");
+
+  using func_type_il = int(*)(int&);
+
+  static_assert( ! is_invocable< func_type_il >(),       "");
+
+  static_assert( ! is_invocable< func_type_il, int >(),              "");
+  static_assert( ! is_invocable_r< int,  func_type_il, int >(),  "");
+  static_assert( ! is_invocable_r< int&, func_type_il, int >(),  "");
+  static_assert( ! is_invocable_r< long, func_type_il, int >(),  "");
+
+  static_assert(   is_invocable< func_type_il, int& >(),             "");
+  static_assert(   is_invocable_r< int,  func_type_il, int& >(), "");
+  static_assert( ! is_invocable_r< int&, func_type_il, int& >(), "");
+  static_assert(   is_invocable_r< long, func_type_il, int& >(), "");
+
+  using func_type_ir = int(*)(int&&);
+
+  static_assert( ! is_invocable< func_type_ir >(),       "");
+
+  static_assert(   is_invocable< func_type_ir, int >(),              "");
+  static_assert(   is_invocable_r< int,  func_type_ir, int >(),  "");
+  static_assert( ! is_invocable_r< int&, func_type_ir, int >(),  "");
+  static_assert(   is_invocable_r< long, func_type_ir, int >(),  "");
+
+  static_assert( ! is_invocable< func_type_ir, int& >(),             "");
+  static_assert( ! is_invocable_r< int,  func_type_ir, int& >(), "");
+  static_assert( ! is_invocable_r< int&, func_type_ir, int& >(), "");
+  static_assert( ! is_invocable_r< long, func_type_ir, int& >(), "");
+
+  struct X { };
+
+  using mem_type_i = int X::*;
+
+  static_assert( ! is_invocable< mem_type_i >(),         "");
+
+  static_assert( ! is_invocable< mem_type_i, int >(),      "");
+  static_assert( ! is_invocable_r< int,  mem_type_i, int >(),  "");
+  static_assert( ! is_invocable_r< int&, mem_type_i, int >(),  "");
+  static_assert( ! is_invocable_r< long, mem_type_i, int >(),  "");
+
+  static_assert( ! is_invocable< mem_type_i, int& >(),     "");
+  static_assert( ! is_invocable_r< int,  mem_type_i, int& >(), "");
+  static_assert( ! is_invocable_r< int&, mem_type_i, int& >(), "");
+  static_assert( ! is_invocable_r< long, mem_type_i, int& >(), "");
+
+  static_assert(   is_invocable< mem_type_i, X& >(),     "");
+  static_assert(   is_invocable_r< int,  mem_type_i, X& >(), "");
+  static_assert(   is_invocable_r< int&, mem_type_i, X& >(), "");
+  static_assert(   is_invocable_r< long, mem_type_i, X& >(), "");
+
+  using memfun_type_i = int (X::*)();
+
+  static_assert( ! is_invocable< memfun_type_i >(),     "");
+
+  static_assert( ! is_invocable< memfun_type_i, int >(),        "");
+
+  static_assert( ! is_invocable< memfun_type_i, int& >(), "");
+
+  static_assert(   is_invocable< memfun_type_i, X& >(),              "");
+  static_assert(   is_invocable_r< int,  memfun_type_i, X& >(),  "");
+  static_assert( ! is_invocable_r< int&, memfun_type_i, X& >(),  "");
+  static_assert(   is_invocable_r< long, memfun_type_i, X& >(),  "");
+  static_assert(   is_invocable< memfun_type_i, X* >(),              "");
+
+  static_assert( ! is_invocable< memfun_type_i, const X& >(),        "");
+  static_assert( ! is_invocable_r< int,  memfun_type_i, const X& >(),  "");
+  static_assert( ! is_invocable< memfun_type_i, X&, int >(), "");
+
+  using memfun_type_iic = int& (X::*)(int&) const;
+
+  static_assert( ! is_invocable< memfun_type_iic >(),                "");
+  static_assert( ! is_invocable< memfun_type_iic, int  >(),          "");
+  static_assert( ! is_invocable< memfun_type_iic, int& >(),          "");
+  static_assert( ! is_invocable< memfun_type_iic, X&, int >(),       "");
+  static_assert( ! is_invocable< memfun_type_iic, const X&, int >(),  "");
+  static_assert( ! is_invocable< memfun_type_iic, const X&, int&, int  >(), "");
+
+  static_assert(   is_invocable< memfun_type_iic, const X&, int&  >(),    "");
+  static_assert(   is_invocable_r< int,  memfun_type_iic, const X&, int& >(), "");
+  static_assert(   is_invocable_r< int&, memfun_type_iic, const X&, int& >(), "");
+  static_assert(   is_invocable_r< long, memfun_type_iic, const X&, int& >(), "");
+  static_assert( ! is_invocable_r< long&, memfun_type_iic, const X&, int& >(),"");
+  static_assert(   is_invocable< memfun_type_iic, const X*, int&  >(),    "");
+
+  struct F {
+    int& operator()();
+    long& operator()() const;
+    short& operator()(int) &&;
+    char& operator()(int) const&;
+  private:
+    void operator()(int, int);
+  };
+  using CF = const F;
+
+  static_assert(   is_invocable_r< int&,   F        >(), "");
+  static_assert(   is_invocable_r< int&,   F&       >(), "");
+  static_assert(   is_invocable_r< long&,  CF       >(), "");
+  static_assert(   is_invocable_r< long&,  CF&      >(), "");
+  static_assert(   is_invocable_r< short&, F,   int >(), "");
+  static_assert(   is_invocable_r< char&,  F&,  int >(), "");
+  static_assert(   is_invocable_r< char&,  CF,  int >(), "");
+  static_assert(   is_invocable_r< char&,  CF&, int >(), "");
+
+  static_assert( ! is_invocable< F, int, int >(), "");
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_invocable/value_ext.cc b/libstdc++-v3/testsuite/20_util/is_invocable/value_ext.cc
new file mode 100644 (file)
index 0000000..d167cfa
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <type_traits>
+
+template<typename... T>
+  constexpr bool is_invocable() { return std::__is_invocable<T...>::value; }
+
+template<typename R, typename... T>
+  constexpr bool is_invocable_conv(std::true_type)
+  {
+    using result_type = typename std::__invoke_result<T...>::type;
+    return std::is_void<R>::value || std::is_convertible<result_type, R>::value;
+  }
+
+template<typename R, typename... T>
+  constexpr bool is_invocable_conv(std::false_type) { return false; }
+
+template<typename R, typename... T>
+  constexpr bool is_invocable_r()
+  { return is_invocable_conv<R, T...>(std::__is_invocable<T...>{}); }
+
+#define IS_INVOCABLE_DEFINED
+#include "value.cc"
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation.cc
deleted file mode 100644 (file)
index 996b7d8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// { dg-options "-std=gnu++17" }
-// { dg-do compile }
-
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// NB: This file is for testing type_traits with NO OTHER INCLUDES.
-
-#include <type_traits>
-
-namespace std
-{
-  struct test_type { };
-  template struct is_nothrow_callable<test_type(), int>;
-}
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation_ext.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation_ext.cc
deleted file mode 100644 (file)
index 0243f28..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// { dg-do compile { target c++11 } }
-
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// NB: This file is for testing type_traits with NO OTHER INCLUDES.
-
-#include <type_traits>
-
-namespace std
-{
-  struct test_type { };
-  template struct __is_nothrow_callable<test_type(), int>;
-}
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs.cc
deleted file mode 100644 (file)
index 35ffdbb..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// { dg-options "-std=gnu++17" }
-// { dg-do compile }
-
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// NB: This file is for testing type_traits with NO OTHER INCLUDES.
-
-#include <type_traits>
-
-void test01()
-{
-  // Check for required typedefs
-  typedef std::is_nothrow_callable<int(), void>       test_type;
-  static_assert( std::is_base_of_v<std::false_type, test_type> );
-}
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs_ext.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs_ext.cc
deleted file mode 100644 (file)
index 9ba091d..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// { dg-do compile { target c++11 } }
-
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// NB: This file is for testing type_traits with NO OTHER INCLUDES.
-
-#include <type_traits>
-
-void test01()
-{
-  // Check for required typedefs
-  typedef std::__is_nothrow_callable<int(), void>     test_type;
-  static_assert( std::is_base_of<std::false_type, test_type>::value, "" );
-}
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/value.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/value.cc
deleted file mode 100644 (file)
index 16b55da..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// { dg-options "-std=gnu++17" }
-// { dg-do compile }
-
-#include <type_traits>
-
-#ifndef IS_NT_CALLABLE_DEFINED
-template<typename T, typename R = void>
-  constexpr bool is_nt_callable()
-  {
-    static_assert(std::is_nothrow_callable<T, R>::value
-                  == std::is_nothrow_callable_v<T, R>);
-    return std::is_nothrow_callable_v<T, R>;
-  }
-#endif
-
-void test01()
-{
-  using func_type = void(*)();
-  static_assert( ! is_nt_callable< func_type() >(),     "");
-
-#if __cpp_noexcept_function_type
-  using func_type_nt = void(*)() noexcept;
-  static_assert(   is_nt_callable< func_type_nt() >(),  "");
-#endif
-
-  struct X { };
-  using mem_type = int X::*;
-
-  static_assert( ! is_nt_callable< mem_type() >(),     "");
-  static_assert( ! is_nt_callable< mem_type(int) >(),   "");
-  static_assert( ! is_nt_callable< mem_type(int&) >(), "");
-
-  static_assert(   is_nt_callable< mem_type(X&) >(),       "");
-  static_assert(   is_nt_callable< mem_type(X&), int  >(), "");
-  static_assert(   is_nt_callable< mem_type(X&), int& >(), "");
-  static_assert(   is_nt_callable< mem_type(X&), long >(), "");
-  static_assert(   is_nt_callable< mem_type(X*), int& >(), "");
-
-  using memfun_type = int (X::*)();
-
-  static_assert( ! is_nt_callable< memfun_type() >(),     "");
-  static_assert( ! is_nt_callable< memfun_type(int) >(),  "");
-  static_assert( ! is_nt_callable< memfun_type(int&) >(), "");
-  static_assert( ! is_nt_callable< memfun_type(X&) >(),   "");
-  static_assert( ! is_nt_callable< memfun_type(X*) >(),   "");
-
-#if __cpp_noexcept_function_type
-  using memfun_type_nt = int (X::*)() noexcept;
-
-  static_assert( ! is_nt_callable< memfun_type_nt() >(),           "");
-  static_assert( ! is_nt_callable< memfun_type_nt(int) >(),  "");
-  static_assert( ! is_nt_callable< memfun_type_nt(int&) >(), "");
-  static_assert(   is_nt_callable< memfun_type_nt(X&) >(),   "");
-  static_assert(   is_nt_callable< memfun_type_nt(X*) >(),   "");
-#endif
-
-  struct F {
-    int& operator()();
-    long& operator()() const noexcept;
-    short& operator()(int) &&;
-    char& operator()(int) const& noexcept;
-  private:
-    void operator()(int, int) noexcept;
-  };
-  using CF = const F;
-
-  static_assert( ! is_nt_callable< F(),   int&   >(), "");
-  static_assert(   is_nt_callable< CF(),  long& >(),  "");
-  static_assert( ! is_nt_callable< F(int),    short& >(), "");
-  static_assert(   is_nt_callable< F&(int),   char& >(),  "");
-  static_assert(   is_nt_callable< CF(int),   char& >(),  "");
-  static_assert(   is_nt_callable< CF&(int),  char& >(),  "");
-
-  static_assert( ! is_nt_callable< F(int, int) >(), "");
-}
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/value_ext.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/value_ext.cc
deleted file mode 100644 (file)
index 987e52b..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (C) 2016-2017 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// { dg-do compile { target c++11 } }
-
-#include <type_traits>
-
-template<typename T, typename R = void>
-  constexpr bool is_nt_callable()
-  { return std::__is_nothrow_callable<T, R>::value; }
-
-#define IS_NT_CALLABLE_DEFINED
-#include "value.cc"
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/explicit_instantiation.cc
new file mode 100644 (file)
index 0000000..0232698
--- /dev/null
@@ -0,0 +1,30 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+namespace std
+{
+  struct test_type { };
+  template struct is_nothrow_invocable<test_type>;
+  template struct is_nothrow_invocable_r<int, test_type>;
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/explicit_instantiation_ext.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/explicit_instantiation_ext.cc
new file mode 100644 (file)
index 0000000..f9afed6
--- /dev/null
@@ -0,0 +1,28 @@
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+namespace std
+{
+  struct test_type { };
+  template struct __is_nothrow_invocable<test_type>;
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/typedefs.cc
new file mode 100644 (file)
index 0000000..3b31675
--- /dev/null
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+void test01()
+{
+  // Check for required typedefs
+  typedef std::is_nothrow_invocable<int>       test_type;
+  static_assert( std::is_base_of_v<std::false_type, test_type> );
+}
+
+void test02()
+{
+  // Check for required typedefs
+  typedef std::is_nothrow_invocable_r<void, int>       test_type;
+  static_assert( std::is_base_of_v<std::false_type, test_type> );
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/typedefs_ext.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/typedefs_ext.cc
new file mode 100644 (file)
index 0000000..db2ad61
--- /dev/null
@@ -0,0 +1,29 @@
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+void test01()
+{
+  // Check for required typedefs
+  typedef std::__is_nothrow_invocable<int>     test_type;
+  static_assert( std::is_base_of<std::false_type, test_type>::value, "" );
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/value.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/value.cc
new file mode 100644 (file)
index 0000000..4ccb459
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+#include <type_traits>
+
+#ifndef IS_NT_INVOCABLE_DEFINED
+template<typename... T>
+  constexpr bool is_nt_invocable()
+  {
+    constexpr bool result = std::is_nothrow_invocable_v<T...>;
+    static_assert(std::is_nothrow_invocable<T...>::value == result);
+    return result;
+  }
+
+template<typename R, typename... T>
+  constexpr bool is_nt_invocable_r()
+  {
+    constexpr bool result = std::is_nothrow_invocable_r_v<R, T...>;
+    static_assert(std::is_nothrow_invocable_r<R, T...>::value == result);
+    return result;
+  }
+#endif
+
+void test01()
+{
+  using func_type = void(*)();
+  static_assert( ! is_nt_invocable< func_type>(),     "");
+
+#if __cpp_noexcept_function_type
+  using func_type_nt = void(*)() noexcept;
+  static_assert(   is_nt_invocable< func_type_nt >(),  "");
+#endif
+
+  struct X { };
+  using mem_type = int X::*;
+
+  static_assert( ! is_nt_invocable< mem_type >(),      "");
+  static_assert( ! is_nt_invocable< mem_type, int >(),   "");
+  static_assert( ! is_nt_invocable< mem_type, int& >(),        "");
+
+  static_assert(   is_nt_invocable< mem_type, X& >(),       "");
+  static_assert(   is_nt_invocable_r< int,  mem_type, X& >(), "");
+  static_assert(   is_nt_invocable_r< int&, mem_type, X& >(), "");
+  static_assert(   is_nt_invocable_r< long, mem_type, X& >(), "");
+  static_assert(   is_nt_invocable_r< int&, mem_type, X* >(), "");
+
+  using memfun_type = int (X::*)();
+
+  static_assert( ! is_nt_invocable< memfun_type >(),     "");
+  static_assert( ! is_nt_invocable< memfun_type, int >(),  "");
+  static_assert( ! is_nt_invocable< memfun_type, int& >(), "");
+  static_assert( ! is_nt_invocable< memfun_type, X& >(),   "");
+  static_assert( ! is_nt_invocable< memfun_type, X* >(),   "");
+
+#if __cpp_noexcept_function_type
+  using memfun_type_nt = int (X::*)() noexcept;
+
+  static_assert( ! is_nt_invocable< memfun_type_nt >(),            "");
+  static_assert( ! is_nt_invocable< memfun_type_nt, int >(),  "");
+  static_assert( ! is_nt_invocable< memfun_type_nt, int& >(), "");
+  static_assert(   is_nt_invocable< memfun_type_nt, X& >(),   "");
+  static_assert(   is_nt_invocable< memfun_type_nt, X* >(),   "");
+#endif
+
+  struct F {
+    int& operator()();
+    long& operator()() const noexcept;
+    short& operator()(int) &&;
+    char& operator()(int) const& noexcept;
+  private:
+    void operator()(int, int) noexcept;
+  };
+  using CF = const F;
+
+  static_assert( ! is_nt_invocable_r< int&,  F  >(), "");
+  static_assert(   is_nt_invocable_r< long&, CF >(),  "");
+  static_assert( ! is_nt_invocable_r< short&, F,   int >(), "" );
+  static_assert(   is_nt_invocable_r< char&,  F&,  int >(), "" );
+  static_assert(   is_nt_invocable_r< char&,  CF,  int >(), "" );
+  static_assert(   is_nt_invocable_r< char&,  CF&, int >(), "" );
+
+  static_assert( ! is_nt_invocable< F, int, int >(), "");
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/value_ext.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/value_ext.cc
new file mode 100644 (file)
index 0000000..7217324
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright (C) 2016-2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <type_traits>
+
+template<typename... T>
+  constexpr bool is_nt_invocable()
+  { return std::__is_nothrow_invocable<T...>::value; }
+
+  template<typename R, typename... T>
+  constexpr bool is_nt_invocable_conv(std::true_type)
+  {
+    using result_type = typename std::__invoke_result<T...>::type;
+    return std::is_void<R>::value || std::is_convertible<result_type, R>::value;
+  }
+
+template<typename R, typename... T>
+  constexpr bool is_nt_invocable_conv(std::false_type) { return false; }
+
+template<typename R, typename... T>
+  constexpr bool is_nt_invocable_r()
+  {
+    return is_nt_invocable_conv<R, T...>(std::__is_nothrow_invocable<T...>{});
+  }
+
+#define IS_NT_INVOCABLE_DEFINED
+#include "value.cc"
index 297ea2e276b633c21264ce46136658f3aebc758c..c16f0b20fb263e1d15ca3fdb3b7ae7a8dd19417f 100644 (file)
@@ -29,12 +29,10 @@ template<class T>
 auto f(...) -> decltype(std::false_type());
 
 static_assert(!decltype(f<S>(0))::value, "");
-static_assert(!std::is_callable<
-             std::hash<std::optional<S>>&
-             (std::optional<S> const&)>::value, "");
-static_assert(std::is_callable<
-             std::hash<std::optional<int>>&
-             (std::optional<int> const&)>::value, "");
+static_assert(!std::is_invocable_v<
+    std::hash<std::optional<S>>&, std::optional<S> const&> );
+static_assert(std::is_invocable_v<
+    std::hash<std::optional<int>>&, std::optional<int> const&> );
 
 int main()
 {
index 0a267ab68e4a72ff0e2d39e68d35ff6615ff11e7..d747e104d69f33974bbb869d806261d3bb03a2aa 100644 (file)
@@ -33,17 +33,14 @@ static_assert(!decltype(f<std::variant<S>>(0))::value, "");
 static_assert(!decltype(f<std::variant<S, S>>(0))::value, "");
 static_assert(decltype(f<std::variant<int>>(0))::value, "");
 static_assert(decltype(f<std::variant<int, int>>(0))::value, "");
-static_assert(!std::is_callable<
-             std::hash<std::variant<S>>&(std::variant<S> const&)>::value, "");
-static_assert(!std::is_callable<
-             std::hash<std::variant<S, int>>&
-             (std::variant<S, int> const&)>::value, "");
-static_assert(std::is_callable<
-             std::hash<std::variant<int>>&
-             (std::variant<int> const&)>::value, "");
-static_assert(std::is_callable<
-             std::hash<std::variant<int, int>>&
-             (std::variant<int, int> const&)>::value, "");
+static_assert(!std::is_invocable_v<
+    std::hash<std::variant<S>>&, std::variant<S> const&> );
+static_assert(!std::is_invocable_v<
+    std::hash<std::variant<S, int>>&, std::variant<S, int> const&> );
+static_assert(std::is_invocable_v<
+    std::hash<std::variant<int>>&, std::variant<int> const&> );
+static_assert(std::is_invocable_v<
+    std::hash<std::variant<int, int>>&, std::variant<int, int> const&> );
 
 int main()
 {