www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - On opCmp

reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
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)
         }
     }
Feb 27 2015
next sibling parent "anonymous" <anonymous example.com> writes:
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)); } } ----
Feb 27 2015
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 2/27/15 6:04 AM, "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;
              }
          }
      }
 }
Hm... what about: return count < rhs.count ? -1 : count > rhs.count ? 1 : rank < rhs.rank ? -1 : rank > rhs.rank;
 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)
          }
      }
A standard opCmp would be nice. Why wouldn't you use it for count as well? -Steve
Feb 27 2015
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Friday, 27 February 2015 at 15:00:35 UTC, Steven Schveighoffer 
wrote:
 Hm... what about:

 return count < rhs.count ? -1 : count > rhs.count ? 1 : rank < 
 rhs.rank ? -1 : rank > rhs.rank;
Is this more efficient than my version?
Mar 02 2015
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 3/2/15 8:52 AM, "Nordlöw" wrote:
 On Friday, 27 February 2015 at 15:00:35 UTC, Steven Schveighoffer wrote:
 Hm... what about:

 return count < rhs.count ? -1 : count > rhs.count ? 1 : rank <
 rhs.rank ? -1 : rank > rhs.rank;
Is this more efficient than my version?
You said "more compact", not more efficient :) But I think they are probably the same generated code. I'm not doing anything really different (except for the shortcut for rank > rhs.rank being 1 or 0 based on the conversion to int). -Steve
Mar 02 2015
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/27/2015 03:04 AM, "Nordlöw" wrote:

 Is there a more compact way to describe the opCmp function in the
 following struct
Please see: http://forum.dlang.org/thread/lnr99a$vvd$1 digitalmars.com#post-lnr99a:24vvd:241:40digitalmars.com Ali
Feb 27 2015