|
| 1 | +#include <base/Decimal.h> |
| 2 | +#include <base/extended_types.h> |
| 3 | + |
| 4 | +namespace DB |
| 5 | +{ |
| 6 | + |
| 7 | +/// Explicit template instantiations. |
| 8 | + |
| 9 | +#define FOR_EACH_UNDERLYING_DECIMAL_TYPE(M) \ |
| 10 | + M(Int32) \ |
| 11 | + M(Int64) \ |
| 12 | + M(Int128) \ |
| 13 | + M(Int256) |
| 14 | + |
| 15 | +#define FOR_EACH_UNDERLYING_DECIMAL_TYPE_PASS(M, X) \ |
| 16 | + M(Int32, X) \ |
| 17 | + M(Int64, X) \ |
| 18 | + M(Int128, X) \ |
| 19 | + M(Int256, X) |
| 20 | + |
| 21 | +template <typename T> const Decimal<T> & Decimal<T>::operator += (const T & x) { value += x; return *this; } |
| 22 | +template <typename T> const Decimal<T> & Decimal<T>::operator -= (const T & x) { value -= x; return *this; } |
| 23 | +template <typename T> const Decimal<T> & Decimal<T>::operator *= (const T & x) { value *= x; return *this; } |
| 24 | +template <typename T> const Decimal<T> & Decimal<T>::operator /= (const T & x) { value /= x; return *this; } |
| 25 | +template <typename T> const Decimal<T> & Decimal<T>::operator %= (const T & x) { value %= x; return *this; } |
| 26 | + |
| 27 | +template <typename T> void NO_SANITIZE_UNDEFINED Decimal<T>::addOverflow(const T & x) { value += x; } |
| 28 | + |
| 29 | +/// Maybe this explicit instantiation affects performance since operators cannot be inlined. |
| 30 | + |
| 31 | +template <typename T> template <typename U> const Decimal<T> & Decimal<T>::operator += (const Decimal<U> & x) { value += static_cast<T>(x.value); return *this; } |
| 32 | +template <typename T> template <typename U> const Decimal<T> & Decimal<T>::operator -= (const Decimal<U> & x) { value -= static_cast<T>(x.value); return *this; } |
| 33 | +template <typename T> template <typename U> const Decimal<T> & Decimal<T>::operator *= (const Decimal<U> & x) { value *= static_cast<T>(x.value); return *this; } |
| 34 | +template <typename T> template <typename U> const Decimal<T> & Decimal<T>::operator /= (const Decimal<U> & x) { value /= static_cast<T>(x.value); return *this; } |
| 35 | +template <typename T> template <typename U> const Decimal<T> & Decimal<T>::operator %= (const Decimal<U> & x) { value %= static_cast<T>(x.value); return *this; } |
| 36 | + |
| 37 | +#define DISPATCH(TYPE_T, TYPE_U) \ |
| 38 | + template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator += (const Decimal<TYPE_U> & x); \ |
| 39 | + template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator -= (const Decimal<TYPE_U> & x); \ |
| 40 | + template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator *= (const Decimal<TYPE_U> & x); \ |
| 41 | + template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator /= (const Decimal<TYPE_U> & x); \ |
| 42 | + template const Decimal<TYPE_T> & Decimal<TYPE_T>::operator %= (const Decimal<TYPE_U> & x); |
| 43 | +#define INVOKE(X) FOR_EACH_UNDERLYING_DECIMAL_TYPE_PASS(DISPATCH, X) |
| 44 | +FOR_EACH_UNDERLYING_DECIMAL_TYPE(INVOKE); |
| 45 | +#undef INVOKE |
| 46 | +#undef DISPATCH |
| 47 | + |
| 48 | +#define DISPATCH(TYPE) template struct Decimal<TYPE>; |
| 49 | +FOR_EACH_UNDERLYING_DECIMAL_TYPE(DISPATCH) |
| 50 | +#undef DISPATCH |
| 51 | + |
| 52 | +template <typename T> bool operator< (const Decimal<T> & x, const Decimal<T> & y) { return x.value < y.value; } |
| 53 | +template <typename T> bool operator> (const Decimal<T> & x, const Decimal<T> & y) { return x.value > y.value; } |
| 54 | +template <typename T> bool operator<= (const Decimal<T> & x, const Decimal<T> & y) { return x.value <= y.value; } |
| 55 | +template <typename T> bool operator>= (const Decimal<T> & x, const Decimal<T> & y) { return x.value >= y.value; } |
| 56 | +template <typename T> bool operator== (const Decimal<T> & x, const Decimal<T> & y) { return x.value == y.value; } |
| 57 | +template <typename T> bool operator!= (const Decimal<T> & x, const Decimal<T> & y) { return x.value != y.value; } |
| 58 | + |
| 59 | +#define DISPATCH(TYPE) \ |
| 60 | +template bool operator< (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \ |
| 61 | +template bool operator> (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \ |
| 62 | +template bool operator<= (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \ |
| 63 | +template bool operator>= (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \ |
| 64 | +template bool operator== (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \ |
| 65 | +template bool operator!= (const Decimal<TYPE> & x, const Decimal<TYPE> & y); |
| 66 | +FOR_EACH_UNDERLYING_DECIMAL_TYPE(DISPATCH) |
| 67 | +#undef DISPATCH |
| 68 | + |
| 69 | + |
| 70 | +template <typename T> Decimal<T> operator+ (const Decimal<T> & x, const Decimal<T> & y) { return x.value + y.value; } |
| 71 | +template <typename T> Decimal<T> operator- (const Decimal<T> & x, const Decimal<T> & y) { return x.value - y.value; } |
| 72 | +template <typename T> Decimal<T> operator* (const Decimal<T> & x, const Decimal<T> & y) { return x.value * y.value; } |
| 73 | +template <typename T> Decimal<T> operator/ (const Decimal<T> & x, const Decimal<T> & y) { return x.value / y.value; } |
| 74 | +template <typename T> Decimal<T> operator- (const Decimal<T> & x) { return -x.value; } |
| 75 | + |
| 76 | +#define DISPATCH(TYPE) \ |
| 77 | +template Decimal<TYPE> operator+ (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \ |
| 78 | +template Decimal<TYPE> operator- (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \ |
| 79 | +template Decimal<TYPE> operator* (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \ |
| 80 | +template Decimal<TYPE> operator/ (const Decimal<TYPE> & x, const Decimal<TYPE> & y); \ |
| 81 | +template Decimal<TYPE> operator- (const Decimal<TYPE> & x); |
| 82 | +FOR_EACH_UNDERLYING_DECIMAL_TYPE(DISPATCH) |
| 83 | +#undef DISPATCH |
| 84 | + |
| 85 | +#undef FOR_EACH_UNDERLYING_DECIMAL_TYPE_PASS |
| 86 | +#undef FOR_EACH_UNDERLYING_DECIMAL_TYPE |
| 87 | +} |
0 commit comments