I'm attempting to tidy up a C++ framework (PyCXX).
One particular file contains ~400 lines of operator overload functions, which I've managed to reduce to the following:
#define OP( op, l, r, cmpL, cmpR ) \
bool operator op( l, r ) { return cmpL op cmpR; }
#define OPS( l, r, cmpL, cmpR ) \
OP( !=, l, r, cmpL, cmpR ) \
OP( ==, l, r, cmpL, cmpR ) \
OP( > , l, r, cmpL, cmpR ) \
OP( >=, l, r, cmpL, cmpR ) \
OP( < , l, r, cmpL, cmpR ) \
OP( <=, l, r, cmpL, cmpR )
OPS( const Long &a, const Long &b, a.as_long() , b.as_long() )
OPS( const Long &a, int b, a.as_long() , b )
OPS( const Long &a, long b, a.as_long() , b )
OPS( int a, const Long &b, a , b.as_long() )
OPS( long a, const Long &b, a , b.as_long() )
#ifdef HAVE_LONG_LONG
OPS( const Long &a, PY_LONG_LONG b, a.as_long_long() , b )
OPS( PY_LONG_LONG a, const Long &b, a , b.as_long_long() )
#endif
//------------------------------------------------------------
// compare operators
OPS( const Float &a, const Float &b, a.as_double() , b.as_double() )
OPS( const Float &a, double b, a.as_double() , b )
OPS( double a, const Float &b, a , b.as_double() )
} // end of namespace Py
However, I wonder if it may be possible to tidy it up further.
It looks as though I can save having to pass all the parameters each time by using:
#define OPS( ... ) \
OP( !=, ##__VA_ARGS__ ) \
OP( ==, ##__VA_ARGS__ ) \
OP( > , ##__VA_ARGS__ ) \
OP( >=, ##__VA_ARGS__ ) \
OP( < , ##__VA_ARGS__ ) \
OP( <=, ##__VA_ARGS__ )
Although I have a hunch this might be making the code less transparent.
Another possible idea would involve storing pairs:
#define FD(op, x) ( Float &x , op, x.as_double() )
#define L1(op, x) ( const Long &x , op, x.as_long() )
#define L2(op, x) ( const Long &x , op, x.as_long_long() )
:
but I am risking obfuscation through trying too hard. I think it is commonly accepted that other things being equal, readability trumps concise.
What other viable design patterns could I consider?