Skip to content

Commit 7fe6964

Browse files
authored
Merge pull request #312 from qicosmos/update_macro
2 parents 961b93a + 9039124 commit 7fe6964

File tree

5 files changed

+285
-37
lines changed

5 files changed

+285
-37
lines changed

README.md

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ This library provides a portable cross-platform way of:
2525
- serialization of yaml
2626
- serialization of any customized format
2727

28+
### compile time reflection ###
29+
30+
[reflection lib introduction](lang/reflection_introduction.md)
31+
2832
### Tutorial ###
2933
This Tutorial is provided to give you a view of how *iguana* works for serialization.
3034

@@ -38,10 +42,12 @@ struct person
3842
std::string name;
3943
int age;
4044
};
41-
REFLECTION(person, name, age) //define meta data
45+
#if __cplusplus >= 202002L
46+
YLT_REFL(person, name, age) //define meta data
47+
#endif
4248
```
4349

44-
Defining meta data is very simple, and just needs to define in a `REFLECTION` macro.
50+
Defining meta data is very simple, if your compiler is C++20 compiler(gcc11+, clang13+, msvc2022), no need define YLT_REFL, other wise need to define in a `YLT_REFL` macro.
4551

4652
Now let's serialize `person` to `json` string.
4753

@@ -141,15 +147,15 @@ struct one_t
141147
{
142148
int id;
143149
};
144-
REFLECTION(one_t, id);
150+
YLT_REFL(one_t, id);
145151

146152
struct two
147153
{
148154
std::string name;
149155
one_t one;
150156
int age;
151157
};
152-
REFLECTION(two, name, one, age);
158+
YLT_REFL(two, name, one, age);
153159

154160
struct composit_t
155161
{
@@ -161,7 +167,7 @@ struct composit_t
161167
double f;
162168
std::list<one_t> g;
163169
};
164-
REFLECTION(composit_t, a, b, c, d, e, f, g);
170+
YLT_REFL(composit_t, a, b, c, d, e, f, g);
165171
```
166172

167173
Then call the simple interface:
@@ -187,13 +193,13 @@ struct book_t {
187193
std::string author;
188194
float price;
189195
};
190-
REFLECTION(book_t, author, price);
196+
YLT_REFL(book_t, author, price);
191197
struct library_t {
192198
std::string name;
193199
int id;
194200
std::vector<book_t> book;
195201
};
196-
REFLECTION(library_t, name, id, book);
202+
YLT_REFL(library_t, name, id, book);
197203
```
198204

199205
And then, simply call the interface:
@@ -236,7 +242,7 @@ struct plain_type_t {
236242
std::optional<float> num;
237243
std::optional<int> price;
238244
};
239-
REFLECTION(plain_type_t, isok, status, c, hasprice, num, price);
245+
YLT_REFL(plain_type_t, isok, status, c, hasprice, num, price);
240246
```
241247

242248
And then, simply call the interface:
@@ -311,7 +317,7 @@ struct enum_t {
311317
Status a;
312318
Status b;
313319
};
314-
REFLECTION(enum_t, a, b);
320+
YLT_REFL(enum_t, a, b);
315321

316322
// deserialization
317323
enum_t e;
@@ -333,7 +339,7 @@ iguana::to_json(e1, ss);
333339

334340
### Scripts
335341

336-
Automatically generate `REFLECTION` macros based by struct.
342+
Automatically generate `YLT_REFL` macros based by struct.
337343

338344
To get a list of basic options and switches use:
339345

@@ -382,11 +388,11 @@ struct person {
382388
std::string name;
383389
int age;
384390
};
385-
REFLECTION(person, name, age);
391+
YLT_REFL(person, name, age);
386392
char *iguana = NULL;
387393

388394
struct composit_t { int a; std::vector<std::string> b; int c; std::map<int, int> d; std::unordered_map<int, int> e; double f;};
389-
REFLECTION(composit_t, a, b, c, d, e, f);
395+
YLT_REFL(composit_t, a, b, c, d, e, f);
390396

391397
struct composit_t2
392398
{
@@ -397,7 +403,7 @@ struct composit_t2
397403
std::unordered_map<int, int> random_name__;
398404
double __f__number__complex;
399405
};
400-
REFLECTION(composit_t2, a, b, iguana, example_test, random_name__, __f__number__complex);
406+
YLT_REFL(composit_t2, a, b, iguana, example_test, random_name__, __f__number__complex);
401407
```
402408

403409
other example:
@@ -406,7 +412,7 @@ other example:
406412
python automatic_macro_generator.py -i test_macro_generator.cpp -o have_macro.cpp
407413
```
408414

409-
test_macro_generator.cpp will be unchanged, have_macro.cpp will be changed to source file with REFLECTION macro.
415+
test_macro_generator.cpp will be unchanged, have_macro.cpp will be changed to source file with YLT_REFL macro.
410416

411417
scripts works out of the box with Python version 2.7 and 3.x on any platform.
412418

@@ -417,7 +423,7 @@ Notes: In Python3,Will prompt `DeprecationWarning: 'U' mode is deprecated`.Ignor
417423

418424
- **Question**: Why is the library called *iguana*?
419425

420-
- **Answer**: I think serialization is like an iguana, because the only difference is the displaying format, however the meta data is never changed. With changeless meta data and reflection, you can serialize an object to any format, which is like how an iguana does.
426+
- **Answer**: I think serialization is like an iguana, because the only difference is the displaying format, however the meta data is never changed. With changeless meta data and YLT_REFL, you can serialize an object to any format, which is like how an iguana does.
421427

422428
- **Question**: Does *iguana* support raw pointer?
423429

lang/iguana 使用文档.md

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ iguana 是header only的,从github 将iguana clone 下来之后,在cmake 里
1919
gcc9+、clang11+、msvc2019+
2020

