Difference between
modified post b2de5f by Anonymous on Fri 27th Mar 2026 13:21
original post 2bd4db5 by Anonymous on Wed 18th Mar 2026 19:25
Download diff
Show
old version |
new version |
both versions
| 1 | 1 | /* | |
| 2 | 2 | * MIT License | |
| 3 | 3 | * | |
| 4 | 4 | * Copyright (c) 2026 Roland Mainz <roland.mainz@nrubsig.org> | |
| 5 | 5 | * | |
| 6 | 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 7 | 7 | * of this software and associated documentation files (the "Software"), to deal | |
| 8 | 8 | * in the Software without restriction, including without limitation the rights | |
| 9 | 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 10 | 10 | * copies of the Software, and to permit persons to whom the Software is | |
| 11 | 11 | * furnished to do so, subject to the following conditions: | |
| 12 | 12 | * | |
| 13 | 13 | * The above copyright notice and this permission notice shall be included in all | |
| 14 | 14 | * copies or substantial portions of the Software. | |
| 15 | 15 | * | |
| 16 | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 17 | 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 18 | 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 19 | 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 20 | 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 21 | 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| 22 | 22 | * SOFTWARE. | |
| 23 | 23 | */ | |
| 24 | 24 | ||
| 25 | 25 | #ifndef ROV_INT_TEMPLATE_H | |
| 26 | 26 | #define ROV_INT_TEMPLATE_H 1 | |
| 27 | 27 | ||
| 28 | 28 | /* | |
| 29 | 29 | * rov_int_template002.h - ISO C++ wrapper class for integer types to throw | |
| 30 | 30 | * an exception for @(division|modulo)-by-0 | |
| 31 | 31 | * | |
| 32 | - | * WARNING: Great PAIN has been invested to make sure this compiles with | |
| 32 | + | * 1. WARNING: Great PAIN has been invested to make sure this compiles with | |
| 33 | 33 | * any combination of { GNU g++, clang++, Visual Studio 2019 } * { C++11, | |
| 34 | 34 | * C++14, C++17, C++20 }. | |
| 35 | 35 | * Anyone who breaks this will be fed to one of { Ravenous Bugblatter Beast | |
| 36 | 36 | * of Traal, Bel-Shamharoth } WITHOUT MERCY! | |
| 37 | + | * 2. The code is explicitly MIT-licensed so we can pass it to compiler | |
| 37 | 39 | */ | |
| 38 | 40 | ||
| 39 | 41 | /* | |
| 40 | 42 | * Build config | |
| 41 | 43 | */ | |
| 42 | 44 | ||
| 43 | 45 | /* | |
| 44 | 46 | * DEBUG-only: Add random data around internal <T> variable to prevent the usage | |
| 45 | 47 | * as raw object passed to |printf()|&co. | |
| 46 | 48 | */ | |
| 47 | 49 | // #ifndef NDEBUG | |
| 48 | 50 | #define ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING 1 | |
| 49 | 51 | // #endif /* NDEBUG */ | |
| 50 | 52 | #define ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO 1 | |
| 51 | 53 | ||
| 52 | 54 | /* | |
| 53 | 55 | * |template <typename T> class rov_int_template| - wrapper class for integers | |
| 54 | 56 | * to throw an exception if @(division|modulo)-by-zero occurs | |
| 55 | 57 | */ | |
| 56 | 58 | ||
| 57 | 59 | #include <cstdint> | |
| 58 | 60 | #include <type_traits> | |
| 59 | 61 | #include <utility> | |
| 62 | + | #include <stdexcept> | |
| 60 | 63 | ||
| 61 | 64 | /* Does this C++ version have the C++ <=> starship operator ? */ | |
| 62 | 65 | #if __cplusplus >= 202002L | |
| 63 | 66 | #include <compare> | |
| 64 | 67 | #define ROV_HAS_SPACESHIP 1 | |
| 65 | 68 | #endif /* __cplusplus >= 202002L */ | |
| 66 | 69 | ||
| 67 | 70 | /* Do we need |constexpr| to avoid the wrath of the professor ? */ | |
| 68 | 71 | #if __cplusplus >= 201402L | |
| 69 | 72 | #define ROV_CXX14_CONSTEXPR constexpr | |
| 70 | 73 | #else | |
| 71 | 74 | #define ROV_CXX14_CONSTEXPR | |
| 72 | 75 | #endif /* __cplusplus >= 201402L */ | |
| 73 | 76 | ||
| 74 | 77 | template <typename T> | |
| 75 | 78 | class rov_int_template { | |
| 76 | 79 | #if 1 | |
| 77 | 80 | /* Compile-time check to prevent abuse */ | |
| 78 | 81 | static_assert(std::is_integral<T>::value, "rov_int_template: Type must be an integer"); | |
| 79 | 82 | #endif | |
| 80 | 83 | ||
| 81 | 84 | protected: | |
| 82 | 85 | #ifdef ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING | |
| 83 | 86 | long debug_cloaking_pad0 = 0xDEADBEEF; | |
| 84 | 87 | #endif /* ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING */ | |
| 85 | 88 | T value_; | |
| 86 | 89 | #ifdef ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING | |
| 87 | 90 | long debug_cloaking_pad1 = 0x12345678; | |
| 88 | 91 | #endif /* ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING */ | |
| 89 | 92 | ||
| 90 | 93 | public: | |
| 91 | 94 | /* FIXME: Perf issue ? */ | |
| 92 | - | constexpr rov_int_template() noexcept : value_(0) { | |
| 95 | + | constexpr rov_int_template() : value_(0) { | |
| 93 | 96 | } | |
| 94 | 97 | ||
| 95 | 98 | template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> | |
| 96 | - | constexpr rov_int_template(U v) noexcept : value_(static_cast<T>(v)) { | |
| 99 | + | constexpr rov_int_template(U v) : value_(static_cast<T>(v)) { | |
| 97 | 100 | } | |
| 98 | 101 | ||
| 99 | 102 | template <typename U> | |
| 100 | - | constexpr rov_int_template(const rov_int_template<U>& other) noexcept : value_(static_cast<T>(other.get())) { | |
| 103 | + | constexpr rov_int_template(const rov_int_template<U>& other) : value_(static_cast<T>(other.get())) { | |
| 101 | 104 | } | |
| 102 | 105 | ||
| 103 | - | constexpr T get() const noexcept { | |
| 106 | + | constexpr T get() const { | |
| 104 | 107 | return value_; | |
| 105 | 108 | } | |
| 106 | 109 | ||
| 107 | - | constexpr operator T() const noexcept { | |
| 110 | + | constexpr operator T() const { | |
| 108 | 111 | return value_; | |
| 109 | 112 | } | |
| 110 | 113 | ||
| 111 | 114 | template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> | |
| 112 | - | ROV_CXX14_CONSTEXPR rov_int_template& operator=(U v) noexcept { | |
| 115 | + | ROV_CXX14_CONSTEXPR rov_int_template& operator=(U v) { | |
| 113 | 116 | value_ = static_cast<T>(v); | |
| 114 | 117 | return *this; | |
| 115 | 118 | } | |
| 116 | 119 | ||
| 117 | 120 | template <typename U> | |
| 118 | - | ROV_CXX14_CONSTEXPR rov_int_template& operator=(const rov_int_template<U>& other) noexcept { | |
| 121 | + | ROV_CXX14_CONSTEXPR rov_int_template& operator=(const rov_int_template<U>& other) { | |
| 119 | 122 | value_ = static_cast<T>(other.get()); | |
| 120 | 123 | return *this; | |
| 121 | 124 | } | |
| 122 | 125 | ||
| 123 | - | constexpr rov_int_template<decltype(+std::declval<T>())> operator+() const noexcept { | |
| 126 | + | constexpr rov_int_template<decltype(+std::declval<T>())> operator+() const { | |
| 124 | 127 | return rov_int_template<decltype(+std::declval<T>())>(+value_); | |
| 125 | 128 | } | |
| 126 | 129 | ||
| 127 | - | constexpr rov_int_template<decltype(-std::declval<T>())> operator-() const noexcept { | |
| 130 | + | constexpr rov_int_template<decltype(-std::declval<T>())> operator-() const { | |
| 128 | 131 | return rov_int_template<decltype(-std::declval<T>())>(-value_); | |
| 129 | 132 | } | |
| 130 | 133 | ||
| 131 | - | constexpr rov_int_template<decltype(~std::declval<T>())> operator~() const noexcept { | |
| 134 | + | constexpr rov_int_template<decltype(~std::declval<T>())> operator~() const { | |
| 132 | 135 | return rov_int_template<decltype(~std::declval<T>())>(~value_); | |
| 133 | 136 | } | |
| 134 | 137 | ||
| 135 | - | constexpr bool operator!() const noexcept { | |
| 138 | + | constexpr bool operator!() const { | |
| 136 | 139 | return !value_; | |
| 137 | 140 | } | |
| 138 | 141 | ||
| 139 | - | ROV_CXX14_CONSTEXPR rov_int_template& operator++() noexcept { | |
| 142 | + | ROV_CXX14_CONSTEXPR rov_int_template& operator++() { | |
| 140 | 143 | ++value_; | |
| 141 | 144 | return *this; | |
| 142 | 145 | } | |
| 143 | - | ROV_CXX14_CONSTEXPR rov_int_template operator++(int) noexcept { | |
| 146 | + | ROV_CXX14_CONSTEXPR rov_int_template operator++(int) { | |
| 144 | 147 | rov_int_template tmp(*this); | |
| 145 | 148 | ++value_; | |
| 146 | 149 | return tmp; | |
| 147 | 150 | } | |
| 148 | 151 | ||
| 149 | - | ROV_CXX14_CONSTEXPR rov_int_template& operator--() noexcept { | |
| 152 | + | ROV_CXX14_CONSTEXPR rov_int_template& operator--() { | |
| 150 | 153 | --value_; | |
| 151 | 154 | return *this; | |
| 152 | 155 | } | |
| 153 | - | ROV_CXX14_CONSTEXPR rov_int_template operator--(int) noexcept { | |
| 156 | + | ROV_CXX14_CONSTEXPR rov_int_template operator--(int) { | |
| 154 | 157 | rov_int_template tmp(*this); | |
| 155 | 158 | --value_; | |
| 156 | 159 | return tmp; | |
| 157 | 160 | } | |
| 158 | 161 | ||
| 159 | 162 | #define ROV_MEMBER_BINOP(OP) \ | |
| 160 | 163 | template <typename U> \ | |
| 161 | - | constexpr rov_int_template<decltype(std::declval<T>() OP std::declval<U>())> operator OP(const rov_int_template<U>& rhs) const noexcept { \ | |
| 164 | + | constexpr rov_int_template<decltype(std::declval<T>() OP std::declval<U>())> operator OP(const rov_int_template<U>& rhs) const { \ | |
| 162 | 165 | return rov_int_template<decltype(std::declval<T>() OP std::declval<U>())>(value_ OP rhs.get()); \ | |
| 163 | 166 | } \ | |
| 164 | 167 | template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> \ | |
| 165 | - | constexpr rov_int_template<decltype(std::declval<T>() OP std::declval<U>())> operator OP(U rhs) const noexcept { \ | |
| 168 | + | constexpr rov_int_template<decltype(std::declval<T>() OP std::declval<U>())> operator OP(U rhs) const { \ | |
| 166 | 169 | return rov_int_template<decltype(std::declval<T>() OP std::declval<U>())>(value_ OP rhs); \ | |
| 167 | 170 | } | |
| 168 | 171 | ||
| 169 | 172 | ROV_MEMBER_BINOP(+) | |
| 170 | 173 | ROV_MEMBER_BINOP(-) | |
| 171 | 174 | ROV_MEMBER_BINOP(*) | |
| 172 | 175 | #ifdef ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO | |
| 173 | 176 | /* division operator */ | |
| 174 | 177 | template <typename U> | |
| 175 | - | constexpr rov_int_template<decltype(std::declval<T>() / std::declval<U>())> operator /(const rov_int_template<U>& rhs) const noexcept { | |
| 178 | + | constexpr rov_int_template<decltype(std::declval<T>() / std::declval<U>())> operator /(const rov_int_template<U>& rhs) const { | |
| 176 | 179 | if (rhs.get() == 0) | |
| 177 | - | (void)puts("ERROR division by zero"); | |
| 180 | + | throw std::runtime_error("ERROR division by zero"); | |
| 178 | 181 | return rov_int_template<decltype(std::declval<T>() / std::declval<U>())>(value_ / rhs.get()); | |
| 179 | 182 | } | |
| 180 | 183 | ||
| 181 | 184 | template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> | |
| 182 | - | constexpr rov_int_template<decltype(std::declval<T>() / std::declval<U>())> operator /(U rhs) const noexcept { | |
| 185 | + | constexpr rov_int_template<decltype(std::declval<T>() / std::declval<U>())> operator /(U rhs) const { | |
| 183 | 186 | if (rhs == 0) | |
| 184 | - | (void)puts("ERROR division by zero"); | |
| 187 | + | throw std::runtime_error("ERROR division by zero"); | |
| 185 | 188 | return rov_int_template<decltype(std::declval<T>() / std::declval<U>())>(value_ / rhs); | |
| 186 | 189 | } | |
| 187 | 190 | ||
| 188 | 191 | /* Modulo operator */ | |
| 189 | 192 | template <typename U> | |
| 190 | - | constexpr rov_int_template<decltype(std::declval<T>() % std::declval<U>())> operator %(const rov_int_template<U>& rhs) const noexcept { | |
| 193 | + | constexpr rov_int_template<decltype(std::declval<T>() % std::declval<U>())> operator %(const rov_int_template<U>& rhs) const { | |
| 191 | 194 | if (rhs.get() == 0) | |
| 192 | - | (void)puts("ERROR modulo by zero"); | |
| 195 | + | throw std::runtime_error("ERROR modulo by zero"); | |
| 193 | 196 | return rov_int_template<decltype(std::declval<T>() % std::declval<U>())>(value_ % rhs.get()); | |
| 194 | 197 | } | |
| 195 | 198 | template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> | |
| 196 | - | constexpr rov_int_template<decltype(std::declval<T>() % std::declval<U>())> operator %(U rhs) const noexcept { | |
| 199 | + | constexpr rov_int_template<decltype(std::declval<T>() % std::declval<U>())> operator %(U rhs) const { | |
| 197 | 200 | if (rhs == 0) | |
| 198 | - | (void)puts("ERROR modulo by zero"); | |
| 201 | + | throw std::runtime_error("ERROR modulo by zero"); | |
| 199 | 202 | return rov_int_template<decltype(std::declval<T>() % std::declval<U>())>(value_ % rhs); | |
| 200 | 203 | } | |
| 201 | 204 | #else | |
| 202 | 205 | ROV_MEMBER_BINOP(/) | |
| 203 | 206 | ROV_MEMBER_BINOP(%) | |
| 204 | 207 | #endif /* ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO */ | |
| 205 | 208 | ROV_MEMBER_BINOP(<<) | |
| 206 | 209 | ROV_MEMBER_BINOP(>>) | |
| 207 | 210 | ROV_MEMBER_BINOP(|) | |
| 208 | 211 | ROV_MEMBER_BINOP(&) | |
| 209 | 212 | ROV_MEMBER_BINOP(^) | |
| 210 | 213 | #undef ROV_MEMBER_BINOP | |
| 211 | 214 | ||
| 212 | 215 | #define ROV_MEMBER_COMPOUND_OP(OP) \ | |
| 213 | 216 | template <typename U> \ | |
| 214 | - | ROV_CXX14_CONSTEXPR rov_int_template& operator OP(const rov_int_template<U>& rhs) noexcept { \ | |
| 217 | + | ROV_CXX14_CONSTEXPR rov_int_template& operator OP(const rov_int_template<U>& rhs) { \ | |
| 215 | 218 | value_ OP rhs.get(); \ | |
| 216 | 219 | return *this; \ | |
| 217 | 220 | } \ | |
| 218 | 221 | template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> \ | |
| 219 | - | ROV_CXX14_CONSTEXPR rov_int_template& operator OP(U rhs) noexcept { \ | |
| 222 | + | ROV_CXX14_CONSTEXPR rov_int_template& operator OP(U rhs) { \ | |
| 220 | 223 | value_ OP rhs; \ | |
| 221 | 224 | return *this; \ | |
| 222 | 225 | } | |
| 223 | 226 | ||
| 224 | 227 | ROV_MEMBER_COMPOUND_OP(+=) | |
| 225 | 228 | ROV_MEMBER_COMPOUND_OP(-=) | |
| 226 | 229 | ROV_MEMBER_COMPOUND_OP(*=) | |
| 227 | 230 | #ifdef ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO | |
| 228 | 231 | template <typename U> | |
| 229 | - | ROV_CXX14_CONSTEXPR rov_int_template& operator /=(const rov_int_template<U>& rhs) noexcept { | |
| 232 | + | ROV_CXX14_CONSTEXPR rov_int_template& operator /=(const rov_int_template<U>& rhs) { | |
| 230 | 233 | if (rhs.get() == 0) | |
| 231 | - | (void)puts("ERROR division by zero"); | |
| 234 | + | throw std::runtime_error("ERROR division by zero"); | |
| 232 | 235 | value_ /= rhs.get(); | |
| 233 | 236 | return *this; | |
| 234 | 237 | } | |
| 235 | 238 | template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> | |
| 236 | - | ROV_CXX14_CONSTEXPR rov_int_template& operator /=(U rhs) noexcept { | |
| 239 | + | ROV_CXX14_CONSTEXPR rov_int_template& operator /=(U rhs) { | |
| 237 | 240 | if (rhs == 0) | |
| 238 | - | (void)puts("ERROR modulo by zero"); | |
| 241 | + | throw std::runtime_error("ERROR modulo by zero"); | |
| 239 | 242 | value_ /= rhs; | |
| 240 | 243 | return *this; | |
| 241 | 244 | } | |
| 242 | 245 | ||
| 243 | 246 | /* Modulo operator */ | |
| 244 | 247 | template <typename U> | |
| 245 | - | ROV_CXX14_CONSTEXPR rov_int_template& operator %=(const rov_int_template<U>& rhs) noexcept { | |
| 248 | + | ROV_CXX14_CONSTEXPR rov_int_template& operator %=(const rov_int_template<U>& rhs) { | |
| 246 | 249 | if (rhs.get() == 0) | |
| 247 | - | (void)puts("ERROR division by zero"); | |
| 250 | + | throw std::runtime_error("ERROR modulo by zero"); | |
| 248 | 251 | value_ %= rhs.get(); | |
| 249 | 252 | return *this; | |
| 250 | 253 | } | |
| 251 | 254 | template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> | |
| 252 | - | ROV_CXX14_CONSTEXPR rov_int_template& operator %=(U rhs) noexcept { | |
| 255 | + | ROV_CXX14_CONSTEXPR rov_int_template& operator %=(U rhs) { | |
| 253 | 256 | if (rhs == 0) | |
| 254 | - | (void)puts("ERROR modulo by zero"); | |
| 257 | + | throw std::runtime_error("ERROR modulo by zero"); | |
| 255 | 258 | value_ %= rhs; | |
| 256 | 259 | return *this; | |
| 257 | 260 | } | |
| 258 | 261 | #else | |
| 259 | 262 | ROV_MEMBER_COMPOUND_OP(/=) | |
| 260 | 263 | ROV_MEMBER_COMPOUND_OP(%=) | |
| 261 | 264 | #endif /* ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO */ | |
| 262 | 265 | ROV_MEMBER_COMPOUND_OP(<<=) | |
| 263 | 266 | ROV_MEMBER_COMPOUND_OP(>>=) | |
| 264 | 267 | ROV_MEMBER_COMPOUND_OP(|=) | |
| 265 | 268 | ROV_MEMBER_COMPOUND_OP(&=) | |
| 266 | 269 | ROV_MEMBER_COMPOUND_OP(^=) | |
| 267 | 270 | #undef ROV_MEMBER_COMPOUND_OP | |
| 268 | 271 | ||
| 269 | 272 | #ifdef ROV_HAS_SPACESHIP | |
| 270 | 273 | template <typename U> | |
| 271 | - | constexpr auto operator<=>(const rov_int_template<U>& rhs) const noexcept { | |
| 274 | + | constexpr auto operator<=>(const rov_int_template<U>& rhs) const { | |
| 272 | 275 | return value_ <=> rhs.get(); | |
| 273 | 276 | } | |
| 274 | 277 | template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> | |
| 275 | - | constexpr auto operator<=>(U rhs) const noexcept { | |
| 278 | + | constexpr auto operator<=>(U rhs) const { | |
| 276 | 279 | return value_ <=> rhs; | |
| 277 | 280 | } | |
| 278 | 281 | template <typename U> | |
| 279 | - | constexpr bool operator==(const rov_int_template<U>& rhs) const noexcept { | |
| 282 | + | constexpr bool operator==(const rov_int_template<U>& rhs) const { | |
| 280 | 283 | return value_ == rhs.get(); | |
| 281 | 284 | } | |
| 282 | 285 | template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> | |
| 283 | - | constexpr bool operator==(U rhs) const noexcept { | |
| 286 | + | constexpr bool operator==(U rhs) const { | |
| 284 | 287 | return value_ == rhs; | |
| 285 | 288 | } | |
| 286 | 289 | #else | |
| 287 | 290 | #define ROV_COMP_OP(OP) \ | |
| 288 | 291 | template <typename U> \ | |
| 289 | - | constexpr bool operator OP(const rov_int_template<U>& rhs) const noexcept { return value_ OP rhs.get(); } \ | |
| 292 | + | constexpr bool operator OP(const rov_int_template<U>& rhs) const { return value_ OP rhs.get(); } \ | |
| 290 | 293 | template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> \ | |
| 291 | - | constexpr bool operator OP(U rhs) const noexcept { return value_ OP rhs; } | |
| 294 | + | constexpr bool operator OP(U rhs) const { return value_ OP rhs; } | |
| 292 | 295 | ||
| 293 | 296 | ROV_COMP_OP(==) | |
| 294 | 297 | ROV_COMP_OP(!=) | |
| 295 | 298 | ROV_COMP_OP(<) | |
| 296 | 299 | ROV_COMP_OP(<=) | |
| 297 | 300 | ROV_COMP_OP(>) | |
| 298 | 301 | ROV_COMP_OP(>=) | |
| 299 | 302 | ||
| 300 | 303 | #undef ROV_COMP_OP | |
| 301 | 304 | #endif /* ROV_HAS_SPACESHIP */ | |
| 302 | 305 | }; | |
| 303 | 306 | ||
| 304 | 307 | #define ROV_NONMEMBER_BINOP(OP) \ | |
| 305 | 308 | template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type> \ | |
| 306 | - | constexpr rov_int_template<decltype(std::declval<U>() OP std::declval<T>())> operator OP(U lhs, const rov_int_template<T>& rhs) noexcept { \ | |
| 309 | + | constexpr rov_int_template<decltype(std::declval<U>() OP std::declval<T>())> operator OP(U lhs, const rov_int_template<T>& rhs) { \ | |
| 307 | 310 | return rov_int_template<decltype(std::declval<U>() OP std::declval<T>())>(lhs OP rhs.get()); \ | |
| 308 | 311 | } | |
| 309 | 312 | ||
| 310 | 313 | ROV_NONMEMBER_BINOP(+) | |
| 311 | 314 | ROV_NONMEMBER_BINOP(-) | |
| 312 | 315 | ROV_NONMEMBER_BINOP(*) | |
| 313 | 316 | #ifdef ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO | |
| 314 | 317 | /* Division operator */ | |
| 315 | 318 | template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type> | |
| 316 | - | constexpr rov_int_template<decltype(std::declval<U>() / std::declval<T>())> operator /(U lhs, const rov_int_template<T>& rhs) noexcept { | |
| 319 | + | constexpr rov_int_template<decltype(std::declval<U>() / std::declval<T>())> operator /(U lhs, const rov_int_template<T>& rhs) { | |
| 317 | 320 | if (rhs.get() == 0) | |
| 318 | - | (void)puts("ERROR division by zero"); | |
| 321 | + | throw std::runtime_error("ERROR division by zero"); | |
| 319 | 322 | return rov_int_template<decltype(std::declval<U>() / std::declval<T>())>(lhs / rhs.get()); | |
| 320 | 323 | } | |
| 321 | 324 | ||
| 322 | 325 | /* Modulo operator */ | |
| 323 | 326 | template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type> | |
| 324 | - | constexpr rov_int_template<decltype(std::declval<U>() % std::declval<T>())> operator %(U lhs, const rov_int_template<T>& rhs) noexcept { | |
| 327 | + | constexpr rov_int_template<decltype(std::declval<U>() % std::declval<T>())> operator %(U lhs, const rov_int_template<T>& rhs) { | |
| 325 | 328 | if (rhs.get() == 0) | |
| 326 | - | (void)puts("ERROR modulo by zero"); | |
| 329 | + | throw std::runtime_error("ERROR modulo by zero"); | |
| 327 | 330 | return rov_int_template<decltype(std::declval<U>() % std::declval<T>())>(lhs % rhs.get()); | |
| 328 | 331 | } | |
| 329 | 332 | #else | |
| 330 | 333 | ROV_NONMEMBER_BINOP(/) | |
| 331 | 334 | ROV_NONMEMBER_BINOP(%) | |
| 332 | 335 | #endif /* ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO */ | |
| 333 | 336 | ROV_NONMEMBER_BINOP(<<) | |
| 334 | 337 | ROV_NONMEMBER_BINOP(>>) | |
| 335 | 338 | ROV_NONMEMBER_BINOP(|) | |
| 336 | 339 | ROV_NONMEMBER_BINOP(&) | |
| 337 | 340 | ROV_NONMEMBER_BINOP(^) | |
| 338 | 341 | ||
| 339 | 342 | #undef ROV_NONMEMBER_BINOP | |
| 340 | 343 | ||
| 341 | 344 | #ifndef ROV_HAS_SPACESHIP | |
| 342 | 345 | #define ROV_NONMEMBER_COMP_OP(OP) \ | |
| 343 | 346 | template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type> \ | |
| 344 | - | constexpr bool operator OP(U lhs, const rov_int_template<T>& rhs) noexcept { return lhs OP rhs.get(); } | |
| 347 | + | constexpr bool operator OP(U lhs, const rov_int_template<T>& rhs) { return lhs OP rhs.get(); } | |
| 345 | 348 | ||
| 346 | 349 | ROV_NONMEMBER_COMP_OP(==) | |
| 347 | 350 | ROV_NONMEMBER_COMP_OP(!=) | |
| 348 | 351 | ROV_NONMEMBER_COMP_OP(<) | |
| 349 | 352 | ROV_NONMEMBER_COMP_OP(<=) | |
| 350 | 353 | ROV_NONMEMBER_COMP_OP(>) | |
| 351 | 354 | ROV_NONMEMBER_COMP_OP(>=) | |
| 352 | 355 | #undef ROV_NONMEMBER_COMP_OP | |
| 353 | 356 | #endif /* !ROV_HAS_SPACESHIP */ | |
| 354 | 357 | ||
| 355 | 358 | #endif /* !ROV_INT_TEMPLATE_H */ | |
| 356 | 359 |
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.
rovema.kpaste.net RSS