pastebin - collaborative debugging tool
rovema.kpaste.net RSS


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

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

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.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at