www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Compiler generated opCmp(Object)

reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
Since it would be, in the general case, meaningless to compare disparate 
types, why cannot the compiler automatically generate opCmp(Object) from 
opCmp(MyType) (the latter would have to exist, of course), and save 
people having to do the first of the following two example ones (from 
class std.openrj.Field) every time:


  int opCmp(Object rhs)
  {
    Field f = cast(Field)(rhs);

    if(null === f)
    {
      throw new InvalidTypeException("Attempt to compare a Field with an 
instance of another type");
    }

    return opCmp(f);
  }

  int opCmp(Field rhs)
  {
    int res;

    if(this === rhs)
    {
      res = 0;
    }
    else
    {
      res = std.string.cmp(m_name, rhs.m_name);

      if(0 == res)
      {
        res = std.string.cmp(m_value, rhs.m_value);
      }
    }

    return res;
  }


Anyone reasons against??
Mar 07 2005
next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message
news:d0jbq1$1a67$1 digitaldaemon.com...
 Since it would be, in the general case, meaningless to compare disparate
 types, why cannot the compiler automatically generate opCmp(Object) from
 opCmp(MyType) (the latter would have to exist, of course), and save
 people having to do the first of the following two example ones (from
 class std.openrj.Field) every time:

Because it would be a special case for opCmp, and no other virtual function would work like that. I think that would be surprising behavior.
   int opCmp(Object rhs)
   {
     Field f = cast(Field)(rhs);

     if(null === f)
     {
       throw new InvalidTypeException("Attempt to compare a Field with an
 instance of another type");
     }

     return opCmp(f);
   }

   int opCmp(Field rhs)
   {
     int res;

     if(this === rhs)
     {
       res = 0;
     }
     else
     {
       res = std.string.cmp(m_name, rhs.m_name);

       if(0 == res)
       {
         res = std.string.cmp(m_value, rhs.m_value);
       }
     }

     return res;
   }

I'd just write it as: int opCmp(Object o) { Field rhs = cast(Field)o; int result = 0; if (rhs) { if (this == rhs) result = 1; else { result = std.string.cmp(m_name, rhs.m_name); if (result == 0) result = std.string.cmp(m_value, rhs.m_value); } } return result; } It's not necessary to write the opCmp(Field). One could replace the if(rhs) with assert(rhs). Since tripping this would be a programming error, not a user input error, shouldn't it be a contract rather than a custom exception?
Mar 07 2005
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter wrote:

 I'd just write it as:
 
     int opCmp(Object o)
     {    Field rhs = cast(Field)o;
          int result = 0;
         if (rhs)
         {
         if (this == rhs)
             result = 1;
         else
         {    result = std.string.cmp(m_name, rhs.m_name);
             if (result == 0)
                 result = std.string.cmp(m_value, rhs.m_value);
         }
         }
         return result;
    }
 
 It's not necessary to write the opCmp(Field). One could replace the if(rhs)
 with assert(rhs). Since tripping this would be a programming error, not a
 user input error, shouldn't it be a contract rather than a custom exception?

Depends on the D definition of comparing with null, I suppose ? In some other languages, this operation is *defined* as "false". http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#equals(java.lang.Object)
 For any non-null reference value x, x.equals(null) should return false.

Q: Wouldn't the '==' shortcut above belong in opEquals instead ? (since aren't you looping over the same string twice, otherwise ?) And of course, Matthew will probably go ballistic over the use of "int" and 0 and 1, and if with non-bool types, and such... :-D Here's how I wrote it, for a String class:
 	int opEquals(Object o)
 	{
 		if (this is o)
 			return true;
 		String string = cast(String) o;
 		if (string is null)
 			return false;
 
 		return this.str == string.str;
 	}
 
 	int opCmp(Object o)
 	{
 		if (this is o)
 			return true;
 		String string = cast(String) o;
 		if (string is null)
 			return false;
 
 		return std.string.cmp(this.str, string.str);
 	}
 

http://www.algonet.se/~afb/d/javastring/String.d --anders
Mar 07 2005
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Anders F Björklund wrote:

 Here's how I wrote it, for a String class:
 
     int opEquals(Object o)
     {
         if (this is o)
             return true;
         String string = cast(String) o;
         if (string is null)
             return false;

         return this.str == string.str;
     }

     int opCmp(Object o)
     {
         if (this is o)
             return true;
         String string = cast(String) o;
         if (string is null)
             return false;

         return std.string.cmp(this.str, string.str);
     }


Darnit, copy and paste striketh again! int opCmp(Object o) { if (this is o) return 0; String string = cast(String) o; if (string is null) assert(0); return std.string.cmp(this.str, string.str); } Sorry :-( --anders
Mar 07 2005
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Matthew wrote:
 Since it would be, in the general case, meaningless to compare disparate 
 types, why cannot the compiler automatically generate opCmp(Object) from 
 opCmp(MyType) (the latter would have to exist, of course), and save 
 people having to do the first of the following two example ones (from 
 class std.openrj.Field) every time:

To half of us, it remains really just a question of why opCmp(Object) has to exist at all. Did you see this thread a while back? digitalmars.D/10558 Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Mar 08 2005
parent "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message 
news:d0kn8d$2tji$1 digitaldaemon.com...
 Matthew wrote:
 Since it would be, in the general case, meaningless to compare 
 disparate types, why cannot the compiler automatically generate 
 opCmp(Object) from opCmp(MyType) (the latter would have to exist, of 
 course), and save people having to do the first of the following two 
 example ones (from class std.openrj.Field) every time:

To half of us, it remains really just a question of why opCmp(Object) has to exist at all. Did you see this thread a while back? digitalmars.D/10558

Alas, no. In order to catch up I had to do a wholesale "Mark Read". I'll check it out.
Mar 08 2005