1
+ /*
2
+ * Copyright (c) 2023, Alibaba Group Holding Limited;
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #include < cassert>
18
+ #include < cstdint>
19
+ #include < cstdio>
20
+ #include < fstream>
21
+ #include < iostream>
22
+ #include < memory>
23
+ #include < ostream>
24
+ #include < sstream>
25
+
26
+ // It's easy to use struct_pack, just include it!
27
+ #include < ylt/struct_pack.hpp>
28
+
29
+ // 1. make sure your type has a default constructor
30
+ // 2. add marco STRUCT_PACK_REFL(Type, field1, field2...) in the same namespace
31
+ namespace example {
32
+ class person : std::vector<int > {
33
+ private:
34
+ std::string mess;
35
+
36
+ public:
37
+ int age;
38
+ std::string name;
39
+ auto operator ==(const person& rhs) const {
40
+ return age == rhs.age && name == rhs.name ;
41
+ }
42
+ person () = default ;
43
+ person (int age, const std::string& name) : age(age), name(name) {}
44
+ };
45
+
46
+ STRUCT_PACK_REFL (person, age, name);
47
+ } // namespace example
48
+
49
+ // 3. if you want to use private field, add friend declartion marco
50
+
51
+ namespace example2 {
52
+ class person {
53
+ private:
54
+ int age;
55
+ std::string name;
56
+
57
+ public:
58
+ auto operator ==(const person& rhs) const {
59
+ return age == rhs.age && name == rhs.name ;
60
+ }
61
+ person () = default ;
62
+ person (int age, const std::string& name) : age(age), name(name) {}
63
+ STRUCT_PACK_FRIEND_DECL (person);
64
+ };
65
+ STRUCT_PACK_REFL (person, age, name);
66
+ } // namespace example2
67
+
68
+ // 4. you can also add function which return class member reference as
69
+ // struct_pack field.
70
+
71
+ namespace example3 {
72
+ class person {
73
+ private:
74
+ int age_;
75
+ std::string name_;
76
+
77
+ public:
78
+ auto operator ==(const person& rhs) const {
79
+ return age_ == rhs.age_ && name_ == rhs.name_ ;
80
+ }
81
+ person () = default ;
82
+ person (int age, const std::string& name) : age_(age), name_(name) {}
83
+
84
+ int & age () { return age_; };
85
+ const int & age () const { return age_; };
86
+ std::string& name () { return name_; };
87
+ const std::string& name () const { return name_; };
88
+ };
89
+ STRUCT_PACK_REFL (person, age(), name());
90
+ } // namespace example3
91
+
92
+ // 5. Remember, the STURCT_PACK_REFL marco disable the trivial_serialize
93
+ // optimize. So don't use it for trivial type.
94
+ namespace example4 {
95
+ struct point {
96
+ int x, y, z;
97
+ };
98
+ STRUCT_PACK_REFL (point, x, y, z);
99
+ struct point2 {
100
+ int x, y, z;
101
+ };
102
+ } // namespace example4
103
+
104
+ // 6. example5::person ,example::person, example2::person, example3:person are
105
+ // same type in struct_pack type system.
106
+ namespace example5 {
107
+ struct person {
108
+ int age;
109
+ std::string name;
110
+ auto operator ==(const person& rhs) const {
111
+ return age == rhs.age && name == rhs.name ;
112
+ }
113
+ };
114
+ } // namespace example5
115
+
116
+ // clang-format off
117
+ void non_aggregated_type () {
118
+ {
119
+ example::person p{20 , " tom" };
120
+ auto buffer = struct_pack::serialize (p);
121
+ auto p2 = struct_pack::deserialize<example::person>(buffer);
122
+ assert (p2);
123
+ assert (p == p2.value ());
124
+ }
125
+ {
126
+ example2::person p{20 , " tom" };
127
+ auto buffer = struct_pack::serialize (p);
128
+ auto p2 = struct_pack::deserialize<example2::person>(buffer);
129
+ assert (p2);
130
+ assert (p == p2.value ());
131
+ }
132
+ {
133
+ example2::person p{20 , " tom" };
134
+ auto buffer = struct_pack::serialize (p);
135
+ auto p3 = struct_pack::deserialize<example2::person>(buffer);
136
+ assert (p3);
137
+ assert (p == p3.value ());
138
+ }
139
+ {
140
+ assert (struct_pack::get_type_code<example4::point>() !=
141
+ struct_pack::get_type_code<example4::point2>());
142
+ }
143
+ {
144
+ assert (struct_pack::get_type_code<example5::person>() ==
145
+ struct_pack::get_type_code<example::person>());
146
+ assert (struct_pack::get_type_code<example5::person>() ==
147
+ struct_pack::get_type_code<example2::person>());
148
+ assert (struct_pack::get_type_code<example5::person>() ==
149
+ struct_pack::get_type_code<example3::person>());
150
+ }
151
+ }
0 commit comments