Skip to content

Commit 55e4c17

Browse files
committed
- [added] use of enumerations as member and as element of container
- [added] option Required - [changed] option Default for cpp structures - [changed] option Default for containers - [changed] option Default for enumeration - [changed] option NotEmpty for containers - [fixed] if Boundes were set for fields with the same types, then all fields used the same range
1 parent c54416d commit 55e4c17

23 files changed

+1771
-224
lines changed

example/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
set(EXAMPLES
22
array
33
containers
4+
enumeration
45
how_it_work
56
in_struct_reg
67
macro_reg
78
map
89
options
10+
options_default
911
person
1012
simple
1113
struct
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#include <iostream>
2+
#include <list>
3+
#include <map>
4+
#include <sstream>
5+
#include <string>
6+
7+
#include "struct_mapping/struct_mapping.h"
8+
9+
namespace sm = struct_mapping;
10+
11+
enum class Color {
12+
red,
13+
blue,
14+
green,
15+
};
16+
17+
Color color_from_string(const std::string & value) {
18+
if (value == "red") return Color::red;
19+
if (value == "blue") return Color::blue;
20+
21+
return Color::green;
22+
}
23+
24+
std::string color_to_string(Color color) {
25+
switch (color) {
26+
case Color::red: return "red";
27+
case Color::green: return "green";
28+
default: return "blue";
29+
}
30+
}
31+
32+
struct Palette {
33+
Color main_color;
34+
Color background_color;
35+
std::list<Color> special_colors;
36+
std::map<std::string, Color> colors;
37+
38+
friend std::ostream & operator<<(std::ostream & os, const Palette & o) {
39+
os << "main_color : " << color_to_string(o.main_color) << std::endl;
40+
os << "background_color : " << color_to_string(o.background_color) << std::endl;
41+
os << "special_colors : ";
42+
for (auto color : o.special_colors) os << color_to_string(color) << ", ";
43+
os << std::endl << "colors : ";
44+
for (auto [name, color] : o.colors) os << "[" << name << ", " << color_to_string(color) << "], ";
45+
os << std::endl;
46+
47+
return os;
48+
}
49+
};
50+
51+
int main() {
52+
sm::MemberString<Color>::set(color_from_string, color_to_string);
53+
54+
sm::reg(&Palette::main_color, "main_color", sm::Required{});
55+
sm::reg(&Palette::background_color, "background_color", sm::Default{Color::blue});
56+
sm::reg(&Palette::special_colors, "special_colors");
57+
sm::reg(&Palette::colors, "colors");
58+
59+
Palette palette;
60+
61+
std::istringstream json_data(R"json(
62+
{
63+
"main_color": "green",
64+
"special_colors": ["green", "green", "red"],
65+
"colors": {
66+
"dark": "green",
67+
"light": "red",
68+
"neutral": "blue"
69+
}
70+
}
71+
)json");
72+
73+
sm::map_json_to_struct(palette, json_data);
74+
75+
std::cout << palette << std::endl;
76+
}

example/options/options.cpp

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include <iostream>
2+
#include <list>
3+
#include <map>
24
#include <sstream>
35
#include <string>
46

@@ -12,9 +14,9 @@ struct Stage {
1214
long length;
1315

1416
friend std::ostream & operator<<(std::ostream & os, const Stage & o) {
15-
os << " engine_count : " << o.engine_count << std::endl;
16-
os << " fuel : " << o.fuel << std::endl;
17-
os << " length : " << o.length << std::endl;
17+
os << " engine_count : " << o.engine_count << std::endl;
18+
os << " fuel : " << o.fuel << std::endl;
19+
os << " length : " << o.length << std::endl;
1820

1921
return os;
2022
}
@@ -24,15 +26,17 @@ struct Spacecraft {
2426
bool in_development;
2527
std::string name;
2628
int mass;
27-
Stage first_stage;
28-
Stage second_stage;
29+
std::map<std::string, Stage> stages;
30+
std::list<std::string> crew;
2931

3032
friend std::ostream & operator<<(std::ostream & os, const Spacecraft & o) {
3133
os << "in_development : " << std::boolalpha << o.in_development << std::endl;
3234
os << "name : " << o.name << std::endl;
33-
os << "mass : " << o.mass << std::endl << std::endl;
34-
os << "first stage: " << std::endl << o.first_stage << std::endl;
35-
os << "second stage: " << std::endl << o.second_stage << std::endl;
35+
os << "mass : " << o.mass << std::endl;
36+
os << "stages: " << std::endl;
37+
for (auto& s : o.stages) os << " " << s.first << std::endl << s.second;
38+
os << "crew: " << std::endl;
39+
for (auto& p : o.crew) os << " " << p << std::endl;
3640

3741
return os;
3842
}
@@ -43,21 +47,25 @@ int main() {
4347
sm::reg(&Stage::fuel, "fuel", sm::Default{"subcooled"});
4448
sm::reg(&Stage::length, "length", sm::Default{50});
4549

46-
sm::reg(&Spacecraft::in_development, "in_development", sm::Default{true});
50+
sm::reg(&Spacecraft::in_development, "in_development", sm::Required{});
4751
sm::reg(&Spacecraft::name, "name", sm::NotEmpty{});
4852
sm::reg(&Spacecraft::mass, "mass", sm::Default{5000000}, sm::Bounds{100000, 10000000});
49-
sm::reg(&Spacecraft::first_stage, "first_stage");
50-
sm::reg(&Spacecraft::second_stage, "second_stage");
53+
sm::reg(&Spacecraft::stages, "stages", sm::NotEmpty{});
54+
sm::reg(&Spacecraft::crew, "crew", sm::Default{std::list<std::string>{"Arthur", "Ford", "Marvin"}});
5155

5256
Spacecraft starship;
5357

5458
std::istringstream json_data(R"json(
5559
{
60+
"in_development": false,
5661
"name": "Vostok",
57-
"second_stage": {
58-
"engine_count": 31,
59-
"fuel": "compressed gas",
60-
"length": 70
62+
"stages": {
63+
"first": {
64+
"engine_count": 31,
65+
"fuel": "compressed gas",
66+
"length": 70
67+
},
68+
"second": {}
6169
}
6270
}
6371
)json");
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#include <iostream>
2+
#include <list>
3+
#include <map>
4+
#include <sstream>
5+
#include <string>
6+
7+
#include "struct_mapping/struct_mapping.h"
8+
9+
namespace sm = struct_mapping;
10+
11+
struct Reentry_module {
12+
double total_mass;
13+
};
14+
15+
struct Stage {
16+
unsigned short engine_count;
17+
std::string fuel;
18+
long length;
19+
20+
friend std::ostream & operator<<(std::ostream & os, const Stage & o) {
21+
os << " engine_count : " << o.engine_count << std::endl;
22+
os << " fuel : " << o.fuel << std::endl;
23+
os << " length : " << o.length << std::endl;
24+
25+
return os;
26+
}
27+
};
28+
29+
struct Spacecraft {
30+
bool in_development;
31+
std::string name;
32+
int mass;
33+
Reentry_module reentry_module;
34+
std::map<std::string, Stage> stages;
35+
std::list<std::string> crew;
36+
37+
friend std::ostream & operator<<(std::ostream & os, const Spacecraft & o) {
38+
os << "in_development : " << std::boolalpha << o.in_development << std::endl;
39+
os << "name : " << o.name << std::endl;
40+
os << "mass : " << o.mass << std::endl;
41+
os << "reentry_module : " << std::endl;
42+
os << " total_mass : " << o.reentry_module.total_mass << std::endl;
43+
os << "stages: " << std::endl;
44+
for (auto& s : o.stages) os << " " << s.first << std::endl << s.second;
45+
os << "crew: " << std::endl;
46+
for (auto& p : o.crew) os << " " << p << std::endl;
47+
48+
return os;
49+
}
50+
};
51+
52+
int main() {
53+
sm::reg(&Reentry_module::total_mass, "total_mass", sm::Default{145});
54+
55+
sm::reg(&Stage::engine_count, "engine_count", sm::Default{6});
56+
sm::reg(&Stage::fuel, "fuel", sm::Default{"subcooled"});
57+
sm::reg(&Stage::length, "length", sm::Default{50});
58+
59+
sm::reg(&Spacecraft::in_development, "in_development", sm::Default{true});
60+
sm::reg(&Spacecraft::name, "name", sm::Default{"Vostok"});
61+
sm::reg(&Spacecraft::mass, "mass", sm::Default{5000000});
62+
sm::reg(&Spacecraft::reentry_module, "reentry_module", sm::Default{Reentry_module{2900.42}});
63+
sm::reg(&Spacecraft::stages, "stages", sm::Default{std::map<std::string, Stage>{
64+
{
65+
"first",
66+
{
67+
31,
68+
"compressed gas",
69+
70
70+
}
71+
}
72+
}});
73+
sm::reg(&Spacecraft::crew, "crew", sm::Default{std::list<std::string>{"Arthur", "Ford", "Marvin"}});
74+
75+
Spacecraft starship;
76+
77+
std::istringstream json_data(R"json(
78+
{
79+
}
80+
)json");
81+
82+
sm::map_json_to_struct(starship, json_data);
83+
84+
std::cout << starship << std::endl;
85+
}

include/struct_mapping/f.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ static constexpr bool is_integer_or_floating_point_v = !std::is_same_v<T, bool>
1919
template<typename T>
2020
static constexpr bool is_integral_or_floating_point_or_string_v = std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<T, std::string>;
2121

22+
template<typename T>
23+
static constexpr bool is_complex_v = !is_integral_or_floating_point_or_string_v<T> && !std::is_enum_v<T>;
24+
2225
template<typename, typename = std::void_t<>>
2326
struct has_mapped_type : std::false_type{};
2427

include/struct_mapping/f_array.h

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
#include "f.h"
1212
#include "f_struct.h"
13+
#include "member_string.h"
14+
#include "options/option_not_empty.h"
1315

1416
namespace struct_mapping::detail {
1517

@@ -24,13 +26,11 @@ class F<T, true, false> {
2426
template<typename V>
2527
using ValueType = typename V::value_type;
2628

27-
static void finish(T & o) {
28-
for (auto & v : o) {
29-
if constexpr (!is_integral_or_floating_point_or_string_v<ValueType<T>>) F<ValueType<T>>::finish(v);
30-
}
29+
static void check_not_empty(T & o, const std::string & name) {
30+
NotEmpty<>::check_result(o, name);
3131
}
3232

33-
static void init(T &) {}
33+
static void init() {}
3434

3535
static void iterate_over(T & o, const std::string & name) {
3636
F_iterate_over::start_array(name);
@@ -40,6 +40,7 @@ class F<T, true, false> {
4040
else if constexpr (std::is_integral_v<ValueType<T>>) F_iterate_over::set_integral("", v);
4141
else if constexpr (std::is_floating_point_v<ValueType<T>>) F_iterate_over::set_floating_point("", v);
4242
else if constexpr (std::is_same_v<ValueType<T>, std::string>) F_iterate_over::set_string("", v);
43+
else if constexpr (std::is_enum_v<ValueType<T>>) F_iterate_over::set_string("",MemberString<ValueType<T>>::to_string()(v));
4344
else F<ValueType<T>>::iterate_over(v, "");
4445
}
4546

@@ -50,7 +51,7 @@ class F<T, true, false> {
5051
if (!used) {
5152
return true;
5253
} else {
53-
if constexpr (!is_integral_or_floating_point_or_string_v<ValueType<T>>) {
54+
if constexpr (is_complex_v<ValueType<T>>) {
5455
if (F<ValueType<T>>::release(get_last_inserted())) {
5556
used = false;
5657
}
@@ -70,7 +71,7 @@ class F<T, true, false> {
7071
last_inserted = insert(o, value);
7172
} else throw StructMappingException("bad type (bool) '" + (value ? std::string("true") : std::string("false")) + "' in array_like at index " + std::to_string(o.size()));
7273
} else {
73-
if constexpr (!is_integral_or_floating_point_or_string_v<ValueType<T>>) {
74+
if constexpr (is_complex_v<ValueType<T>>) {
7475
F<ValueType<T>>::set_bool(get_last_inserted(), name, value);
7576
}
7677
}
@@ -89,7 +90,7 @@ class F<T, true, false> {
8990
last_inserted = insert(o, static_cast<ValueType<T>>(value));
9091
} else throw StructMappingException("bad type (floating point) '" + std::to_string(value) + "' in array_like at index " + std::to_string(o.size()));
9192
} else {
92-
if constexpr (!is_integral_or_floating_point_or_string_v<ValueType<T>>) {
93+
if constexpr (is_complex_v<ValueType<T>>) {
9394
F<ValueType<T>>::set_floating_point(get_last_inserted(), name, value);
9495
}
9596
}
@@ -108,7 +109,7 @@ class F<T, true, false> {
108109
last_inserted = insert(o, static_cast<ValueType<T>>(value));
109110
} else throw StructMappingException("bad type (integer) '" + std::to_string(value) + "' in array_like at index " + std::to_string(o.size()));
110111
} else {
111-
if constexpr (!is_integral_or_floating_point_or_string_v<ValueType<T>>) {
112+
if constexpr (is_complex_v<ValueType<T>>) {
112113
F<ValueType<T>>::set_integral(get_last_inserted(), name, value);
113114
}
114115
}
@@ -118,20 +119,22 @@ class F<T, true, false> {
118119
if (!used) {
119120
if constexpr (std::is_same_v<ValueType<T>, std::string>) {
120121
last_inserted = insert(o, value);
122+
} else if constexpr (std::is_enum_v<ValueType<T>>) {
123+
last_inserted = insert(o, MemberString<ValueType<T>>::from_string()(value));
121124
} else throw StructMappingException("bad type (string) '" + value + "' in array_like at index " + std::to_string(o.size()));
122125
} else {
123-
if constexpr (!is_integral_or_floating_point_or_string_v<ValueType<T>>) {
126+
if constexpr (is_complex_v<ValueType<T>>) {
124127
F<ValueType<T>>::set_string(get_last_inserted(), name, value);
125128
}
126129
}
127130
}
128131

129132
static void use(T & o, const std::string & name) {
130-
if constexpr (!is_integral_or_floating_point_or_string_v<ValueType<T>>) {
133+
if constexpr (is_complex_v<ValueType<T>>) {
131134
if (!used) {
132135
used = true;
133136
last_inserted = insert(o, ValueType<T>{});
134-
F<ValueType<T>>::init(*last_inserted);
137+
F<ValueType<T>>::init();
135138
} else {
136139
F<ValueType<T>>::use(get_last_inserted(), name);
137140
}

0 commit comments

Comments
 (0)