2 #include <msp/core/except.h>
3 #include <msp/strings/format.h>
4 #include <msp/strings/utils.h>
9 Type::Type(const string &n, Kind k):
13 if(kind==VALUE || kind==ENUM)
16 cpp_type = name+"Setup";
19 Type &Type::set_cpp_type(const string &t, const string &h)
26 Type &Type::set_elements(const Type &t, unsigned c)
28 if(kind!=AGGREGATE && kind!=POINTER && kind!=DYN_ARRAY)
29 throw invalid_state("wrong kind");
30 if((kind==POINTER && c>1) || (kind==DYN_ARRAY && c>0))
31 throw invalid_argument("Type::set_elements");
34 element_count = (kind==POINTER ? 1 : c);
38 cpp_type = format("%s *", t.get_cpp_type());
39 else if(kind==DYN_ARRAY)
40 cpp_type = format("std::vector<%s>", t.get_cpp_type());
46 Type &Type::set_struct(const Struct &s)
49 throw invalid_state("wrong kind");
54 Type &Type::set_enum(const Enum &e)
57 throw invalid_state("wrong kind");
62 Type &Type::set_load(const string &l, const string &c)
65 throw invalid_state("wrong kind");
71 const Type &Type::get_element_type() const
73 if(kind!=AGGREGATE && kind!=POINTER && kind!=DYN_ARRAY)
74 throw invalid_state("wrong kind");
76 throw invalid_state("no element type");
80 const Struct &Type::get_struct() const
83 throw invalid_state("wrong kind");
85 throw invalid_state("no struct");
89 const Enum &Type::get_enum() const
92 throw invalid_state("wrong kind");
94 throw invalid_state("no enum");
98 bool Type::needs_loader_function() const
102 case VALUE: return !load_type.empty();
104 case ENUM: return false;
107 case STRUCT: return true;
108 default: throw invalid_state("bad kind");
112 string Type::create_loader_params(bool with_names) const
117 for(unsigned i=0; i<element_count; ++i)
120 append(result, ", ", format("%s _a%d", element_type->get_cpp_type(), i));
122 append(result, ", ", element_type->get_cpp_type());
128 const string &type = (load_type.empty() ? cpp_type : load_type);
129 return (with_names ? format("%s _a", type) : type);
131 else if(kind==DYN_ARRAY)
133 Kind elem_kind = element_type->get_kind();
134 if(elem_kind==VALUE || elem_kind==ENUM)
136 string type = format("std::vector<%s>", element_type->get_cpp_type());
137 return (with_names ? format("%s _a", type) : type);
142 else if(kind==STRUCT)
145 throw invalid_state("wrong kind");
148 string Type::create_loader_statement() const
153 for(unsigned i=0; i<element_count; ++i)
154 append(init, ", ", format("_a%d", i));
155 return format("_v = { %s };", init);
158 return format("_v = %s(_a);", (conversion.empty() ? cpp_type : conversion));
159 else if(kind==STRUCT)
160 return "load_sub(_v);";
161 else if(kind==DYN_ARRAY)
163 Kind elem_kind = element_type->get_kind();
164 if(elem_kind==VALUE || elem_kind==ENUM)
165 return "_v.insert(_v.end(), _a.begin(), _a.end());";
167 return format("%s _e; load_sub(_e); _v.emplace_back(move(_e));", cpp_type);
170 throw invalid_state("wrong kind");