Type promotion for comparison

This commit is contained in:
Erica Fischer
2023-12-18 12:25:32 -08:00
parent 97867ecab0
commit 6f3256f5af
3 changed files with 104 additions and 0 deletions
+7
View File
@@ -798,6 +798,13 @@ struct sorter {
mvt_value av = a.value(attr);
mvt_value bv = b.value(attr);
av = av.promote_for_comparison_with(bv);
bv = bv.promote_for_comparison_with(av);
if (av.type != bv.type) {
fprintf(stderr, "Sorter: can't happen\n");
exit(EXIT_IMPOSSIBLE);
}
return av < bv;
}
};
+96
View File
@@ -470,6 +470,102 @@ bool mvt_value::operator<(const mvt_value &o) const {
return false;
}
mvt_value mvt_value::promote_for_comparison_with(mvt_value const &o) const {
// promotes this value either to string or double,
// depending on what it is intended to be compared with.
//
// comparison of a string and anything else is a string.
//
// (should there also be special cases for uint/sint/int
// for comparison of pairs of 64-bit integers? probably.)
if (o.type == mvt_string) {
if (type == mvt_string) {
return *this;
} else if (type == mvt_float) {
mvt_value v;
v.type = mvt_string;
v.string_value = std::to_string(numeric_value.float_value);
return v;
} else if (type == mvt_double) {
mvt_value v;
v.type = mvt_string;
v.string_value = std::to_string(numeric_value.double_value);
return v;
} else if (type == mvt_int) {
mvt_value v;
v.type = mvt_string;
v.string_value = std::to_string(numeric_value.int_value);
return v;
} else if (type == mvt_uint) {
mvt_value v;
v.type = mvt_string;
v.string_value = std::to_string(numeric_value.uint_value);
return v;
} else if (type == mvt_sint) {
mvt_value v;
v.type = mvt_string;
v.string_value = std::to_string(numeric_value.sint_value);
return v;
} else if (type == mvt_bool) {
mvt_value v;
v.type = mvt_string;
v.string_value = numeric_value.bool_value ? "true" : "false";
return v;
} else if (type == mvt_null) {
mvt_value v;
v.type = mvt_string;
v.string_value = "";
return v;
} else {
fprintf(stderr, "mvt_value::promote_for_comparison_with: can't happen\n");
exit(EXIT_IMPOSSIBLE);
}
} else {
if (type == mvt_string) {
return *this;
} else if (type == mvt_float) {
mvt_value v;
v.type = mvt_double;
v.numeric_value.double_value = numeric_value.float_value;
return v;
} else if (type == mvt_double) {
mvt_value v;
v.type = mvt_double;
v.numeric_value.double_value = numeric_value.double_value;
return v;
} else if (type == mvt_int) {
mvt_value v;
v.type = mvt_double;
v.numeric_value.double_value = numeric_value.int_value;
return v;
} else if (type == mvt_uint) {
mvt_value v;
v.type = mvt_double;
v.numeric_value.double_value = numeric_value.uint_value;
return v;
} else if (type == mvt_sint) {
mvt_value v;
v.type = mvt_double;
v.numeric_value.double_value = numeric_value.sint_value;
return v;
} else if (type == mvt_bool) {
mvt_value v;
v.type = mvt_double;
v.numeric_value.double_value = numeric_value.bool_value ? 1 : 0;
return v;
} else if (type == mvt_null) {
mvt_value v;
v.type = mvt_double;
v.numeric_value.double_value = 0;
return v;
} else {
fprintf(stderr, "mvt_value::promote_for_comparison_with: can't happen\n");
exit(EXIT_IMPOSSIBLE);
}
}
}
static std::string quote(std::string const &s) {
std::string buf;
+1
View File
@@ -81,6 +81,7 @@ struct mvt_value {
} numeric_value;
bool operator<(const mvt_value &o) const;
mvt_value promote_for_comparison_with(mvt_value const &o) const;
std::string toString() const;
mvt_value() {