File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/CPP/panda/lib.x/i/panda/function_utils.h
Criterion Covered Total %
statement 24 25 96.0
branch 18 36 50.0
condition n/a
subroutine n/a
pod n/a
total 42 61 68.8


line stmt bran cond sub pod time code
1             #pragma once
2              
3             #include
4             #include
5              
6             namespace panda {
7              
8             using panda::shared_ptr;
9              
10             template
11             class function;
12              
13             template
14 20           struct Ifunction : virtual public RefCounted {
15 20 50         virtual ~Ifunction() {}
    50          
    50          
    50          
16             virtual Ret operator()(Args...) = 0;
17             virtual bool equals(const Ifunction* oth) const = 0;
18             };
19              
20             template::value>
21             struct is_comparable {
22             static const bool value = true;
23             };
24              
25             template
26             struct is_comparable {
27             struct fallback { bool operator==(const fallback& oth); };
28             struct mixed_type: std::remove_reference::type, fallback {};
29             template < typename U, U > struct type_check {};
30              
31             template < typename U > static std::false_type test( type_check< bool (fallback::*)(const fallback&), &U::operator== >* = 0 );
32             template < typename U > static std::true_type test( ... );
33              
34             static const bool value = std::is_same(nullptr)), std::true_type>::value;
35             };
36              
37              
38             template
39             struct has_call_operator {
40             private:
41             typedef std::true_type yes;
42             typedef std::false_type no;
43              
44             template static auto test(int) -> decltype(std::declval()(std::declval()...), yes());
45             template static no test(...);
46              
47             public:
48             static constexpr bool value = std::is_same(0)),yes>::value;
49             };
50              
51              
52             template
53             class abstract_function {};
54              
55             template
56             class callable {};
57              
58             template
59 6           class callable
60             {
61             public:
62             template
63 6           explicit callable(F&& f) : func(std::forward(f)) {}
64              
65 9           Ret operator()(Self&, Args... args) {
66 9           return func(args...);
67             }
68             protected:
69             typename std::remove_reference::type func;
70             };
71              
72             template
73             class callable
74             {
75             public:
76             template
77             explicit callable(F&& f) : func(std::forward(f)) {}
78              
79             Ret operator()(Self& self, Args... args) {
80             return func(self, args...);
81             }
82             protected:
83             typename std::remove_reference::type func;
84             };
85              
86              
87             template
88 20 50         class abstract_function : public Ifunction{
    50          
    50          
    50          
89             public:
90             template
91 11 50         explicit abstract_function(F&& f) : func(std::forward(f)) {}
92              
93 9           Ret operator()(Args... args) override {
94             static_assert(std::is_convertible::value, "return type mismatch");
95 9           return func(args...);
96             }
97              
98 4           bool equals(const Ifunction* oth) const override {
99 4 50         auto foth = dynamic_cast(oth);
    50          
100 4 50         if (foth == nullptr) {
    50          
101 0           return false;
102             }
103              
104 4           return func == foth->func;
105             }
106              
107             typename std::remove_reference::type func;
108             };
109              
110             template
111 12 50         class abstract_function : public Ifunction
    50          
    50          
    50          
