Skip to content

Commit 8cada17

Browse files
committed
unify the representation of lambda type
1 parent 79a4036 commit 8cada17

File tree

7 files changed

+106
-32
lines changed

7 files changed

+106
-32
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ It's the custom name, isn't it convenient? I have pre-defined some commonly used
5656
Considering that some terminals do not support color, or do not support `utf` characters, the display will appear garbled, so we provide options to turn off these functions
5757
```cpp
5858
magic::VisualizeOption option;
59-
option.UTF8_SUPPORT = false; // do not use utf8 characters
60-
option.COLORFUL_SUPPORT = false; // turn off color support
61-
option.FULL_NAME = true; // use full name instead of custom alias
59+
option.utf_support = false; // do not use utf8 characters
60+
option.color_support = false; // turn off color support
61+
option.full_name = true; // use full name instead of custom alias
6262
std::cout << magic::visualize<std::string>(option) << std::endl;
6363
```
6464
Output:

README.zh.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ struct magic::type_info<std::string>
5555
考虑到有的终端并不支持彩色,或者不支持`utf`字符,这样的话显示就出出现乱码,所以我们提供选项来关闭这些功能
5656
```cpp
5757
magic::VisualizeOption option;
58-
option.UTF8_SUPPORT = false; // 不使用utf8字符
59-
option.COLORFUL_SUPPORT = false; // 关闭彩色支持
60-
option.FULL_NAME = true; // 使用全名而不是自定义的别名
58+
option.utf_support = false; // 不使用utf8字符
59+
option.color_support = false; // 关闭彩色支持
60+
option.full_name = true; // 使用全名而不是自定义的别名
6161
std::cout << magic::visualize<std::string>(option) << std::endl;
6262
```
6363

include/magic/field_count.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
#ifndef MAGIC_CPP_FIELD_COUNT_H
22
#define MAGIC_CPP_FIELD_COUNT_H
33

4-
#include <array>
5-
6-
#define MAGIC_CPP_C_ARRAY_SUPPORT 0
4+
#define MAGIC_CPP_C_ARRAY_SUPPORT 1
75

6+
#include <array>
87
namespace magic::details
98
{
9+
struct Any;
10+
1011
struct Any
1112
{
1213
constexpr Any(int) {}
@@ -19,8 +20,12 @@ namespace magic::details
1920
requires std::is_move_constructible_v<T>
2021
operator T&&();
2122

23+
struct Empty
24+
{
25+
};
26+
2227
template <typename T>
23-
requires(!std::is_copy_constructible_v<T> && !std::is_move_constructible_v<T>)
28+
requires(!std::is_copy_constructible_v<T> && !std::is_move_constructible_v<T> && !std::is_constructible_v<T, Empty>)
2429
operator T();
2530
};
2631

include/magic/raw_name.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ namespace magic
2222
return start == std::string_view::npos ? name : std::string_view{name.data() + start + 1, name.size() - start - 1};
2323
#else
2424
static_assert(false, "Unsupported compiler");
25-
2625
#endif
2726
}
2827

@@ -42,7 +41,6 @@ namespace magic
4241
return start == std::string_view::npos ? name : std::string_view{name.data() + start + 1, name.size() - start - 1};
4342
#else
4443
static_assert(false, "Unsupported compiler");
45-
4644
#endif
4745
}
4846

@@ -62,7 +60,6 @@ namespace magic
6260
return start == std::string_view::npos ? name : std::string_view{name.data() + start + 1, name.size() - start - 1};
6361
#else
6462
static_assert(false, "Unsupported compiler");
65-
6663
#endif
6764
}
6865

include/magic/struct.h

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,22 @@
1010

1111
namespace magic::details
1212
{
13-
// clang-format off
13+
1414
template <typename T>
1515
constexpr auto field_types_of_impl(T object)
1616
{
1717
constexpr auto N = field_count_of<T>();
18-
#include "generate/struct_bind_of_field_types.code"
18+
#include "generate/struct_bind_of_field_types.code"
1919
}
2020

2121
template <std::size_t Index>
2222
constexpr auto&& field_of_impl(auto&& object)
2323
{
2424
using T = std::remove_cvref_t<decltype(object)>;
2525
constexpr auto N = field_count_of<T>();
26-
#include "generate/struct_bind_of_field_access.code"
27-
26+
#include "generate/struct_bind_of_field_access.code"
2827
}
29-
// clang-format on
28+
3029
} // namespace magic::details
3130

3231
namespace magic
@@ -82,9 +81,6 @@ namespace magic
8281
return field_names_of<T>()[Index];
8382
}
8483

85-
template <typename T>
86-
constexpr std::string_view name_of();
87-
8884
template <std::size_t N, typename T>
8985
struct Field
9086
{
@@ -98,7 +94,7 @@ namespace magic
9894

9995
constexpr static std::string_view name() { return field_name_of<std::remove_cvref_t<T>>(N); }
10096

101-
constexpr static std::string_view type_name() { return name_of<type>(); }
97+
constexpr static std::string_view type_name() { return raw_name_of<type>(); }
10298

10399
constexpr static std::size_t index() { return N; }
104100

@@ -110,6 +106,22 @@ namespace magic
110106
friend constexpr void foreach (Object&& object, auto&& functor);
111107
};
112108

