UgMisc 0.3
Miscellaneous C++ header library
Loading...
Searching...
No Matches
samples_types_printer.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: © 2026 Larry Chips <larry@larrychips.net>
3 * SPDX-Licence-Identifier: MIT
4 */
8#ifndef UGMISC_SAMPLES_TYPES_PRINTER_HPP
9#define UGMISC_SAMPLES_TYPES_PRINTER_HPP
10
11#include <ugmisc/member.hpp>
12#include <ugmisc/typelist.hpp>
13#include <variant>
14#include <tuple>
15#include <type_traits>
16#include <typeinfo>
17#include <utility>
18
19
21namespace _samples {
22
23UGMISC_DECL_MEMBER_ACCESS(TypeNameAccess, sTypeName);
24
25
26} /* ::_samples */
28
29
30
31
42template<typename T>
44 using Access = _samples::TypeNameAccess;
46
48 // If we are here, Calling sTypeName() failed.
49 // So we try to get the value of sTypeName.
50 // And finally fall back to typeid(U).name().
51 return value_get.get([]() {
52 return typeid(T).name();
53 });
54 })();
55}
56
57
58
59
69template<class OStream>
70class TypesPrinter {
71 OStream& oStream;
72
73 template<class T>
74 struct Types;
75
76 template<class, template<class...> class Tmp>
77 struct Template;
78
79 template<template<class...> class Tmp, class...T>
80 class Types<Tmp<T...>> {
81 using Type = Tmp<T...>;
82
83 template<class U>
84 static void printOneType(OStream& os) {
85 if constexpr ( std::is_const_v<U> ) {
86 os << " const ";
87 } else {
88 os << " ";
89 }
90 auto name = getTypeName<U>();
91 os << name;
92 if constexpr ( std::is_lvalue_reference_v<U> ) {
93 os << "&";
94 } else if constexpr ( std::is_rvalue_reference_v<U> ) {
95 os << "&&";
96 }
97 }
98
99 public:
100 static void print(OStream& os) {
101 Template<void, Tmp>::print(os);
102 constexpr auto n = sizeof...(T);
103
104 if constexpr ( n == 0 ) {
105 os << " <no types>\n";
106 } else {
107 os << " ";
108 (... , printOneType<T>(os));
109 os << "\n";
110 }
111 }
112 };
113
114 template<class V>
115 struct Template<V, std::variant> {
116 static void print(OStream& os) { os << "variant\n"; }
117 };
118
119 template<class V>
120 struct Template<V, std::tuple> {
121 static void print(OStream& os) { os << "tuple\n"; }
122 };
123
124 template<class V>
125 struct Template<V, ugmisc::type_list> {
126 static void print(OStream& os) { os << "type_list\n"; }
127 };
128
129 template<class, template<class...> class>
130 struct Template {
131 static void print(OStream& os) { os << "other\n"; }
132 };
133
134public:
135 TypesPrinter(OStream& os) : oStream(os) {}
136 TypesPrinter(const TypesPrinter&) = default;
137 TypesPrinter(TypesPrinter&&) = default;
138
139 template<class T>
140 const TypesPrinter& print() const {
141 using PlainT = std::remove_cv_t<std::remove_reference_t<T>>;
142 Types<PlainT>::print(oStream);
143 return *this;
144 }
145
146 template<class T>
147 const TypesPrinter& print(T&&) const {
148 return print<T>();
149 }
150
151 template<class T>
152 const TypesPrinter& operator()() const {
153 return print<T>();
154 }
155};
156
157template<class OStream>
159
160#endif /* UGMISC_SAMPLES_TYPES_PRINTER_HPP */
Testing for and using named static and non static members of types.
#define UGMISC_DECL_MEMBER_ACCESS(TNAME, NAME)
Definition member.hpp:150
auto getTypeName()
static constexpr member_::fallback_caller< static_member_caller, F > fallback(F &&functor)
Definition member.hpp:671
static constexpr decltype(auto) get(F &&default_get, A &&...args)
Lists of types which may be used in some of the ugmisc templates where a single type would usually be...