Lumiera  0.pre.03
»edityourfreedom«
duck-detector-extension-test.cpp
Go to the documentation of this file.
1 /*
2  DuckDetectorExtension(Test) - detecting support for extension points at compile time
3 
4  Copyright (C) Lumiera.org
5  2017, 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"
30 #include "lib/util.hpp"
31 
32 #include <string>
33 
34 
35 namespace lib {
36 namespace meta{
37 namespace test{
38 
39  using std::string;
40 
41 
42  namespace { // test types and definitions to explore....
43 
44  void
45  fun (long)
46  { }
47 
48  int
49  fun (string, long)
50  {
51  return 12;
52  }
53 
54  void
55  fun ()
56  { }
57 
58 
59  class Cheesy
60  {
61  public:
62  double funny (char, char, string);
63  void funky() const;
64  short fuzzy (float, float);
65  long long fuzzy();
66  double fully;
67  };
68 
69  class Fishy
70  {
72  long long fuzzy();
73 
75  friend void fun (Fishy&);
76  };
77 
78 
79  }//(End) test definitions
80 
81 
82 
83 
84  /***********************************************************************************/
99  class DuckDetectorExtension_test : public Test
100  {
101 
104 
105  META_DETECT_FUNCTION (double, funny, (char, char, string));
106  META_DETECT_FUNCTION (long long, fuzzy, (void));
111  META_DETECT_MEMBER(funny);
112  META_DETECT_MEMBER(funky);
113  META_DETECT_MEMBER(fuzzy);
114  META_DETECT_MEMBER(fully);
118 
119 
120  void
122  {
123  detect_freeFunctionADL_ExtensionPoint();
124  detect_memberFunctionVariations();
125  }
126 
127 
143  void
145  {
146  fun ();
147  fun (23);
148  fun ("FUN", 45);
149 
150  CHECK ( not HasExtensionPoint_funZ<long>::value );
151 
152  CHECK ( HasExtensionPoint_fun<long> ::value );
153  CHECK ( HasExtensionPoint_fun<long&> ::value );
154  CHECK ( HasExtensionPoint_fun<long&&> ::value );
155  CHECK ( HasExtensionPoint_fun<char> ::value );
156  CHECK ( HasExtensionPoint_fun<char&> ::value );
157  CHECK ( HasExtensionPoint_fun<char&&> ::value );
158  CHECK ( not HasExtensionPoint_fun<string> ::value );
159  CHECK ( not HasExtensionPoint_fun<void> ::value );
160 
161  CHECK ( not HasExtensionPoint_fun<Cheesy> ::value );
162  CHECK ( not HasExtensionPoint_fun<Fishy> ::value );
163  CHECK ( HasExtensionPoint_fun<Fishy&> ::value );
164  CHECK ( not HasExtensionPoint_fun<Fishy&&> ::value );
165  CHECK ( not HasExtensionPoint_fun<Fishy const&>::value );
166 
167  CHECK ( not HasExtensionPoint_fun<Fishy const&>::value );
168  }
169 
170 
180  void
182  {
183  CHECK ( HasFunSig_funny<Cheesy> ::value ); // explicit function signature detected
184  CHECK ( HasFunSig_funny<Cheesy const> ::value ); // const qualifier is irrelevant
185  CHECK ( not HasFunSig_funny<Cheesy const&> ::value ); // but reference does not work, obviously
186 
187  CHECK ( HasFunSig_fuzzy<Cheesy> ::value ); // explicit function signature detected, overload is irrelevant
188 
189  CHECK ( HasFunName_funny<Cheesy> ::value ); // function name detected (arguments irrelevant)
190  CHECK ( HasFunName_funky<Cheesy> ::value ); // detected irrespective of const modifier
191  CHECK ( not HasFunName_fuzzy<Cheesy> ::value ); // function name fuzzy *not* detected due to overload ambiguity
192  CHECK ( not HasFunName_fully<Cheesy> ::value ); // name fully is a member, not a function
193 
194  CHECK ( HasMember_funny<Cheesy> ::value ); // 'funny' is not only a function, it is also a member
195  CHECK ( HasMember_funky<Cheesy> ::value );
196  CHECK ( not HasMember_fuzzy<Cheesy> ::value ); // WARNING: member 'fuzzy' *not* detected due to overload ambiguity
197  CHECK ( HasMember_fully<Cheesy> ::value ); // 'fully' is not a function, but it is detected as member here
198 
199  CHECK ( not HasArglessFun_funny<Cheesy> ::value ); // there is no argument less function 'funny' (it takes arguments)
200  CHECK ( HasArglessFun_funky<Cheesy> ::value ); // but an argument-less 'funky'
201  CHECK ( HasArglessFun_fuzzy<Cheesy> ::value ); // and one of the 'fuzzy' overloads also takes no arguments
202 
203  CHECK ( not HasFunSig_fuzzy<Fishy> ::value ); // Fishy::fuzzy() is private and can thus never be detected
204  CHECK ( not HasFunSig_funny<Fishy> ::value ); // and no fun with Fishy beyond that...
205  CHECK ( not HasFunName_funny<Fishy> ::value );
206  CHECK ( not HasFunName_funky<Fishy> ::value );
207  CHECK ( not HasFunName_fuzzy<Fishy> ::value );
208  CHECK ( not HasFunName_fully<Fishy> ::value );
209  CHECK ( not HasMember_funny<Fishy> ::value );
210  CHECK ( not HasMember_funky<Fishy> ::value );
211  CHECK ( not HasMember_fuzzy<Fishy> ::value );
212  CHECK ( not HasMember_fully<Fishy> ::value );
213  CHECK ( not HasArglessFun_funny<Fishy> ::value );
214  CHECK ( not HasArglessFun_funky<Fishy> ::value );
215  CHECK ( not HasArglessFun_fuzzy<Fishy> ::value );
216  CHECK ( not HasFunSig_fuzzy<short> ::value );
217  }
218  };
219 
220 
222  LAUNCHER (DuckDetectorExtension_test, "unit meta");
223 
224 
225 
226 }}} // namespace lib::meta::test
Definition: run.hpp:49
#define META_DETECT_MEMBER(_NAME_)
Detector for a nested member (field or function).
#define META_DETECT_FUNCTION(_RET_TYPE_, _FUN_NAME_, _ARGS_)
Detector for a specific member function.
Implementation namespace for support and library code.
#define META_DETECT_FUNCTION_ARGLESS(_FUN_)
Detector for an argument-less member function with the given name.
LAUNCHER(ConfigFlags_test, "unit common")
Register this test class...
std::vector< string > & Arg
Definition: run.hpp:54
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
#define META_DETECT_FUNCTION_NAME(_FUN_NAME_)
Detector for a member function with the given name.
#define META_DETECT_EXTENSION_POINT(_FUN_)
Detector for support of a free-function extension point.
Metaprogramming helpers to check for specific properties of a type in question.