Last active
August 4, 2019 09:36
-
-
Save tjkendev/bb587733b3739ea1ffc33b91be33a687 to your computer and use it in GitHub Desktop.
主にlong long intに対するオーバーフロー検知用クラス。とりあえず作ったので置いとく。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using lli = long long int; | |
template<typename T> | |
class NumValid { | |
T testVal; | |
__int128 val128; | |
public: | |
NumValid() : testVal(0), val128(0) {} | |
NumValid(T val) : testVal(val), val128(val) {} | |
operator lli() { return testVal; } | |
const T get() const { return testVal; } | |
lli operator=(lli val) { return testVal = val128 = val; } | |
int operator=(int val) { return testVal = val128 = val; } | |
void operator+=(lli val) { | |
if(testVal + val != val128 + val) { | |
cout << "overflowed!! (" << testVal << " * " << val << ")" << endl; | |
assert(0); | |
} | |
testVal += val; val128 += val; | |
} | |
void operator*=(lli val) { | |
if(testVal * val != val128 * val) { | |
cout << "overflowed!! (" << testVal << " * " << val << ")" << endl; | |
assert(0); | |
} | |
testVal *= val; val128 *= val; | |
} | |
void operator%=(lli val) { testVal %= val; val128 %= val; } | |
void operator%=(const NumValid<T> val) { | |
*this %= val.testVal; | |
} | |
void operator>>=(lli val) { | |
testVal >>= val; val128 >>= val; | |
} | |
void operator<<=(lli val) { | |
if(testVal << val != val128 << val) { | |
cout << "overflowed!! (" << testVal << " << " << val << ")" << endl; | |
assert(0); | |
} | |
testVal <<= val; val128 <<= val; | |
} | |
void operator+=(const NumValid<T> val) { | |
if(testVal + val.testVal != val128 + val.testVal) { | |
cout << "overflowed!! (" << testVal << " * " << val.testVal << ")" << endl; | |
assert(0); | |
} | |
testVal += val.testVal; val128 += val.testVal; | |
} | |
void operator*=(const NumValid<T> val) { | |
if(testVal * val.testVal != val128 * val.testVal) { | |
cout << "overflowed!! (" << testVal << " * " << val.testVal << ")" << endl; | |
assert(0); | |
} | |
testVal *= val.testVal; val128 *= val.testVal; | |
} | |
NumValid<T>& operator++() { | |
testVal++; val128++; return *this; | |
} | |
NumValid<T>& operator--() { | |
testVal++; val128++; return *this; | |
} | |
NumValid<T> operator++(int) { | |
val128++; | |
return NumValid<T>(testVal++); | |
} | |
NumValid<T> operator--(int) { | |
val128--; | |
return NumValid<T>(testVal--); | |
} | |
friend NumValid<T> operator+(const NumValid<T> &left, const lli right) { | |
if(left.testVal + right != left.val128 + right) { | |
cout << "overflowed!! (" << left.testVal << " + " << right << ")" << endl; | |
assert(0); | |
} | |
return NumValid<T>(left.testVal + right); | |
} | |
friend NumValid<T> operator+(const NumValid<T> &left, const int right) { return left + (lli) right; } | |
friend NumValid<T> operator+(const int left, const NumValid<T> &right) { return left + right.testVal; } | |
friend NumValid<T> operator-(const NumValid<T> &left, const lli right) { | |
if(left.testVal - right != left.val128 - right) { | |
cout << "overflowed!! (" << left.testVal << " - " << right << ")" << endl; | |
assert(0); | |
} | |
return NumValid<T>(left.testVal - right); | |
} | |
friend NumValid<T> operator-(const NumValid<T> &left, const int right) { return left - (lli) right; } | |
friend NumValid<T> operator-(const NumValid<T> &left, const size_t right) { return left - (lli) right; } | |
friend NumValid<T> operator*(const NumValid<T> &left, const lli right) { | |
if(left.testVal * right != left.val128 * right) { | |
cout << "overflowed!! (" << left.testVal << " * " << right << ")" << endl; | |
assert(0); | |
} | |
return NumValid<T>(left.testVal * right); | |
} | |
friend NumValid<T> operator*(const NumValid<T> &left, const int right) { return left * (lli) right; } | |
friend NumValid<T> operator*(const int left, const NumValid<T> &right) { return left * right.testVal; } | |
friend NumValid<T> operator/(const NumValid<T> &left, const lli right) { | |
return NumValid<T>(left.testVal / right); | |
} | |
friend NumValid<T> operator/(const NumValid<T> &left, const int right) { return left / (lli) right; } | |
friend NumValid<T> operator%(const NumValid<T> &left, const lli right) { | |
return NumValid<T>(left.testVal % right); | |
} | |
friend NumValid<T> operator%(const NumValid<T> &left, const int right) { return left % (lli) right; } | |
friend NumValid<T> operator&(const NumValid<T> &left, const lli right) { | |
return NumValid<T>(left.testVal & right); | |
} | |
friend NumValid<T> operator&(const NumValid<T> &left, const int right) { return left & (lli) right; } | |
friend NumValid<T> operator|(const NumValid<T> &left, const lli right) { | |
return NumValid<T>(left.testVal | right); | |
} | |
friend NumValid<T> operator|(const NumValid<T> &left, const int right) { return left | (lli) right; } | |
friend NumValid<T> operator^(const NumValid<T> &left, const lli right) { | |
return NumValid<T>(left.testVal ^ right); | |
} | |
friend NumValid<T> operator^(const NumValid<T> &left, const int right) { return left ^ (lli) right; } | |
friend bool operator<(const NumValid<T> &left, const lli right) { return left.testVal < right; } | |
friend bool operator<(const NumValid<T> &left, const int right) { return left< (lli) right; } | |
friend bool operator<(const lli left, const NumValid<T> &right) { return left < right.testVal; } | |
friend bool operator<(const int left, const NumValid<T> &right) { return (lli) left < right; } | |
friend bool operator>(const NumValid<T> &left, const lli right) { return left.testVal > right; } | |
friend bool operator>(const NumValid<T> &left, const int right) { return left> (lli) right; } | |
friend bool operator>(const lli left, const NumValid<T> &right) { return left > right.testVal; } | |
friend bool operator>(const int left, const NumValid<T> &right) { return (lli) left > right; } | |
friend bool operator==(const NumValid<T> &left, const lli right) { return left.testVal == right; } | |
friend bool operator==(const NumValid<T> &left, const int right) { return left == (lli) right; } | |
friend bool operator==(const lli left, const NumValid<T> &right) { return left == right.testVal; } | |
friend bool operator==(const int left, const NumValid<T> &right) { return (lli) left == right; } | |
friend bool operator==(const NumValid<T> &left, const NumValid<T> &right) { return left.testVal == right.testVal; } | |
friend NumValid<T> operator+(const NumValid<T> &left, const NumValid<T> &right) { | |
if(left.testVal + right.testVal != left.val128 + right.val128) { | |
cout << "overflowed!! (" << left.testVal << " + " << right.testVal << ")" << endl; | |
assert(0); | |
} | |
return NumValid<T>(left.testVal + right.testVal); | |
} | |
friend NumValid<T> operator-(const NumValid<T> &left, const NumValid<T> &right) { | |
if(left.testVal - right.testVal != left.val128 - right.val128) { | |
cout << "overflowed!! (" << left.testVal << " - " << right.testVal << ")" << endl; | |
assert(0); | |
} | |
return NumValid<T>(left.testVal - right.testVal); | |
} | |
friend NumValid<T> operator*(const NumValid<T> &left, const NumValid<T> &right) { | |
if(left.testVal * right.testVal != left.val128 * right.val128) { | |
cout << "overflowed!! (" << left.testVal << " * " << right.testVal << ")" << endl; | |
assert(0); | |
} | |
return NumValid<T>(left.testVal * right.testVal); | |
} | |
friend NumValid<T> operator/(const NumValid<T> &left, const NumValid<T> &right) { | |
return NumValid<T>(left.testVal / right.testVal); | |
} | |
friend NumValid<T> operator%(const NumValid<T> &left, const NumValid<T> &right) { | |
return NumValid<T>(left.testVal % right.testVal); | |
} | |
friend istream& operator>> (istream &in, NumValid<T> &num) { | |
lli val; | |
in >> val; | |
num = val; | |
return in; | |
} | |
friend ostream& operator<< (ostream &out, NumValid<T> &num) { | |
out << num.testVal; | |
return out; | |
} | |
}; | |
typedef NumValid<long long int> ll; | |
// for hash-table | |
namespace std { | |
template<class T> struct hash<NumValid<T> > { | |
std::size_t operator()(const NumValid<T> &key) const { | |
return std::hash<T>{}(key.get()); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment