Lumiera  0.pre.03
»edit your freedom«
late-bind-instance-test.cpp
Go to the documentation of this file.
1 /*
2  LateBindInstance(Test) - verify rewriting of member function invocation
3 
4  Copyright (C) Lumiera.org
5  2023, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/test/run.hpp"
29 #include "lib/meta/function.hpp"
31 #include "lib/test/test-helper.hpp"
32 #include "lib/test/testdummy.hpp"
33 #include "lib/format-cout.hpp"
34 #include "lib/format-util.hpp"
35 #include "lib/util.hpp"
36 
37 #include <tuple>
38 #include <string>
39 #include <cstdlib>
40 
41 
42 namespace lib {
43 namespace meta {
44 namespace test {
45 
46  using std::move;
47  using std::rand;
48  using std::tuple;
49  using std::string;
50  using lib::meta::dump;
51  using lib::test::Tracker;
52 
53 
54 
55 
56 
57 
58  /**********************************************************************************/
66  class LateBindInstance_test : public Test
67  {
68  void
69  run (Arg)
70  {
74  }
75 
76 
77 
84  void
86  {
87  uint randomLimit = 2 + rand() % 98;
88 
89  auto plannedArgs
91  ,randomLimit
92  };
93 
94  // the actual instance may be available only later...
95  Test& instanceRef = *this;
96 
97  // now rewrite the argument tuple to inject the instance-ptr
98  auto preparedArgs = lateBindInstance (instanceRef, plannedArgs);
99 
100  uint res = std::apply (&LateBindInstance_test::theMember, preparedArgs);
101  CHECK (res < randomLimit);
102  }
103 
104  uint
105  theMember (uint limit)
106  {
107  return rand() % limit;
108  }
109 
110 
111 
114  void
116  {
117  auto& log = Tracker::log;
118  log.clear (this);
119 
121  Tracker t1(11);
122 
123  log.event("construct tuple");
124  tuple tup(t1, marker, Tracker{23}, 55);
125 
126  Test& instanceRef = *this;
127 
128  log.event("invoke lateBindInstance");
129  auto tup1r = lateBindInstance (instanceRef, tup);
130  log.event("got result");
131 
132  // before invocation the Tracker instances are created (obviously..)
133  CHECK (log.verifyCall("ctor").arg(11)
134  .beforeCall("ctor-copy").arg("Track{11}")
135  .beforeEvent("invoke lateBindInstance"));
136  CHECK (log.verifyCall("ctor").arg(23)
137  .beforeCall("ctor-move").arg("Track{23}")
138  .beforeCall("dtor").arg(Tracker::DEFUNCT)
139  .beforeEvent("invoke lateBindInstance"));
140 
141  // but there is no copy operation after the invocation
142  CHECK (log.ensureNot("ctor-copy")
143  .afterEvent("invoke lateBindInstance"));
144 
145  // both Tracker instances are moved two times
146  // - once to create the maybeInject-invocation and
147  // - once to consolidate the result
148  // for each instance one moved-away temporary is destroyed
149  CHECK (log.verifyEvent("invoke lateBindInstance")
150  .beforeCall("ctor-move").arg("Track{11}")
151  .beforeCall("ctor-move").arg("Track{11}")
152  .beforeCall("dtor").arg(Tracker::DEFUNCT)
153  .beforeEvent("got result"));
154  CHECK (log.verifyEvent("invoke lateBindInstance")
155  .beforeCall("ctor-move").arg("Track{23}")
156  .beforeCall("ctor-move").arg("Track{23}")
157  .beforeCall("dtor").arg(Tracker::DEFUNCT)
158  .beforeEvent("got result"));
159 
160  cout << "____Tracker-Log_______________\n"
161  << util::join(Tracker::log, "\n")
162  << "\n───╼━━━━━━━━━━━╾──────────────"<<endl;
163  }
164 
165 
168  void
170  {
171  long dummy{555};
173  CHECK (dump(lateBindInstance (dummy, tuple<>{})) == "()"_expect);
174  CHECK (dump(lateBindInstance (dummy, tuple{42})) == "(42)"_expect);
175  CHECK (dump(lateBindInstance (dummy, tuple{1,2,3})) == "(1,2,3)"_expect);
176  CHECK (dump(lateBindInstance (dummy, tuple{marker,2,3})) == "(↗555,2,3)"_expect);
177  CHECK (dump(lateBindInstance (dummy, tuple{1,marker,3})) == "(1,↗555,3)"_expect);
178  CHECK (dump(lateBindInstance (dummy, tuple{1,2,marker})) == "(1,2,↗555)"_expect);
179  CHECK (dump(lateBindInstance (dummy, tuple{marker})) == "(↗555)"_expect);
180  CHECK (dump(lateBindInstance (dummy, tuple{string{"1"}
181  ,"2"
182  ,marker
183  ,tuple(2,3)
184  , 5.5
185  })) == "(1,2,↗555,«tuple<int, int>»──(2,3),5.5)"_expect);
186  }
187  };
188 
189 
191  LAUNCHER (LateBindInstance_test, "unit meta");
192 
193 
194 
195 }}} // namespace lib::meta::test
constexpr auto lateBindInstance(W &instance, TUP &&invocation)
Fix-up the arguments for a member-function invocation, allowing to inject the actual this instance in...
Definition: function.hpp:327
Automatically use custom string conversion in C++ stream output.
Definition: run.hpp:49
Implementation namespace for support and library code.
unittest helper code: test dummy objects to track instances.
Metaprogramming with tuples-of-types and the std::tuple record.
Placeholder marker for a special argument position to be supplied later.
Definition: function.hpp:293
Metaprogramming tools for transforming functor types.
A tracking Dummy object for tests.
Definition: testdummy.hpp:145
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A collection of frequently used helper functions to support unit testing.
Collection of small helpers and convenience shortcuts for diagnostics & formatting.
std::string dump(std::tuple< TYPES... > const &tuple)
convenience function to dump a given tuple&#39;s contents.