109+
template <typename T>
110+
concept FIELD = requires(T t) {
111+
{
112+
t.name()
113+
} -> std::same_as<std::string_view>;
114+
{
115+
t.type_name()
116+
} -> std::same_as<std::string_view>;
117+
{
118+
t.index()
119+
} -> std::same_as<std::size_t>;
120+
{
121+
t.value()
122+
};
123+
};
124+
113125
template <typename Object>
114126
constexpr void foreach (Object&& object, auto&& functor)
115127
{

include/magic/type_tree.h

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,54 @@ namespace magic::details
153153
virtual TypeKind Kind() const override { return TypeKind::FUNCTION; }
154154
};
155155

156+
struct never_functor
157+
{
158+
};
159+
160+
struct always_functor
161+
{
162+
void operator()();
163+
};
164+
165+
template <typename T>
166+
struct is_functor_impl : always_functor, std::conditional_t<std::is_class_v<T>, T, never_functor>
167+
{
168+
};
169+
170+
template <typename T, typename U = void>
171+
struct is_functor : std::true_type
172+
{
173+
};
174+
175+
template <typename T>
176+
struct is_functor<T, std::void_t<decltype(&is_functor_impl<T>::operator())>> : std::false_type
177+
{
178+
};
179+
180+
template <typename T>
181+
constexpr bool is_functor_v = is_functor<T>::value;
182+
183+
template <typename T>
184+
constexpr bool is_lambda()
185+
{
186+
if constexpr (is_functor_v<T>)
187+
{
188+
constexpr auto name = raw_name_of<T>();
189+
return name.find("lambda") != std::string_view::npos;
190+
}
191+
else
192+
{
193+
return false;
194+
}
195+
}
156196
template <typename T>
157197
Type* parse(bool is_full_name);
158198

159199
template <auto Value>
160200
Type* parse_nttp(bool is_full_name)
161201
{
162202
NTTP* nttp = new NTTP{};
163-
nttp->type = parse<decltype(Value)>(is_full_name);
203+
nttp->type = parse<std::remove_cv_t<decltype(Value)>>(is_full_name);
164204
using Type = decltype(Value);
165205
if constexpr (std::is_enum_v<Type>)
166206
{
@@ -174,13 +214,26 @@ namespace magic::details
174214
{
175215
nttp->name = std::to_string(Value);
176216
}
217+
else if constexpr (is_lambda<Type>())
218+
{
219+
nttp->name = "<lambda object>";
220+
}
177221
else
178222
{
179223
nttp->name = raw_name_of<Value>();
180224
}
181225
return nttp;
182226
}
183227

228+
inline std::size_t lambda_id = 0;
229+
230+
template <typename T>
231+
std::string resolve_lambda()
232+
{
233+
static std::size_t id = lambda_id++;
234+
return "<lambda{" + std::to_string(id) + "}>";
235+
}
236+
184237
template <typename Tuple, std::size_t... Is>
185238
void parse_function_params(std::index_sequence<Is...>, std::vector<Type*>& parameters, bool is_full_name)
186239
{
@@ -309,7 +362,14 @@ namespace magic::details
309362
else
310363
{
311364
BasicType* basic_type = new BasicType{};
312-
basic_type->name = raw_name_of<Primary>();
365+
if constexpr (is_lambda<Primary>())
366+
{
367+
basic_type->name = resolve_lambda<Primary>();
368+
}
369+
else
370+
{
371+
basic_type->name = raw_name_of<Primary>();
372+
}
313373
basic_type->is_const = is_const;
314374
basic_type->is_volatile = is_volatile;
315375
return basic_type;

include/magic/visualize.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ namespace magic
1414
{
1515
struct VisualizeOption
1616
{
17-
bool UTF8_SUPPORT = true;
18-
bool COLORFUL_SUPPORT = true;
19-
bool FULL_NAME = false;
17+
bool utf_support = true;
18+
bool color_support = true;
19+
bool full_name = false;
2020
};
2121

2222
struct HighlightConfig
@@ -124,13 +124,13 @@ namespace magic::details
124124
std::string result;
125125
HighlightConfig config;
126126
DirectoryTreeSymbols symbols;
127-
bool colorful_support;
127+
bool color_support;
128128

129129
public:
130130
VisualizationImpl(const VisualizeOption& option, const HighlightConfig& config)
131-
: result(), config(config), colorful_support(option.COLORFUL_SUPPORT)
131+
: result(), config(config), color_support(option.color_support)
132132
{
133-
if (option.UTF8_SUPPORT)
133+
if (option.utf_support)
134134
{
135135
symbols = {"├── ", "", "└── ", " "};
136136
}
@@ -143,7 +143,7 @@ namespace magic::details
143143
template <typename T>
144144
std::string colorize(T&& text, std::uint32_t color)
145145
{
146-
if (!colorful_support)
146+
if (!color_support)
147147
{
148148
return std::forward<T>(text);
149149
}
@@ -291,7 +291,7 @@ namespace magic
291291
std::string visualize(const VisualizeOption& option, const HighlightConfig& config)
292292
{
293293
std::string result;
294-
Type* type = details::parse<T>(option.FULL_NAME);
294+
Type* type = details::parse<T>(option.full_name);
295295
details::VisualizationImpl visualizationImpl{option, config};
296296
visualizationImpl.visualize(type, "", "", true);
297297
delete type;

0 commit comments

Comments
 (0)