Advertisement
Guest User

Multiple user-defined conversions on initialization

a guest
Sep 21st, 2015
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.31 KB | None | 0 0
  1. #include <cmath>
  2. int gcd(int a, int b) { return 1; }
  3.  
  4. #define EQ_OP(T, BODY) \
  5.     bool operator ==(const T& other) const { BODY; } \
  6.     bool operator !=(const T& other) const { return !(*this == other); }
  7. #define ASS_OP(T, OP, BODY) T& operator OP(const T& other) { BODY return *this; }
  8. #define ARITHM_OP(T, OP) const T operator OP(const T& other) const { return T(*this) OP ## = other; }
  9.  
  10. class Rational {
  11. private:
  12.     typedef Rational T;
  13.     void normalize() { int d = gcd(num, den); num /= d; den /= d; }
  14. public:
  15.     int num, den;
  16.  
  17.     Rational() : num(0), den(1) {}
  18.     Rational(int n) : num(n), den(1) {}
  19.     Rational(int num, int den) : num(num), den(den) {}
  20.  
  21.     explicit operator double() const { return (double)num / (double)den; }
  22.     explicit operator int() const { return (int)(double)(*this); }
  23.  
  24.     EQ_OP(T, return num * other.den == other.num * den;)
  25.  
  26.     ASS_OP(T, +=, num  = num * other.den + other.num * den; den *= other.den; normalize();)
  27.     ASS_OP(T, -=, num  = num * other.den - other.num * den; den *= other.den; normalize();)
  28.     ASS_OP(T, *=, num *= other.num;                         den *= other.den; normalize();)
  29.     ASS_OP(T, /=, num *= other.den;                         den *= other.num; normalize();)
  30.  
  31.     ARITHM_OP(T, +)
  32.     ARITHM_OP(T, -)
  33.     ARITHM_OP(T, *)
  34.     ARITHM_OP(T, /)
  35. };
  36.  
  37. template<typename R, int N>
  38. class RingExtension {
  39.     typedef RingExtension<R, N> T;
  40. public:
  41.     R a, b;
  42.  
  43.     RingExtension<R, N>() : a(0), b(0) {}
  44.     RingExtension<R, N>(R a) : a(a), b(0) {}
  45.     RingExtension<R, N>(R a, R b) : a(a), b(b) {}
  46.  
  47.     explicit operator double() const { return (double)a + (double)b * sqrt(N); }
  48.     explicit operator int() const { return (int)(double)*this; }
  49.  
  50.     EQ_OP(T, return a == other.a && b == other.b; )
  51.  
  52.     ASS_OP(T, +=, a += other.a; b += other.b;)
  53.     ASS_OP(T, -=, a -= other.a; b -= other.b;)
  54.  
  55.     ASS_OP(T, *=,
  56.         R aa = a * other.a + b * other.b * N;
  57.         R bb = a * other.b + b * other.a;
  58.         a = aa;
  59.         b = bb;
  60.     )
  61.     ASS_OP(T, /=,
  62.         R den = other.a * other.a - other.b * other.b * N;
  63.         R aa = (a * other.a - b * other.b * N) / den;
  64.         R bb = (b * other.a - a * other.b) / den;
  65.         a = aa;
  66.         b = bb;
  67.     )
  68.  
  69.     ARITHM_OP(T, +)
  70.     ARITHM_OP(T, -)
  71.     ARITHM_OP(T, *)
  72.     ARITHM_OP(T, / )
  73. };
  74. typedef RingExtension<int, -1> GaussianInt; //works, except for conversions
  75.  
  76. int main() {
  77.     RingExtension<Rational, 2> x = 3;
  78.     return 1;
  79. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement