Line |
Branch |
Exec |
Source |
1 |
|
|
#pragma once |
2 |
|
|
#include <functional> |
3 |
|
|
#include <type_traits> |
4 |
|
|
#include <utility> |
5 |
|
|
|
6 |
|
|
#include "SmallStorage.hpp" |
7 |
|
|
|
8 |
|
|
namespace utils { |
9 |
|
|
|
10 |
|
|
template <typename Func, typename Return, typename... Args> |
11 |
|
|
concept InvocableWith = std::is_invocable_r_v<Return, Func, Args...>; |
12 |
|
|
|
13 |
|
|
template <typename...> |
14 |
|
|
class Function; |
15 |
|
|
|
16 |
|
|
template <typename Return, typename... Args> |
17 |
|
|
class Function<Return(Args...)> { |
18 |
|
|
public: |
19 |
|
|
Function() = default; |
20 |
|
|
|
21 |
|
|
template <InvocableWith<Return, Args...> Func> |
22 |
|
16 |
explicit Function(Func&& func) { |
23 |
|
|
using FuncType = std::remove_cvref_t<Func>; |
24 |
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
16 |
callable_.template emplace<CallableDerived<FuncType>>( |
25 |
|
|
std::forward<Func>(func)); |
26 |
|
16 |
} |
27 |
|
|
|
28 |
|
1 |
Function(Return (*func)(Args...)) { |
29 |
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 |
callable_.template emplace<CallableDerived<Return (*)(Args...)>>(func); |
30 |
|
1 |
} |
31 |
|
|
|
32 |
|
28 |
Return operator()(Args... args) const { |
33 |
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 11 times.
|
28 |
if (callable_.empty()) { |
34 |
|
6 |
throw std::bad_function_call(); |
35 |
|
|
} |
36 |
|
22 |
return callable_->invoke(std::forward<Args>(args)...); |
37 |
|
|
} |
38 |
|
|
|
39 |
|
|
private: |
40 |
|
|
class CallableBase { |
41 |
|
|
public: |
42 |
|
18 |
explicit CallableBase() = default; |
43 |
|
|
explicit CallableBase(const CallableBase&) = default; |
44 |
|
|
explicit CallableBase(CallableBase&&) = default; |
45 |
|
|
CallableBase& operator=(const CallableBase&) = default; |
46 |
|
|
CallableBase& operator=(CallableBase&&) = default; |
47 |
|
18 |
virtual ~CallableBase() = default; |
48 |
|
|
virtual Return invoke(Args... args) = 0; |
49 |
|
|
}; |
50 |
|
|
template <InvocableWith<Return, Args...> FuncType> |
51 |
|
|
class CallableDerived final : public CallableBase { |
52 |
|
|
public: |
53 |
|
|
template <InvocableWith<Return, Args...> FuncForwardType> |
54 |
|
18 |
CallableDerived(FuncForwardType&& func) |
55 |
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
18 |
: func_(std::forward<FuncForwardType>(func)) {} |
56 |
|
|
|
57 |
|
11 |
Return invoke(Args... args) override { |
58 |
|
11 |
return std::invoke(func_, std::forward<Args>(args)...); |
59 |
|
|
} |
60 |
|
|
|
61 |
|
|
private: |
62 |
|
|
FuncType func_; |
63 |
|
|
}; |
64 |
|
|
|
65 |
|
|
static constexpr int smallStorageSize = 64; |
66 |
|
|
SmallStorage<CallableBase, smallStorageSize> callable_{}; |
67 |
|
|
}; |
68 |
|
|
} // namespace utils |
69 |
|
|
|