On Friday, 27 February 2015 at 11:04:51 UTC, Nordlöw wrote:
Is there a more compact way to describe the opCmp function in
the following struct
struct Hit
{
size_t count; // number of walkers that found this node
NWeight rank; // rank (either minimum distance or maximum
strength)
auto opCmp(const Hit rhs) const
{
if (this.count < rhs.count)
{
return -1;
}
else if (this.count > rhs.count)
{
return +1;
}
else
{
if (this.rank < rhs.rank)
{
return -1;
}
else if (this.rank > rhs.rank)
{
return +1;
}
else
{
return 0;
}
}
}
}
by reusing something like
auto opCmp(const Hit rhs) const
{
if (this.count < rhs.count)
{
return -1;
}
else if (this.count > rhs.count)
{
return +1;
}
else
{
return this.rank.standardOpCmp(rhs.rank)
}
}
Two things come to mind:
A) std.algorithm.cmp
----
auto opCmp(const Hit rhs) const
{
import std.algorithm: cmp;
import std.range: only;
if(auto c = cmp(only(count), only(rhs.count)))
{
return c;
}
else /* 'count' values are equal. */
{
return cmp(only(rank), only(rhs.rank));
}
}
----
Maybe there should be a std.algorithm.cmp for non-ranges, too, so
that `only` wouldn't be needed here.
B) std.typecons.Tuple has an opCmp that compares all fields in
order.
----
auto opCmp(const Hit rhs) const
{
import std.typecons: tuple;
return tuple(count, rank).opCmp(tuple(rhs.count, rhs.rank));
}
----
This exact behaviour is not documented, though. So I guess it
should not be relied on. Maybe the documentation should be more
specific. In the meantime, you could duplicate the functionality
in a function of your own:
----
import std.typecons: Tuple;
/** Put a proper, specific description here.
*/
int cmpTuples(Types ...)(Tuple!Types a, Tuple!Types b)
{
// copied from std.typecons.Tuple.opCmp
foreach (i, Unused; Types)
{
if (a[i] != b[i])
{
return a[i] < b[i] ? -1 : 1;
}
}
return 0;
}
struct Hit
{
size_t count;
NWeight rank;
auto opCmp(const Hit rhs) const
{
import std.typecons: tuple;
return cmpTuples(tuple(count, rank), tuple(rhs.count,
rhs.rank));
}
}
----