112             , public callable::value, Ifunction, Args...>
113             {
114             public:
115             using Derfed = typename std::remove_reference::type;
116             using Caller = callable::value, Ifunction, Args...>;
117              
118             template
119 4 50         explicit abstract_function(F&& f) : Caller(std::forward(f)) {}
120              
121 9           Ret operator()(Args... args) override {
122 9           return Caller::operator()(*this, args...);
123             }
124              
125 1           bool equals(const Ifunction* oth) const override {
126 1           return static_cast*>(this) == oth;
127             }
128              
129             private:
130             template
131             Ret call(Args... args) {
132             return (this->template func.*meth)(args...);
133             }
134              
135             // template
136             // Ret call(Args... args) {
137             // return (this->template func.*meth)(10, args...);
138             // }
139             };
140              
141              
142             template
143             class abstract_function : public Ifunction {
144             public:
145             using Func = Ret (*)(Args...);
146             explicit abstract_function(const Func& f) : func(f) {}
147              
148             Ret operator()(Args... args) override {
149             return func(args...);
150             }
151              
152             bool equals(const Ifunction* oth) const override {
153             auto foth = dynamic_cast(oth);
154             if (foth == nullptr) return false;
155              
156             return func == foth->func;
157             }
158              
159             Ret (*func)(Args...);
160             };
161              
162             template
163             auto make_abstract_function(Ret (*f)(Args...)) -> shared_ptr> {
164             return panda::make_shared>(f);
165             }
166              
167             template
168             auto tmp_abstract_function(Ret (*f)(Args...)) -> abstract_function {
169             return abstract_function(f);
170             }
171              
172             template
173             typename Functor, bool IsComp = is_comparable::type>::value,
174             typename DeFunctor = typename std::remove_reference::type,
175             typename Check = decltype(std::declval()(std::declval()...)),
176             typename = typename std::enable_if::value>::type>
177 6           shared_ptr> make_abstract_function(Functor&& f, Check(*)() = 0) {
178 6           return panda::make_shared>(std::forward(f));
179             }
180              
181             template
182             typename Functor, bool IsComp = is_comparable::type>::value,
183             typename DeFunctor = typename std::remove_reference::type,
184             typename Check = decltype(std::declval()(std::declval()...)),
185             typename = typename std::enable_if::value>::type>
186 4           abstract_function tmp_abstract_function(Functor&& f, Check(*)() = 0) {
187 4           return abstract_function(std::forward(f));
188             }
189              
190             template
191             typename Functor, bool IsComp = is_comparable::type>::value,
192             typename DeFunctor = typename std::remove_reference::type,
193             typename Check = decltype(std::declval()(std::declval&>(), std::declval()...))>
194             shared_ptr> make_abstract_function(Functor&& f) {
195             return panda::make_shared>(std::forward(f));
196             }
197              
198             template
199             typename Functor, bool IsComp = is_comparable::type>::value,
200             typename DeFunctor = typename std::remove_reference::type,
201             typename Check = decltype(std::declval()(std::declval&>(), std::declval()...))>
202             abstract_function tmp_abstract_function(Functor&& f) {
203             return abstract_function(std::forward(f));
204             }
205              
206             template
207             struct method : public Ifunction{
208             using Method = Ret (Class::*)(Args...);
209             using ifunction = Ifunction;
210              
211             method(Method method, shared_ptr thiz = nullptr) : thiz(thiz), meth(method) {}
212             shared_ptr bind(shared_ptr thiz) {
213             this->thiz = thiz;
214             return shared_ptr(this);
215             }
216              
217             Ret operator()(Args... args) override {
218             return (thiz.get()->*meth)(std::forward(args)...);
219             }
220              
221             bool equals(const ifunction* oth) const override {
222             auto moth = dynamic_cast*>(oth);
223             if (moth == nullptr) return false;
224              
225             return operator ==(*moth);
226             }
227              
228             bool operator==(const method& oth) const {
229             return thiz == oth.thiz && meth == oth.meth;
230             }
231              
232             bool operator !=(const method& oth) const {
233             return !operator ==(oth);
234             }
235              
236             explicit operator bool() const {
237             return thiz && meth;
238             }
239              
240             private:
241             shared_ptr thiz;
242             Method meth;
243             };
244              
245             template
246             inline shared_ptr> make_method(Ret (Class::*meth)(Args...), shared_ptr thiz = nullptr) {
247             return panda::make_shared>(meth, thiz);
248             }
249              
250             template
251             inline shared_ptr> make_abstract_function(Ret (Class::*meth)(Args...), shared_ptr thiz = nullptr) {
252             return panda::make_shared>(meth, thiz);
253             }
254              
255             template
256             inline method tmp_abstract_function(Ret (Class::*meth)(Args...), shared_ptr thiz = nullptr) {
257             return method(meth, thiz);
258             }
259             }