2121
# json 序列化/反序列化
22-
iguana 序列化需要先定义一个可反射的对象,通过REFLECTION 可以轻松定义一个可反射对象。
22+
iguana 序列化需要先定义一个可反射的对象,通过YLT_REFL 可以轻松定义一个可反射对象。
2323

2424
```c++
2525
struct person
2626
{
2727
std::string_view name;
2828
int age;
2929
};
30-
REFLECTION(person, name, age); // 通过这个宏定义元数据让person 成为一个可反射对象
30+
YLT_REFL(person, name, age); // 通过这个宏定义元数据让person 成为一个可反射对象
3131
```
32-
通过REFLECTION 宏定义元数据之后就可以一行代码实现json 的序列化与反序列化了。
32+
通过YLT_REFL 宏定义元数据之后就可以一行代码实现json 的序列化与反序列化了。
3333
3434
```c++
3535
person p = { "tom", 28 };
@@ -74,7 +74,7 @@ struct some_obj {
7474
std::string_view name;
7575
iguana::numeric_str age;
7676
};
77-
REFLECTION(some_obj, name, age);
77+
YLT_REFL(some_obj, name, age);
7878
7979
void test_view(){
8080
std::string_view str = "{\"name\":\"tom\", \"age\":20}";
@@ -110,7 +110,7 @@ struct some_obj {
110110
std::string_view name;
111111
int age;
112112
};
113-
REFLECTION(some_obj, name, age);
113+
YLT_REFL(some_obj, name, age);
114114

115115
void test() {
116116
person p = {"admin", 20};
@@ -135,7 +135,7 @@ struct person {
135135
std::string_view name;
136136
int age;
137137
};
138-
REFLECTION(person, name, age);
138+
YLT_REFL(person, name, age);
139139
140140
void test_pretty() {
141141
person p{"tom", 20};
@@ -171,11 +171,11 @@ struct book_t {
171171
std::string title;
172172
std::string author;
173173
};
174-
REFLECTION(book_t, title, author);
174+
YLT_REFL(book_t, title, author);
175175
struct library {
176176
iguana::xml_attr_t<book_t> book;
177177
};
178-
REFLECTION(library, book);
178+
YLT_REFL(library, book);
179179
TEST_CASE("test library with attr") {
180180
auto validator = [](library lib) {
181181
CHECK(lib.book.attr()["id"] == "1234");
@@ -214,7 +214,7 @@ struct some_obj {
214214
std::string_view name;
215215
int age;
216216
};
217-
REFLECTION(some_obj, name, age);
217+
YLT_REFL(some_obj, name, age);
218218
219219
void test() {
220220
std::string_view xml = R"(
@@ -249,7 +249,13 @@ public:
249249
person() = default;
250250
person(std::shared_ptr<std::string> id, std::unique_ptr<std::string> name) : id_(id), name_(std::move(name)) {}
251251
252-
REFLECTION_ALIAS(person, "rootnode", FLDALIAS(&person::id_, "id"), FLDALIAS(&person::name_, "name"));
252+
static constexpr auto get_alias_field_names(person*) {
253+
return std::array{field_alias_t{"id", 0}, field_alias_t{"name", 1}};
254+
}
255+
static constexpr std::string_view get_alias_struct_name(person*) {
256+
return "rootnode";
257+
}
258+
YLT_REFL(person, id_, name_);
253259
254260
void parse_xml() {
255261
iguana::from_xml(*this, xml_str);
@@ -259,18 +265,18 @@ public:
259265
}
260266
}
261267
```
262-
REFLECTION_ALIAS 中需要填写结构体的别名和字段的别名,通过别名将标签和结构体字段关联起来就可以保证正确的解析了。
268+
get_alias_field_names 函数中需要填写结构体的别名,get_alias_struct_name 函数中填写字段的别名,别名字段的索引需要和YLT_REFL宏定义的字段顺序一致,通过别名将标签和结构体字段关联起来就可以保证正确的解析了。
263269

264270
这个例子同时也展示了iguana 支持智能指针的序列化和反序列化。
265271

266272
# 如何处理私有字段
267-
如果类里面有私有字段,在外面定义REFLECTION 宏会出错,因为无法访问私有字段,这时候把宏定义到类里面即可,但要保证宏是public的。
273+
如果类里面有私有字段,在外面定义YLT_REFL 宏会出错,因为无法访问私有字段,这时候把宏定义到类里面即可,但要保证宏是public的。
268274
```c++
269275
class person {
270276
std::string name;
271277
int age;
272278
public:
273-
REFLECTION(person, name, age);
279+
YLT_REFL(person, name, age);
274280
};
275281
```
276282
@@ -289,7 +295,7 @@ struct plain_type_t {
289295
std::optional<float> num;
290296
std::optional<int> price;
291297
};
292-
REFLECTION(plain_type_t, isok, status, c, hasprice, num, price);
298+
YLT_REFL(plain_type_t, isok, status, c, hasprice, num, price);
293299
```
294300

295301
```c++
@@ -320,7 +326,7 @@ struct enum_t {
320326
Status a;
321327
Status b;
322328
};
323-
REFLECTION(enum_t, a, b);
329+
YLT_REFL(enum_t, a, b);
324330
325331
namespace iguana {
326332
template <> struct enum_value<Status> {
@@ -390,7 +396,7 @@ struct test_float_t {
390396
double a;
391397
float b;
392398
};
393-
REFLECTION(test_float_t, a, b);
399+
YLT_REFL(test_float_t, a, b);
394400
void user_defined_tochars_example() {
395401
test_float_t t{2.011111, 2.54};
396402
std::string ss;

0 commit comments

Comments
 (0)