Thread overview
struct opCmp confustion
Aug 26, 2012
Charles Hixson
Aug 26, 2012
Era Scarecrow
Aug 26, 2012
Charles Hixson
Aug 26, 2012
Era Scarecrow
Aug 26, 2012
Namespace
Aug 26, 2012
Era Scarecrow
Aug 26, 2012
Namespace
August 26, 2012
Currently the code is:

struct	Triplet
{	string	wrd1;
	string	wrd2;
	string	wrd3;
	int		val	=	1;

	int opCmp(ref const Triplet t) const
	{	if	(wrd1 < t.wrd1)	return	-1;
		if	(wrd1 > t.wrd1)	return	1;
		if	(wrd2 < t.wrd2)	return	-1;
		if	(wrd2 > t.wrd2)	return	1;
		if	(wrd3 < t.wrd3)	return	-1;
		if	(wrd3 > t.wrd3)	return	1;
		return	0;
		//auto	i	=	wrd1.opCmp (t.wrd1);
		//if	(i !=	0)	return	i;
		//i	=	wrd2.opCmp (t.wrd2);
		//if	(i != 0)	return	i;
		//return	wrd3.opCmp (t.wrd3);
	}
}
The commented out code was the original version, which wouldn't compile.  (The current code replaces it.) It gave messages like:
...ser$ rdmd --main -unittest -DdDocs parse1.d
parse1.d(114): Error: undefined identifier 'opCmp'
parse1.d(116): Error: undefined identifier 'opCmp'
parse1.d(118): Error: undefined identifier 'opCmp'

What was I doing wrong?
August 26, 2012
On Sunday, 26 August 2012 at 16:27:32 UTC, Charles Hixson wrote:
> Currently the code is:
>
> struct	Triplet
> {	string	wrd1;
> 	string	wrd2;
> 	string	wrd3;
> 	int		val	=	1;
>
> 	int opCmp(ref const Triplet t) const
> 	{	if	(wrd1 < t.wrd1)	return	-1;
> 		if	(wrd1 > t.wrd1)	return	1;
> 		if	(wrd2 < t.wrd2)	return	-1;
> 		if	(wrd2 > t.wrd2)	return	1;
> 		if	(wrd3 < t.wrd3)	return	-1;
> 		if	(wrd3 > t.wrd3)	return	1;
> 		return	0;
> 		//auto	i	=	wrd1.opCmp (t.wrd1);
> 		//if	(i !=	0)	return	i;
> 		//i	=	wrd2.opCmp (t.wrd2);
> 		//if	(i != 0)	return	i;
> 		//return	wrd3.opCmp (t.wrd3);
> 	}
> }
> The commented out code was the original version, which wouldn't compile.
>  (The current code replaces it.) It gave messages like:
> ...ser$ rdmd --main -unittest -DdDocs parse1.d
> parse1.d(114): Error: undefined identifier 'opCmp'
> parse1.d(116): Error: undefined identifier 'opCmp'
> parse1.d(118): Error: undefined identifier 'opCmp'
>
> What was I doing wrong?

 I would think it's you attempting to compare a string. Try using cmp?.

untested:

import std.algorithm : cmp;

struct Triplet {
  string wrd1, wrd2, wrd3;

  int opCmp(ref const Triplet t) const {
    int result1 = cmp(wrd1, t.wrd1);
    int result2 = cmp(wrd2, t.wrd2);
    int result3 = cmp(wrd3, t.wrd3);

    if (result1) return result1;
    if (result2) return result2;
    if (result3) return result3;

    return 0;
  }
}
August 26, 2012
On 08/26/2012 10:14 AM, Era Scarecrow wrote:
> On Sunday, 26 August 2012 at 16:27:32 UTC, Charles Hixson wrote:
>> Currently the code is:
>>
>> struct Triplet
>> { string wrd1;
>> string wrd2;
>> string wrd3;
>> int val = 1;
>>
>>...
>>
>> What was I doing wrong?
>
> I would think it's you attempting to compare a string. Try using cmp?.
>
> untested:
>
> import std.algorithm : cmp;
>
> struct Triplet {
> string wrd1, wrd2, wrd3;
>
> int opCmp(ref const Triplet t) const {
> int result1 = cmp(wrd1, t.wrd1);
> int result2 = cmp(wrd2, t.wrd2);
> int result3 = cmp(wrd3, t.wrd3);
>
> if (result1) return result1;
> if (result2) return result2;
> if (result3) return result3;
>
> return 0;
> }
> }

Thank you.

So string doesn't respond to opCmp.  Pity.
August 26, 2012
On Sunday, 26 August 2012 at 19:23:10 UTC, Charles Hixson wrote:
> Thank you.
>
> So string doesn't respond to opCmp.  Pity.

 A string is an array of chars. Structs and Classes have opCmp. You could make a wrapper for the string to include the opCmp then, but that seems irrelevant.

 Although another option is to make a separate opCmp function that would do it. Tested and works :)

import std.algorithm;

 //simple wrapper
 int opCmp(string a, string b) {
   return cmp(a,b);
 }

 unittest {
	assert("abc" < "efg");
	assert("efg" > "abc");
	assert("abc" == "abc");
 }
August 26, 2012
>  A string is an array of chars. Structs and Classes have opCmp. You could make a wrapper for the string to include the opCmp then, but that seems irrelevant.
>
>  Although another option is to make a separate opCmp function that would do it. Tested and works :)
>
> import std.algorithm;
>
>  //simple wrapper
>  int opCmp(string a, string b) {
>    return cmp(a,b);
>  }
>
>  unittest {
> 	assert("abc" < "efg");
> 	assert("efg" > "abc");
> 	assert("abc" == "abc");
>  }

Maybe I'm wrong but this method is never called by one of these compares. Or is this the point?
I wished many times that something like this work, even for other constructs. That would be a way to avoid nasty opCmp, opEquals and so on in the object.d.
August 26, 2012
On Sunday, 26 August 2012 at 21:45:38 UTC, Namespace wrote:
> Maybe I'm wrong but this method is never called by one of these compares. Or is this the point?

 Mmmm you're right. Due to the re-writing I thought it would work. "abc" < "def" converts to "abc".opCmp("def") < 0, which then doesn't work so it rewrites to opCmp("abc", "def") < 0. Maybe I did it wrong; Or perhaps it's getting the values at compile-time and saving them (less likely).

> I wished many times that something like this work, even for other constructs. That would be a way to avoid nasty opCmp, opEquals and so on in the object.d.

 Well unless whole functionality of certain types are required, writing a compare function for that particular case isn't so bad (or calling it in this case).
August 26, 2012
On Sunday, 26 August 2012 at 22:57:27 UTC, Era Scarecrow wrote:
> On Sunday, 26 August 2012 at 21:45:38 UTC, Namespace wrote:
>> Maybe I'm wrong but this method is never called by one of these compares. Or is this the point?
>
>  Mmmm you're right. Due to the re-writing I thought it would work. "abc" < "def" converts to "abc".opCmp("def") < 0, which then doesn't work so it rewrites to opCmp("abc", "def") < 0. Maybe I did it wrong; Or perhaps it's getting the values at compile-time and saving them (less likely).
>
>> I wished many times that something like this work, even for other constructs. That would be a way to avoid nasty opCmp, opEquals and so on in the object.d.
>
>  Well unless whole functionality of certain types are required, writing a compare function for that particular case isn't so bad (or calling it in this case).

I prefer implicit calling. ;)