Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
test_functiondef01.cpp
Go to the documentation of this file.
1 /*
2  * Author: Sven Gothel <sgothel@jausoft.com>
3  * Copyright (c) 2020 Gothel Software e.K.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #include <iostream>
25 #include <cassert>
26 #include <cinttypes>
27 #include <cstring>
28 
29 #define CATCH_CONFIG_MAIN
30 #include <catch2/catch_amalgamated.hpp>
31 
32 #include <jau/function_def.hpp>
33 
34 using namespace jau;
35 
36 // Test examples.
38  private:
39 
40  int func2a_member(int i) {
41  int res = i+100;
42  return res;;
43  }
44  int func2b_member(int i) {
45  int res = i+1000;
46  return res;;
47  }
48  static int Func3a_static(int i) {
49  int res = i+100;
50  return res;;
51  }
52  static int Func3b_static(int i) {
53  int res = i+1000;
54  return res;;
55  }
56 
57  // template<typename R, typename... A>
59 
60  struct IntOffset {
61  int value;
62  IntOffset(int v) : value(v) {}
63 
64  IntOffset(const IntOffset &o)
65  : value(o.value)
66  {
67  INFO("IntOffset::copy_ctor");
68  }
69  IntOffset(IntOffset &&o)
70  : value(std::move(o.value))
71  {
72  INFO("IntOffset::move_ctor");
73  }
74  IntOffset& operator=(const IntOffset &o) {
75  INFO("IntOffset::copy_assign");
76  if( &o == this ) {
77  return *this;
78  }
79  value = o.value;
80  return *this;
81  }
82  IntOffset& operator=(IntOffset &&o) {
83  INFO("IntOffset::move_assign");
84  value = std::move(o.value);
85  (void)value;
86  return *this;
87  }
88 
89  bool operator==(const IntOffset& rhs) const {
90  if( &rhs == this ) {
91  return true;
92  }
93  return value == rhs.value;
94  }
95 
96  bool operator!=(const IntOffset& rhs) const
97  { return !( *this == rhs ); }
98 
99  };
100 
101  void test_FunctionPointer00(std::string msg, bool expEqual, int value, int expRes, MyClassFunction & f1, MyClassFunction &f2) {
102  // test std::function identity
103  INFO(msg+": FunctionPointer00 Fun f1p == f2p : " + std::to_string( f1 == f2 ) + ", f1p: " + f1.toString() + ", f2 "+f2.toString() );
104  int f1r = f1.invoke(value);
105  int f2r = f2.invoke(value);
106  INFO(msg+": FunctionPointer00 Res f1r == f2r : " + std::to_string( f1r == f2r ) + ", f1r: " + std::to_string( f1r ) + ", f2r "+std::to_string( f2r ) );
107  if( expEqual ) {
108  REQUIRE(f1r == expRes);
109  REQUIRE(f2r == expRes);
110  REQUIRE(f1 == f2);
111  } else {
112  REQUIRE(f1 != f2);
113  }
114  }
115  void test_FunctionPointer01(std::string msg, bool expEqual, MyClassFunction & f1, MyClassFunction &f2) {
116  // test std::function identity
117  INFO(msg+": FunctionPointer00 Fun f1p == f2p : " + std::to_string( f1 == f2 ) + ", f1p: " + f1.toString() + ", f2 "+f2.toString() );
118  if( expEqual ) {
119  REQUIRE(f1 == f2);
120  } else {
121  REQUIRE(f1 != f2);
122  }
123  }
124 
125  public:
127  INFO("FuncPtr2_member: bindMemberFunc<int, TestFunctionDef01, int>: START");
128  // FunctionDef(TestFunctionDef01 &base, Func1Type func)
129  MyClassFunction f2a_1 = bindMemberFunc<int, TestFunctionDef01, int>(this, &TestFunctionDef01::func2a_member);
130  MyClassFunction f2a_2 = bindMemberFunc(this, &TestFunctionDef01::func2a_member);
131  test_FunctionPointer00("FuncPtr2a_member_11", true, 1, 101, f2a_1, f2a_1);
132  test_FunctionPointer00("FuncPtr2a_member_12", true, 1, 101, f2a_1, f2a_2);
133 
134  MyClassFunction f2b_1 = bindMemberFunc(this, &TestFunctionDef01::func2b_member);
135  MyClassFunction f2b_2 = bindMemberFunc(this, &TestFunctionDef01::func2b_member);
136  test_FunctionPointer00("FuncPtr2b_member_11", true, 1, 1001, f2b_1, f2b_1);
137  test_FunctionPointer00("FuncPtr2b_member_12", true, 1, 1001, f2b_1, f2b_2);
138 
139  test_FunctionPointer00("FuncPtr2ab_member_11", false, 1, 0, f2a_1, f2b_1);
140  test_FunctionPointer00("FuncPtr2ab_member_22", false, 1, 0, f2a_2, f2b_2);
141  INFO("FuncPtr2_member: bindMemberFunc<int, TestFunctionDef01, int>: END");
142  }
143 
145  INFO("FuncPtr3_plain: bindPlainFunc<int, int>: START");
146  // FunctionDef(Func1Type func)
147  MyClassFunction f3a_1 = bindPlainFunc<int, int>(&TestFunctionDef01::Func3a_static);
148  MyClassFunction f3a_2 = bindPlainFunc(&TestFunctionDef01::Func3a_static);
149  test_FunctionPointer00("FuncPtr3a_plain_11", true, 1, 101, f3a_1, f3a_1);
150  test_FunctionPointer00("FuncPtr3a_plain_12", true, 1, 101, f3a_1, f3a_2);
151 
152  MyClassFunction f3b_1 = bindPlainFunc(&TestFunctionDef01::Func3b_static);
153  MyClassFunction f3b_2 = bindPlainFunc(&Func3b_static);
154  test_FunctionPointer00("FuncPtr3b_plain_11", true, 1, 1001, f3b_1, f3b_1);
155  test_FunctionPointer00("FuncPtr3b_plain_12", true, 1, 1001, f3b_1, f3b_2);
156 
157  test_FunctionPointer00("FuncPtr3ab_plain_11", false, 1, 0, f3a_1, f3b_1);
158  test_FunctionPointer00("FuncPtr3ab_plain_22", false, 1, 0, f3a_2, f3b_2);
159  INFO("FuncPtr3_plain: bindPlainFunc<int, int>: END");
160  }
161 
163  INFO("FuncPtr4_stdlambda: bindStdFunc<int, int>: START");
164  // FunctionDef(Func1Type func) <int, int>
165  std::function<int(int i)> func4a_stdlambda = [](int i)->int {
166  int res = i+100;
167  return res;;
168  };
169  std::function<int(int i)> func4b_stdlambda = [](int i)->int {
170  int res = i+1000;
171  return res;;
172  };
173  MyClassFunction f4a_1 = bindStdFunc<int, int>(100, func4a_stdlambda);
174  MyClassFunction f4a_2 = bindStdFunc(100, func4a_stdlambda);
175  test_FunctionPointer00("FuncPtr4a_stdlambda_11", true, 1, 101, f4a_1, f4a_1);
176  test_FunctionPointer00("FuncPtr4a_stdlambda_12", true, 1, 101, f4a_1, f4a_2);
177 
178  MyClassFunction f4b_1 = bindStdFunc(200, func4b_stdlambda);
179  MyClassFunction f4b_2 = bindStdFunc(200, func4b_stdlambda);
180  test_FunctionPointer00("FuncPtr4b_stdlambda_11", true, 1, 1001, f4b_1, f4b_1);
181  test_FunctionPointer00("FuncPtr4b_stdlambda_12", true, 1, 1001, f4b_1, f4b_2);
182 
183  test_FunctionPointer00("FuncPtr4ab_stdlambda_11", false, 1, 0, f4a_1, f4b_1);
184  test_FunctionPointer00("FuncPtr4ab_stdlambda_22", false, 1, 0, f4a_2, f4b_2);
185 
186  MyClassFunction f4a_0 = bindStdFunc<int, int>(100);
187  MyClassFunction f4b_0 = bindStdFunc<int, int>(200);
188  test_FunctionPointer01("FuncPtr4a_stdlambda_01", true, f4a_0, f4a_1);
189  test_FunctionPointer01("FuncPtr4a_stdlambda_02", true, f4a_0, f4a_2);
190  test_FunctionPointer01("FuncPtr4b_stdlambda_01", true, f4b_0, f4b_1);
191  test_FunctionPointer01("FuncPtr4b_stdlambda_02", true, f4b_0, f4b_2);
192  test_FunctionPointer01("FuncPtr4ab_stdlambda_00", false, f4a_0, f4b_0);
193  test_FunctionPointer01("FuncPtr4ab_stdlambda_01", false, f4a_0, f4b_1);
194  test_FunctionPointer01("FuncPtr4ab_stdlambda_10", false, f4a_1, f4b_0);
195  INFO("FuncPtr4_stdlambda: bindStdFunc<int, int>: END");
196  }
197 
199  INFO("FuncPtr5_capture: bindCaptureFunc<int, int, int>: START");
200  // bindCaptureFunc(I& data, R(*func)(I&, A...))
201  // FunctionDef(Func1Type func) <int, int>
202  int offset100 = 100;
203  int offset1000 = 1000;
204 
205  int(*func5a_capture)(int&, int) = [](int& offset, int i)->int {
206  int res = i+10000+offset;
207  return res;
208  };
209  int(*func5b_capture)(int&, int) = [](int& offset, int i)->int {
210  int res = i+100000+offset;
211  return res;
212  };
213 
214 #if 0
215  MyClassFunction f5a_o100_0 = bindCaptureFunc<int, int, int>(offset100,
216  [](int& offset, int i)->int {
217  int res = i+10000+offset;
218  return res;;
219  } );
220  test_FunctionPointer01("FuncPtr5a_o100_capture_00", true, f5a_o100_0, f5a_o100_0);
221 #endif
222  MyClassFunction f5a_o100_1 = bindCaptureFunc<int, int, int>(offset100, func5a_capture);
223  MyClassFunction f5a_o100_2 = bindCaptureFunc(offset100, func5a_capture);
224  test_FunctionPointer01("FuncPtr5a_o100_capture_12", true, f5a_o100_1, f5a_o100_2);
225  test_FunctionPointer00("FuncPtr5a_o100_capture_11", true, 1, 10101, f5a_o100_1, f5a_o100_1);
226  test_FunctionPointer00("FuncPtr5a_o100_capture_12", true, 1, 10101, f5a_o100_1, f5a_o100_2);
227  // test_FunctionPointer01("FuncPtr5a_o100_capture_01", false, f5a_o100_0, f5a_o100_1);
228  MyClassFunction f5a_o1000_1 = bindCaptureFunc(offset1000, func5a_capture);
229  MyClassFunction f5a_o1000_2 = bindCaptureFunc(offset1000, func5a_capture);
230  test_FunctionPointer01("FuncPtr5a_o1000_capture_12", true, f5a_o1000_1, f5a_o1000_2);
231  test_FunctionPointer01("FuncPtr5a_o100_o1000_capture_11", false, f5a_o100_1, f5a_o1000_1);
232 
233  MyClassFunction f5b_o100_1 = bindCaptureFunc(offset100, func5b_capture);
234  MyClassFunction f5b_o100_2 = bindCaptureFunc(offset100, func5b_capture);
235  test_FunctionPointer00("FuncPtr5b_o100_capture_11", true, 1, 100101, f5b_o100_1, f5b_o100_1);
236  test_FunctionPointer00("FuncPtr5b_o100_capture_12", true, 1, 100101, f5b_o100_1, f5b_o100_2);
237 
238  test_FunctionPointer00("FuncPtr5ab_o100_capture_11", false, 1, 0, f5a_o100_1, f5b_o100_1);
239  test_FunctionPointer00("FuncPtr5ab_o100_capture_22", false, 1, 0, f5a_o100_2, f5b_o100_2);
240  INFO("FuncPtr5_capture: bindCaptureFunc<int, int, int>: END");
241  }
242 
244  INFO("FuncPtr6_capture: bindCaptureFunc<int, std::shared_ptr<IntOffset>, int>: START");
245  // bindCaptureFunc(I& data, R(*func)(I&, A...))
246  // FunctionDef(Func1Type func) <int, int>
247  std::shared_ptr<IntOffset> offset100(new IntOffset(100));
248  std::shared_ptr<IntOffset> offset1000(new IntOffset(1000));
249 
250  int(*func6a_capture)(std::shared_ptr<IntOffset>&, int) = [](std::shared_ptr<IntOffset>& sharedOffset, int i)->int {
251  int res = i+10000+sharedOffset->value;
252  return res;
253  };
254  int(*func6b_capture)(std::shared_ptr<IntOffset>&, int) = [](std::shared_ptr<IntOffset>& sharedOffset, int i)->int {
255  int res = i+100000+sharedOffset->value;
256  return res;
257  };
258 
259 #if 0
260  MyClassFunction f6a_o100_0 = bindCaptureFunc<int, std::shared_ptr<IntOffset>, int>(offset100,
261  [](std::shared_ptr<IntOffset>& sharedOffset, int i)->int {
262  int res = i+10000+sharedOffset->value;
263  return res;;
264  } );
265  test_FunctionPointer01("FuncPtr6a_o100_capture_00", true, f6a_o100_0, f6a_o100_0);
266 #endif
267  MyClassFunction f6a_o100_1 = bindCaptureFunc<int, std::shared_ptr<IntOffset>, int>(offset100, func6a_capture);
268  MyClassFunction f6a_o100_2 = bindCaptureFunc(offset100, func6a_capture);
269  test_FunctionPointer01("FuncPtr6a_o100_capture_12", true, f6a_o100_1, f6a_o100_2);
270  test_FunctionPointer00("FuncPtr6a_o100_capture_11", true, 1, 10101, f6a_o100_1, f6a_o100_1);
271  test_FunctionPointer00("FuncPtr6a_o100_capture_12", true, 1, 10101, f6a_o100_1, f6a_o100_2);
272  // test_FunctionPointer01("FuncPtr6a_o100_capture_01", false, f6a_o100_0, f6a_o100_1);
273  MyClassFunction f6a_o1000_1 = bindCaptureFunc(offset1000, func6a_capture);
274  MyClassFunction f6a_o1000_2 = bindCaptureFunc(offset1000, func6a_capture);
275  test_FunctionPointer01("FuncPtr6a_o1000_capture_12", true, f6a_o1000_1, f6a_o1000_2);
276  test_FunctionPointer01("FuncPtr6a_o100_o1000_capture_11", false, f6a_o100_1, f6a_o1000_1);
277 
278  MyClassFunction f6b_o100_1 = bindCaptureFunc(offset100, func6b_capture);
279  MyClassFunction f6b_o100_2 = bindCaptureFunc(offset100, func6b_capture);
280  test_FunctionPointer00("FuncPtr6b_o100_capture_11", true, 1, 100101, f6b_o100_1, f6b_o100_1);
281  test_FunctionPointer00("FuncPtr6b_o100_capture_12", true, 1, 100101, f6b_o100_1, f6b_o100_2);
282 
283  test_FunctionPointer00("FuncPtr6ab_o100_capture_11", false, 1, 0, f6a_o100_1, f6b_o100_1);
284  test_FunctionPointer00("FuncPtr6ab_o100_capture_22", false, 1, 0, f6a_o100_2, f6b_o100_2);
285  INFO("FuncPtr6_capture: bindCaptureFunc<int, std::shared_ptr<IntOffset>, int>: END");
286  }
287 
289  INFO("FuncPtr7_capture: bindCaptureFunc<int, IntOffset, int>: START");
290  // bindCaptureFunc(I& data, R(*func)(I&, A...))
291  // FunctionDef(Func1Type func) <int, int>
292  IntOffset offset100(100);
293  IntOffset offset1000(1000);
294 
295  int(*func7a_capture)(IntOffset&, int) = [](IntOffset& sharedOffset, int i)->int {
296  int res = i+10000+sharedOffset.value;
297  return res;
298  };
299  int(*func7b_capture)(IntOffset&, int) = [](IntOffset& sharedOffset, int i)->int {
300  int res = i+100000+sharedOffset.value;
301  return res;
302  };
303 
304 #if 0
305  MyClassFunction f7a_o100_0 = bindCaptureFunc<int, IntOffset, int>(offset100,
306  [](IntOffset& sharedOffset, int i)->int {
307  int res = i+10000+sharedOffset.value;
308  return res;;
309  } );
310  test_FunctionPointer01("FuncPtr7a_o100_capture_00", true, f7a_o100_0, f7a_o100_0);
311 #endif
312  INFO("f7a_o100_1 copy_ctor");
313  MyClassFunction f7a_o100_1 = bindCaptureFunc<int, IntOffset, int>(offset100, func7a_capture);
314  INFO("f7a_o100_1 copy_ctor done");
315  INFO("f7a_o100_2 move_ctor");
316  MyClassFunction f7a_o100_2 = bindCaptureFunc(IntOffset(100), func7a_capture);
317  INFO("f7a_o100_2 move_ctor done");
318  test_FunctionPointer01("FuncPtr7a_o100_capture_12", true, f7a_o100_1, f7a_o100_2);
319  test_FunctionPointer00("FuncPtr7a_o100_capture_11", true, 1, 10101, f7a_o100_1, f7a_o100_1);
320  test_FunctionPointer00("FuncPtr7a_o100_capture_12", true, 1, 10101, f7a_o100_1, f7a_o100_2);
321  // test_FunctionPointer01("FuncPtr7a_o100_capture_01", false, f7a_o100_0, f7a_o100_1);
322  MyClassFunction f7a_o1000_1 = bindCaptureFunc(offset1000, func7a_capture);
323  MyClassFunction f7a_o1000_2 = bindCaptureFunc(offset1000, func7a_capture);
324  test_FunctionPointer01("FuncPtr7a_o1000_capture_12", true, f7a_o1000_1, f7a_o1000_2);
325  test_FunctionPointer01("FuncPtr7a_o100_o1000_capture_11", false, f7a_o100_1, f7a_o1000_1);
326 
327  MyClassFunction f7b_o100_1 = bindCaptureFunc(offset100, func7b_capture);
328  MyClassFunction f7b_o100_2 = bindCaptureFunc(offset100, func7b_capture);
329  test_FunctionPointer00("FuncPtr7b_o100_capture_11", true, 1, 100101, f7b_o100_1, f7b_o100_1);
330  test_FunctionPointer00("FuncPtr7b_o100_capture_12", true, 1, 100101, f7b_o100_1, f7b_o100_2);
331 
332  test_FunctionPointer00("FuncPtr7ab_o100_capture_11", false, 1, 0, f7a_o100_1, f7b_o100_1);
333  test_FunctionPointer00("FuncPtr7ab_o100_capture_22", false, 1, 0, f7a_o100_2, f7b_o100_2);
334  INFO("FuncPtr7_capture: bindCaptureFunc<int, IntOffset, int>: END");
335  }
336 };
337 
338 METHOD_AS_TEST_CASE( TestFunctionDef01::test01_memberfunc_this, "Test FunctionDef 01 - 01 memberfunc");
339 METHOD_AS_TEST_CASE( TestFunctionDef01::test02_plainfunc_static, "Test FunctionDef 01 - 02 plainfunc");
340 METHOD_AS_TEST_CASE( TestFunctionDef01::test03_stdfunc_lambda, "Test FunctionDef 01 - 03 stdfunc");
341 METHOD_AS_TEST_CASE( TestFunctionDef01::test04_captfunc_lambda, "Test FunctionDef 01 - 04 captfunc");
342 METHOD_AS_TEST_CASE( TestFunctionDef01::test05_captfunc_lambda, "Test FunctionDef 01 - 05 captfunc");
343 METHOD_AS_TEST_CASE( TestFunctionDef01::test06_captfunc_lambda, "Test FunctionDef 01 - 06 captfunc");
344 
METHOD_AS_TEST_CASE
METHOD_AS_TEST_CASE(TestFunctionDef01::test01_memberfunc_this, "Test FunctionDef 01 - 01 memberfunc")
TestFunctionDef01::test03_stdfunc_lambda
void test03_stdfunc_lambda()
Definition: test_functiondef01.cpp:162
TestFunctionDef01::test02_plainfunc_static
void test02_plainfunc_static()
Definition: test_functiondef01.cpp:144
jau::bindCaptureFunc
jau::FunctionDef< R, A... > bindCaptureFunc(const I &data, R(*func)(I &, A...), bool dataIsIdentity=true) noexcept
const I& data will be copied into the InvocationFunc<..> specialization and hence captured by copy.
Definition: function_def.hpp:380
function_def.hpp
TestFunctionDef01::test01_memberfunc_this
void test01_memberfunc_this()
Definition: test_functiondef01.cpp:126
jau::FunctionDef::toString
std::string toString() const
Definition: function_def.hpp:350
TestFunctionDef01
Definition: test_functiondef01.cpp:37
jau
Definition: basic_algos.hpp:34
jau::to_string
PRAGMA_DISABLE_WARNING_POP constexpr_cxx20 std::string to_string(const endian &v) noexcept
Return std::string representation of the given jau::endian.
Definition: byte_util.hpp:198
jau::FunctionDef
Definition: function_def.hpp:309
TestFunctionDef01::test05_captfunc_lambda
void test05_captfunc_lambda()
Definition: test_functiondef01.cpp:243
jau::bindMemberFunc
jau::FunctionDef< R, A... > bindMemberFunc(C *base, R(C::*mfunc)(A...)) noexcept
Definition: function_def.hpp:361
jau::bindPlainFunc
jau::FunctionDef< R, A... > bindPlainFunc(R(*func)(A...)) noexcept
Definition: function_def.hpp:367
jau::bindStdFunc
jau::FunctionDef< R, A... > bindStdFunc(uint64_t id, std::function< R(A...)> func) noexcept
Definition: function_def.hpp:398
TestFunctionDef01::test06_captfunc_lambda
void test06_captfunc_lambda()
Definition: test_functiondef01.cpp:288
jau::FunctionDef::invoke
R invoke(A... args)
Definition: function_def.hpp:354
TestFunctionDef01::test04_captfunc_lambda
void test04_captfunc_lambda()
Definition: test_functiondef01.cpp:198
jau::operator!=
bool operator!=(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Definition: callocator.hpp:155
jau::operator==
bool operator==(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Definition: callocator.hpp:142