50#ifndef DOXYGEN_SHOULD_SKIP_THIS
63 const std::vector< std::string >& missing_symbols,
64 std::size_t max_dico_entries) :
70 _variable_(
"var",
"", 1, 0) {
75 bool non_int_symbol_found =
false;
76 for (
const auto& symbol: this->missing_symbols_) {
77 if (DBCell::isInteger(symbol)) {
78 _status_int_missing_symbols_.insert(symbol,
false);
79 }
else if (!non_int_symbol_found) {
80 non_int_symbol_found =
true;
81 _nonint_missing_symbol_ = symbol;
85 GUM_CONSTRUCTOR(DBTranslator4RangeVariable);
89 DBTranslator4RangeVariable::DBTranslator4RangeVariable(std::size_t max_dico_entries) :
90 DBTranslator(DBTranslatedValueType::
DISCRETE, true, true, max_dico_entries),
91 _variable_(
"var",
"", 1, 0) {
92 GUM_CONSTRUCTOR(DBTranslator4RangeVariable);
96 DBTranslator4RangeVariable::DBTranslator4RangeVariable(
97 const RangeVariable& var,
98 const std::vector< std::string >& missing_symbols,
99 const bool editable_dictionary,
100 std::size_t max_dico_entries) :
101 DBTranslator(DBTranslatedValueType::
DISCRETE,
108 const long lower_bound = var.minVal();
109 const long upper_bound = var.maxVal();
112 if ((upper_bound >= lower_bound)
113 && (std::size_t(upper_bound - lower_bound + 1) > this->max_dico_entries_)) {
120 if (lower_bound <= upper_bound) {
121 for (
auto iter = this->missing_symbols_.beginSafe();
122 iter != this->missing_symbols_.endSafe();
124 if (DBCell::isInteger(*iter)) {
125 const long missing_val = std::stol(*iter);
126 if ((missing_val >= lower_bound) && (missing_val <= upper_bound)) {
127 this->missing_symbols_.erase(iter);
134 std::size_t size = 0;
135 for (
const auto& label: var.labels()) {
137 this->back_dico_.insert(size, label);
145 bool non_int_symbol_found =
false;
146 for (
const auto& symbol: this->missing_symbols_) {
147 if (DBCell::isInteger(symbol)) {
148 _status_int_missing_symbols_.insert(symbol,
false);
149 }
else if (!non_int_symbol_found) {
150 non_int_symbol_found =
true;
151 _nonint_missing_symbol_ = symbol;
155 GUM_CONSTRUCTOR(DBTranslator4RangeVariable);
159 DBTranslator4RangeVariable::DBTranslator4RangeVariable(
const RangeVariable& var,
160 const bool editable_dictionary,
161 std::size_t max_dico_entries) :
162 DBTranslator(DBTranslatedValueType::
DISCRETE, true, editable_dictionary, max_dico_entries),
165 const long lower_bound = var.minVal();
166 const long upper_bound = var.maxVal();
169 if ((upper_bound >= lower_bound)
170 && (std::size_t(upper_bound - lower_bound + 1) > this->max_dico_entries_)) {
175 std::size_t size = 0;
176 for (
const auto& label: var.labels()) {
178 this->back_dico_.insert(size, label);
182 GUM_CONSTRUCTOR(DBTranslator4RangeVariable);
186 DBTranslator4RangeVariable::DBTranslator4RangeVariable(
const DBTranslator4RangeVariable& from) :
187 DBTranslator(from), _variable_(from._variable_),
188 _status_int_missing_symbols_(from._status_int_missing_symbols_),
189 _translated_int_missing_symbols_(from._translated_int_missing_symbols_),
190 _nonint_missing_symbol_(from._nonint_missing_symbol_) {
191 GUM_CONS_CPY(DBTranslator4RangeVariable);
195 DBTranslator4RangeVariable::DBTranslator4RangeVariable(DBTranslator4RangeVariable&& from) :
196 DBTranslator(
std::move(from)), _variable_(
std::move(from._variable_)),
197 _status_int_missing_symbols_(
std::move(from._status_int_missing_symbols_)),
198 _translated_int_missing_symbols_(
std::move(from._translated_int_missing_symbols_)),
199 _nonint_missing_symbol_(
std::move(from._nonint_missing_symbol_)) {
200 GUM_CONS_MOV(DBTranslator4RangeVariable);
204 DBTranslator4RangeVariable* DBTranslator4RangeVariable::clone()
const {
205 return new DBTranslator4RangeVariable(*
this);
209 DBTranslator4RangeVariable&
210 DBTranslator4RangeVariable::operator=(
const DBTranslator4RangeVariable& from) {
212 DBTranslator::operator=(from);
213 _variable_ = from._variable_;
214 _status_int_missing_symbols_ = from._status_int_missing_symbols_;
215 _translated_int_missing_symbols_ = from._translated_int_missing_symbols_;
216 _nonint_missing_symbol_ = from._nonint_missing_symbol_;
223 DBTranslator4RangeVariable&
224 DBTranslator4RangeVariable::operator=(DBTranslator4RangeVariable&& from) {
226 DBTranslator::operator=(std::move(from));
227 _variable_ = std::move(from._variable_);
228 _status_int_missing_symbols_ = std::move(from._status_int_missing_symbols_);
229 _translated_int_missing_symbols_ = std::move(from._translated_int_missing_symbols_);
230 _nonint_missing_symbol_ = std::move(from._nonint_missing_symbol_);
237 DBTranslatedValue DBTranslator4RangeVariable::translate(
const std::string& str) {
243 return DBTranslatedValue{this->back_dico_.first(str)};
246 if (this->isMissingSymbol(str)) {
248 const bool is_str_translated = _status_int_missing_symbols_[str];
249 if (!is_str_translated) {
250 _status_int_missing_symbols_[str] =
true;
251 _translated_int_missing_symbols_.insert(std::stol(str));
253 }
catch (gum::NotFound&) {}
254 return DBTranslatedValue{std::numeric_limits< std::size_t >::max()};
258 if (!this->hasEditableDictionary()) {
260 "The translation of String \"" << str <<
"\" could not be found for variable '"
261 << _variable_ <<
"'.");
265 if (!DBCell::isInteger(str)) {
267 "String \"" << str <<
"\" cannot be translated because "
268 <<
"it cannot be converted into an integer");
270 const long new_value = std::stol(str);
274 if (_translated_int_missing_symbols_.exists(new_value)) {
276 "String \"" << str <<
"\" cannot be translated because "
277 <<
"it corresponds to an already translated missing symbol");
287 if (_variable_.minVal() > _variable_.maxVal()) {
288 if (this->max_dico_entries_ == 0) {
290 "String \"" << str <<
"\" cannot be translated because "
291 <<
"the dictionary is already full");
293 _variable_.setMinVal(new_value);
294 _variable_.setMaxVal(new_value);
295 this->back_dico_.insert(std::size_t(0), str);
296 return DBTranslatedValue{std::size_t(0)};
303 const long lower_bound = _variable_.minVal();
304 const long upper_bound = _variable_.maxVal();
306 std::size_t size = upper_bound - lower_bound + 1;
308 if (new_value < _variable_.minVal()) {
309 if (std::size_t(upper_bound - new_value + 1) > this->max_dico_entries_)
311 "String \"" << str <<
"\" cannot be translated because "
312 <<
"the dictionary is already full");
316 for (
const auto& missing: _translated_int_missing_symbols_) {
317 if ((missing >= new_value) && (missing <= upper_bound)) {
319 "String \"" << str <<
"\" cannot be translated "
320 <<
"because it would induce a new range containing "
321 <<
"an already translated missing symbol");
327 for (
auto iter = _status_int_missing_symbols_.beginSafe();
328 iter != _status_int_missing_symbols_.endSafe();
330 if (iter.val() ==
false) {
331 const long missing = std::stol(iter.key());
332 if ((missing >= new_value) && (missing <= upper_bound)) {
333 this->missing_symbols_.erase(iter.key());
334 _status_int_missing_symbols_.erase(iter);
340 const std::size_t index = size;
341 for (
long i = new_value; i < _variable_.minVal(); ++i) {
342 this->back_dico_.insert(size, std::to_string(i));
345 _variable_.setMinVal(new_value);
347 return DBTranslatedValue{index};
349 if (std::size_t(new_value - lower_bound + 1) > this->max_dico_entries_)
351 "String \"" << str <<
"\" cannot be translated because "
352 <<
"the dictionary is already full");
356 for (
const auto& missing: _translated_int_missing_symbols_) {
357 if ((missing <= new_value) && (missing >= lower_bound)) {
359 "String \"" << str <<
"\" cannot be translated "
360 <<
"because it would induce a new range containing "
361 <<
"an already translated missing symbol");
367 for (
auto iter = _status_int_missing_symbols_.beginSafe();
368 iter != _status_int_missing_symbols_.endSafe();
370 if (iter.val() ==
false) {
371 const long missing = std::stol(iter.key());
372 if ((missing <= new_value) && (missing >= lower_bound)) {
373 this->missing_symbols_.erase(iter.key());
374 _status_int_missing_symbols_.erase(iter);
380 for (
long i = _variable_.maxVal() + 1; i <= new_value; ++i) {
381 this->back_dico_.insert(size, std::to_string(i));
384 _variable_.setMaxVal(new_value);
386 return DBTranslatedValue{size - std::size_t(1)};
392 bool DBTranslator4RangeVariable::needsReordering()
const {
394 const auto& labels = _variable_.labels();
395 std::size_t last_number = std::numeric_limits< std::size_t >::lowest();
397 for (
const auto& label: labels) {
398 number = this->back_dico_.first(label);
399 if (number < last_number)
return true;
400 last_number = number;
The databases' cell translators for range variables.
The databases' cell translators for range variables.
Base class for all aGrUM's exceptions.
Exception : operation not allowed.
Exception : problem with size.
Exception : wrong type for this operation.
Error: An unknown label is found in the database.
DBTranslator4RangeVariable(const std::vector< std::string > &missing_symbols, std::size_t max_dico_entries=std::numeric_limits< std::size_t >::max())
default constructor without any initial variable
The base class for all the tabular database cell translators.
#define GUM_ERROR(type, msg)
DBTranslatedValueType
The nature of the elements handled by translators (discrete, continuous).
include the inlined functions if necessary
gum is the global namespace for all aGrUM entities