Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
meta/util.hpp
Go to the documentation of this file.
1/*
2 UTIL.hpp - metaprogramming helpers and utilities
3
4 Copyright (C)
5 2008, 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
14
28#ifndef LIB_META_UTIL_H
29#define LIB_META_UTIL_H
30
31#include "lib/integral.hpp"
32
33#include <typeinfo>
34#include <string>
35
36namespace std {
37
38 // forward declarations for common smart ptrs
39 template<typename T>
40 class shared_ptr;
41
42 template <typename T, typename D>
43 class unique_ptr;
44
45}
46
47
48
49namespace lib {
50 class Literal;
51 class Symbol;
52
53namespace meta {
54
55 template<size_t siz>
56 using SizConst = std::integral_constant<size_t, siz>;
57
58
59 /* === conditional definition selector === */
60
61 template <bool B, class T = void>
62 struct enable_if_c {
63 typedef T type;
64 };
65
66 template <class T>
67 struct enable_if_c<false, T> {};
68
69
86 template <class Cond, class T = void>
88
89 template <class Cond, class T = void>
91
92
93
94
95 /* === building metafunctions === */
96
99 typedef char Yes_t;
100 struct No_t { char more_than_one[4]; };
101
102
103
104
105 namespace {
113 template<typename TY>
115 {
116 template<class ZZ>
117 static Yes_t check(ZZ::type *);
118 template<class X>
119 static Yes_t check(X::Type *);
120 template<class>
121 static No_t check(...);
122
123 public:
124 static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0)));
125 };
126
127 }
129 template<typename X>
130 struct has_TypeResult : std::bool_constant<_DetectNested_TypeResult<X>::value> { };
131
132
133
134 namespace {
135 template<typename...>
137 {
138 using Type = void;
139 };
140 template<typename X, typename...XS>
141 struct _ExtractFirst<X,XS...>
142 {
143 using Type = X;
144 };
145 }
147 template<typename...XS>
148 using extractFirst_t = _ExtractFirst<XS...>::Type;
149
150
151
153 template<class SELF, typename ...ARGS>
154 using disable_if_self = disable_if<std::is_same<std::remove_cv_t<std::remove_reference_t<extractFirst_t<ARGS...>>>
155 , SELF>>;
156
157
158
166 template<typename X>
168 {
169
170 static Yes_t check_implicit(std::string);
171 static Yes_t check_implicit(std::string_view);
172 static Yes_t check_implicit(const char*);
173 static No_t check_implicit(...);
174
175
176 template<class XX, int i = sizeof(&XX::operator std::string)>
177 struct Probe
178 { };
179
180 template <class XX>
182 template <class>
183 static No_t check_explicit(...);
184
185 public:
186 static const bool value = (sizeof(Yes_t)==sizeof(check_implicit (std::declval<X>())))
187 or (sizeof(Yes_t)==sizeof(check_explicit<X>(0)));
188 };
189
191 template<typename X>
193
194
195
196
197
203 template<typename TY>
205 {
206 template<class X>
207 static Yes_t check(X::List *);
208 template<class>
209 static No_t check(...);
210
211 public:
212 static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0)));
213 };
214
215
219 template<typename FUN>
221 {
222 template<typename FF,
223 typename SEL = decltype(&FF::operator())>
224 struct Probe
225 { };
226
227 template<class X>
228 static Yes_t check(Probe<X> * );
229 template<class>
230 static No_t check(...);
231
232 public:
233 static const bool value = (sizeof(Yes_t)==sizeof(check<FUN>(0)));
234 };
235
236
243 template<class BAS, size_t m=0>
244 struct Marked
245 : BAS
246 {
247 using BAS::BAS;
248 };
249
250 template<class BAS, typename TAG =void>
251 struct Tagged
252 : BAS
253 {
254 using BAS::BAS;
255 };
256
257
258
259
260
261
262
263 /* ==== generic string representation ==== */
264
268 std::string humanReadableTypeID (lib::Literal);
269
275
278
283 std::string sanitisedSymbol(std::string const&);
284
294 std::string demangleCxx (lib::Literal rawName);
295
296
297 extern const std::string FUNCTION_INDICATOR;
298 extern const std::string FAILURE_INDICATOR;
299 extern const std::string BOTTOM_INDICATOR;
300 extern const std::string VOID_INDICATOR;
301
302 extern const std::string BOOL_FALSE_STR;
303 extern const std::string BOOL_TRUE_STR;
304
305
325 template<typename TY>
326 inline std::string
327 typeStr (TY const* obj =nullptr) noexcept
328 try {
329 auto mangledType = obj? typeid(*obj).name()
330 : typeid(TY).name();
332 }
333 catch(...)
334 { return FAILURE_INDICATOR; }
335
336 template<typename TY>
338 std::string >
339 typeStr (TY const& ref) noexcept
340 {
341 return typeStr (&ref);
342 }
343
344 inline std::string
345 typeStr (void const*) noexcept
346 {
347 return VOID_INDICATOR;
348 }
349
350
351
352
357 template<typename TY>
358 inline std::string
359 typeSymbol (TY const* obj =nullptr)
360 {
361 auto mangledType = obj? typeid(*obj).name()
362 : typeid(TY).name();
364 }
365
366 template<typename TY>
368 std::string >
369 typeSymbol (TY const& ref)
370 {
371 return typeSymbol (&ref);
372 }
373
374}}// namespace lib::meta
375
376
377
378
379namespace util {
380
381 using lib::meta::typeStr;
384
385
400 template<typename X, typename COND =void>
402 {
403 static std::string
404 invoke (X const& x) noexcept
405 try { return "«"+typeStr(x)+"»"; }
406 catch(...) { return FAILURE_INDICATOR; }
407 };
408
409 template<typename X>
410 struct StringConv<X, lib::meta::enable_CustomStringConversion<X>>
411 {
412 static std::string
413 invoke (X const& val) noexcept
414 try { return std::string(val); }
415 catch(...) { return FAILURE_INDICATOR; }
416 };
417
423 template<typename X>
425 ,std::is_same<std::remove_cv_t<X>, void>
426 > >>
427 {
428 static std::string
429 invoke (X const* ptr) noexcept
430 try { return ptr? "↗" + StringConv<X>::invoke(*ptr)
431 : BOTTOM_INDICATOR + "«"+typeStr(ptr)+"»";
432 }
433 catch(...) { return FAILURE_INDICATOR; }
434 };
435
436 // NOTE: this is meant to be extensible;
437 // more specialisations are e.g. in format-obj.hpp
438
439
440
441
445 inline std::string
446 showBool (bool yes) noexcept
447 {
448 return yes? lib::meta::BOOL_TRUE_STR
450 }
451
453 std::string showDouble (double) noexcept;
454 std::string showFloat (float) noexcept;
455
457 std::string showDecimal (double) noexcept;
458 std::string showDecimal (float) noexcept;
459 std::string showDecimal (f128) noexcept;
460
462 std::string showComplete (double) noexcept;
463 std::string showComplete (float) noexcept;
464 std::string showComplete (f128) noexcept;
465
466 std::string showSize (size_t) noexcept;
467
468
469
471 std::string showAdr (void const* addr) noexcept;
472
473 template<typename X>
475 std::string >
476 showAdr (X& elm) noexcept
477 {
478 return showAdr(&elm);
479 }
480
481
483 template<typename X>
484 inline std::string
485 showPtr (X* ptr =nullptr)
486 {
487 return ptr? showAdr(ptr) + " ↗" + StringConv<X>::invoke(*ptr)
488 : BOTTOM_INDICATOR + " «" + typeStr(ptr) + "»";
489 }
490
491 template<typename SP>
492 inline std::string
493 showSmartPtr (SP const& smPtr, std::string label = "smP")
494 {
495 using TargetType = SP::element_type;
496
497 return smPtr? label+"("+showAdr(smPtr.get()) + ") ↗" + StringConv<TargetType>::invoke(*smPtr)
498 : BOTTOM_INDICATOR + " «" + typeStr(smPtr) + "»";
499 }
500
501
502}// namespace util
503
504
505
506/* === Literals for common size designations === */
507
508inline uint
509operator""_KiB (ullong const siz)
510{
511 return uint(siz) * 1024u;
512}
513
514inline uint
515operator""_MiB (ullong const siz)
516{
517 return uint(siz) * 1024u*1024u;
518}
519
520inline ullong
521operator""_GiB (ullong const siz)
522{
523 return siz * 1024uLL*1024uLL*1024uLL;
524}
525
526
527#endif /*LIB_META_UTIL_H*/
Inline string literal.
Definition symbol.hpp:78
Trait template to detect presence of a simple function call operator.
static Yes_t check(Probe< X > *)
Trait template for detecting a typelist type.
static const bool value
static No_t check(...)
static Yes_t check(X::List *)
Inclusion for common place integral types and constants.
unsigned long long int ullong
Definition integral.hpp:33
unsigned int uint
Definition integral.hpp:29
long double f128
Definition integral.hpp:36
char more_than_one[4]
string sanitisedFullTypeName(lib::Literal rawName)
build a sanitised ID from full type name
_ExtractFirst< XS... >::Type extractFirst_t
helper to extract the first argument from a variadic arg pack, if any
std::string typeStr(TY const *obj=nullptr) noexcept
failsafe human readable type display
char Yes_t
helper types to detect the overload resolution chosen by the compiler
Definition meta/util.hpp:99
enable_if< can_convertToString< X > > enable_CustomStringConversion
toggle for explicit specialisations
disable_if< std::is_same< std::remove_cv_t< std::remove_reference_t< extractFirst_t< ARGS... > > >, SELF > > disable_if_self
helper to prevent a template constructor from shadowing inherited copy ctors
const string FUNCTION_INDICATOR
const string BOOL_TRUE_STR
string humanReadableTypeID(Literal rawType)
pretty-print an internal C++ type representation
string primaryTypeComponent(Literal rawType)
extract core name component from a raw type spec
enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition meta/util.hpp:87
string sanitisedSymbol(string const &text)
condense a string and retain only valid identifiers
string demangleCxx(Literal rawName)
Fallback type-ID:
const string VOID_INDICATOR
const string BOTTOM_INDICATOR
enable_if_c< not Cond::value, T >::type disable_if
Definition meta/util.hpp:90
const string BOOL_FALSE_STR
const string FAILURE_INDICATOR
std::integral_constant< size_t, siz > SizConst
Definition meta/util.hpp:56
Implementation namespace for support and library code.
STL namespace.
string showComplete(double val) noexcept
show enough decimal digits to represent every distinct value
string showDouble(double val) noexcept
pretty-print a double in (rounded) fixed-point format
std::string showBool(bool yes) noexcept
human readable display of boolean values
ostream & showAdr(ostream &stream, void const *addr)
preconfigured format for pretty-printing of addresses
string showSize(size_t val) noexcept
string showDecimal(double val) noexcept
show maximum reproducible decimal representation
std::string showPtr(X *ptr=nullptr)
diagnostics helper for explicitly indicating pointers
string showFloat(float val) noexcept
std::string showSmartPtr(SP const &smPtr, std::string label="smP")
#define Type(_EXPR_)
Metaprogramming helper to mark some arbitrary base type by subclassing.
detect possibility of a conversion to string.
static Yes_t check_implicit(const char *)
static Yes_t check_explicit(Probe< XX > *)
static No_t check_explicit(...)
static Yes_t check_implicit(std::string)
static Yes_t check_implicit(std::string_view)
static No_t check_implicit(...)
helper to check if another metafunction produced a result type
failsafe invocation of custom string conversion.
static std::string invoke(X const &x) noexcept