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
8
#include <
librepr/macro/format.h
>
9
#include <
librepr/name/type.h
>
10
#include <
librepr/reflection/aggregate.h
>
11
#include <
librepr/reflection/category.h
>
12
#include <
librepr/util/concepts.h
>
13
#include <
librepr/util/string/buffer.h
>
14
#include <
librepr/reflection/reflect.h
>
15
16
namespace
librepr
{
17
struct
CppVisitor
{
18
std::size_t
indent_level
= 0;
19
std::size_t
indent_amount
= 4;
20
std::size_t
unnamed_count
= 0;
21
detail::StringBuffer
result
;
22
23
private
:
24
template
<
typename
T>
25
requires
category::has_name<T>
26
auto
name(T
const
&
info
) {
27
return
std::string
{
info
.name()};
28
}
29
30
template
<
typename
T>
31
auto
name(T
const
&) {
32
++
unnamed_count
;
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
49
indent_level
++;
50
info
.visit(*
this
);
51
indent_level
--;
52
53
result
<< get_indent() <<
'}'
;
54
}
55
56
public
:
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
69
result
.
set_cursor
(0);
70
auto
last_indent
=
indent_level
;
71
indent_level
= 0;
72
73
std::string_view
namespace_
{};
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
}
88
indent_level
=
last_indent
;
89
result
.
set_cursor
();
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>
103
requires
librepr::category::has_enumerator_names<T>
104
auto
operator()
(T
info
) {
105
result
<< get_indent() <<
"enum "
;
106
constexpr
auto
is_scoped
=
detail::is_scoped_enum<typename T::type>
;
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>
133
requires
category::has_extent<T>
134
auto
operator()
(T
info
) {
135
result << get_indent() << get_name<typename T::element_type>
();
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
aggregate.h
REPR_FORMAT
#define REPR_FORMAT(...)
std::string
std::string_view
buffer.h
category.h
librepr::category::has_enumerator_names
Definition
category.h:37
librepr::category::has_extent
Definition
category.h:29
librepr::category::has_name
Definition
category.h:20
librepr::category::has_parent
Definition
category.h:23
librepr::detail::is_scoped_enum
Definition
concepts.h:21
concepts.h
cstddef
format.h
librepr
Definition
ctvi/ctvi.h:9
librepr::code_for
std::string code_for()
Definition
repr:39
reflect.h
std::size_t
string
string_view
librepr::CppVisitor
Definition
cpp.h:17
librepr::CppVisitor::unnamed_count
std::size_t unnamed_count
Definition
cpp.h:20
librepr::CppVisitor::operator()
auto operator()(T info)
Definition
cpp.h:104
librepr::CppVisitor::indent_level
std::size_t indent_level
Definition
cpp.h:18
librepr::CppVisitor::operator()
auto operator()(T info)
Definition
cpp.h:58
librepr::CppVisitor::result
detail::StringBuffer result
Definition
cpp.h:21
librepr::CppVisitor::indent_amount
std::size_t indent_amount
Definition
cpp.h:19
librepr::CppVisitor::operator()
auto operator()(T info)
Definition
cpp.h:134
librepr::detail::StringBuffer
Wrapper around std::string.
Definition
buffer.h:14
librepr::detail::StringBuffer::set_cursor
void set_cursor(std::size_t index=std::string::npos)
Definition
buffer.h:77
std::to_string
T to_string(T... args)
type.h
type_traits
include
librepr
visitors
cpp.h
Generated by
1.9.8, using the excellent
Doxygen Awesome
Theme