1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef TEST_SUPPORT_INVOCABLE_WITH_TELEMETRY_H
10 #define TEST_SUPPORT_INVOCABLE_WITH_TELEMETRY_H
18 # error invocable_with_telemetry requires C++20
20 struct invocable_telemetry
{
27 class invocable_with_telemetry
{
29 constexpr invocable_with_telemetry(F f
, invocable_telemetry
& telemetry
) : f_(f
), telemetry_(&telemetry
) {}
31 constexpr invocable_with_telemetry(invocable_with_telemetry
&& other
)
32 requires
std::move_constructible
<F
>
33 : f_(std::move(other
.f_
)),
34 telemetry_(assert(other
.telemetry_
!= nullptr), std::exchange(other
.telemetry_
, nullptr)) {
38 constexpr invocable_with_telemetry(invocable_with_telemetry
const& other
)
39 requires
std::copy_constructible
<F
>
40 : f_(other
.f_
), telemetry_((assert(other
.telemetry_
!= nullptr), other
.telemetry_
)) {
44 constexpr invocable_with_telemetry
& operator=(invocable_with_telemetry
&& other
)
45 requires
std::movable
<F
>
47 // Not using move-and-swap idiom to ensure that copies and moves remain accurate.
48 assert(&other
!= this);
49 assert(other
.telemetry_
!= nullptr);
51 f_
= std::move(other
.f_
);
52 telemetry_
= std::exchange(other
.telemetry_
, nullptr);
58 constexpr invocable_with_telemetry
& operator=(invocable_with_telemetry
const& other
)
59 requires
std::copyable
<F
>
61 // Not using copy-and-swap idiom to ensure that copies and moves remain accurate.
62 assert(&other
!= this);
63 assert(other
.telemetry_
!= nullptr);
66 telemetry_
= other
.telemetry_
;
72 template <class... Args
>
73 requires
std::invocable
<F
&, Args
...>
74 constexpr decltype(auto) operator()(Args
&&... args
) noexcept(std::is_nothrow_invocable_v
<F
&, Args
...>) {
76 ++telemetry_
->invocations
;
77 return std::invoke(f_
, std::forward
<Args
>(args
)...);
82 invocable_telemetry
* telemetry_
= nullptr;
86 invocable_with_telemetry(F f
, int& invocations
, int& moves
, int& copies
) -> invocable_with_telemetry
<F
>;
88 #endif // TEST_STD_VER < 20
89 #endif // TEST_SUPPORT_INVOCABLE_WITH_TELEMETRY_H