Zack Lee
Zack Lee

Reputation: 3044

How to make the SWIG binded class to use operators in Lua?

Here, I have a class called Value which simply can get and set float.

class Value
{
public:
    Value(float f)
    :f(f){};
    float get()
    {
        return f;
    }
    void set(float f)
    {
        this->f = f;
    }
private:
    float f;
};

And I want my class to be able to work like the following example in Lua.

local value = my.Value(3);
value = value * 2 - 1
if (value == 5) then
    print("succeed");
else
    print("failed");
end

And it should output the following result.

succeed

How should I correct my class so I can use operators with it?

Upvotes: 1

Views: 90

Answers (1)

Henri Menke
Henri Menke

Reputation: 10939

You have to overload every operator you want to use, i.e. operator*, operator+, and operator==. Unfortunately, the comparison operator does not work because Lua only considers the __eq metamethod if both operands in the comparison have the same metatable. From the Lua users wiki:

__eq - Check for equality. This method is invoked when "myTable1 == myTable2" is evaluated, but only if both tables have the exact same metamethod for __eq.

You can work around that by wrapping the other operand in the comparison into the Value constructor.

%module my
%{
class Value
{
public:
    Value(float f) :f(f) {};
    Value operator*(float f) const {
        return this->f * f;
    }
    Value operator-(float f) const {
        return this->f - f;
    }
    bool operator==(Value const &rhs) const {
        return this->f == rhs.f;
    }
private:
    float f;
};
%}

class Value {
public:
    Value(float f);
    Value operator*(float f) const;
    Value operator-(float f) const;
    bool operator==(Value const &rhs) const;
};
local my = require("my")

local value = my.Value(3);
value = value * 2 - 1

if (value == my.Value(5)) then
    print("succeed");
else
    print("failed");
end

Upvotes: 1

Related Questions