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));
    }
}
----

Reply via email to