@@ -19,6 +19,32 @@ namespace gltfpp {
19
19
const nlohmann::json *json = nullptr ;
20
20
};
21
21
22
+ template <typename T>
23
+ struct defaulted {
24
+ template <typename ... Args>
25
+ defaulted (Args &&... args)
26
+ : val{std::forward<Args>(args)...} {}
27
+
28
+ operator T &() {
29
+ return val;
30
+ }
31
+
32
+ operator const T &() const {
33
+ return val;
34
+ }
35
+
36
+ T &get () {
37
+ return val;
38
+ }
39
+
40
+ const T &get () const {
41
+ return val;
42
+ }
43
+
44
+ private:
45
+ T val;
46
+ };
47
+
22
48
template <typename T, typename std::enable_if_t <detail::is_field_aggregate<T>> * = nullptr >
23
49
auto parse (T &target);
24
50
@@ -27,10 +53,13 @@ namespace gltfpp {
27
53
28
54
template <typename T, typename std::enable_if_t <detail::is_field_list<T>> * = nullptr >
29
55
auto parse (T &target);
56
+
57
+ template <typename T, typename std::enable_if_t <detail::is_enumeration<T>> * = nullptr >
58
+ auto parse (T &target);
30
59
31
60
template <typename T>
32
61
auto field (option<T> &target, const char *key) {
33
- return [&, key](ParseContext ctx) -> gltf_result<ParseContext> {
62
+ return [&target , key](ParseContext ctx) -> gltf_result<ParseContext> {
34
63
auto valIt = ctx.json ->find (key);
35
64
if (valIt != ctx.json ->end ()) {
36
65
target.set_value ();
@@ -47,7 +76,7 @@ namespace gltfpp {
47
76
48
77
template <typename T>
49
78
auto field (T &target, const char *key) {
50
- return [&, key](ParseContext ctx) -> gltf_result<ParseContext> {
79
+ return [&target , key](ParseContext ctx) -> gltf_result<ParseContext> {
51
80
auto valIt = ctx.json ->find (key);
52
81
if (valIt != ctx.json ->end ()) {
53
82
auto newCtx = ParseContext{ctx.root , std::addressof (*valIt)};
@@ -65,19 +94,19 @@ namespace gltfpp {
65
94
66
95
template <typename T>
67
96
auto aggregate (T &target) {
68
- return [&](ParseContext ctx) -> gltf_result<ParseContext> {
69
- constexpr auto accessor = boost::hana::accessors<T>() ;
70
- auto names = boost::hana::transform (accessor, boost::hana::first );
71
- auto members = boost::hana:: transform (accessor, boost::hana::second );
72
- auto refs = boost::hana:: transform (members, [&]( auto acc) { return std::ref ( acc (target)); } );
73
-
74
- auto res = boost::hana::fold (
75
- boost::hana:: zip (names, refs), gltf_result<ParseContext>{ctx}, [&](auto c, auto entry) {
97
+ return [&target ](ParseContext ctx) -> gltf_result<ParseContext> {
98
+ using namespace boost ::hana;
99
+ constexpr auto accessor = accessors<T>( );
100
+ auto names = transform (accessor, first );
101
+ auto members = transform (accessor, second );
102
+ auto refs = transform (members, [&]( auto acc) { return std::ref ( acc (target)); });
103
+
104
+ auto res = fold ( zip (names, refs), gltf_result<ParseContext>{ctx}, [&](auto c, auto entry) {
76
105
if (!c) {
77
106
return c; // I hope the optimizer understands that...
78
107
}
79
- auto name = boost::hana:: to<const char *>(entry[boost::hana:: size_c<0 >]);
80
- auto &member = entry[boost::hana:: size_c<1 >].get ();
108
+ auto name = to<const char *>(entry[size_c<0 >]);
109
+ auto &member = entry[size_c<1 >].get ();
81
110
return c >> field (member, name);
82
111
});
83
112
if (!res) {
@@ -94,7 +123,7 @@ namespace gltfpp {
94
123
95
124
template <typename T, typename std::enable_if_t <detail::is_fundamental_json_type<T>> *>
96
125
auto parse (T &target) {
97
- return [&](ParseContext ctx) -> gltf_result<ParseContext> {
126
+ return [&target ](ParseContext ctx) -> gltf_result<ParseContext> {
98
127
// TODO this is not a complete check
99
128
if (ctx.json ) {
100
129
target = ctx.json ->template get <T>();
@@ -106,7 +135,7 @@ namespace gltfpp {
106
135
107
136
template <typename T, typename std::enable_if_t <detail::is_field_list<T>> *>
108
137
auto parse (T &target) {
109
- return [&](ParseContext ctx) -> gltf_result<ParseContext> {
138
+ return [&target ](ParseContext ctx) -> gltf_result<ParseContext> {
110
139
if (!ctx.json ) {
111
140
return make_unexpected (gltf_error::key_not_found);
112
141
}
@@ -116,10 +145,10 @@ namespace gltfpp {
116
145
117
146
target.resize (ctx.json ->size ());
118
147
119
- auto in = ctx.json ;
148
+ auto in = ctx.json -> begin () ;
120
149
auto out = target.begin ();
121
150
for (; out != target.end (); ++in, ++out) {
122
- auto res = parse (*out)({ctx.root , in});
151
+ auto res = parse (*out)({ctx.root , &* in});
123
152
static_assert (std::is_same<gltf_result<ParseContext>, decltype (res)>{},
124
153
" Return type of the parser function must be gltf_result<ParseContext>" );
125
154
if (!res) {
@@ -129,6 +158,22 @@ namespace gltfpp {
129
158
return ctx;
130
159
};
131
160
}
161
+
162
+ template <typename T, typename std::enable_if_t <detail::is_enumeration<T>> *>
163
+ auto parse (T &target) {
164
+ return [&target](ParseContext ctx) -> gltf_result<ParseContext> {
165
+ if (!ctx.json ) {
166
+ return make_unexpected (gltf_error::key_not_found);
167
+ }
168
+ const auto str = ctx.json ->get <std::string>();
169
+ const auto parsed = T::_from_string_nothrow (str.c_str ());
170
+ if (!parsed) {
171
+ return make_unexpected (gltf_error::decode_error);
172
+ }
173
+ target = *parsed;
174
+ return ctx;
175
+ };
176
+ }
132
177
133
178
template <typename CharInputIterator, typename ByteOutputIterator>
134
179
auto decode_embedded_base64 (CharInputIterator first, CharInputIterator last, ByteOutputIterator out) {
0 commit comments