Two new traits for C++17, as well as identical __is__callable and __is_nothrow_callable traits defined for C++11 mode (so I can use the latter to add an exception specification to std::__invoke).
* doc/xml/manual/status_cxx2017.xml: Update status table. * include/std/functional (__inv_unwrap): Move to <type_traits>. (__invoke_impl): Remove exception specifications. (__invoke, invoke): Add exception specifications using __is_nothrow_callable. * include/std/type_traits (__inv_unwrap): Move from <functional>. (__is_callable_impl, __call_is_nt, __call_is_nothrow): New helpers. (__is_callable, __is_nothrow_callable): New traits. (is_callable, is_callable_v): New C++17 traits. (is_nothrow_callable, is_nothrow_callable_v): Likewise. * testsuite/20_util/is_callable/requirements/ explicit_instantiation.cc: New test. * testsuite/20_util/is_callable/requirements/ explicit_instantiation_ext.cc: New test. * testsuite/20_util/is_callable/requirements/typedefs.cc: New test. * testsuite/20_util/is_callable/requirements/typedefs_ext.cc: New test. * testsuite/20_util/is_callable/value.cc: New test. * testsuite/20_util/is_callable/value_ext.cc: New test. * testsuite/20_util/is_nothrow_callable/requirements/ explicit_instantiation.cc: New test. * testsuite/20_util/is_nothrow_callable/requirements/ explicit_instantiation_ext.cc: New test. * testsuite/20_util/is_nothrow_callable/requirements/typedefs.cc: New test. * testsuite/20_util/is_nothrow_callable/requirements/typedefs_ext.cc: New test. * testsuite/20_util/is_nothrow_callable/value.cc: New test. * testsuite/20_util/is_nothrow_callable/value_ext.cc: New test. Tested x86_64-linux, committed to trunk.
commit 8f42033a7c8f66b5a8abd05758f176e3cb3c2933 Author: Jonathan Wakely <jwak...@redhat.com> Date: Thu Aug 4 01:48:56 2016 +0100 Define std::is_callable and std::is_nothrow_callable * doc/xml/manual/status_cxx2017.xml: Update status table. * include/std/functional (__inv_unwrap): Move to <type_traits>. (__invoke_impl): Remove exception specifications. (__invoke, invoke): Add exception specifications using __is_nothrow_callable. * include/std/type_traits (__inv_unwrap): Move from <functional>. (__is_callable_impl, __call_is_nt, __call_is_nothrow): New helpers. (__is_callable, __is_nothrow_callable): New traits. (is_callable, is_callable_v): New C++17 traits. (is_nothrow_callable, is_nothrow_callable_v): Likewise. * testsuite/20_util/is_callable/requirements/ explicit_instantiation.cc: New test. * testsuite/20_util/is_callable/requirements/ explicit_instantiation_ext.cc: New test. * testsuite/20_util/is_callable/requirements/typedefs.cc: New test. * testsuite/20_util/is_callable/requirements/typedefs_ext.cc: New test. * testsuite/20_util/is_callable/value.cc: New test. * testsuite/20_util/is_callable/value_ext.cc: New test. * testsuite/20_util/is_nothrow_callable/requirements/ explicit_instantiation.cc: New test. * testsuite/20_util/is_nothrow_callable/requirements/ explicit_instantiation_ext.cc: New test. * testsuite/20_util/is_nothrow_callable/requirements/typedefs.cc: New test. * testsuite/20_util/is_nothrow_callable/requirements/typedefs_ext.cc: New test. * testsuite/20_util/is_nothrow_callable/value.cc: New test. * testsuite/20_util/is_nothrow_callable/value_ext.cc: New test. diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml index d32399d..8391758 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml @@ -402,14 +402,13 @@ Feature-testing recommendations for C++</link>. </row> <row> - <?dbhtml bgcolor="#C8B0B0" ?> <entry> <code>is_callable</code>, the missing INVOKE related trait</entry> <entry> <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0077r2.html"> P0077R2 </link> </entry> - <entry align="center"> No </entry> + <entry align="center"> 7 </entry> <entry><code> __cpp_lib_is_callable >= 201603 </code></entry> </row> diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index d635ef5..843dc83 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -184,18 +184,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _Weak_result_type_impl<typename remove_cv<_Functor>::type> { }; - 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&; - }; - // Used by __invoke_impl instead of std::forward<_Tp> so that a // reference_wrapper is converted to an lvalue-reference. template<typename _Tp, typename _Up = typename __inv_unwrap<_Tp>::type> @@ -206,23 +194,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Res, typename _Fn, typename... _Args> inline _Res __invoke_impl(__invoke_other, _Fn&& __f, _Args&&... __args) - noexcept(noexcept(std::forward<_Fn>(__f)(std::forward<_Args>(__args)...))) { return std::forward<_Fn>(__f)(std::forward<_Args>(__args)...); } template<typename _Res, typename _MemFun, typename _Tp, typename... _Args> inline _Res __invoke_impl(__invoke_memfun_ref, _MemFun&& __f, _Tp&& __t, _Args&&... __args) - noexcept(noexcept( - (__invfwd<_Tp>(__t).*__f)(std::forward<_Args>(__args)...))) { return (__invfwd<_Tp>(__t).*__f)(std::forward<_Args>(__args)...); } template<typename _Res, typename _MemFun, typename _Tp, typename... _Args> inline _Res __invoke_impl(__invoke_memfun_deref, _MemFun&& __f, _Tp&& __t, _Args&&... __args) - noexcept(noexcept( - ((*std::forward<_Tp>(__t)).*__f)(std::forward<_Args>(__args)...))) { return ((*std::forward<_Tp>(__t)).*__f)(std::forward<_Args>(__args)...); } @@ -230,19 +213,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Res, typename _MemPtr, typename _Tp> inline _Res __invoke_impl(__invoke_memobj_ref, _MemPtr&& __f, _Tp&& __t) - noexcept(noexcept(__invfwd<_Tp>(__t).*__f)) { return __invfwd<_Tp>(__t).*__f; } template<typename _Res, typename _MemPtr, typename _Tp> inline _Res __invoke_impl(__invoke_memobj_deref, _MemPtr&& __f, _Tp&& __t) - noexcept(noexcept((*std::forward<_Tp>(__t)).*__f)) { return (*std::forward<_Tp>(__t)).*__f; } /// Invoke a callable object. template<typename _Callable, typename... _Args> inline typename result_of<_Callable&&(_Args&&...)>::type __invoke(_Callable&& __fn, _Args&&... __args) + noexcept(__is_nothrow_callable<_Callable(_Args...)>::value) { using __result_of = result_of<_Callable&&(_Args&&...)>; using __type = typename __result_of::type; @@ -258,6 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Callable, typename... _Args> inline result_of_t<_Callable&&(_Args&&...)> invoke(_Callable&& __fn, _Args&&... __args) + noexcept(is_nothrow_callable_v<_Callable(_Args...)>) { return std::__invoke(std::forward<_Callable>(__fn), std::forward<_Args>(__args)...); diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 693952a..baa4d1f 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -176,11 +176,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename... _Bn> constexpr bool conjunction_v = conjunction<_Bn...>::value; - + template<typename... _Bn> constexpr bool disjunction_v = disjunction<_Bn...>::value; - + template<typename _Pp> constexpr bool negation_v = negation<_Pp>::value; @@ -2762,6 +2762,121 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION is_nothrow_swappable_with<_Tp, _Up>::value; #endif // __cplusplus >= 201402L +#endif// c++1z or gnu++11 + + // __is_callable (std::is_callable for C++11) + + template<typename _Result, typename _Ret, typename = __void_t<>> + struct __is_callable_impl : false_type { }; + + template<typename _Result, typename _Ret> + struct __is_callable_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 + { }; + + // 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) + { + using _Up = typename __inv_unwrap<_Tp>::type; + return noexcept((std::declval<_Up>().*std::declval<_Fn>())( + std::declval<_Args>()...)); + } + + template<typename _Fn, typename _Tp, typename... _Args> + constexpr bool __call_is_nt(__invoke_memfun_deref) + { + return noexcept(((*std::declval<_Tp>()).*std::declval<_Fn>())( + std::declval<_Args>()...)); + } + + template<typename _Fn, typename _Tp> + constexpr bool __call_is_nt(__invoke_memobj_ref) + { + using _Up = typename __inv_unwrap<_Tp>::type; + return noexcept(std::declval<_Up>().*std::declval<_Fn>()); + } + + template<typename _Fn, typename _Tp> + constexpr bool __call_is_nt(__invoke_memobj_deref) + { + return noexcept((*std::declval<_Tp>()).*std::declval<_Fn>()); + } + + template<typename _Fn, typename... _Args> + constexpr bool __call_is_nt(__invoke_other) + { + return noexcept(std::declval<_Fn>()(std::declval<_Args>()...)); + } + + template<typename _ResultOf, typename _Fn, typename... _Args> + struct __call_is_nothrow + : __bool_constant< + std::__call_is_nt<_Fn, _Args...>(typename _ResultOf::__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, 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 + { }; + +#if __cplusplus > 201402L +# define __cpp_lib_is_callable 201603 + + /// 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::is_nothrow_callable + template<typename, typename _Ret = void> + struct is_nothrow_callable; // not defined + + template<typename _Fn, typename... _ArgTypes, typename _Ret> + struct is_nothrow_callable<_Fn(_ArgTypes...), _Ret> + : __is_nothrow_callable<_Fn(_ArgTypes...), _Ret>::type + { }; + + /// std::is_callable_v + template<typename T, typename _Ret = void> + constexpr bool is_callable_v = is_callable<T, _Ret>::value; + + /// std::is_nothrow_callable_v + template<typename T, typename _Ret = void> + constexpr bool is_nothrow_callable_v = is_nothrow_callable<T, _Ret>::value; +#endif // C++17 + + #if __cplusplus > 201402L # define __cpp_lib_type_trait_variable_templates 201510L template <typename _Tp> @@ -2915,7 +3030,6 @@ template <typename _Base, typename _Derived> template <typename _From, typename _To> constexpr bool is_convertible_v = is_convertible<_From, _To>::value; #endif // C++17 -#endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std 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 new file mode 100644 index 0000000..0ce5bfe --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation.cc @@ -0,0 +1,29 @@ +// { dg-options "-std=gnu++17" } +// { dg-do compile } + +// Copyright (C) 2016 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 new file mode 100644 index 0000000..a3d3f49 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation_ext.cc @@ -0,0 +1,28 @@ +// { dg-do compile { target c++11 } } + +// Copyright (C) 2016 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 new file mode 100644 index 0000000..9f21dfb --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs.cc @@ -0,0 +1,30 @@ +// { dg-options "-std=gnu++17" } +// { dg-do compile } + +// Copyright (C) 2016 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 new file mode 100644 index 0000000..e582be0 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs_ext.cc @@ -0,0 +1,29 @@ +// { dg-do compile { target c++11 } } + +// Copyright (C) 2016 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 new file mode 100644 index 0000000..aafd55f --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_callable/value.cc @@ -0,0 +1,191 @@ +// Copyright (C) 2016 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 new file mode 100644 index 0000000..3884d6c --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_callable/value_ext.cc @@ -0,0 +1,26 @@ +// Copyright (C) 2016 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_nothrow_callable/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation.cc new file mode 100644 index 0000000..dbcdd9f --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation.cc @@ -0,0 +1,29 @@ +// { dg-options "-std=gnu++17" } +// { dg-do compile } + +// Copyright (C) 2016 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 new file mode 100644 index 0000000..9e4f74f --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation_ext.cc @@ -0,0 +1,28 @@ +// { dg-do compile { target c++11 } } + +// Copyright (C) 2016 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 new file mode 100644 index 0000000..395eb15 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs.cc @@ -0,0 +1,30 @@ +// { dg-options "-std=gnu++17" } +// { dg-do compile } + +// Copyright (C) 2016 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 new file mode 100644 index 0000000..23df15e --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs_ext.cc @@ -0,0 +1,29 @@ +// { dg-do compile { target c++11 } } + +// Copyright (C) 2016 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 new file mode 100644 index 0000000..b24d369 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/value.cc @@ -0,0 +1,92 @@ +// Copyright (C) 2016 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 new file mode 100644 index 0000000..8d84db6 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_callable/value_ext.cc @@ -0,0 +1,27 @@ +// Copyright (C) 2016 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"