Lumiera  0.pre.03
»edit your freedom«
meta/util.hpp
Go to the documentation of this file.
1 /*
2  UTIL.hpp - metaprogramming helpers and utilities
3 
4  Copyright (C) Lumiera.org
5  2008, 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 
23 
37 #ifndef LIB_META_UTIL_H
38 #define LIB_META_UTIL_H
39 
40 
41 #include <typeinfo>
42 #include <string>
43 
44 namespace std {
45 
46  // forward declarations for common smart ptrs
47  template<typename T>
48  class shared_ptr;
49 
50  template <typename T, typename D>
51  class unique_ptr;
52 
53 }
54 
55 
56 
57 namespace lib {
58  class Literal;
59  class Symbol;
60 
61 namespace meta {
62 
63  /* === conditional definition selector === */
64 
65  template <bool B, class T = void>
66  struct enable_if_c {
67  typedef T type;
68  };
69 
70  template <class T>
71  struct enable_if_c<false, T> {};
72 
73 
90  template <class Cond, class T = void>
91  using enable_if = typename enable_if_c<Cond::value, T>::type;
92 
93  template <class Cond, class T = void>
94  using disable_if = typename enable_if_c<not Cond::value, T>::type;
95 
96 
97 
98 
99  /* === building metafunctions === */
100 
103  typedef char Yes_t;
104  struct No_t { char more_than_one[4]; };
105 
106 
107 
108 
109  namespace {
117  template<typename TY>
119  {
120  template<class ZZ>
121  static Yes_t check(typename ZZ::type *);
122  template<class X>
123  static Yes_t check(typename X::Type *);
124  template<class>
125  static No_t check(...);
126 
127  public:
128  static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0)));
129  };
130 
131  }
133  template<typename X>
134  struct has_TypeResult : std::bool_constant<_DetectNested_TypeResult<X>::value> { };
135 
136 
137 
145  template<typename X>
147  {
148 
149  static Yes_t check_implicit(std::string);
150  static No_t check_implicit(...);
151 
152 
153  template<class XX, int i = sizeof(&XX::operator std::string)>
154  struct Probe
155  { };
156 
157  template <class XX>
158  static Yes_t check_explicit(Probe<XX> * );
159  template <class>
160  static No_t check_explicit(...);
161 
162  public:
163  static const bool value = (sizeof(Yes_t)==sizeof(check_implicit (std::declval<X>())))
164  or (sizeof(Yes_t)==sizeof(check_explicit<X>(0)));
165  };
166 
168  template<typename X>
170 
171 
172 
173 
179  template<typename TY>
181  {
182  template<class X>
183  static Yes_t check(typename X::List *);
184  template<class>
185  static No_t check(...);
186 
187  public:
188  static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0)));
189  };
190 
191 
195  template<typename FUN>
197  {
198  template<typename FF,
199  typename SEL = decltype(&FF::operator())>
200  struct Probe
201  { };
202 
203  template<class X>
204  static Yes_t check(Probe<X> * );
205  template<class>
206  static No_t check(...);
207 
208  public:
209  static const bool value = (sizeof(Yes_t)==sizeof(check<FUN>(0)));
210  };
211 
212 
219  template<class BAS, size_t m=0>
220  struct Marked
221  : BAS
222  {
223  using BAS::BAS;
224  };
225 
226 
227 
228 
229 
230 
231 
232 
233  /* ==== generic string representation ==== */
234 
238  std::string humanReadableTypeID (lib::Literal);
239 
244  std::string primaryTypeComponent (lib::Literal);
245 
247  std::string sanitisedFullTypeName(lib::Literal);
248 
253  std::string sanitisedSymbol(std::string const&);
254 
264  std::string demangleCxx (lib::Literal rawName);
265 
266 
267  extern const std::string FUNCTION_INDICATOR;
268  extern const std::string FAILURE_INDICATOR;
269  extern const std::string BOTTOM_INDICATOR;
270  extern const std::string VOID_INDICATOR;
271 
272  extern const std::string BOOL_FALSE_STR;
273  extern const std::string BOOL_TRUE_STR;
274 
275 
295  template<typename TY>
296  inline std::string
297  typeStr (TY const* obj =nullptr) noexcept
298  try {
299  auto mangledType = obj? typeid(*obj).name()
300  : typeid(TY).name();
301  return humanReadableTypeID (mangledType);
302  }
303  catch(...)
304  { return FAILURE_INDICATOR; }
305 
306  template<typename TY>
307  inline disable_if<std::is_pointer<TY>,
308  std::string >
309  typeStr (TY const& ref) noexcept
310  {
311  return typeStr (&ref);
312  }
313 
314  inline std::string
315  typeStr (void const*) noexcept
316  {
317  return VOID_INDICATOR;
318  }
319 
320 
321 
322 
327  template<typename TY>
328  inline std::string
329  typeSymbol (TY const* obj =nullptr)
330  {
331  auto mangledType = obj? typeid(*obj).name()
332  : typeid(TY).name();
333  return primaryTypeComponent (mangledType);
334  }
335 
336  template<typename TY>
337  inline disable_if<std::is_pointer<TY>,
338  std::string >
339  typeSymbol (TY const& ref)
340  {
341  return typeSymbol (&ref);
342  }
343 
344 }}// namespace lib::meta
345 
346 
347 
348 
349 namespace util {
350 
351  using lib::meta::typeStr;
352  using lib::meta::FAILURE_INDICATOR;
353  using lib::meta::BOTTOM_INDICATOR;
354 
355 
370  template<typename X, typename COND =void>
371  struct StringConv
372  {
373  static std::string
374  invoke (X const& x) noexcept
375  try { return "«"+typeStr(x)+"»"; }
376  catch(...) { return FAILURE_INDICATOR; }
377  };
378 
379  template<typename X>
380  struct StringConv<X, lib::meta::enable_CustomStringConversion<X>>
381  {
382  static std::string
383  invoke (X const& val) noexcept
384  try { return std::string(val); }
385  catch(...) { return FAILURE_INDICATOR; }
386  };
387 
393  template<typename X>
394  struct StringConv<X*, lib::meta::disable_if<std::__or_<std::is_same<std::remove_cv_t<X>, char>
395  ,std::is_same<std::remove_cv_t<X>, void>
396  > >>
397  {
398  static std::string
399  invoke (X const* ptr) noexcept
400  try { return ptr? "↗" + StringConv<X>::invoke(*ptr)
401  : BOTTOM_INDICATOR + "«"+typeStr(ptr)+"»";
402  }
403  catch(...) { return FAILURE_INDICATOR; }
404  };
405 
406  // NOTE: this is meant to be extensible;
407  // more specialisations are e.g. in format-obj.hpp
408 
409 
410 
411 
415  inline std::string
416  showBool (bool yes) noexcept
417  {
418  return yes? lib::meta::BOOL_TRUE_STR
419  : lib::meta::BOOL_FALSE_STR;
420  }
421 
423  std::string showDouble (double) noexcept;
424  std::string showFloat (float) noexcept;
425 
426 
427 
428 
430  std::string showAddr (void const* addr) noexcept;
431 
432  template<typename X>
433  inline std::string
434  showAddr (X& elm) noexcept
435  {
436  return showAddr(&elm);
437  }
438 
439 
441  template<typename X>
442  inline std::string
443  showPtr (X* ptr =nullptr)
444  {
445  return ptr? showAddr(ptr) + " ↗" + StringConv<X>::invoke(*ptr)
446  : BOTTOM_INDICATOR + " «" + typeStr(ptr) + "»";
447  }
448 
449  template<typename SP>
450  inline std::string
451  showSmartPtr (SP const& smPtr, std::string label = "smP")
452  {
453  using TargetType = typename SP::element_type;
454 
455  return smPtr? label+"("+showAddr(smPtr.get()) + ") ↗" + StringConv<TargetType>::invoke(*smPtr)
456  : BOTTOM_INDICATOR + " «" + typeStr(smPtr) + "»";
457  }
458 
459 
460 }// namespace util
461 #endif /*LIB_META_UTIL_H*/
ostream & showAddr(ostream &stream, void const *addr)
preconfigured format for pretty-printing of addresses
Definition: format-obj.cpp:377
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:75
STL namespace.
string showDouble(double val) noexcept
pretty-print a double in fixed-point format
Definition: format-obj.cpp:341
helper to check if another metafunction produced a result type
Definition: meta/util.hpp:134
std::string showBool(bool yes) noexcept
human readable display of boolean values
Definition: meta/util.hpp:416
Implementation namespace for support and library code.
typename enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition: meta/util.hpp:91
string primaryTypeComponent(Literal rawType)
extract core name component from a raw type spec
Definition: format-obj.cpp:260
enable_if< can_convertToString< X > > enable_CustomStringConversion
toggle for explicit specialisations
Definition: meta/util.hpp:169
string sanitisedFullTypeName(lib::Literal rawName)
build a sanitised ID from full type name
Definition: format-obj.cpp:298
string demangleCxx(Literal rawName)
Fallback type-ID:
Definition: format-obj.cpp:158
Trait template for detecting a typelist type.
Definition: meta/util.hpp:180
char Yes_t
helper types to detect the overload resolution chosen by the compiler
Definition: meta/util.hpp:103
string humanReadableTypeID(Literal rawType)
pretty-print an internal C++ type representation
Definition: format-obj.cpp:189
detect possibility of a conversion to string.
Definition: meta/util.hpp:146
Metaprogramming helper to mark some arbitrary base type by subclassing.
Definition: meta/util.hpp:220
string sanitisedSymbol(string const &text)
condense a string and retain only valid identifiers
Definition: format-obj.cpp:305
std::string showPtr(X *ptr=nullptr)
diagnostics helper for explicitly indicating pointers
Definition: meta/util.hpp:443
failsafe invocation of custom string conversion.
Definition: meta/util.hpp:371
std::string typeStr(TY const *obj=nullptr) noexcept
failsafe human readable type display
Definition: meta/util.hpp:297
ElementBoxWidget::Config::Qualifier name(string id)
define the name-ID displayed in the caption
Trait template to detect presence of a simple function call operator.
Definition: meta/util.hpp:196