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
39template<typename T>
40inline auto getTypeName() {
41 using Access = _samples::TypeNameAccess;
43
45 // If we are here, Calling sTypeName() failed.
46 // So we try to get the value of sTypeName.
47 // And finally fall back to typeid(U).name().
48 return value_get.get([]() {
49 return typeid(T).name();
50 });
51 })();
52}
53
54
55
56
63template<class OStream>
64class TypesPrinter {
65 OStream& oStream;
66
67 template<class T>
68 struct Types;
69
70 template<class, template<class...> class Tmp>
71 struct Template;
72
73 template<template<class...> class Tmp, class...T>
74 class Types<Tmp<T...>> {
75 using Type = Tmp<T...>;
76
77 template<class U>
78 static void printOneType(OStream& os) {
79 if constexpr ( std::is_const_v<U> ) {
80 os << " const ";
81 } else {
82 os << " ";
83 }
84 auto name = getTypeName<U>();
85 os << name;
86 if constexpr ( std::is_lvalue_reference_v<U> ) {
87 os << "&";
88 } else if constexpr ( std::is_rvalue_reference_v<U> ) {
89 os << "&&";
90 }
91 }
92
93 public:
94 static void print(OStream& os) {
95 Template<void, Tmp>::print(os);
96 constexpr auto n = sizeof...(T);
97
98 if constexpr ( n == 0 ) {
99 os << " <no types>\n";
100 } else {
101 os << " ";
102 (... , printOneType<T>(os));
103 os << "\n";
104 }
105 }
106 };
107
108 template<class V>
109 struct Template<V, std::variant> {
110 static void print(OStream& os) { os << "variant\n"; }
111 };
112
113 template<class V>
114 struct Template<V, std::tuple> {
115 static void print(OStream& os) { os << "tuple\n"; }
116 };
117
118 template<class V>
119 struct Template<V, ugmisc::type_list> {
120 static void print(OStream& os) { os << "type_list\n"; }
121 };
122
123 template<class, template<class...> class>
124 struct Template {
125 static void print(OStream& os) { os << "other\n"; }
126 };
127
128public:
129 TypesPrinter(OStream& os) : oStream(os) {}
130 TypesPrinter(const TypesPrinter&) = default;
131 TypesPrinter(TypesPrinter&&) = default;
132
133 template<class T>
134 const TypesPrinter& print() const {
135 using PlainT = std::remove_cv_t<std::remove_reference_t<T>>;
136 Types<PlainT>::print(oStream);
137 return *this;
138 }
139
140 template<class T>
141 const TypesPrinter& print(T&&) const {
142 return print<T>();
143 }
144
145 template<class T>
146 const TypesPrinter& operator()() const {
147 return print<T>();
148 }
149};
150
151template<class OStream>
153
154#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:148
static constexpr member_::fallback_caller< static_member_caller, F > fallback(F &&functor)
Definition member.hpp:669
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...