2121// SOFTWARE.
2222
2323
24+ #include < algorithm>
2425#include < boost/utility/string_view.hpp>
25- #include < unordered_map>
2626#include < limits>
27+ #include < ostream>
28+ #include < string>
2729#include < tuple>
28- #include < algorithm>
30+ #include < unordered_map>
31+
2932#include < daw/json/daw_json_link.h>
3033
3134#include " json_to_cpp.h"
@@ -114,7 +117,23 @@ namespace daw {
114117 void parse_json_array ( boost::string_view cur_name, daw::json::impl::value_t const & cur_item, std::vector<obj_info_t > & obj_info, state_t & obj_state );
115118
116119 auto find_by_name ( std::vector<obj_info_t > & obj_info, std::string const & name ) {
117- return std::find_if ( obj_info.begin ( ), obj_info.end ( ), [&]( auto const & v ) { return v.name == name; } );
120+ return std::find_if ( obj_info.begin ( ), obj_info.end ( ),
121+
122+ [&name]( auto const & v ) {
123+ return v.name == name;
124+ } );
125+ }
126+
127+ void add_or_merge ( std::vector<obj_info_t > & obj_info, obj_info_t cur_obj ) {
128+ assert ( !cur_obj.name .empty ( ) );
129+ auto old_item = find_by_name ( obj_info, cur_obj.name );
130+ if ( old_item == obj_info.end ( ) ) {
131+ old_item = obj_info.insert ( obj_info.end ( ), cur_obj );
132+ } else {
133+ for ( auto const & member: cur_obj.members ) {
134+ old_item->members [member.first ] = member.second ;
135+ }
136+ }
118137 }
119138
120139 void parse_json_object ( boost::string_view cur_name, daw::json::impl::object_value const & cur_item, std::vector<obj_info_t > & obj_info, state_t & obj_state ) {
@@ -132,32 +151,26 @@ namespace daw {
132151 cur_obj.members [val_info.name ] = val_info;
133152
134153 switch ( val_info.type ) {
135- case value_t ::value_types::array:
136- obj_state.has_arrays = true ;
137- parse_json_array ( val_info.name , member.second , obj_info, obj_state );
138- break ;
139- case value_t ::value_types::object:
140- parse_json_object ( val_info.name , member.second .get_object ( ), obj_info, obj_state );
141- break ;
142- case value_t ::value_types::integral:
143- obj_state.has_integrals = true ;
144- break ;
145- case value_t ::value_types::string:
146- obj_state.has_strings = true ;
147- break ;
148- default :
149- break ;
150- }
151- }
152-
153- auto old_item = find_by_name ( obj_info, cur_obj.name );
154- if ( old_item != obj_info.end ( ) ) {
155- for ( auto const & member: cur_obj.members ) {
156- old_item->members [member.first ] = member.second ;
154+ case value_t ::value_types::array:
155+ obj_state.has_arrays = true ;
156+ parse_json_array ( val_info.name , member.second , obj_info, obj_state );
157+ break ;
158+ case value_t ::value_types::object:
159+ parse_json_object ( val_info.name , member.second .get_object ( ), obj_info, obj_state );
160+ break ;
161+ case value_t ::value_types::integral:
162+ obj_state.has_integrals = true ;
163+ break ;
164+ case value_t ::value_types::string:
165+ obj_state.has_strings = true ;
166+ break ;
167+ case value_t ::value_types::real:
168+ case value_t ::value_types::boolean:
169+ case value_t ::value_types::null:
170+ break ;
157171 }
158- } else {
159- obj_info.push_back ( cur_obj );
160172 }
173+ add_or_merge ( obj_info, std::move ( cur_obj ) );
161174 }
162175
163176 void parse_json_array ( boost::string_view cur_name, daw::json::impl::value_t const & cur_item, std::vector<obj_info_t > & obj_info, state_t & obj_state ) {
@@ -191,20 +204,14 @@ namespace daw {
191204 case value_t ::value_types::string:
192205 obj_state.has_strings = true ;
193206 break ;
194- default :
207+ case value_t ::value_types::real:
208+ case value_t ::value_types::boolean:
209+ case value_t ::value_types::null:
195210 break ;
196211 }
197212
198213 cur_obj.members [val_info.name ] = val_info;
199-
200- auto old_item = find_by_name ( obj_info, cur_obj.name );
201- if ( old_item != obj_info.end ( ) ) {
202- for ( auto const & member: cur_obj.members ) {
203- old_item->members [member.first ] = member.second ;
204- }
205- } else {
206- obj_info.push_back ( cur_obj );
207- }
214+ add_or_merge ( obj_info, std::move ( cur_obj ) );
208215 }
209216
210217 std::vector<obj_info_t > parse_json_object ( daw::json::impl::value_t const & json_obj, state_t & obj_state ) {
@@ -263,7 +270,7 @@ namespace daw {
263270 std::abort ( );
264271 }
265272
266- void generate_default_constructor ( bool definition, std::stringstream & ss, std::string const & obj_type, obj_info_t cur_obj ) {
273+ void generate_default_constructor ( bool definition, std::ostream & ss, std::string const & obj_type, obj_info_t cur_obj ) {
267274 if ( definition ) {
268275 ss << obj_type << " ::" << obj_type << " ( ):\n " ;
269276 ss << " \t\t daw::json::JsonLink<" << obj_type << " >{ }" ;
@@ -276,7 +283,7 @@ namespace daw {
276283 }
277284 }
278285
279- void generate_copy_constructor ( bool definition, std::stringstream & ss, std::string const & obj_type, obj_info_t cur_obj ) {
286+ void generate_copy_constructor ( bool definition, std::ostream & ss, std::string const & obj_type, obj_info_t cur_obj ) {
280287 if ( definition ) {
281288 ss << obj_type << " ::" ;
282289 ss << obj_type << " ( " << obj_type << " const & other )" ;
@@ -290,7 +297,7 @@ namespace daw {
290297 }
291298 }
292299
293- void generate_move_constructor ( bool definition, std::stringstream & ss, std::string const & obj_type, obj_info_t cur_obj ) {
300+ void generate_move_constructor ( bool definition, std::ostream & ss, std::string const & obj_type, obj_info_t cur_obj ) {
294301 if ( definition ) {
295302 ss << obj_type << " ::" << obj_type << " ( " << obj_type << " && other ):\n " ;
296303 ss << " \t\t daw::json::JsonLink<" << obj_type << " >{ }" ;
@@ -303,15 +310,15 @@ namespace daw {
303310 }
304311 }
305312
306- void generate_destructor ( bool definition, std::stringstream & ss, std::string const & obj_type ) {
313+ void generate_destructor ( bool definition, std::ostream & ss, std::string const & obj_type ) {
307314 if ( definition ) {
308315 ss << obj_type << " ::~" << obj_type << " ( ) { }\n\n " ;
309316 } else {
310317 ss << " \t ~" << obj_type << " ( );\n " ;
311318 }
312319 }
313320
314- void generate_set_links ( bool definition, std::stringstream & ss, std::string const & obj_type, obj_info_t cur_obj ) {
321+ void generate_set_links ( bool definition, std::ostream & ss, std::string const & obj_type, obj_info_t cur_obj ) {
315322 if ( definition ) {
316323 ss << " void " << obj_type << " ::set_links( ) {\n " ;
317324 for ( auto const & item: cur_obj.members ) {
@@ -330,7 +337,7 @@ namespace daw {
330337 }
331338 }
332339
333- void generate_jsonlink ( bool definition, std::stringstream & ss, std::string const & obj_type, obj_info_t cur_obj ) {
340+ void generate_jsonlink ( bool definition, std::ostream & ss, std::string const & obj_type, obj_info_t cur_obj ) {
334341 generate_default_constructor ( definition, ss, obj_type, cur_obj );
335342 generate_copy_constructor ( definition, ss, obj_type, cur_obj );
336343 generate_move_constructor ( definition, ss, obj_type, cur_obj );
@@ -342,7 +349,7 @@ namespace daw {
342349 }
343350 }
344351
345- void generate_includes ( std::stringstream & ss, config_t const & config, state_t const & obj_state ) {
352+ void generate_includes ( std::ostream & ss, config_t const & config, state_t const & obj_state ) {
346353 if ( obj_state.has_optionals ) ss << " #include <boost/optional.hpp>\n " ;
347354 if ( obj_state.has_integrals ) ss << " #include <cstdint>\n " ;
348355 if ( obj_state.has_strings ) ss << " #include <string>\n " ;
@@ -351,11 +358,7 @@ namespace daw {
351358 ss << ' \n ' ;
352359 }
353360
354- std::string generate_code ( std::vector<obj_info_t > obj_info, config_t const & config, state_t const & obj_state ) {
355- using daw::json::impl::value_t ;
356- std::stringstream ss;
357- ss << " // Code auto generated from json file.\n " ;
358- generate_includes ( ss, config, obj_state );
361+ void generate_declarations ( std::vector<obj_info_t > const & obj_info, std::ostream & ss, config_t const & config, state_t const & obj_state ) {
359362 for ( auto const & cur_obj: obj_info ) {
360363 auto const obj_type = cur_obj.name + " _t" ;
361364
@@ -391,32 +394,33 @@ namespace daw {
391394 if ( config.enable_comments ) {
392395 ss << " \t // " << obj_type;
393396 }
394- ss << " \n " ;
397+ ss << " \n\n " ;
395398 }
399+ }
400+
401+ void generate_definitions ( std::vector<obj_info_t > const & obj_info, std::ostream & ss, config_t const & config, state_t const & obj_state ) {
396402 for ( auto const & cur_obj: obj_info ) {
397403 auto const obj_type = cur_obj.name + " _t" ;
398- for ( auto const & item: cur_obj.members ) {
399- auto const & member = item.second ;
400- auto const member_type = type_to_string ( member.name , member.type );
401- if ( config.enable_jsonlink ) {
402- generate_jsonlink ( true , ss, obj_type, cur_obj );
403- }
404- ss << ' \n ' ;
405- }
404+ generate_jsonlink ( true , ss, obj_type, cur_obj );
405+ }
406+ }
407+
408+ void generate_code ( std::vector<obj_info_t > const & obj_info, std::ostream & ss, config_t const & config, state_t const & obj_state ) {
409+ ss << " // Code auto generated from json file.\n " ;
410+ generate_includes ( ss, config, obj_state );
411+ generate_declarations ( obj_info, ss, config, obj_state );
412+ if ( config.enable_jsonlink ) {
413+ generate_definitions ( obj_info, ss, config, obj_state );
406414 }
407- return ss.str ( );
408415 }
409416
410417 } // namespace anonymous
411418
412- std::string generate_cpp ( boost::string_view json_string, config_t const & config ) {
419+ void generate_cpp ( boost::string_view json_string, std::ostream & ss , config_t const & config ) {
413420 state_t obj_state;
414421 auto json_obj = daw::json::parse_json ( json_string );
415422 auto obj_info = parse_json_object ( json_obj, obj_state );
416- std::string result = generate_code ( obj_info, config, obj_state );
417-
418- return result;
419-
423+ generate_code ( obj_info, ss, config, obj_state );
420424 }
421425 } // namespace json_to_cpp
422426} // namespace daw
0 commit comments