From be8c7cd31c09bfef6cd3bb05b9ba00d2d6608d39 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 25 Sep 2023 14:45:17 -0700 Subject: [PATCH 1/5] Implement and test P1169R4 static operator() --- stl/inc/functional | 27 ++++++++- stl/inc/yvals_core.h | 1 + tests/std/test.lst | 1 + .../P1169R4_static_call_operator/env.lst | 4 ++ .../test.compile.pass.cpp | 55 +++++++++++++++++++ 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 tests/std/tests/P1169R4_static_call_operator/env.lst create mode 100644 tests/std/tests/P1169R4_static_call_operator/test.compile.pass.cpp diff --git a/stl/inc/functional b/stl/inc/functional index a0c97586e40..b5274c9f0b4 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -1139,12 +1139,37 @@ public: _NON_MEMBER_CALL(_FUNCTION_POINTER_DEDUCTION_GUIDE, X1, X2, X3) #undef _FUNCTION_POINTER_DEDUCTION_GUIDE +template +struct _Deduce_from_call_operator : _Is_memfunptr<_Call_op>::_Guide_type {}; // N4958 [func.wrap.func.con]/16.1 + +#ifdef __cpp_static_call_operator // TRANSITION, P1169R4 +template +struct _Inspect_static_call_operator {}; + +#define _STATIC_CALL_OPERATOR_GUIDES(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \ + template \ + struct _Inspect_static_call_operator<_Ret(CALL_OPT*)(_Args...) NOEXCEPT_OPT> { \ + using type = _Ret(_Args...); \ + }; + +_NON_MEMBER_CALL(_STATIC_CALL_OPERATOR_GUIDES, , , ) +#ifdef __cpp_noexcept_function_type +_NON_MEMBER_CALL(_STATIC_CALL_OPERATOR_GUIDES, , , noexcept) +#endif // ^^^ defined(__cpp_noexcept_function_type) ^^^ + +#undef _STATIC_CALL_OPERATOR_GUIDES + +template +struct _Deduce_from_call_operator<_Fx, _Call_op, void_t().operator())>> + : _Inspect_static_call_operator<_Call_op> {}; // N4958 [func.wrap.func.con]/16.2 +#endif // ^^^ defined(__cpp_static_call_operator) ^^^ + template struct _Deduce_signature {}; // can't deduce signature when &_Fx::operator() is missing, inaccessible, or ambiguous template struct _Deduce_signature<_Fx, void_t> - : _Is_memfunptr::_Guide_type {}; // N4950 [func.wrap.func.con]/16.1 + : _Deduce_from_call_operator<_Fx, decltype(&_Fx::operator())> {}; template function(_Fx) -> function::type>; diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index e1df05934dd..19f28862251 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -328,6 +328,7 @@ // P1072R10 basic_string::resize_and_overwrite // P1132R7 out_ptr(), inout_ptr() // P1147R1 Printing volatile Pointers +// P1169R4 static operator() // P1206R7 Conversions From Ranges To Containers // P1223R5 ranges::find_last, ranges::find_last_if, ranges::find_last_if_not // P1272R4 byteswap() diff --git a/tests/std/test.lst b/tests/std/test.lst index 8c1a3602607..7b1396a5932 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -509,6 +509,7 @@ tests\P1135R6_latch tests\P1135R6_semaphore tests\P1147R1_printing_volatile_pointers tests\P1165R1_consistently_propagating_stateful_allocators +tests\P1169R4_static_call_operator tests\P1206R7_deque_append_range tests\P1206R7_deque_assign_range tests\P1206R7_deque_from_range diff --git a/tests/std/tests/P1169R4_static_call_operator/env.lst b/tests/std/tests/P1169R4_static_call_operator/env.lst new file mode 100644 index 00000000000..642f530ffad --- /dev/null +++ b/tests/std/tests/P1169R4_static_call_operator/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_latest_matrix.lst diff --git a/tests/std/tests/P1169R4_static_call_operator/test.compile.pass.cpp b/tests/std/tests/P1169R4_static_call_operator/test.compile.pass.cpp new file mode 100644 index 00000000000..8d0607a8ebe --- /dev/null +++ b/tests/std/tests/P1169R4_static_call_operator/test.compile.pass.cpp @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifdef __cpp_static_call_operator // TRANSITION, P1169R4 + +#include +#include +#include +using namespace std; + +struct F0 { + static char operator()(); +}; + +struct F1 { + static short operator()(float); +}; + +struct F2 { + static int operator()(double*, double&); +}; + +struct F3 { + static void operator()(const long&, long&&, const long&&); +}; + +struct Base { + static bool operator()(unsigned int); +}; + +struct Derived : Base {}; + +struct Nothrow { + static char16_t operator()(char32_t) noexcept; +}; + +template