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()) ==
']') {
90 if (
auto posBrack = var_description.find(
'['); posBrack != std::string::npos) {
91 name = var_description.substr(0, posBrack);
93 = var_description.substr(posBrack + 1, var_description.size() - posBrack - 2);
94 const auto& args =
split(s_args,
",");
98 }
else if (args.size() == 1) {
101 const auto& labels =
split(args[0],
":");
103 if (labels.size() == 3) {
105 const double fmin = std::stod(labels[0]);
106 const double fmax = std::stod(labels[1]);
107 const int nbr = std::stoi(labels[2]);
111 const auto step = (fmax - fmin) / nbr;
112 double current = fmin;
113 for (
auto i = 0; i <= nbr; i += 1) {
114 ticks.push_back(current);
120 int n = std::stoi(args[0]);
121 if ((n < 2) && (default_domain !=
"[1]"))
123 ds =
static_cast< Size >(n);
125 range_max =
static_cast< long >(ds) - 1;
127 }
else if (args.size() == 2) {
129 range_min = std::stol(args[0]);
130 range_max = std::stol(args[1]);
132 if (range_max < range_min)
134 "Invalid range for variable " << var_description <<
": max<min")
135 if (range_max == range_min && default_domain !=
"[1]")
137 "Invalid range for variable "
138 << var_description <<
": max==min not allowed if default_domain_size>1")
140 ds =
static_cast< Size >(1 + range_max - range_min);
143 for (
const auto& tick: args) {
144 ticks.push_back(
static_cast< GUM_SCALAR
>(std::strtod(tick.c_str(),
nullptr)));
146 ds = args.size() - 1;
150 }
else if (*(var_description.rbegin()) ==
'}') {
151 if (
auto posBrack = var_description.find(
'{'); posBrack != std::string::npos) {
152 name = var_description.substr(0, posBrack);
153 labels =
split(var_description.substr(posBrack + 1, var_description.size() - posBrack - 2),
155 if (labels.size() == 3) {
157 const auto fmin = std::stod(labels[0]);
158 const auto fmax = std::stod(labels[1]);
159 const int nbr = std::stoi(labels[2]);
163 const auto step =
double((fmax - fmin) / (nbr - 1));
165 if ((trunc(step) == step) && (trunc(fmin) == fmin) && (trunc(fmax) == fmax)) {
168 numerical_values.clear();
170 for (
int i = 1; i <= nbr; i++) {
171 labels.push_back(std::to_string(v));
178 numerical_values.clear();
181 numerical_values.push_back(v);
182 for (
auto i = 1; i < nbr - 1; i++) {
184 numerical_values.push_back(v);
186 numerical_values.push_back(fmax);
190 =
split(var_description.substr(posBrack + 1, var_description.size() - posBrack - 2),
192 if (labels.size() < 2) {
193 if (labels.size() == 1
194 && default_domain !=
"[1]")
197 if (!hasUniqueElts(labels)) {
204 name = var_description;
209 }
else if (ds == 1) {
210 if (default_domain !=
"[1]")
212 "Only one value for variable " << var_description <<
" (2 at least are needed).")
215 if (!labels.empty()) {
216 if (std::all_of(labels.cbegin(), labels.cend(),
isInteger)) {
217 for (
const auto& label: labels)
218 values.push_back(std::stoi(label));
219 if (values.size() >= 2) {
221 std::sort(values.begin(), values.end());
222 range_min = values[0];
224 bool is_range =
true;
225 for (
const auto item: values) {
226 if (item != v) { is_range =
false; }
235 }
else if (std::all_of(labels.cbegin(), labels.cend(),
isNumerical))
236 for (
const auto& label: labels)
237 numerical_values.push_back(std::stod(label));
242 if (!values.empty()) {
243 return std::make_unique< IntegerVariable >(name, name, values);
244 }
else if (!numerical_values.empty()) {
245 if (!std::all_of(numerical_values.cbegin(),
246 numerical_values.cend(),
250 return std::make_unique< NumericalDiscreteVariable >(name, name, numerical_values);
251 }
else if (!labels.empty()) {
252 return std::make_unique< LabelizedVariable >(name, name, labels);
253 }
else if (!ticks.empty()) {
259 if (name.back() ==
'+') {
262 return std::make_unique< DiscretizedVariable< GUM_SCALAR > >(name, name, ticks,
true);
264 return std::make_unique< DiscretizedVariable< GUM_SCALAR > >(name, name, ticks);
267 return std::make_unique< RangeVariable >(name, name, range_min, range_max);