- /*
- * MIT License
- *
- * Copyright (c) 2026 Roland Mainz <roland.mainz@nrubsig.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
- #ifndef ROV_INT_TEMPLATE_H
- #define ROV_INT_TEMPLATE_H 1
- /*
- * rov_int_template002.h - ISO C++ wrapper class for integer types to throw
- * an exception for @(division|modulo)-by-0
- *
- * WARNING: Great PAIN has been invested to make sure this compiles with
- * any combination of { GNU g++, clang++, Visual Studio 2019 } * { C++11,
- * C++14, C++17, C++20 }.
- * Anyone who breaks this will be fed to one of { Ravenous Bugblatter Beast
- * of Traal, Bel-Shamharoth } WITHOUT MERCY!
- */
- /*
- * Build config
- */
- /*
- * DEBUG-only: Add random data around internal <T> variable to prevent the usage
- * as raw object passed to |printf()|&co.
- */
- // #ifndef NDEBUG
- #define ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING 1
- // #endif /* NDEBUG */
- #define ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO 1
- /*
- * |template <typename T> class rov_int_template| - wrapper class for integers
- * to throw an exception if @(division|modulo)-by-zero occurs
- */
- #include <cstdint>
- #include <type_traits>
- #include <utility>
- /* Does this C++ version have the C++ <=> starship operator ? */
- #if __cplusplus >= 202002L
- #include <compare>
- #define ROV_HAS_SPACESHIP 1
- #endif /* __cplusplus >= 202002L */
- /* Do we need |constexpr| to avoid the wrath of the professor ? */
- #if __cplusplus >= 201402L
- #define ROV_CXX14_CONSTEXPR constexpr
- #else
- #define ROV_CXX14_CONSTEXPR
- #endif /* __cplusplus >= 201402L */
- template <typename T>
- class rov_int_template {
- #if 1
- /* Compile-time check to prevent abuse */
- static_assert(std::is_integral<T>::value, "rov_int_template: Type must be an integer");
- #endif
- protected:
- #ifdef ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING
- long debug_cloaking_pad0 = 0xDEADBEEF;
- #endif /* ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING */
- T value_;
- #ifdef ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING
- long debug_cloaking_pad1 = 0x12345678;
- #endif /* ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING */
- public:
- /* FIXME: Perf issue ? */
- constexpr rov_int_template() noexcept : value_(0) {
- }
- template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
- constexpr rov_int_template(U v) noexcept : value_(static_cast<T>(v)) {
- }
- template <typename U>
- constexpr rov_int_template(const rov_int_template<U>& other) noexcept : value_(static_cast<T>(other.get())) {
- }
- constexpr T get() const noexcept {
- return value_;
- }
- constexpr operator T() const noexcept {
- return value_;
- }
- template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
- ROV_CXX14_CONSTEXPR rov_int_template& operator=(U v) noexcept {
- value_ = static_cast<T>(v);
- return *this;
- }
- template <typename U>
- ROV_CXX14_CONSTEXPR rov_int_template& operator=(const rov_int_template<U>& other) noexcept {
- value_ = static_cast<T>(other.get());
- return *this;
- }
- constexpr rov_int_template<decltype(+std::declval<T>())> operator+() const noexcept {
- return rov_int_template<decltype(+std::declval<T>())>(+value_);
- }
- constexpr rov_int_template<decltype(-std::declval<T>())> operator-() const noexcept {
- return rov_int_template<decltype(-std::declval<T>())>(-value_);
- }
- constexpr rov_int_template<decltype(~std::declval<T>())> operator~() const noexcept {
- return rov_int_template<decltype(~std::declval<T>())>(~value_);
- }
- constexpr bool operator!() const noexcept {
- return !value_;
- }
- ROV_CXX14_CONSTEXPR rov_int_template& operator++() noexcept {
- ++value_;
- return *this;
- }
- ROV_CXX14_CONSTEXPR rov_int_template operator++(int) noexcept {
- rov_int_template tmp(*this);
- ++value_;
- return tmp;
- }
- ROV_CXX14_CONSTEXPR rov_int_template& operator--() noexcept {
- --value_;
- return *this;
- }
- ROV_CXX14_CONSTEXPR rov_int_template operator--(int) noexcept {
- rov_int_template tmp(*this);
- --value_;
- return tmp;
- }
- #define ROV_MEMBER_BINOP(OP) \
- template <typename U> \
- constexpr rov_int_template<decltype(std::declval<T>() OP std::declval<U>())> operator OP(const rov_int_template<U>& rhs) const noexcept { \
- return rov_int_template<decltype(std::declval<T>() OP std::declval<U>())>(value_ OP rhs.get()); \
- } \
- template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> \
- constexpr rov_int_template<decltype(std::declval<T>() OP std::declval<U>())> operator OP(U rhs) const noexcept { \
- return rov_int_template<decltype(std::declval<T>() OP std::declval<U>())>(value_ OP rhs); \
- }
- ROV_MEMBER_BINOP(+)
- ROV_MEMBER_BINOP(-)
- ROV_MEMBER_BINOP(*)
- #ifdef ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO
- /* division operator */
- template <typename U>
- constexpr rov_int_template<decltype(std::declval<T>() / std::declval<U>())> operator /(const rov_int_template<U>& rhs) const noexcept {
- if (rhs.get() == 0)
- (void)puts("ERROR division by zero");
- return rov_int_template<decltype(std::declval<T>() / std::declval<U>())>(value_ / rhs.get());
- }
- template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
- constexpr rov_int_template<decltype(std::declval<T>() / std::declval<U>())> operator /(U rhs) const noexcept {
- if (rhs == 0)
- (void)puts("ERROR division by zero");
- return rov_int_template<decltype(std::declval<T>() / std::declval<U>())>(value_ / rhs);
- }
- /* Modulo operator */
- template <typename U>
- constexpr rov_int_template<decltype(std::declval<T>() % std::declval<U>())> operator %(const rov_int_template<U>& rhs) const noexcept {
- if (rhs.get() == 0)
- (void)puts("ERROR modulo by zero");
- return rov_int_template<decltype(std::declval<T>() % std::declval<U>())>(value_ % rhs.get());
- }
- template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
- constexpr rov_int_template<decltype(std::declval<T>() % std::declval<U>())> operator %(U rhs) const noexcept {
- if (rhs == 0)
- (void)puts("ERROR modulo by zero");
- return rov_int_template<decltype(std::declval<T>() % std::declval<U>())>(value_ % rhs);
- }
- #else
- ROV_MEMBER_BINOP(/)
- ROV_MEMBER_BINOP(%)
- #endif /* ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO */
- ROV_MEMBER_BINOP(<<)
- ROV_MEMBER_BINOP(>>)
- ROV_MEMBER_BINOP(|)
- ROV_MEMBER_BINOP(&)
- ROV_MEMBER_BINOP(^)
- #undef ROV_MEMBER_BINOP
- #define ROV_MEMBER_COMPOUND_OP(OP) \
- template <typename U> \
- ROV_CXX14_CONSTEXPR rov_int_template& operator OP(const rov_int_template<U>& rhs) noexcept { \
- value_ OP rhs.get(); \
- return *this; \
- } \
- template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> \
- ROV_CXX14_CONSTEXPR rov_int_template& operator OP(U rhs) noexcept { \
- value_ OP rhs; \
- return *this; \
- }
- ROV_MEMBER_COMPOUND_OP(+=)
- ROV_MEMBER_COMPOUND_OP(-=)
- ROV_MEMBER_COMPOUND_OP(*=)
- #ifdef ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO
- template <typename U>
- ROV_CXX14_CONSTEXPR rov_int_template& operator /=(const rov_int_template<U>& rhs) noexcept {
- if (rhs.get() == 0)
- (void)puts("ERROR division by zero");
- value_ /= rhs.get();
- return *this;
- }
- template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
- ROV_CXX14_CONSTEXPR rov_int_template& operator /=(U rhs) noexcept {
- if (rhs == 0)
- (void)puts("ERROR modulo by zero");
- value_ /= rhs;
- return *this;
- }
- /* Modulo operator */
- template <typename U>
- ROV_CXX14_CONSTEXPR rov_int_template& operator %=(const rov_int_template<U>& rhs) noexcept {
- if (rhs.get() == 0)
- (void)puts("ERROR division by zero");
- value_ %= rhs.get();
- return *this;
- }
- template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
- ROV_CXX14_CONSTEXPR rov_int_template& operator %=(U rhs) noexcept {
- if (rhs == 0)
- (void)puts("ERROR modulo by zero");
- value_ %= rhs;
- return *this;
- }
- #else
- ROV_MEMBER_COMPOUND_OP(/=)
- ROV_MEMBER_COMPOUND_OP(%=)
- #endif /* ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO */
- ROV_MEMBER_COMPOUND_OP(<<=)
- ROV_MEMBER_COMPOUND_OP(>>=)
- ROV_MEMBER_COMPOUND_OP(|=)
- ROV_MEMBER_COMPOUND_OP(&=)
- ROV_MEMBER_COMPOUND_OP(^=)
- #undef ROV_MEMBER_COMPOUND_OP
- #ifdef ROV_HAS_SPACESHIP
- template <typename U>
- constexpr auto operator<=>(const rov_int_template<U>& rhs) const noexcept {
- return value_ <=> rhs.get();
- }
- template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
- constexpr auto operator<=>(U rhs) const noexcept {
- return value_ <=> rhs;
- }
- template <typename U>
- constexpr bool operator==(const rov_int_template<U>& rhs) const noexcept {
- return value_ == rhs.get();
- }
- template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
- constexpr bool operator==(U rhs) const noexcept {
- return value_ == rhs;
- }
- #else
- #define ROV_COMP_OP(OP) \
- template <typename U> \
- constexpr bool operator OP(const rov_int_template<U>& rhs) const noexcept { return value_ OP rhs.get(); } \
- template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> \
- constexpr bool operator OP(U rhs) const noexcept { return value_ OP rhs; }
- ROV_COMP_OP(==)
- ROV_COMP_OP(!=)
- ROV_COMP_OP(<)
- ROV_COMP_OP(<=)
- ROV_COMP_OP(>)
- ROV_COMP_OP(>=)
- #undef ROV_COMP_OP
- #endif /* ROV_HAS_SPACESHIP */
- };
- #define ROV_NONMEMBER_BINOP(OP) \
- template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type> \
- constexpr rov_int_template<decltype(std::declval<U>() OP std::declval<T>())> operator OP(U lhs, const rov_int_template<T>& rhs) noexcept { \
- return rov_int_template<decltype(std::declval<U>() OP std::declval<T>())>(lhs OP rhs.get()); \
- }
- ROV_NONMEMBER_BINOP(+)
- ROV_NONMEMBER_BINOP(-)
- ROV_NONMEMBER_BINOP(*)
- #ifdef ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO
- /* Division operator */
- template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type>
- constexpr rov_int_template<decltype(std::declval<U>() / std::declval<T>())> operator /(U lhs, const rov_int_template<T>& rhs) noexcept {
- if (rhs.get() == 0)
- (void)puts("ERROR division by zero");
- return rov_int_template<decltype(std::declval<U>() / std::declval<T>())>(lhs / rhs.get());
- }
- /* Modulo operator */
- template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type>
- constexpr rov_int_template<decltype(std::declval<U>() % std::declval<T>())> operator %(U lhs, const rov_int_template<T>& rhs) noexcept {
- if (rhs.get() == 0)
- (void)puts("ERROR modulo by zero");
- return rov_int_template<decltype(std::declval<U>() % std::declval<T>())>(lhs % rhs.get());
- }
- #else
- ROV_NONMEMBER_BINOP(/)
- ROV_NONMEMBER_BINOP(%)
- #endif /* ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO */
- ROV_NONMEMBER_BINOP(<<)
- ROV_NONMEMBER_BINOP(>>)
- ROV_NONMEMBER_BINOP(|)
- ROV_NONMEMBER_BINOP(&)
- ROV_NONMEMBER_BINOP(^)
- #undef ROV_NONMEMBER_BINOP
- #ifndef ROV_HAS_SPACESHIP
- #define ROV_NONMEMBER_COMP_OP(OP) \
- template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type> \
- constexpr bool operator OP(U lhs, const rov_int_template<T>& rhs) noexcept { return lhs OP rhs.get(); }
- ROV_NONMEMBER_COMP_OP(==)
- ROV_NONMEMBER_COMP_OP(!=)
- ROV_NONMEMBER_COMP_OP(<)
- ROV_NONMEMBER_COMP_OP(<=)
- ROV_NONMEMBER_COMP_OP(>)
- ROV_NONMEMBER_COMP_OP(>=)
- #undef ROV_NONMEMBER_COMP_OP
- #endif /* !ROV_HAS_SPACESHIP */
- #endif /* !ROV_INT_TEMPLATE_H */
rov_int_template002.h - ISO C++ wrapper class for integer types to throw an exception for @(division|modulo)-by-0
Posted by Anonymous on Wed 18th Mar 2026 19:25
raw | new post
view followups (newest first): rov_int_template002.h - ISO C++ wrapper class for integer types to throw an exception for @(division|modulo)-by-0 by Anonymous
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