Comparisons.cpp
// Comparisons.cpp
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2007
@import "Ceda/cxPython/cxPython.h"
#include "Ceda/cxUtils/TracerUtils.h"
@def mPrint(v) = print @str(v = ) + `v`
@def mShowComparisons(x,y) =
{
print `x` + ' ' + `y` + ' : ',
@def m(op) =
{
if x op y:
print @str( op ),
}
m(==)
m(!=)
m(<)
m(>)
m(<=)
m(>=)
print
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
Class value comparisons
-----------------------
A reflected class/struct that has operator==() allows for equality comparisons in Python
using == and !=.
A reflected class/struct that has operator<() allows for order comparisons in Python
using < > <= >=.
*/
namespace Comparisons1
{
$struct+ X <<os returnbyvalue passbyvalue /*should only appear when no default ctor or dtor present */ >>
{
//X(ceda::int32 x = 0) : m_x(x) {}
//~X() {}
$ceda::int32 Get() const { return m_x; }
void Set(int x) { m_x = x; }
void Write(ceda::xostream& os) { os << m_x; }
$ceda::int32 m_x;
};
bool operator==(X x1, X x2) { return x1.m_x == x2.m_x; }
bool operator<(X x1, X x2)
{
Tracer() << "X::operator<(x1 = " << x1 << ", x2 = " << x2 << "\n";
return x1.m_x < x2.m_x;
}
bool operator<=(X x1, X x2) { return x1.m_x <= x2.m_x; }
$function+ X CreateX(ceda::int32 x)
{
X ret;
ret.m_x = x;
Tracer() << "CreateX(), x = " << x << "\n";
return ret;
//return X(x);
}
$function+ void SetX(X& x, ceda::int32 val)
{
x.m_x = val;
Tracer() << "Setting x at " << &x << " to " << val << "\n";
}
void Run()
{
ceda::TraceGroup g("Class Comparisons");
PyRun_SimpleString(
@strx
(
Comparisons1 = rootnamespace.Comparisons1
CreateX = Comparisons1.CreateX
SetX = Comparisons1.SetX
print 'Create x1'
x1 = CreateX(100)
#SetX(x1,99)
print 'x1 = ' + `x1`
x2 = CreateX(200)
#SetX(x2,199)
print 'x2 =' + `x2`
Assert(x1 < x2)
mShowComparisons(CreateX(100), CreateX(100))
mShowComparisons(CreateX(100), CreateX(200))
mShowComparisons(CreateX(200), CreateX(100))
));
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
Vector comparisons
------------------
Two xvector<T> values in the same element type T can be compared as long a T can be compared.
xvectors can be compared in Python using the following operators
== != < > <= >=
*/
namespace Comparisons2
{
$function+ ceda::xvector<ceda::int32> Create()
{
return ceda::xvector<ceda::int32>();
}
void Run()
{
ceda::TraceGroup g("xvector Comparisons");
PyRun_SimpleString(
@strx
(
Create = rootnamespace.Comparisons2.Create
mShowComparisons(Create(), Create())
mShowComparisons(Create(), Create() + [1])
mShowComparisons(Create() + [1], Create())
mShowComparisons(Create() + [1], Create() + [1])
mShowComparisons(Create() + [1], Create() + [2])
mShowComparisons(Create() + [2], Create() + [1])
mShowComparisons(Create() + [1,2,10], Create() + [1,2,10])
mShowComparisons(Create() + [1,2,10], Create() + [1,2,20])
mShowComparisons(Create() + [1,2,20], Create() + [1,2,10])
));
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
int64, uint64 comparisons
-------------------------
int64, uint64 can be compared in Python using the following operators
== != < > <= >=
*/
namespace Comparisons3
{
void Run()
{
ceda::TraceGroup g("int64, uint64 comparisons");
PyRun_SimpleString(
@strx
(
i64 = rootnamespace.Int64.Make
ui64 = rootnamespace.UInt64.Make
mShowComparisons(i64(1,0), i64(1,0))
mShowComparisons(i64(1,0), i64(2,0))
mShowComparisons(i64(2,0), i64(1,0))
mShowComparisons(ui64(1,0), ui64(1,0))
mShowComparisons(ui64(1,0), ui64(2,0))
mShowComparisons(ui64(2,0), ui64(1,0))
mShowComparisons(i64(-1,-1), i64(0,0))
mShowComparisons(i64(0,0), i64(-1,-1))
mShowComparisons(ui64(-1,-1), ui64(0,0))
mShowComparisons(ui64(0,0), ui64(-1,-1))
));
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
ptr<T> comparisons
------------------
ptr<T> can be compared in Python using the following operators
== != < > <= >=
This ends up comparing the AnyInterface.m_self values, and allows for identity comparison through
different implemented interfaces.
*/
namespace Comparisons4
{
$interface+ Ix : ceda::IObject
{
void foo();
};
$interface+ Iy : ceda::IObject
{
void bar();
};
$struct+ X isa Ix,Iy
{
void foo() {}
void bar() {}
};
$function+ ceda::ptr<Ix> CreateX() { return new X(); }
$function+ ceda::ptr<Iy> AsIy(ceda::ptr<Ix> ix) { return ceda::qicast<Iy>(ix); }
void Run()
{
ceda::TraceGroup g("ptr<T> comparisons");
@if (true)
{
/*
Appropriate if ptr<T>::operator==() only tests m_self.
*/
PyRun_SimpleString(
@strx
(
CreateX = rootnamespace.Comparisons4.CreateX
AsIy = rootnamespace.Comparisons4.AsIy
ix = CreateX()
iy = AsIy(ix)
Assert( ix == iy )
Assert( ix <= iy )
Assert( ix >= iy )
ix1 = ix
Assert( ix1 == ix )
ix2 = CreateX()
Assert( ix1 != ix2 )
));
}
@else
{
/*
Appropriate if ptr<T>::operator==() tests both the m_self and m_table pointers.
*/
PyRun_SimpleString(
@strx
(
CreateX = rootnamespace.Comparisons4.CreateX
AsIy = rootnamespace.Comparisons4.AsIy
ix = CreateX()
iy = AsIy(ix)
Assert( ix != iy )
ix1 = ix
Assert( ix1 == ix )
ix2 = CreateX()
Assert( ix1 != ix2 )
));
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
namespace Comparisons
{
void Run()
{
Comparisons1::Run();
Comparisons2::Run();
Comparisons3::Run();
Comparisons4::Run();
}
}