repr 0.1
Reconstructable string representations and more
Loading...
Searching...
No Matches
cpp.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <string>
5#include <string_view>
6#include <type_traits>
7
9#include <librepr/name/type.h>
15
16namespace librepr {
17struct CppVisitor {
22
23private:
24 template <typename T>
26 auto name(T const& info) {
27 return std::string{info.name()};
28 }
29
30 template <typename T>
31 auto name(T const&) {
33 return REPR_FORMAT("UNNAMED_{}", unnamed_count);
34 }
35
36 template <typename T>
37 void print_name(T const& info) {
38 if constexpr (std::is_const_v<typename T::type>){
39 result << " const";
40 }
41 result << ' ' << name(info);
42 }
43
44 [[nodiscard]] auto get_indent() const { return std::string(indent_amount * indent_level, ' '); }
45
46 void print_struct(category::has_members auto info, std::string_view name) {
47 result << get_indent() << "struct " << name << " {\n";
48
50 info.visit(*this);
52
53 result << get_indent() << '}';
54 }
55
56public:
57 template <category::has_members T>
58 auto operator()(T info) {
59 auto full_name = info.type_name();
60 auto name = std::string_view{full_name};
61
62 if constexpr (category::has_parent<T>) {
63 auto parent_name = T::parent::type_name();
64 if (name.starts_with(parent_name)) {
65 name.remove_prefix(parent_name.size() + 2);
66 print_struct(info, name);
67 } else {
68 // namespace mismatch -> defined out of line
71 indent_level = 0;
72
74 if (auto pos = name.rfind("::"); pos != std::string_view::npos) {
75 namespace_ = name.substr(0, pos);
76 name = name.substr(pos + 2);
77 }
78 if (!namespace_.empty()) {
79 result << get_indent() << "namespace " << namespace_ << " { \n";
80 }
81
82 print_struct(info, name);
83 result << ";\n";
84
85 if (!namespace_.empty()) {
86 result << "}\n";
87 }
90 result << get_indent() << full_name; // output type name
91 }
92 } else {
93 print_struct(info, name);
94 }
95
96 if (indent_level != 0){
97 print_name(info);
98 }
99 result << ";\n";
100 }
101
102 template <typename T>
104 auto operator()(T info) {
105 result << get_indent() << "enum ";
107 if constexpr (is_scoped) {
108 result << "class ";
109 }
110
111 auto raw_name = info.type_name();
112 auto name = std::string_view{raw_name};
113 if constexpr (category::has_parent<T>){
114 auto parent_name = T::parent::type_name();
115 if (name.starts_with(parent_name)) {
116 name.remove_prefix(parent_name.size() + 2);
117 }
118 }
119
120 result << name << " {\n";
121 ++indent_level;
122 for (auto const& enumerator : info.enumerator_names) {
123 auto name = (is_scoped) ? enumerator : enumerator.substr(enumerator.rfind("::") + 2);
124 result << get_indent() << name << ",\n";
125 }
126 --indent_level;
127 result << get_indent() << "}";
128 print_name(info);
129 result << ";\n";
130 }
131
132 template <typename T>
134 auto operator()(T info) {
136 print_name(info);
137 result << '[' << std::to_string(info.extent) << "];\n";
138 }
139
140 template <typename T>
141 auto operator()(T info) {
142 result << get_indent() << info.type_name();
143 print_name(info);
144 result << ";\n";
145 }
146};
147} // namespace librepr
#define REPR_FORMAT(...)
Definition category.h:29
Definition category.h:20
Definition category.h:23
Definition concepts.h:21
Definition ctvi/ctvi.h:9
std::string code_for()
Definition repr:39
Definition cpp.h:17
std::size_t unnamed_count
Definition cpp.h:20
auto operator()(T info)
Definition cpp.h:104
std::size_t indent_level
Definition cpp.h:18
auto operator()(T info)
Definition cpp.h:58
detail::StringBuffer result
Definition cpp.h:21
std::size_t indent_amount
Definition cpp.h:19
auto operator()(T info)
Definition cpp.h:134
Wrapper around std::string.
Definition buffer.h:14
void set_cursor(std::size_t index=std::string::npos)
Definition buffer.h:77
T to_string(T... args)