1 #pragma once 2 #include <stdexcept> 3 4 class wrapped_int { 5 public: 6 long long val; wrapped_int()7 wrapped_int() { val = 0; } wrapped_int(long long val)8 wrapped_int(long long val) { this->val = val; } wrapped_int(long long v1,long long v2)9 wrapped_int(long long v1, long long v2) { 10 if (v2 == 4) { 11 throw std::domain_error("4 isn't good for initialization!"); 12 } 13 this->val = v1; 14 } operator +(wrapped_int & other)15 wrapped_int operator+(wrapped_int &other) { 16 if (other.val == 4) { 17 throw std::invalid_argument("tried to add 4"); 18 } 19 return wrapped_int(this->val + other.val); 20 } operator +()21 wrapped_int operator+() { 22 if (this->val == 4) { 23 throw std::domain_error("'4' not in valid domain."); 24 } 25 return *this; 26 } operator -(wrapped_int & other)27 wrapped_int operator-(wrapped_int &other) { 28 if (other.val == 4) { 29 throw std::overflow_error("Value '4' is no good."); 30 } 31 return *this; 32 } operator -()33 wrapped_int operator-() { 34 if (this->val == 4) { 35 throw std::range_error("Can't take the negative of 4."); 36 } 37 return wrapped_int(-this->val); 38 } operator *(wrapped_int & other)39 wrapped_int operator*(wrapped_int &other) { 40 if (other.val == 4) { 41 throw std::out_of_range("Multiplying by 4 isn't going to work."); 42 } 43 return wrapped_int(this->val * other.val); 44 } operator /(wrapped_int & other)45 wrapped_int operator/(wrapped_int &other) { 46 if (other.val == 4) { 47 throw std::out_of_range("Multiplying by 4 isn't going to work."); 48 } 49 return wrapped_int(this->val / other.val); 50 } operator %(wrapped_int & other)51 wrapped_int operator%(wrapped_int &other) { 52 if (other.val == 4) { 53 throw std::out_of_range("Multiplying by 4 isn't going to work."); 54 } 55 return wrapped_int(this->val % other.val); 56 } operator ^(wrapped_int & other)57 long long operator^(wrapped_int &other) { 58 if (other.val == 4) { 59 throw std::out_of_range("Multiplying by 4 isn't going to work."); 60 } 61 return this->val ^ other.val; 62 } operator &(wrapped_int & other)63 long long operator&(wrapped_int &other) { 64 if (other.val == 4) { 65 throw std::underflow_error("Can't do this with 4!"); 66 } 67 return this->val & other.val; 68 } operator |(wrapped_int & other)69 long long operator|(wrapped_int &other) { 70 if (other.val == 4) { 71 throw std::underflow_error("Can't do this with 4!"); 72 } 73 return this->val & other.val; 74 } operator ~()75 wrapped_int operator~() { 76 if (this->val == 4) { 77 throw std::range_error("4 is really just no good for this!"); 78 } 79 return *this; 80 } operator &()81 long long operator&() { 82 if (this->val == 4) { 83 throw std::out_of_range("4 cannot be located!"); 84 } 85 return this->val; 86 } operator ==(wrapped_int & other)87 long long operator==(wrapped_int &other) { 88 if (other.val == 4) { 89 throw std::invalid_argument("4 isn't logical and can't be equal to anything!"); 90 } 91 return this->val == other.val; 92 } operator !=(wrapped_int & other)93 long long operator!=(wrapped_int &other) { 94 if (other.val == 4) { 95 throw std::invalid_argument("4 isn't logical and can'd be not equal to anything either!"); 96 } 97 return this->val != other.val; 98 } operator <(wrapped_int & other)99 long long operator<(wrapped_int &other) { 100 if (other.val == 4) { 101 throw std::invalid_argument("Can't compare with 4!"); 102 } 103 return this->val < other.val; 104 } operator <=(wrapped_int & other)105 long long operator<=(wrapped_int &other) { 106 if (other.val == 4) { 107 throw std::invalid_argument("Can't compare with 4!"); 108 } 109 return this->val <= other.val; 110 } operator >(wrapped_int & other)111 long long operator>(wrapped_int &other) { 112 if (other.val == 4) { 113 throw std::invalid_argument("Can't compare with 4!"); 114 } 115 return this->val > other.val; 116 } operator >=(wrapped_int & other)117 long long operator>=(wrapped_int &other) { 118 if (other.val == 4) { 119 throw std::invalid_argument("Can't compare with 4!"); 120 } 121 return this->val >= other.val; 122 } operator <<(long long & shift)123 wrapped_int operator<<(long long &shift) { 124 if (shift == 4) { 125 throw std::overflow_error("Shifting by 4 is just bad."); 126 } 127 return wrapped_int(this->val << shift); 128 } operator >>(long long & shift)129 wrapped_int operator>>(long long &shift) { 130 if (shift == 4) { 131 throw std::underflow_error("Shifting by 4 is just bad."); 132 } 133 return wrapped_int(this->val >> shift); 134 } operator ++()135 wrapped_int &operator++() { 136 if (this->val == 4) { 137 throw std::out_of_range("Can't increment 4!"); 138 } 139 this->val += 1; 140 return *this; 141 } operator --()142 wrapped_int &operator--() { 143 if (this->val == 4) { 144 throw std::out_of_range("Can't decrement 4!"); 145 } 146 this->val -= 1; 147 return *this; 148 } operator ++(int)149 wrapped_int operator++(int) { 150 if (this->val == 4) { 151 throw std::out_of_range("Can't increment 4!"); 152 } 153 wrapped_int t = *this; 154 this->val += 1; 155 return t; 156 } operator --(int)157 wrapped_int operator--(int) { 158 if (this->val == 4) { 159 throw std::out_of_range("Can't decrement 4!"); 160 } 161 wrapped_int t = *this; 162 this->val -= 1; 163 return t; 164 } operator !()165 wrapped_int operator!() { 166 if (this->val == 4) { 167 throw std::out_of_range("Can't negate 4!"); 168 } 169 return wrapped_int(!this->val); 170 } operator bool()171 operator bool() { 172 if (this->val == 4) { 173 throw std::invalid_argument("4 can't be cast to a boolean value!"); 174 } 175 return (this->val != 0); 176 } operator [](long long & idx)177 wrapped_int &operator[](long long &idx) { 178 if (idx == 4) { 179 throw std::invalid_argument("Index of 4 not allowed."); 180 } 181 return *this; 182 } operator ()()183 long long &operator()() { 184 if (this->val == 4) { 185 throw std::range_error("Can't call 4!"); 186 } 187 return this->val; 188 } operator =(const wrapped_int & other)189 wrapped_int &operator=(const wrapped_int &other) { 190 if ((other.val == 4) && (this->val == 4)) { 191 throw std::overflow_error("Can't assign 4 to 4!"); 192 } 193 this->val = other.val; 194 return *this; 195 } operator =(const long long & v)196 wrapped_int &operator=(const long long &v) { 197 if ((v == 4) && (this->val == 4)) { 198 throw std::overflow_error("Can't assign 4 to 4!"); 199 } 200 this->val = v; 201 return *this; 202 } 203 }; 204 205 class second_call_is_different { 206 int count; 207 public: second_call_is_different()208 second_call_is_different(): count(0) {} operator <(const second_call_is_different & lhs)209 bool operator<(const second_call_is_different& lhs) { 210 if (count>0) { 211 return true; 212 } 213 ++count; 214 return false; 215 } 216 }; 217