Lumiera  0.pre.03
»edit your freedom«
verb-visitor-dispatch-test.cpp
Go to the documentation of this file.
1 /*
2  VerbVisitorDispatch(Test) - Setup to dispatch to arbitrary functions on a receiver interface
3 
4  Copyright (C)
5  2019, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
20 #include "lib/test/run.hpp"
21 #include "lib/verb-visitor.hpp"
22 #include "lib/format-string.hpp"
23 #include "lib/format-cout.hpp"
24 #include "lib/format-util.hpp"
26 #include "lib/iter-explorer.hpp"
27 
28 #include <string>
29 #include <vector>
30 #include <tuple>
31 
32 using std::string;
33 using util::_Fmt;
34 using util::join;
35 using std::vector;
36 using std::forward;
37 using std::make_tuple;
38 
39 
40 namespace lib {
41 namespace test{
42 
43  namespace { // Test Fixture
44 
46  class Receiver
47  {
48  public:
49  virtual ~Receiver() { }
50 
51  virtual string woof (bool huge, uint cnt) =0;
52  virtual string honk (string) =0;
53  virtual string moo (size_t num) =0;
54  virtual string meh () =0;
55  };
56 
57 
58  using Token = VerbPack<Receiver, string, sizeof(string)>; // the argument list for honk(string) requires the most inline storage
59  using TokenSeq = vector<Token>;
60 
61 
67  : public Receiver
68  {
69  string
70  woof (bool huge, uint cnt) override
71  {
72  string woof;
73  while (0 < cnt--)
74  woof += isnil(woof)? string {huge? "Woof..":"haw-haw"}
75  : woof;
76  return woof;
77  }
78  string
79  honk (string theHonk) override
80  {
81  return theHonk+"-"+theHonk+"!";
82  }
83  string
84  moo (size_t num) override
85  {
86  return join (vector<string>{num, "Moo"}, "__");
87  }
88  string
89  meh() override
90  {
91  return "Meh?";
92  }
93  };
94 
99  : public Receiver
100  {
101  string woof (bool huge, uint cnt) override { return report("woof", huge, cnt); }
102  string honk (string theHonk) override { return report("honk", theHonk); }
103  string moo (size_t num) override { return report("moo", num); }
104  string meh() override { return report("meh"); }
105 
106  template<typename...ARGS>
107  string
108  report (Literal func, ARGS&&...args)
109  {
110  return string(func)
111  + meta::dump (make_tuple (forward<ARGS>(args)...));
112  }
113  };
114 
115  }//(End)Test Fixture
116 
117 
118 
119 
120 
121 
122  /***********************************************************************/
129  class VerbVisitorDispatch_test : public Test
130  {
131 
132  virtual void
133  run (Arg)
134  {
135  TokenSeq tokens = build_and_copy_tokens();
136  apply_VerboseRenderer (tokens);
137  apply_different_receivers (tokens);
138  verify_copy_and_equality (tokens);
139  }
140 
141 
145  TokenSeq
147  {
148  Token littleWoof(&Receiver::woof, "woof", 0, 3); // NOTE: argument type conversion
149  Token bigWoof(&Receiver::woof, "woof", true, 2);
150  Token quack(&Receiver::honk, "honk", "quaack");
151  Token honk(&Receiver::honk, "honk", "Hoonk");
152  Token moo(&Receiver::moo, "moo", 3);
153  Token meh(&Receiver::meh, "meh");
154 
155  CHECK (sizeof(Token) == sizeof(string) // storage size reserved for the arguments (by declaration of type Token)
156  + sizeof(void*) // additional overhead for the VTable for dispatch
157  + sizeof(void(Receiver::*)()) // storage for the function pointer to the interface function
158  + sizeof(Literal) // storage for the verb symbol (for diagnostics and equality comparisions)
159  );
160 
161  // add LVal-copies to result sequence
162  return TokenSeq{{littleWoof, quack, honk, bigWoof, moo, meh}};
163  }
164 
170  void
171  apply_VerboseRenderer (TokenSeq& tokens)
172  {
173  VerboseRenderer receiver;
174  for (Token& tok : tokens)
175  cout << "dispatching " << tok
176  << " -> '"
177  << tok.applyTo(receiver)
178  << "'\n";
179  }
180 
187  void
188  apply_different_receivers (TokenSeq& tokens)
189  {
190  VerboseRenderer verbose;
191  DiagnosticRenderer diagnostic;
192  auto render = [&](Receiver& renderer)
193  {
194  return join (lib::explore(tokens)
195  .transform ([&](Token tok)
196  {
197  return tok.applyTo (renderer);
198  })
199  ,"-");
200  };
201 
202  CHECK (render(diagnostic) == "woof(false,3)-honk(quaack)-honk(Hoonk)-woof(true,2)-moo(3)-meh()");
203  CHECK (render(verbose) == "haw-hawhaw-hawhaw-hawhaw-haw-quaack-quaack!-Hoonk-Hoonk!-Woof..Woof..-Moo__Moo__Moo-Meh?");
204  }
205 
206 
207  void
208  verify_copy_and_equality (TokenSeq& tokens)
209  {
210  Token bigWoof = tokens[3];
211  Token oldWoof{&Receiver::woof, "woof", true, 1};
212  Token oldWolf{&Receiver::woof, "wolf", true, 0};
213 
214  CHECK (bigWoof == oldWoof);
215  CHECK (bigWoof != oldWolf);
216 
217  CHECK (not util::isSameObject (bigWoof, oldWoof));
218  CHECK (string(bigWoof) == "VerbPack(woof)");
219  CHECK (string(oldWoof) == "VerbPack(woof)");
220  CHECK (string(oldWolf) == "VerbPack(wolf)");
221 
222  VerboseRenderer bark;
223  CHECK (bigWoof.applyTo(bark) == "Woof..Woof..");
224  CHECK (oldWoof.applyTo(bark) == "Woof..");
225  CHECK (oldWolf.applyTo(bark) == "");
226  }
227  };
228 
229 
231  LAUNCHER (VerbVisitorDispatch_test, "unit common");
232 
233 
234 
235 }} // namespace lib::test
Automatically use custom string conversion in C++ stream output.
auto explore(IT &&srcSeq)
start building a IterExplorer by suitably wrapping the given iterable source.
a concrete receiver of verb-tokens, which renders them verbosely
Definition: run.hpp:40
A self-contained token to embody a specific yet abstracted operation, together with a concrete set of...
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:76
Front-end for printf-style string template interpolation.
A front-end for using printf-style formatting.
Implementation namespace for support and library code.
Metaprogramming with tuples-of-types and the std::tuple record.
Simplistic test class runner.
A specific double dispatch variation for function invocation.
another concrete receiver to report any invocation with arguments
Collection of small helpers and convenience shortcuts for diagnostics & formatting.
Building tree expanding and backtracking evaluations within hierarchical scopes.
the "visitor" interface used by all VerbPacks in this test