Reputation: 11681
I currently have a structure like this
struct foo
{
UINT64 optionA = 0;
UINT64 optionB = 0;
UINT64 optionC = 0;
}
I am attempting to write a function for comparing two objects of foo
based on optionA
, optionB
and optionC
. Essentially what I would like the function to do is check if optionA
is the same in both if no then return the lowest object back. If the optionA
in both objects are the same then it will check optionB
in both objects and would return the lowest one. If optionB
are the same in both then it will look at optionC
and return the lowest.
I am thinking that this could be accomplished by assigning a UINT64 no to each object. Then assigning bits based on priority to that no and then comparing each and returning back the lesser one. I am not sure how to go about that approach any suggestions to do this would be appreciated.
Upvotes: 0
Views: 84
Reputation: 9643
It would be simpler and more readable to just have a comparison function that directly compares the data members in the right order, but if having bit masks that store which data members are bigger is helpful for some other reason then here is how I would do it:
foo compare(foo x, foo y)
{
// needs to hold status for 3 data members (one bit each)
int x_status = 0, y_status = 0;
// each bit is 1 if this member is bigger, 0 if smaller
x_status |= (x.optionC > y.optionC)<<0;
x_status |= (x.optionB > y.optionB)<<1;
x_status |= (x.optionA > y.optionA)<<2;
// each bit is 1 if this member is bigger, 0 if smaller
y_status |= (x.optionC < y.optionC)<<0;
y_status |= (x.optionB < y.optionB)<<1;
y_status |= (x.optionA < y.optionA)<<2;
// so now we can compare the values
// if all the data members were bigger the value will be 7 (0b111)
// if all the data members were smaller the value will be 0 (0b000)
if (x_status < y_status) return x; else return y;
}
Try it online here: https://onlinegdb.com/XpdOSFLFa
Upvotes: 1
Reputation: 218288
With C++20, default operator <=>
and operator ==
would do the job.
struct foo
{
UINT64 optionA = 0;
UINT64 optionB = 0;
UINT64 optionC = 0;
auto operator <=>(const foo&) const = default;
bool operator ==(const foo&) const = default;
};
else, std::tuple
might help:
bool operator ==(const foo& lhs, const foo& rhs)
{
return std::tie(lhs.optionA, lhs.optionB, lhs.optionC)
== std::tie(rhs.optionA, rhs.optionB, rhs.optionC);
}
bool operator <(const foo& lhs, const foo& rhs)
{
return std::tie(lhs.optionA, lhs.optionB, lhs.optionC)
< std::tie(rhs.optionA, rhs.optionB, rhs.optionC);
}
Upvotes: 2
Reputation: 118047
The code is currently missing an operator that checks for equallity.
Example:
constexpr bool operator==(const foo& a, const foo& b) {
return
a.optionA == b.optionA &&
a.optionB == b.optionB &&
a.optionC == b.optionC;
}
With that, the below would compile (meaningfully):
using UINT64 = /* unsigned long long */; // usually
struct foo {
UINT64 optionA = 0;
UINT64 optionB = 0;
UINT64 optionC = 0;
};
constexpr bool operator==(const foo& a, const foo& b) {
return
a.optionA == b.optionA &&
a.optionB == b.optionB &&
a.optionC == b.optionC;
}
int main() {
constexpr foo a, b;
static_assert(a == b);
}
Upvotes: 1