Add remaining changes from P1065R2 "constexpr INVOKE"
* include/bits/refwrap.h (reference_wrapper, ref, cref): Add constexpr specifiers for C++20. * include/std/functional (_Mem_fn, mem_fn, _Bind, _Bind_result, bind) (bind_front, _Not_fn, not_fn): Likewise. * testsuite/20_util/bind/constexpr.cc: New test. * testsuite/20_util/function_objects/bind_front/constexpr.cc: New test. * testsuite/20_util/function_objects/mem_fn/constexpr.cc: New test. * testsuite/20_util/function_objects/not_fn/constexpr.cc: New test. * testsuite/20_util/reference_wrapper/constexpr.cc: New test. From-SVN: r277698
This commit is contained in:
parent
328b52d675
commit
2670a7aa8f
@ -1,5 +1,15 @@
|
|||||||
2019-10-31 Jonathan Wakely <jwakely@redhat.com>
|
2019-10-31 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
* include/bits/refwrap.h (reference_wrapper, ref, cref): Add constexpr
|
||||||
|
specifiers for C++20.
|
||||||
|
* include/std/functional (_Mem_fn, mem_fn, _Bind, _Bind_result, bind)
|
||||||
|
(bind_front, _Not_fn, not_fn): Likewise.
|
||||||
|
* testsuite/20_util/bind/constexpr.cc: New test.
|
||||||
|
* testsuite/20_util/function_objects/bind_front/constexpr.cc: New test.
|
||||||
|
* testsuite/20_util/function_objects/mem_fn/constexpr.cc: New test.
|
||||||
|
* testsuite/20_util/function_objects/not_fn/constexpr.cc: New test.
|
||||||
|
* testsuite/20_util/reference_wrapper/constexpr.cc: New test.
|
||||||
|
|
||||||
* doc/doxygen/user.cfg.in: Add new header.
|
* doc/doxygen/user.cfg.in: Add new header.
|
||||||
* include/Makefile.am: Add new header.
|
* include/Makefile.am: Add new header.
|
||||||
* include/Makefile.in: Regenerate.
|
* include/Makefile.in: Regenerate.
|
||||||
|
@ -300,7 +300,9 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type)
|
|||||||
{
|
{
|
||||||
_Tp* _M_data;
|
_Tp* _M_data;
|
||||||
|
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
static _Tp* _S_fun(_Tp& __r) noexcept { return std::__addressof(__r); }
|
static _Tp* _S_fun(_Tp& __r) noexcept { return std::__addressof(__r); }
|
||||||
|
|
||||||
static void _S_fun(_Tp&&) = delete;
|
static void _S_fun(_Tp&&) = delete;
|
||||||
|
|
||||||
template<typename _Up, typename _Up2 = __remove_cvref_t<_Up>>
|
template<typename _Up, typename _Up2 = __remove_cvref_t<_Up>>
|
||||||
@ -315,6 +317,7 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type)
|
|||||||
// 3041. Unnecessary decay in reference_wrapper
|
// 3041. Unnecessary decay in reference_wrapper
|
||||||
template<typename _Up, typename = __not_same<_Up>, typename
|
template<typename _Up, typename = __not_same<_Up>, typename
|
||||||
= decltype(reference_wrapper::_S_fun(std::declval<_Up>()))>
|
= decltype(reference_wrapper::_S_fun(std::declval<_Up>()))>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
reference_wrapper(_Up&& __uref)
|
reference_wrapper(_Up&& __uref)
|
||||||
noexcept(noexcept(reference_wrapper::_S_fun(std::declval<_Up>())))
|
noexcept(noexcept(reference_wrapper::_S_fun(std::declval<_Up>())))
|
||||||
: _M_data(reference_wrapper::_S_fun(std::forward<_Up>(__uref)))
|
: _M_data(reference_wrapper::_S_fun(std::forward<_Up>(__uref)))
|
||||||
@ -325,14 +328,17 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type)
|
|||||||
reference_wrapper&
|
reference_wrapper&
|
||||||
operator=(const reference_wrapper&) = default;
|
operator=(const reference_wrapper&) = default;
|
||||||
|
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
operator _Tp&() const noexcept
|
operator _Tp&() const noexcept
|
||||||
{ return this->get(); }
|
{ return this->get(); }
|
||||||
|
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_Tp&
|
_Tp&
|
||||||
get() const noexcept
|
get() const noexcept
|
||||||
{ return *_M_data; }
|
{ return *_M_data; }
|
||||||
|
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
typename result_of<_Tp&(_Args&&...)>::type
|
typename result_of<_Tp&(_Args&&...)>::type
|
||||||
operator()(_Args&&... __args) const
|
operator()(_Args&&... __args) const
|
||||||
{
|
{
|
||||||
@ -352,12 +358,14 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type)
|
|||||||
|
|
||||||
/// Denotes a reference should be taken to a variable.
|
/// Denotes a reference should be taken to a variable.
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
inline reference_wrapper<_Tp>
|
inline reference_wrapper<_Tp>
|
||||||
ref(_Tp& __t) noexcept
|
ref(_Tp& __t) noexcept
|
||||||
{ return reference_wrapper<_Tp>(__t); }
|
{ return reference_wrapper<_Tp>(__t); }
|
||||||
|
|
||||||
/// Denotes a const reference should be taken to a variable.
|
/// Denotes a const reference should be taken to a variable.
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
inline reference_wrapper<const _Tp>
|
inline reference_wrapper<const _Tp>
|
||||||
cref(const _Tp& __t) noexcept
|
cref(const _Tp& __t) noexcept
|
||||||
{ return reference_wrapper<const _Tp>(__t); }
|
{ return reference_wrapper<const _Tp>(__t); }
|
||||||
@ -370,12 +378,14 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type)
|
|||||||
|
|
||||||
/// std::ref overload to prevent wrapping a reference_wrapper
|
/// std::ref overload to prevent wrapping a reference_wrapper
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
inline reference_wrapper<_Tp>
|
inline reference_wrapper<_Tp>
|
||||||
ref(reference_wrapper<_Tp> __t) noexcept
|
ref(reference_wrapper<_Tp> __t) noexcept
|
||||||
{ return __t; }
|
{ return __t; }
|
||||||
|
|
||||||
/// std::cref overload to prevent wrapping a reference_wrapper
|
/// std::cref overload to prevent wrapping a reference_wrapper
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
inline reference_wrapper<const _Tp>
|
inline reference_wrapper<const _Tp>
|
||||||
cref(reference_wrapper<_Tp> __t) noexcept
|
cref(reference_wrapper<_Tp> __t) noexcept
|
||||||
{ return { __t.get() }; }
|
{ return { __t.get() }; }
|
||||||
|
@ -112,6 +112,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
_Mem_fn_base(_MemFunPtr __pmf) noexcept : _M_pmf(__pmf) { }
|
_Mem_fn_base(_MemFunPtr __pmf) noexcept : _M_pmf(__pmf) { }
|
||||||
|
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
auto
|
auto
|
||||||
operator()(_Args&&... __args) const
|
operator()(_Args&&... __args) const
|
||||||
noexcept(noexcept(
|
noexcept(noexcept(
|
||||||
@ -137,6 +138,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
_Mem_fn_base(_MemObjPtr __pm) noexcept : _M_pm(__pm) { }
|
_Mem_fn_base(_MemObjPtr __pm) noexcept : _M_pm(__pm) { }
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
auto
|
auto
|
||||||
operator()(_Tp&& __obj) const
|
operator()(_Tp&& __obj) const
|
||||||
noexcept(noexcept(std::__invoke(_M_pm, std::forward<_Tp>(__obj))))
|
noexcept(noexcept(std::__invoke(_M_pm, std::forward<_Tp>(__obj))))
|
||||||
@ -162,6 +164,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
* @ingroup functors
|
* @ingroup functors
|
||||||
*/
|
*/
|
||||||
template<typename _Tp, typename _Class>
|
template<typename _Tp, typename _Class>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
inline _Mem_fn<_Tp _Class::*>
|
inline _Mem_fn<_Tp _Class::*>
|
||||||
mem_fn(_Tp _Class::* __pm) noexcept
|
mem_fn(_Tp _Class::* __pm) noexcept
|
||||||
{
|
{
|
||||||
@ -297,6 +300,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
* but not volatile-qualified. This might be a defect in the TR.
|
* but not volatile-qualified. This might be a defect in the TR.
|
||||||
*/
|
*/
|
||||||
template<typename _CVRef, typename _Tuple>
|
template<typename _CVRef, typename _Tuple>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_Tp&
|
_Tp&
|
||||||
operator()(_CVRef& __arg, _Tuple&) const volatile
|
operator()(_CVRef& __arg, _Tuple&) const volatile
|
||||||
{ return __arg.get(); }
|
{ return __arg.get(); }
|
||||||
@ -313,6 +317,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<typename _CVArg, typename... _Args>
|
template<typename _CVArg, typename... _Args>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
auto
|
auto
|
||||||
operator()(_CVArg& __arg,
|
operator()(_CVArg& __arg,
|
||||||
tuple<_Args...>& __tuple) const volatile
|
tuple<_Args...>& __tuple) const volatile
|
||||||
@ -328,6 +333,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
// Invokes the underlying function object __arg by unpacking all
|
// Invokes the underlying function object __arg by unpacking all
|
||||||
// of the arguments in the tuple.
|
// of the arguments in the tuple.
|
||||||
template<typename _CVArg, typename... _Args, std::size_t... _Indexes>
|
template<typename _CVArg, typename... _Args, std::size_t... _Indexes>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
auto
|
auto
|
||||||
__call(_CVArg& __arg, tuple<_Args...>& __tuple,
|
__call(_CVArg& __arg, tuple<_Args...>& __tuple,
|
||||||
const _Index_tuple<_Indexes...>&) const volatile
|
const _Index_tuple<_Indexes...>&) const volatile
|
||||||
@ -347,6 +353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<typename _Tuple>
|
template<typename _Tuple>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_Safe_tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>&&
|
_Safe_tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>&&
|
||||||
operator()(const volatile _Arg&, _Tuple& __tuple) const volatile
|
operator()(const volatile _Arg&, _Tuple& __tuple) const volatile
|
||||||
{
|
{
|
||||||
@ -365,6 +372,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<typename _CVArg, typename _Tuple>
|
template<typename _CVArg, typename _Tuple>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_CVArg&&
|
_CVArg&&
|
||||||
operator()(_CVArg&& __arg, _Tuple&) const volatile
|
operator()(_CVArg&& __arg, _Tuple&) const volatile
|
||||||
{ return std::forward<_CVArg>(__arg); }
|
{ return std::forward<_CVArg>(__arg); }
|
||||||
@ -400,6 +408,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
// Call unqualified
|
// Call unqualified
|
||||||
template<typename _Result, typename... _Args, std::size_t... _Indexes>
|
template<typename _Result, typename... _Args, std::size_t... _Indexes>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_Result
|
_Result
|
||||||
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
|
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
|
||||||
{
|
{
|
||||||
@ -410,6 +419,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
// Call as const
|
// Call as const
|
||||||
template<typename _Result, typename... _Args, std::size_t... _Indexes>
|
template<typename _Result, typename... _Args, std::size_t... _Indexes>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_Result
|
_Result
|
||||||
__call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
|
__call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
|
||||||
{
|
{
|
||||||
@ -464,24 +474,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
explicit _Bind(const _Functor& __f, _Args&&... __args)
|
explicit _GLIBCXX20_CONSTEXPR
|
||||||
|
_Bind(const _Functor& __f, _Args&&... __args)
|
||||||
: _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...)
|
: _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
explicit _Bind(_Functor&& __f, _Args&&... __args)
|
explicit _GLIBCXX20_CONSTEXPR
|
||||||
|
_Bind(_Functor&& __f, _Args&&... __args)
|
||||||
: _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
|
: _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
_Bind(const _Bind&) = default;
|
_Bind(const _Bind&) = default;
|
||||||
|
_Bind(_Bind&&) = default;
|
||||||
_Bind(_Bind&& __b)
|
|
||||||
: _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
// Call unqualified
|
// Call unqualified
|
||||||
template<typename... _Args,
|
template<typename... _Args,
|
||||||
typename _Result = _Res_type<tuple<_Args...>>>
|
typename _Result = _Res_type<tuple<_Args...>>>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_Result
|
_Result
|
||||||
operator()(_Args&&... __args)
|
operator()(_Args&&... __args)
|
||||||
{
|
{
|
||||||
@ -493,6 +503,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
// Call as const
|
// Call as const
|
||||||
template<typename... _Args,
|
template<typename... _Args,
|
||||||
typename _Result = _Res_type_cv<tuple<_Args...>, add_const>>
|
typename _Result = _Res_type_cv<tuple<_Args...>, add_const>>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_Result
|
_Result
|
||||||
operator()(_Args&&... __args) const
|
operator()(_Args&&... __args) const
|
||||||
{
|
{
|
||||||
@ -547,6 +558,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
// Call unqualified
|
// Call unqualified
|
||||||
template<typename _Res, typename... _Args, std::size_t... _Indexes>
|
template<typename _Res, typename... _Args, std::size_t... _Indexes>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_Res
|
_Res
|
||||||
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
|
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
|
||||||
{
|
{
|
||||||
@ -556,6 +568,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
// Call as const
|
// Call as const
|
||||||
template<typename _Res, typename... _Args, std::size_t... _Indexes>
|
template<typename _Res, typename... _Args, std::size_t... _Indexes>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_Res
|
_Res
|
||||||
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
|
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
|
||||||
{
|
{
|
||||||
@ -565,6 +578,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
// Call as volatile
|
// Call as volatile
|
||||||
template<typename _Res, typename... _Args, std::size_t... _Indexes>
|
template<typename _Res, typename... _Args, std::size_t... _Indexes>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_Res
|
_Res
|
||||||
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile
|
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile
|
||||||
{
|
{
|
||||||
@ -574,6 +588,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
// Call as const volatile
|
// Call as const volatile
|
||||||
template<typename _Res, typename... _Args, std::size_t... _Indexes>
|
template<typename _Res, typename... _Args, std::size_t... _Indexes>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
_Res
|
_Res
|
||||||
__call(tuple<_Args...>&& __args,
|
__call(tuple<_Args...>&& __args,
|
||||||
_Index_tuple<_Indexes...>) const volatile
|
_Index_tuple<_Indexes...>) const volatile
|
||||||
@ -586,23 +601,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
typedef _Result result_type;
|
typedef _Result result_type;
|
||||||
|
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
explicit _Bind_result(const _Functor& __f, _Args&&... __args)
|
explicit _GLIBCXX20_CONSTEXPR
|
||||||
|
_Bind_result(const _Functor& __f, _Args&&... __args)
|
||||||
: _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...)
|
: _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
explicit _Bind_result(_Functor&& __f, _Args&&... __args)
|
explicit _GLIBCXX20_CONSTEXPR
|
||||||
|
_Bind_result(_Functor&& __f, _Args&&... __args)
|
||||||
: _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
|
: _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
_Bind_result(const _Bind_result&) = default;
|
_Bind_result(const _Bind_result&) = default;
|
||||||
|
_Bind_result(_Bind_result&&) = default;
|
||||||
_Bind_result(_Bind_result&& __b)
|
|
||||||
: _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
// Call unqualified
|
// Call unqualified
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
result_type
|
result_type
|
||||||
operator()(_Args&&... __args)
|
operator()(_Args&&... __args)
|
||||||
{
|
{
|
||||||
@ -613,6 +628,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
// Call as const
|
// Call as const
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
result_type
|
result_type
|
||||||
operator()(_Args&&... __args) const
|
operator()(_Args&&... __args) const
|
||||||
{
|
{
|
||||||
@ -763,7 +779,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
* @ingroup binders
|
* @ingroup binders
|
||||||
*/
|
*/
|
||||||
template<typename _Func, typename... _BoundArgs>
|
template<typename _Func, typename... _BoundArgs>
|
||||||
inline typename
|
inline _GLIBCXX20_CONSTEXPR typename
|
||||||
_Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type
|
_Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type
|
||||||
bind(_Func&& __f, _BoundArgs&&... __args)
|
bind(_Func&& __f, _BoundArgs&&... __args)
|
||||||
{
|
{
|
||||||
@ -787,7 +803,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
* @ingroup binders
|
* @ingroup binders
|
||||||
*/
|
*/
|
||||||
template<typename _Result, typename _Func, typename... _BoundArgs>
|
template<typename _Result, typename _Func, typename... _BoundArgs>
|
||||||
inline
|
inline _GLIBCXX20_CONSTEXPR
|
||||||
typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type
|
typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type
|
||||||
bind(_Func&& __f, _BoundArgs&&... __args)
|
bind(_Func&& __f, _BoundArgs&&... __args)
|
||||||
{
|
{
|
||||||
@ -886,7 +902,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
= _Bind_front<decay_t<_Fn>, decay_t<_Args>...>;
|
= _Bind_front<decay_t<_Fn>, decay_t<_Args>...>;
|
||||||
|
|
||||||
template<typename _Fn, typename... _Args>
|
template<typename _Fn, typename... _Args>
|
||||||
_Bind_front_t<_Fn, _Args...>
|
constexpr _Bind_front_t<_Fn, _Args...>
|
||||||
bind_front(_Fn&& __fn, _Args&&... __args)
|
bind_front(_Fn&& __fn, _Args&&... __args)
|
||||||
noexcept(is_nothrow_constructible_v<int, _Bind_front_t<_Fn, _Args...>,
|
noexcept(is_nothrow_constructible_v<int, _Bind_front_t<_Fn, _Args...>,
|
||||||
_Fn, _Args...>)
|
_Fn, _Args...>)
|
||||||
@ -910,6 +926,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename _Fn2>
|
template<typename _Fn2>
|
||||||
|
constexpr
|
||||||
_Not_fn(_Fn2&& __fn, int)
|
_Not_fn(_Fn2&& __fn, int)
|
||||||
: _M_fn(std::forward<_Fn2>(__fn)) { }
|
: _M_fn(std::forward<_Fn2>(__fn)) { }
|
||||||
|
|
||||||
@ -922,6 +939,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
// and deducing the return type and exception-specification.
|
// and deducing the return type and exception-specification.
|
||||||
#define _GLIBCXX_NOT_FN_CALL_OP( _QUALS ) \
|
#define _GLIBCXX_NOT_FN_CALL_OP( _QUALS ) \
|
||||||
template<typename... _Args> \
|
template<typename... _Args> \
|
||||||
|
_GLIBCXX20_CONSTEXPR \
|
||||||
decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()) \
|
decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()) \
|
||||||
operator()(_Args&&... __args) _QUALS \
|
operator()(_Args&&... __args) _QUALS \
|
||||||
noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value \
|
noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value \
|
||||||
@ -966,6 +984,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
#define __cpp_lib_not_fn 201603
|
#define __cpp_lib_not_fn 201603
|
||||||
/// [func.not_fn] Function template not_fn
|
/// [func.not_fn] Function template not_fn
|
||||||
template<typename _Fn>
|
template<typename _Fn>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
inline auto
|
inline auto
|
||||||
not_fn(_Fn&& __fn)
|
not_fn(_Fn&& __fn)
|
||||||
noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value)
|
noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value)
|
||||||
|
43
libstdc++-v3/testsuite/20_util/bind/constexpr.cc
Normal file
43
libstdc++-v3/testsuite/20_util/bind/constexpr.cc
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (C) 2019 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++2a" }
|
||||||
|
// { dg-do compile { target c++2a } }
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
struct add
|
||||||
|
{
|
||||||
|
constexpr int operator()(int i, int j) const { return i + j; }
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int
|
||||||
|
test01(int i, int j)
|
||||||
|
{
|
||||||
|
add a;
|
||||||
|
return std::bind(a, i, std::placeholders::_1)(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert( test01(1, 2) == 3 );
|
||||||
|
|
||||||
|
constexpr int
|
||||||
|
test02(int i, int j)
|
||||||
|
{
|
||||||
|
return std::bind<int>(add{}, i, std::placeholders::_1)(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert( test02(4, 5) == 9 );
|
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (C) 2019 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++2a" }
|
||||||
|
// { dg-do compile { target c++2a } }
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
struct add
|
||||||
|
{
|
||||||
|
constexpr int operator()(int i, int j) const { return i + j; }
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int
|
||||||
|
test01(int i, int j)
|
||||||
|
{
|
||||||
|
add a;
|
||||||
|
return std::bind_front(a, i)(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert( test01(1, 2) == 3 );
|
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright (C) 2019 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++2a" }
|
||||||
|
// { dg-do compile { target c++2a } }
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
struct F
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
constexpr int add(int j) { return i + j; }
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int
|
||||||
|
test01(int i)
|
||||||
|
{
|
||||||
|
F f{i};
|
||||||
|
return std::mem_fn(&F::i)(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert( test01(2) == 2 );
|
||||||
|
|
||||||
|
constexpr int
|
||||||
|
test02(int i, int j)
|
||||||
|
{
|
||||||
|
F f{i};
|
||||||
|
return std::mem_fn(&F::add)(&f, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert( test02(3, 4) == 7 );
|
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (C) 2019 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++2a" }
|
||||||
|
// { dg-do compile { target c++2a } }
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
struct F
|
||||||
|
{
|
||||||
|
constexpr bool operator()(int i, int j) const { return i == j; }
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int
|
||||||
|
test01(int i, int j)
|
||||||
|
{
|
||||||
|
F f;
|
||||||
|
return std::not_fn(f)(1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert( test01(1, 2) );
|
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright (C) 2019 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++2a" }
|
||||||
|
// { dg-do compile { target c++2a } }
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
struct F
|
||||||
|
{
|
||||||
|
constexpr int operator()(int i, int j) { return i + j; }
|
||||||
|
constexpr int operator()(int i, int j) const { return i * j; }
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int
|
||||||
|
test01(int i, int j)
|
||||||
|
{
|
||||||
|
F f;
|
||||||
|
return std::ref(std::ref(f))(i, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert( test01(1, 2) == 3 );
|
||||||
|
|
||||||
|
constexpr int
|
||||||
|
test02(int i, int j)
|
||||||
|
{
|
||||||
|
F f;
|
||||||
|
return std::cref(std::cref(f))(i, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert( test02(4, 5) == 20 );
|
Loading…
x
Reference in New Issue
Block a user