From 42183d034d47e05814c971b2911c847e2a700941 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 4 Aug 2016 19:02:56 +0100 Subject: [PATCH] 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 . (__invoke_impl): Remove exception specifications. (__invoke, invoke): Add exception specifications using __is_nothrow_callable. * include/std/type_traits (__inv_unwrap): Move from . (__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. From-SVN: r239145 --- libstdc++-v3/ChangeLog | 30 +++ .../doc/xml/manual/status_cxx2017.xml | 3 +- libstdc++-v3/include/std/functional | 21 +- libstdc++-v3/include/std/type_traits | 120 ++++++++++- .../requirements/explicit_instantiation.cc | 29 +++ .../explicit_instantiation_ext.cc | 28 +++ .../is_callable/requirements/typedefs.cc | 30 +++ .../is_callable/requirements/typedefs_ext.cc | 29 +++ .../testsuite/20_util/is_callable/value.cc | 191 ++++++++++++++++++ .../20_util/is_callable/value_ext.cc | 26 +++ .../requirements/explicit_instantiation.cc | 29 +++ .../explicit_instantiation_ext.cc | 28 +++ .../requirements/typedefs.cc | 30 +++ .../requirements/typedefs_ext.cc | 29 +++ .../20_util/is_nothrow_callable/value.cc | 92 +++++++++ .../20_util/is_nothrow_callable/value_ext.cc | 27 +++ 16 files changed, 718 insertions(+), 24 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_callable/requirements/explicit_instantiation_ext.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_callable/requirements/typedefs_ext.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_callable/value.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_callable/value_ext.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/explicit_instantiation_ext.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_nothrow_callable/requirements/typedefs_ext.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_nothrow_callable/value.cc create mode 100644 libstdc++-v3/testsuite/20_util/is_nothrow_callable/value_ext.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 59d11884ff2..5c4bb5c2605 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,35 @@ 2016-08-04 Jonathan Wakely + * doc/xml/manual/status_cxx2017.xml: Update status table. + * include/std/functional (__inv_unwrap): Move to . + (__invoke_impl): Remove exception specifications. + (__invoke, invoke): Add exception specifications using + __is_nothrow_callable. + * include/std/type_traits (__inv_unwrap): Move from . + (__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. + * doc/xml/manual/status_cxx2017.xml: Update C++17 status table. * doc/html/manual/status.html: Regenerate. diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml index d32399d551a..8391758333c 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++. - is_callable, the missing INVOKE related trait P0077R2 - No + 7 __cpp_lib_is_callable >= 201603 diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index d635ef53769..843dc83e761 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::type> { }; - template::type> - struct __inv_unwrap - { - using type = _Tp; - }; - - template - 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::type> @@ -206,23 +194,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template 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 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 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 inline _Res __invoke_impl(__invoke_memobj_ref, _MemPtr&& __f, _Tp&& __t) - noexcept(noexcept(__invfwd<_Tp>(__t).*__f)) { return __invfwd<_Tp>(__t).*__f; } template 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 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 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 693952ac012..baa4d1ffe96 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -176,11 +176,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template constexpr bool conjunction_v = conjunction<_Bn...>::value; - + template constexpr bool disjunction_v = disjunction<_Bn...>::value; - + template 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> + struct __is_callable_impl : false_type { }; + + template + struct __is_callable_impl<_Result, _Ret, __void_t> + : __or_, is_convertible>::type + { }; + + template + struct __is_callable; // not defined + + template + struct __is_callable<_Fn(_ArgTypes...), _Ret> + : __is_callable_impl, _Ret>::type + { }; + + // Used by __invoke and __is_nothrow_callable to unwrap a reference_wrapper. + template::type> + struct __inv_unwrap + { + using type = _Tp; + }; + + template + struct __inv_unwrap<_Tp, reference_wrapper<_Up>> + { + using type = _Up&; + }; + + template + 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 + constexpr bool __call_is_nt(__invoke_memfun_deref) + { + return noexcept(((*std::declval<_Tp>()).*std::declval<_Fn>())( + std::declval<_Args>()...)); + } + + template + constexpr bool __call_is_nt(__invoke_memobj_ref) + { + using _Up = typename __inv_unwrap<_Tp>::type; + return noexcept(std::declval<_Up>().*std::declval<_Fn>()); + } + + template + constexpr bool __call_is_nt(__invoke_memobj_deref) + { + return noexcept((*std::declval<_Tp>()).*std::declval<_Fn>()); + } + + template + constexpr bool __call_is_nt(__invoke_other) + { + return noexcept(std::declval<_Fn>()(std::declval<_Args>()...)); + } + + template + 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 + struct __is_nothrow_callable; // not defined + + template + struct __is_nothrow_callable<_Fn(_Args...), _Ret> + : __and_<__is_callable<_Fn(_Args...), _Ret>, + __call_is_nothrow, _Fn, _Args...>>::type + { }; + +#if __cplusplus > 201402L +# define __cpp_lib_is_callable 201603 + + /// std::is_callable + template + struct is_callable; // not defined + + template + struct is_callable<_Fn(_ArgTypes...), _Ret> + : __is_callable<_Fn(_ArgTypes...), _Ret>::type + { }; + + /// std::is_nothrow_callable + template + struct is_nothrow_callable; // not defined + + template + struct is_nothrow_callable<_Fn(_ArgTypes...), _Ret> + : __is_nothrow_callable<_Fn(_ArgTypes...), _Ret>::type + { }; + + /// std::is_callable_v + template + constexpr bool is_callable_v = is_callable::value; + + /// std::is_nothrow_callable_v + template + constexpr bool is_nothrow_callable_v = is_nothrow_callable::value; +#endif // C++17 + + #if __cplusplus > 201402L # define __cpp_lib_type_trait_variable_templates 201510L template @@ -2915,7 +3030,6 @@ template template 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 00000000000..0ce5bfe72a8 --- /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 +// . + +// NB: This file is for testing type_traits with NO OTHER INCLUDES. + +#include + +namespace std +{ + struct test_type { }; + template struct is_callable; +} 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 00000000000..a3d3f496de8 --- /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 +// . + +// NB: This file is for testing type_traits with NO OTHER INCLUDES. + +#include + +namespace std +{ + struct test_type { }; + template struct __is_callable; +} 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 00000000000..9f21dfb90ae --- /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 +// . + +// NB: This file is for testing type_traits with NO OTHER INCLUDES. + +#include + +void test01() +{ + // Check for required typedefs + typedef std::is_callable test_type; + static_assert( std::is_base_of_v ); +} 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 00000000000..e582be0674a --- /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 +// . + +// NB: This file is for testing type_traits with NO OTHER INCLUDES. + +#include + +void test01() +{ + // Check for required typedefs + typedef std::__is_callable test_type; + static_assert( std::is_base_of::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 00000000000..aafd55f06be --- /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 +// . + +// { dg-options "-std=gnu++17" } +// { dg-do compile } + +#include + +#ifndef IS_CALLABLE_DEFINED +template + constexpr bool is_callable() + { + static_assert(std::is_callable::value == std::is_callable_v); + return std::is_callable_v; + } +#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 00000000000..3884d6c517e --- /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 +// . + +// { dg-do compile { target c++11 } } + +#include + +template + constexpr bool is_callable() { return std::__is_callable::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 00000000000..dbcdd9fd34c --- /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 +// . + +// NB: This file is for testing type_traits with NO OTHER INCLUDES. + +#include + +namespace std +{ + struct test_type { }; + template struct is_nothrow_callable; +} 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 00000000000..9e4f74f5d20 --- /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 +// . + +// NB: This file is for testing type_traits with NO OTHER INCLUDES. + +#include + +namespace std +{ + struct test_type { }; + template struct __is_nothrow_callable; +} 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 00000000000..395eb156e12 --- /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 +// . + +// NB: This file is for testing type_traits with NO OTHER INCLUDES. + +#include + +void test01() +{ + // Check for required typedefs + typedef std::is_nothrow_callable test_type; + static_assert( std::is_base_of_v ); +} 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 00000000000..23df15ebd58 --- /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 +// . + +// NB: This file is for testing type_traits with NO OTHER INCLUDES. + +#include + +void test01() +{ + // Check for required typedefs + typedef std::__is_nothrow_callable test_type; + static_assert( std::is_base_of::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 00000000000..b24d369d39d --- /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 +// . + +// { dg-options "-std=gnu++17" } +// { dg-do compile } + +#include + +#ifndef IS_NT_CALLABLE_DEFINED +template + constexpr bool is_nt_callable() + { + static_assert(std::is_nothrow_callable::value + == std::is_nothrow_callable_v); + return std::is_nothrow_callable_v; + } +#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 00000000000..8d84db629d1 --- /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 +// . + +// { dg-do compile { target c++11 } } + +#include + +template + constexpr bool is_nt_callable() + { return std::__is_nothrow_callable::value; } + +#define IS_NT_CALLABLE_DEFINED +#include "value.cc" -- 2.30.2