diff mbox

P0604R0 add invoke_result, is_invocable etc. for C++17

Message ID 20170309215243.GM3501@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely March 9, 2017, 9:52 p.m. UTC
At the WG21 meeting last week we approved P0604R0 which replaces the
error-prone result_of<F(Args...)> and is_callable<F(Args...) R> APIs
with invoke_result<F, Args...> and is_invocable<F, Args...> and
is_invocable_r<R, F, Args...>. Only result_of exists in previous
standards, the rest are new for C++17.

This patch replaces the is_callable family with the new is_invocable
ones, replaces our internal __is_callable with __is_invocable (so it
can be used in C++11 mode) and also adds __invoke_result.

Most of the patch changes C++17 stuff and tests. The parts that affect
C++11 and C++14 are mostly trivial. The new invoke_result trait
revealed that there were no partial specializations of
__result_of_memobj and __result_of_memfun for const reference_wrapper
prvalues. Rather than add them I realised we already use __inv_unwrap
elsewhere, and doing so here makes the partial specializations
unnecessary.

	* 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.

Tested powerpc64le-linux, I plan to commit this to trunk tomorrow.
commit 486ce6d3a528eb8afa446774a2ade95c7894b374
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Mar 9 21:10:09 2017 +0000

    P0604R0 add invoke_result, is_invocable etc. for C++17
    
    	* 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.
diff mbox

Patch

diff --git a/libstdc++-v3/include/bits/invoke.h b/libstdc++-v3/include/bits/invoke.h
index 56d9afb..eba8707 100644
--- a/libstdc++-v3/include/bits/invoke.h
+++ b/libstdc++-v3/include/bits/invoke.h
@@ -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)...);
     }
diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h
index 770a094..a203f42 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -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);
 	}
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index 366a7fb..ae5bc0a 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -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>())
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 76865f4..7d067ca 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -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&>
-    { };
+  // 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>
-    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...>
-    { };
-
-  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 _Fn, typename... _Args>
+    using __call_is_nothrow_
+      = __call_is_nothrow<__invoke_result<_Fn, _Args...>, _Fn, _Args...>;
 
-  template<typename, typename _Ret = void>
-    struct __is_nothrow_callable; // not defined
-
-  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,37 +2823,64 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   };
 
 #if __cplusplus > 201402L
-# define __cpp_lib_is_callable 201603
+# define __cpp_lib_is_invocable 201703
 
-  /// std::is_callable
-  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<_Fn(_ArgTypes...), _Ret>::type
+  /// std::invoke_result
+  template<typename _Functor, typename... _ArgTypes>
+    struct invoke_result
+    : public __invoke_result<_Functor, _ArgTypes...>
     { };
 
-  /// std::is_nothrow_callable
-  template<typename, typename _Ret = void>
-    struct is_nothrow_callable; // not defined
+  /// std::invoke_result_t
+  template<typename _Fn, typename... _Args>
+    using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
 
-  template<typename _Fn, typename... _ArgTypes, typename _Ret>
-    struct is_nothrow_callable<_Fn(_ArgTypes...), _Ret>
-    : __is_nothrow_callable<_Fn(_ArgTypes...), _Ret>::type
+  /// std::is_invocable
+  template<typename _Fn, typename... _ArgTypes>
+    struct is_invocable
+    : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
     { };
 
-  /// std::is_callable_v
-  template<typename _Tp, typename _Ret = void>
-    constexpr bool is_callable_v = is_callable<_Tp, _Ret>::value;
+  /// 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_v
-  template<typename _Tp, typename _Ret = void>
-    constexpr bool is_nothrow_callable_v
-      = is_nothrow_callable<_Tp, _Ret>::value;
+  /// 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
+    { };
+
+  /// 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_invocable_v
+  template<typename _Fn, typename... _Args>
+    inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
+
+  /// 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
 template <typename _Tp>
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 0cc50d0..46d7b92 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -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())
 	  {
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/invoke/59768.cc b/libstdc++-v3/testsuite/20_util/function_objects/invoke/59768.cc
index 2536d22..823e9e0 100644
--- a/libstdc++-v3/testsuite/20_util/function_objects/invoke/59768.cc
+++ b/libstdc++-v3/testsuite/20_util/function_objects/invoke/59768.cc
@@ -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();
-}
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/not_fn/1.cc b/libstdc++-v3/testsuite/20_util/function_objects/not_fn/1.cc
index 0311d01..f3cae38 100644
--- a/libstdc++-v3/testsuite/20_util/function_objects/not_fn/1.cc
+++ b/libstdc++-v3/testsuite/20_util/function_objects/not_fn/1.cc
@@ -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
index e1d6384..0000000
--- a/libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation.cc
+++ /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
index b55ce7a..0000000
--- a/libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation_ext.cc
+++ /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
index c429f95..0000000
--- a/libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs.cc
+++ /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
index 09ba06e..0000000
--- a/libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs_ext.cc
+++ /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
index e0bb815..0000000
--- a/libstdc++-v3/testsuite/20_util/is_callable/value.cc
+++ /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
index f7c8be9..0000000
--- a/libstdc++-v3/testsuite/20_util/is_callable/value_ext.cc
+++ /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
index 0000000..da4d480
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_invocable/requirements/explicit_instantiation.cc
@@ -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
index 0000000..d91d765
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_invocable/requirements/explicit_instantiation_ext.cc
@@ -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
index 0000000..9b42080
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_invocable/requirements/typedefs.cc
@@ -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
index 0000000..10d4f9d
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_invocable/requirements/typedefs_ext.cc
@@ -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
index 0000000..adfa879
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_invocable/value.cc
@@ -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
index 0000000..d167cfa
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_invocable/value_ext.cc
@@ -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
index 996b7d8..0000000
--- a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation.cc
+++ /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
index 0243f28..0000000
--- a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation_ext.cc
+++ /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
index 35ffdbb..0000000
--- a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs.cc
+++ /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
index 9ba091d..0000000
--- a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs_ext.cc
+++ /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
index 16b55da..0000000
--- a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/value.cc
+++ /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
index 987e52b..0000000
--- a/libstdc++-v3/testsuite/20_util/is_nothrow_callable/value_ext.cc
+++ /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
index 0000000..0232698
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/explicit_instantiation.cc
@@ -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
index 0000000..f9afed6
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/explicit_instantiation_ext.cc
@@ -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
index 0000000..3b31675
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/typedefs.cc
@@ -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
index 0000000..db2ad61
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/requirements/typedefs_ext.cc
@@ -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
index 0000000..4ccb459
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/value.cc
@@ -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
index 0000000..7217324
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/value_ext.cc
@@ -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"
diff --git a/libstdc++-v3/testsuite/20_util/optional/hash.cc b/libstdc++-v3/testsuite/20_util/optional/hash.cc
index 297ea2e..c16f0b2 100644
--- a/libstdc++-v3/testsuite/20_util/optional/hash.cc
+++ b/libstdc++-v3/testsuite/20_util/optional/hash.cc
@@ -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()
 {
diff --git a/libstdc++-v3/testsuite/20_util/variant/hash.cc b/libstdc++-v3/testsuite/20_util/variant/hash.cc
index 0a267ab..d747e10 100644
--- a/libstdc++-v3/testsuite/20_util/variant/hash.cc
+++ b/libstdc++-v3/testsuite/20_util/variant/hash.cc
@@ -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()
 {