Thread overview
How to using opCmp
Dec 17, 2011
Heromyth
Dec 17, 2011
bearophile
Dec 17, 2011
Heromyth
Dec 17, 2011
Manfred_Nowak
Dec 17, 2011
Jesse Phillips
Dec 18, 2011
Heromyth
December 17, 2011
I have defined a opCmp function to overload comparison operators, then how can I use it correctly?

I can use it like this:
   int b = t1.opCmp(info);
and is it right like this:
   int b = t1 < info;

In my test code, I get different value for b. What can I do? Thanks for helps.

//=============
//Test code:
//=============
import std.stdio;
import std.conv;
import std.file;
import std.algorithm;
import std.range;
import std.array;
import std.format;
import std.path;
import std.ascii;
import std.utf;
import std.process;

public final class LogLevel
{
    @property public static LogLevel Trace()
    {
        if( m_Trace is null )
            m_Trace = new LogLevel("Trace", 0);
        return m_Trace;
    }
    private static LogLevel m_Trace;

    @property public static LogLevel Info()
    {
        if( m_Info is null )
            m_Info = new LogLevel("Info", 2);
        return m_Info;
    }
    private static LogLevel m_Info;


    public string getName()
    {
        return name;

    }

    private int ordinal;
    private string name;

    public static LogLevel FromString(string levelName)
    {
        if (levelName.empty())
        {
            throw new Exception("levelName");
        }

        return Trace;
    }

	public  int  opCmp(LogLevel level1)
	{
		int result = 0;
		if( this.Ordinal > level1.Ordinal)
			result = 1;
		else if( this.Ordinal == level1.Ordinal)
			result = 0;
		else
			result = -1;
		writefln("result == %d", result);
		return result;
	}

    @property package int Ordinal()
    {
        return this.ordinal;
    }


    private this(string name, int ordinal)
    {
        this.name = name;
        this.ordinal = ordinal;
    }
}


int main(string[] args)
{
    LogLevel t1 = LogLevel.Trace;
    LogLevel t2 = LogLevel.Trace;
    LogLevel info = LogLevel.Info;
	int a = t1 > t2;
	writefln("a == %d", a);

	int b = t1.opCmp(info);
	writefln("b == %d", b);

	b = t1 < info;
	writefln("b == %d", b);

	b = t1 > info;
	writefln("b == %d", b);

    return 0;
}
//=============
December 17, 2011
Heromyth:

> I have defined a opCmp function to overload comparison operators, then how can I use it correctly?

I don't have an answer yet, but I suggest you to look at the D docs that describe how to use opCmp. Probably you need to accept a const Object, and to use override. I suggest to strip your code from all the not essential things, so you will see the problems better.

Bye,
bearophile
December 17, 2011
Heromyth wrote:

> I can use it like this:
>    int b = t1.opCmp(info);
> and is it right like this:
>    int b = t1 < info;
> 
> In my test code, I get different value for b. What can I do?

Nothing because the call of the operator `<' interprets the result of the call of `opCmp', which is constant in this case!

Remember that the result of `opCmp' is used for at least the operators `<', `>', `<=' and `>='.

-manfred

December 17, 2011
== Quote from bearophile (bearophileHUGS@lycos.com)'s article
> Heromyth:
> > I have defined a opCmp function to overload comparison operators, then how can I use it correctly?
> I don't have an answer yet, but I suggest you to look at the D docs that
describe how to use opCmp. Probably you need to accept a const Object, and to use override. I suggest to strip your code from all the not essential things, so you will see the problems better.
> Bye,
> bearophile

I tested
public override  int opCmp(Object o)
and got the same result.

The D document suggests rewriting
a < b
into
a.opCmp(b) < 0

While doing code porting from C# to D, I wander if I can directly use the comparing operation between two class object.

Maybe the compiler should give some messages for not using "a < b".
Is it a compiler bug? Can anyone give some suggertion. It will be well grateful.
December 17, 2011
On Sat, 17 Dec 2011 14:06:48 +0000, Heromyth wrote:

> I have defined a opCmp function to overload comparison operators, then how can I use it correctly?
> 
> I can use it like this:
>    int b = t1.opCmp(info);
> and is it right like this:
>    int b = t1 < info;

Consider the code more to the point of:

int b = t1.opCmp(info);
bool c = t1 < info;
December 18, 2011
== Quote from Jesse Phillips (jessekphillips+d@gmail.com)'s article
> On Sat, 17 Dec 2011 14:06:48 +0000, Heromyth wrote:
> > I have defined a opCmp function to overload comparison operators, then how can I use it correctly?
> >
> > I can use it like this:
> >    int b = t1.opCmp(info);
> > and is it right like this:
> >    int b = t1 < info;
> Consider the code more to the point of:
> int b = t1.opCmp(info);
> bool c = t1 < info;
That's it. Thanks, I got what I wanted.
Here is the modified test code:
// Test.d
import std.stdio;
import std.algorithm;
import std.range;
import std.array;

public class LogLevel
{
    @property public static LogLevel Trace()
    {
        if( m_Trace is null )
            m_Trace = new LogLevel("Trace", 0);
        return m_Trace;
    }
    private static LogLevel m_Trace;

    @property public static LogLevel Info()
    {
        if( m_Info is null )
            m_Info = new LogLevel("Info", 2);
        return m_Info;
    }
    private static LogLevel m_Info;


    private int ordinal;
    private string name;

	public override  int opCmp(Object o)
	{
		LogLevel level1 = cast(LogLevel) o;
		int result = 0;
		if( this.Ordinal > level1.Ordinal)
			result = 1;
		else
			result = -1;
		writefln("result == %d", result);
		return result;
	}


    @property package int Ordinal()
    {
        return this.ordinal;
    }


    private this(string name, int ordinal)
    {
        this.name = name;
        this.ordinal = ordinal;
    }
}


int main(string[] args)
{
    LogLevel t1 = LogLevel.Trace;
    LogLevel t2 = LogLevel.Trace;
    LogLevel info = LogLevel.Info;
	bool a = t1 == t2;
	writefln("a == %s", a);

	int b = t1.opCmp(info);
	writefln("b == %d", b);

	b = t1 < info;
	writefln("b == %d", b);

	bool c = t1 > info;
	writefln("c == %s", c);

	c = t1 < info;
	writefln("c == %s", c);

    return 0;
}

/*
a == true
result == -1
b == -1
result == -1
b == 1
result == -1
c == false
result == -1
c == true
*/