Re:Sentimental Versioning
by Lvl999Noob on Monday October 12, 2020 @10:11AM
(#24754483)
Your second code is wrong. For lhs = "4.3.7" and rhs = "3.3.7", your code will give true. It should be false.
[ Parent
| on HN ]
Uh, no it won't?
cat >test_ver.cpp << EOF
#include <cstdio>
struct version {
int Major;
int Minor;
int Patch;
version(int major, int minor, int patch)
: Major(major)
, Minor(minor)
, Patch(patch)
{ }
};
bool operator<=(version lhs, version rhs) {
return (lhs.Major < rhs.Major)
|| ((lhs.Major == rhs.Major) && ((lhs.Minor < rhs.Minor)
|| ((lhs.Minor == rhs.Minor) && (lhs.Patch <= rhs.Patch))));
}
int main(int argc, char **argv) {
version lhs(4, 3, 7);
version rhs(3, 3, 7);
printf("lhs <= rhs? %s\n", lhs <= rhs ? "true" : "false");
}
EOF
g++ test_ver.cpp -o test_ver && ./test_ver
prints lhs <= rhs? falseNo, it works. It's just non-obvious that it does due to the reliance on 4 levels of braces.
It is equivalent to the following:
lhs.Major < rhs.Major
or (lhs.Major == rhs.Major and lhs.Minor < rhs.Minor)
or (lhs.Major == rhs.Major and lhs.Minor == rhs.Minor and lhs.Patch <= rhs.Patch)
Deduplicating (lhs.Major == rhs.Major) decreased readability enough to be confusing.There is so many ways to write this comparison that after a couple of times you really wish there were something in the standard library to help you so that you could write e.g.
bool operator<=(version lhs, version rhs) {
return std::tie(lhs.Major, lhs.Minor, lhs.Patch) <= std::tie(rhs.Major, rhs.Minor, rhs.Patch);
}
Wait, there is! And Python has something like this too, even more laconic: you don't need to write "std::tie", naked parentheses are enough.