diff --git a/clip.cpp b/clip.cpp index b8afe72d..1b6afd4b 100644 --- a/clip.cpp +++ b/clip.cpp @@ -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; } }; diff --git a/mvt.cpp b/mvt.cpp index 4c21716e..2511f744 100644 --- a/mvt.cpp +++ b/mvt.cpp @@ -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; diff --git a/mvt.hpp b/mvt.hpp index 696e2535..f8d6b996 100644 --- a/mvt.hpp +++ b/mvt.hpp @@ -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() {