62 std::unique_ptr< DiscreteVariable >
fastVariable(std::string var_description,
63 std::string_view default_domain) {
67 std::vector< std::string > labels;
68 std::vector< GUM_SCALAR > ticks;
71 std::vector< int > values;
72 std::vector< double > numerical_values;
74 trim(var_description);
79 if (
auto t = *default_domain.begin(); t !=
'[' && t !=
'{')
81 "default_domain (" << default_domain <<
") must start with '[' or '{'")
83 if (var_description.find(
'[') == std::string::npos
84 && var_description.find(
'{') == std::string::npos) {
85 var_description += default_domain;
89 if (*(var_description.rbegin()) ==
']') {
93 if (
auto posBrack = var_description.rfind(
'['); posBrack != std::string::npos) {
94 name = var_description.substr(0, posBrack);
96 = var_description.substr(posBrack + 1, var_description.size() - posBrack - 2);
97 const auto& args =
split(s_args,
",");
101 }
else if (args.size() == 1) {
104 const auto& labels =
split(args[0],
":");
106 if (labels.size() == 3) {
108 const double fmin = std::stod(labels[0]);
109 const double fmax = std::stod(labels[1]);
110 const int nbr = std::stoi(labels[2]);
114 const auto step = (fmax - fmin) / nbr;
115 double current = fmin;
116 for (
auto i = 0; i <= nbr; i += 1) {
117 ticks.push_back(current);
123 int n = std::stoi(args[0]);
124 if ((n < 2) && (default_domain !=
"[1]"))
126 ds =
static_cast< Size >(n);
128 range_max =
static_cast< long >(ds) - 1;
130 }
else if (args.size() == 2) {
132 range_min = std::stol(args[0]);
133 range_max = std::stol(args[1]);
135 if (range_max < range_min)
137 "Invalid range for variable " << var_description <<
": max<min")
138 if (range_max == range_min && default_domain !=
"[1]")
140 "Invalid range for variable "
141 << var_description <<
": max==min not allowed if default_domain_size>1")
143 ds =
static_cast< Size >(1 + range_max - range_min);
146 for (
const auto& tick: args) {
147 ticks.push_back(
static_cast< GUM_SCALAR
>(std::strtod(tick.c_str(),
nullptr)));
149 ds = args.size() - 1;
153 }
else if (*(var_description.rbegin()) ==
'}') {
154 if (
auto posBrack = var_description.find(
'{'); posBrack != std::string::npos) {
155 name = var_description.substr(0, posBrack);
156 labels =
split(var_description.substr(posBrack + 1, var_description.size() - posBrack - 2),
158 if (labels.size() == 3) {
160 const auto fmin = std::stod(labels[0]);
161 const auto fmax = std::stod(labels[1]);
162 const int nbr = std::stoi(labels[2]);
166 const auto step =
double((fmax - fmin) / (nbr - 1));
168 if ((trunc(step) == step) && (trunc(fmin) == fmin) && (trunc(fmax) == fmax)) {
171 numerical_values.clear();
173 for (
int i = 1; i <= nbr; i++) {
174 labels.push_back(std::to_string(v));
181 numerical_values.clear();
184 numerical_values.push_back(v);
185 for (
auto i = 1; i < nbr - 1; i++) {
187 numerical_values.push_back(v);
189 numerical_values.push_back(fmax);
193 =
split(var_description.substr(posBrack + 1, var_description.size() - posBrack - 2),
195 if (labels.size() < 2) {
196 if (labels.size() == 1
197 && default_domain !=
"[1]")
200 if (!hasUniqueElts(labels)) {
207 name = var_description;
212 }
else if (ds == 1) {
213 if (default_domain !=
"[1]")
215 "Only one value for variable " << var_description <<
" (2 at least are needed).")
218 if (!labels.empty()) {
219 if (std::all_of(labels.cbegin(), labels.cend(),
isInteger)) {
220 for (
const auto& label: labels)
221 values.push_back(std::stoi(label));
222 if (values.size() >= 2) {
224 std::sort(values.begin(), values.end());
225 range_min = values[0];
227 bool is_range =
true;
228 for (
const auto item: values) {
229 if (item != v) { is_range =
false; }
238 }
else if (std::all_of(labels.cbegin(), labels.cend(),
isNumerical))
239 for (
const auto& label: labels)
240 numerical_values.push_back(std::stod(label));
245 if (!values.empty()) {
246 return std::make_unique< IntegerVariable >(name, name, values);
247 }
else if (!numerical_values.empty()) {
248 if (!std::all_of(numerical_values.cbegin(),
249 numerical_values.cend(),
253 return std::make_unique< NumericalDiscreteVariable >(name, name, numerical_values);
254 }
else if (!labels.empty()) {
255 return std::make_unique< LabelizedVariable >(name, name, labels);
256 }
else if (!ticks.empty()) {
262 if (name.back() ==
'+') {
265 return std::make_unique< DiscretizedVariable< GUM_SCALAR > >(name, name, ticks,
true);
267 return std::make_unique< DiscretizedVariable< GUM_SCALAR > >(name, name, ticks);
270 return std::make_unique< RangeVariable >(name, name, range_min, range_max);