1 /*++ 2 Copyright (c) 2011 Microsoft Corporation 3 4 Module Name: 5 6 scoped_numeral.h 7 8 Abstract: 9 10 Wrapper for easying the pain when using primitive numeral objects such as: 11 mpz, mpq, mpbq, mpf, mpzp 12 13 Author: 14 15 Leonardo de Moura (leonardo) 2011-12-03 16 17 Revision History: 18 19 --*/ 20 #pragma once 21 22 template<typename Manager> 23 class _scoped_numeral { 24 public: 25 typedef typename Manager::numeral numeral; 26 private: 27 Manager & m_manager; 28 numeral m_num; 29 public: _scoped_numeral(Manager & m)30 _scoped_numeral(Manager & m):m_manager(m) {} _scoped_numeral(_scoped_numeral const & n)31 _scoped_numeral(_scoped_numeral const & n):m_manager(n.m_manager) { m().set(m_num, n.m_num); } 32 _scoped_numeral(_scoped_numeral &&) = default; ~_scoped_numeral()33 ~_scoped_numeral() { m_manager.del(m_num); } 34 m()35 Manager & m() const { return m_manager; } 36 37 operator numeral const &() const { return m_num; } 38 operator numeral&() { return m_num; } get()39 numeral const & get() const { return m_num; } get()40 numeral & get() { return m_num; } 41 42 _scoped_numeral & operator=(_scoped_numeral const & n) { 43 if (this == &n) 44 return *this; 45 m().set(m_num, n.m_num); 46 return *this; 47 } 48 49 _scoped_numeral & operator=(int n) { 50 m().set(m_num, n); 51 return *this; 52 } 53 54 _scoped_numeral & operator=(numeral const & n) { 55 m().set(m_num, n); 56 return *this; 57 } 58 reset()59 void reset() { 60 m().reset(m_num); 61 } 62 swap(_scoped_numeral & n)63 void swap(_scoped_numeral & n) { 64 m_num.swap(n.m_num); 65 } 66 swap(numeral & n)67 void swap(numeral & n) { 68 m_num.swap(n); 69 } 70 71 _scoped_numeral & operator+=(numeral const & a) { 72 m().add(m_num, a, m_num); 73 return *this; 74 } 75 76 _scoped_numeral & operator-=(numeral const & a) { 77 m().sub(m_num, a, m_num); 78 return *this; 79 } 80 81 _scoped_numeral & operator*=(numeral const & a) { 82 m().mul(m_num, a, m_num); 83 return *this; 84 } 85 86 _scoped_numeral & operator/=(numeral const & a) { 87 m().div(m_num, a, m_num); 88 return *this; 89 } 90 91 _scoped_numeral & operator%=(numeral const & a) { 92 m().rem(m_num, a, m_num); 93 return *this; 94 } 95 96 friend bool operator==(_scoped_numeral const & a, numeral const & b) { 97 return a.m().eq(a, b); 98 } 99 100 friend bool operator!=(_scoped_numeral const & a, numeral const & b) { 101 return !a.m().eq(a, b); 102 } 103 104 friend bool operator<(_scoped_numeral const & a, numeral const & b) { 105 return a.m().lt(a, b); 106 } 107 108 friend bool operator>(_scoped_numeral const & a, numeral const & b) { 109 return a.m().gt(a, b); 110 } 111 112 friend bool operator<=(_scoped_numeral const & a, numeral const & b) { 113 return a.m().le(a, b); 114 } 115 116 friend bool operator>=(_scoped_numeral const & a, numeral const & b) { 117 return a.m().ge(a, b); 118 } 119 is_zero()120 bool is_zero() const { 121 return m().is_zero(*this); 122 } 123 is_pos()124 bool is_pos() const { 125 return m().is_pos(*this); 126 } 127 is_neg()128 bool is_neg() const { 129 return m().is_neg(*this); 130 } 131 is_nonpos()132 bool is_nonpos() const { 133 return m().is_nonpos(*this); 134 } 135 is_nonneg()136 bool is_nonneg() const { 137 return m().is_nonneg(*this); 138 } 139 is_zero(_scoped_numeral const & a)140 friend bool is_zero(_scoped_numeral const & a) { 141 return a.m().is_zero(a); 142 } 143 is_pos(_scoped_numeral const & a)144 friend bool is_pos(_scoped_numeral const & a) { 145 return a.m().is_pos(a); 146 } 147 is_neg(_scoped_numeral const & a)148 friend bool is_neg(_scoped_numeral const & a) { 149 return a.m().is_neg(a); 150 } 151 is_nonneg(_scoped_numeral const & a)152 friend bool is_nonneg(_scoped_numeral const & a) { 153 return a.m().is_nonneg(a); 154 } 155 is_nonpos(_scoped_numeral const & a)156 friend bool is_nonpos(_scoped_numeral const & a) { 157 return a.m().is_nonpos(a); 158 } 159 abs(_scoped_numeral const & a)160 friend _scoped_numeral abs(_scoped_numeral const& a) { 161 _scoped_numeral res(a); 162 a.m().abs(res); 163 return res; 164 } 165 neg()166 void neg() { 167 m().neg(m_num); 168 } 169 170 friend _scoped_numeral operator+(_scoped_numeral const & r1, numeral const & r2) { 171 return _scoped_numeral(r1) += r2; 172 } 173 174 friend _scoped_numeral operator-(_scoped_numeral const & r1, numeral const & r2) { 175 return _scoped_numeral(r1) -= r2; 176 } 177 178 friend _scoped_numeral operator*(_scoped_numeral const & r1, numeral const & r2) { 179 return _scoped_numeral(r1) *= r2; 180 } 181 182 friend _scoped_numeral operator/(_scoped_numeral const & r1, numeral const & r2) { 183 return _scoped_numeral(r1) /= r2; 184 } 185 186 friend std::ostream & operator<<(std::ostream & out, _scoped_numeral const & s) { 187 s.m().display(out, s); 188 return out; 189 } 190 191 }; 192