c++11 - Tidying up C++ operator overloads -


i have been tidying old c++ code.

i've reduced pages of operator overload functions using couple of macros:

.hpp

    // context, long , object wrap respective python primitives     class long: public object     {...};      #define ops( a, b ) \     bool operator == ( a, b ); \     bool operator != ( a, b ); \     bool operator >  ( a, b ); \     bool operator <  ( a, b ); \     bool operator >= ( a, b ); \     bool operator <= ( a, b );  #define uni( ) \     ops( a, )  #define bi_( a, b ) \     ops( a, b ) \     ops( b, )      uni( const long&  )     bi_( const long& , int )     bi_( const long& , long )      uni( const float&  )     bi_( const float& ,  double )  #undef bi_ #undef uni #undef ops #undef op 

.cpp

#define op( op, l, r, cmpl, cmpr ) \     bool operator op( l, r ) { return cmpl op cmpr; }  #define ops( ... ) \     op( != , ##__va_args__ ) \     op( == , ##__va_args__ ) \     op( >  , ##__va_args__ ) \     op( >= , ##__va_args__ ) \     op( <  , ##__va_args__ ) \     op( <= , ##__va_args__ )  #define bi_( a, b, conva, convb ) \     ops( a, b, conva, convb ) \     ops( b, a, convb, conva )      ops( const long&  a, const long&  b  ,  a.as_long()      , b.as_long()    )     bi_( const long&  a, int          b  ,  a.as_long()      , b              )     bi_( const long&  a, long         b  ,  a.as_long()      , b              )      ops( const float& a, const float& b  ,  a.as_double()    , b.as_double()  )     bi_( const float& a, double       b  ,  a.as_double()    , b              )  #undef bi_ #undef ops #undef op 

it still doesn't feel quite right.

it spreads class on 3 separate locations: class declaration itself, declarations operators later in same header, , in separate .cxx file actual definitions.

is there cleaner way implement these operators in c++11?

why not use crtp base class provide operators?

template<typename c, typename t> struct ops_base {   friend bool operator==(const ops_base& l, const ops_base& r)   {     const c& cl = static_cast<const c&>(l);     const c& cr = static_cast<const c&>(r);     return (caster<c, t>::cast(cl) == caster<c, t>::cast(cr));   }    friend bool operator==(const ops_base& l, t r)   {     const c& cl = static_cast<const c&>(l);     return (caster<c, t>::cast(cl) == r);   }    friend bool operator==(t l, const ops_base& r)   {     const c& cr = static_cast<const c&>(r);     return (l == caster<c, t>::cast(cr));   }    friend bool operator!=(const ops_base& l, const ops_base& r)   { return !(l == r); }    friend bool operator!=(const ops_base& l, t r)   { return !(l == r); }    friend bool operator!=(t l, const ops_base& r)   { return !(l == r); }    friend bool operator<(const ops_base& l, const ops_base& r)   {     const c& cl = static_cast<const c&>(l);     const c& cr = static_cast<const c&>(r);     return (caster<c, t>::cast(cl) < caster<c, t>::cast(cr));   }    friend bool operator<(const ops_base& l, t r)   {     const c& cl = static_cast<const c&>(l);     return (caster<c, t>::cast(cl) < r);   }    friend bool operator<(t l, const ops_base& r)   {     const c& cr = static_cast<const c&>(r);     return (l < caster<c, t>::cast(cr));   }    friend bool operator>(const ops_base& l, const ops_base& r)   {     const c& cl = static_cast<const c&>(l);     const c& cr = static_cast<const c&>(r);     return (caster<c, t>::cast(cl) > caster<c, t>::cast(cr));   }    friend bool operator>(const ops_base& l, t r)   {     const c& cl = static_cast<const c&>(l);     return (caster<c, t>::cast(cl) > r);   }    friend bool operator>(t l, const ops_base& r)   {     const c& cr = static_cast<const c&>(r);     return (l > caster<c, t>::cast(cr));   }    friend bool operator<=(const ops_base& l, const ops_base& r)   { return !(l > r); }    friend bool operator<=(const ops_base& l, t r)   { return !(l > r); }    friend bool operator<=(t l, const ops_base& r)   { return !(l > r); }    friend bool operator>=(const ops_base& l, const ops_base& r)   { return !(l < r); }    friend bool operator>=(const ops_base& l, t r)   { return !(l < r); }    friend bool operator>=(t l, const ops_base& r)   { return !(l < r); } }; 

and use this:

struct long : ops_base<long, long> {   long(long val) : value_(val) { }    long as_long() const { return value_; }  private:   long value_; };  struct float : ops_base<float, double> {   float(double val) : value_(val) { }    double as_double() const { return value_; }  private:   double value_; }; 

running example on ideone.


Comments

Popular posts from this blog

matlab - "Contour not rendered for non-finite ZData" -

delphi - Indy UDP Read Contents of Adata -

javascript - Any ideas when Firefox is likely to implement lengthAdjust and textLength? -