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 Fri 27th Mar 2026 13:21
raw | new post
modification of post by Anonymous (view diff)

  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.  * 1. 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.  * 2. The code is explicitly MIT-licensed so we can pass it to compiler
  38.  * vendors without compliciated license debates
  39.  */
  40.  
  41. /*
  42.  * Build config
  43.  */
  44.  
  45. /*
  46.  * DEBUG-only: Add random data around internal <T> variable to prevent the usage
  47.  * as raw object passed to |printf()|&co.
  48.  */
  49. // #ifndef NDEBUG
  50. #define ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING 1
  51. // #endif /* NDEBUG */
  52. #define ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO 1
  53.  
  54. /*
  55.  * |template <typename T> class rov_int_template| - wrapper class for integers
  56.  * to throw an exception if @(division|modulo)-by-zero occurs
  57.  */
  58.  
  59. #include <cstdint>
  60. #include <type_traits>
  61. #include <utility>
  62. #include <stdexcept>
  63.  
  64. /* Does this C++ version have the C++ <=> starship operator ? */
  65. #if __cplusplus >= 202002L
  66. #include <compare>
  67. #define ROV_HAS_SPACESHIP 1
  68. #endif /* __cplusplus >= 202002L */
  69.  
  70. /* Do we need |constexpr| to avoid the wrath of the professor ? */
  71. #if __cplusplus >= 201402L
  72. #define ROV_CXX14_CONSTEXPR constexpr
  73. #else
  74. #define ROV_CXX14_CONSTEXPR
  75. #endif /* __cplusplus >= 201402L */
  76.  
  77. template <typename T>
  78. class rov_int_template {
  79. #if 1
  80.         /* Compile-time check to prevent abuse */
  81.         static_assert(std::is_integral<T>::value, "rov_int_template: Type must be an integer");
  82. #endif
  83.  
  84. protected:
  85. #ifdef ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING
  86.         long debug_cloaking_pad0 = 0xDEADBEEF;
  87. #endif /* ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING */
  88.         T value_;
  89. #ifdef ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING
  90.         long debug_cloaking_pad1 = 0x12345678;
  91. #endif /* ROV_INT_BUILD_TEST_RAW_VALUE_CLOAKING_PADDING */
  92.  
  93. public:
  94.         /* FIXME: Perf issue ? */
  95.         constexpr rov_int_template() : value_(0) {
  96.         }
  97.  
  98.         template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
  99.         constexpr rov_int_template(U v) : value_(static_cast<T>(v)) {
  100.         }
  101.  
  102.         template <typename U>
  103.         constexpr rov_int_template(const rov_int_template<U>& other) : value_(static_cast<T>(other.get())) {
  104.         }
  105.  
  106.         constexpr T get() const {
  107.                 return value_;
  108.         }
  109.  
  110.         constexpr operator T() const {
  111.                 return value_;
  112.         }
  113.  
  114.         template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
  115.         ROV_CXX14_CONSTEXPR rov_int_template& operator=(U v) {
  116.                 value_ = static_cast<T>(v);
  117.                 return *this;
  118.         }
  119.  
  120.         template <typename U>
  121.         ROV_CXX14_CONSTEXPR rov_int_template& operator=(const rov_int_template<U>& other) {
  122.                 value_ = static_cast<T>(other.get());
  123.                 return *this;
  124.         }
  125.  
  126.         constexpr rov_int_template<decltype(+std::declval<T>())> operator+() const {
  127.                 return rov_int_template<decltype(+std::declval<T>())>(+value_);
  128.         }
  129.        
  130.         constexpr rov_int_template<decltype(-std::declval<T>())> operator-() const {
  131.                 return rov_int_template<decltype(-std::declval<T>())>(-value_);
  132.         }
  133.        
  134.         constexpr rov_int_template<decltype(~std::declval<T>())> operator~() const {
  135.                 return rov_int_template<decltype(~std::declval<T>())>(~value_);
  136.         }
  137.  
  138.         constexpr bool operator!() const {
  139.                 return !value_;
  140.         }
  141.  
  142.         ROV_CXX14_CONSTEXPR rov_int_template& operator++() {
  143.                 ++value_;
  144.                 return *this;
  145.         }
  146.         ROV_CXX14_CONSTEXPR rov_int_template operator++(int) {
  147.                 rov_int_template tmp(*this);
  148.                 ++value_;
  149.                 return tmp;
  150.         }
  151.  
  152.         ROV_CXX14_CONSTEXPR rov_int_template& operator--() {
  153.                 --value_;
  154.                 return *this;
  155.         }
  156.         ROV_CXX14_CONSTEXPR rov_int_template operator--(int) {
  157.                 rov_int_template tmp(*this);
  158.                 --value_;
  159.                 return tmp;
  160.         }
  161.  
  162. #define ROV_MEMBER_BINOP(OP) \
  163.         template <typename U> \
  164.         constexpr rov_int_template<decltype(std::declval<T>() OP std::declval<U>())> operator OP(const rov_int_template<U>& rhs) const { \
  165.                 return rov_int_template<decltype(std::declval<T>() OP std::declval<U>())>(value_ OP rhs.get()); \
  166.         } \
  167.         template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> \
  168.         constexpr rov_int_template<decltype(std::declval<T>() OP std::declval<U>())> operator OP(U rhs) const { \
  169.                 return rov_int_template<decltype(std::declval<T>() OP std::declval<U>())>(value_ OP rhs); \
  170.         }
  171.  
  172.         ROV_MEMBER_BINOP(+)
  173.         ROV_MEMBER_BINOP(-)
  174.         ROV_MEMBER_BINOP(*)
  175. #ifdef ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO
  176.         /* division operator */
  177.         template <typename U>
  178.         constexpr rov_int_template<decltype(std::declval<T>() / std::declval<U>())> operator /(const rov_int_template<U>& rhs) const {
  179.                 if (rhs.get() == 0)
  180.                         throw std::runtime_error("ERROR division by zero");
  181.                 return rov_int_template<decltype(std::declval<T>() / std::declval<U>())>(value_ / rhs.get());
  182.         }
  183.  
  184.         template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
  185.         constexpr rov_int_template<decltype(std::declval<T>() / std::declval<U>())> operator /(U rhs) const {
  186.                 if (rhs == 0)
  187.                         throw std::runtime_error("ERROR division by zero");
  188.                 return rov_int_template<decltype(std::declval<T>() / std::declval<U>())>(value_ / rhs);
  189.         }
  190.  
  191.         /* Modulo operator */
  192.         template <typename U>
  193.         constexpr rov_int_template<decltype(std::declval<T>() % std::declval<U>())> operator %(const rov_int_template<U>& rhs) const {
  194.                 if (rhs.get() == 0)
  195.                         throw std::runtime_error("ERROR modulo by zero");
  196.                 return rov_int_template<decltype(std::declval<T>() % std::declval<U>())>(value_ % rhs.get());
  197.         }
  198.         template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
  199.         constexpr rov_int_template<decltype(std::declval<T>() % std::declval<U>())> operator %(U rhs) const {
  200.                 if (rhs == 0)
  201.                         throw std::runtime_error("ERROR modulo by zero");
  202.                 return rov_int_template<decltype(std::declval<T>() % std::declval<U>())>(value_ % rhs);
  203.         }
  204. #else
  205.         ROV_MEMBER_BINOP(/)
  206.         ROV_MEMBER_BINOP(%)
  207. #endif /* ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO */
  208.         ROV_MEMBER_BINOP(<<)
  209.         ROV_MEMBER_BINOP(>>)
  210.         ROV_MEMBER_BINOP(|)
  211.         ROV_MEMBER_BINOP(&)
  212.         ROV_MEMBER_BINOP(^)
  213. #undef ROV_MEMBER_BINOP
  214.  
  215. #define ROV_MEMBER_COMPOUND_OP(OP) \
  216.         template <typename U> \
  217.         ROV_CXX14_CONSTEXPR rov_int_template& operator OP(const rov_int_template<U>& rhs) { \
  218.                 value_ OP rhs.get(); \
  219.                 return *this; \
  220.         } \
  221.         template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> \
  222.         ROV_CXX14_CONSTEXPR rov_int_template& operator OP(U rhs) { \
  223.                 value_ OP rhs; \
  224.                 return *this; \
  225.         }
  226.  
  227.         ROV_MEMBER_COMPOUND_OP(+=)
  228.         ROV_MEMBER_COMPOUND_OP(-=)
  229.         ROV_MEMBER_COMPOUND_OP(*=)
  230. #ifdef ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO
  231.         template <typename U>
  232.         ROV_CXX14_CONSTEXPR rov_int_template& operator /=(const rov_int_template<U>& rhs) {
  233.                 if (rhs.get() == 0)
  234.                         throw std::runtime_error("ERROR division by zero");
  235.                 value_ /= rhs.get();
  236.                 return *this;
  237.         }
  238.         template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
  239.         ROV_CXX14_CONSTEXPR rov_int_template& operator /=(U rhs) {
  240.                 if (rhs == 0)
  241.                         throw std::runtime_error("ERROR modulo by zero");
  242.                 value_ /= rhs;
  243.                 return *this;
  244.         }
  245.  
  246.         /* Modulo operator */
  247.         template <typename U>
  248.         ROV_CXX14_CONSTEXPR rov_int_template& operator %=(const rov_int_template<U>& rhs) {
  249.                 if (rhs.get() == 0)
  250.                         throw std::runtime_error("ERROR modulo by zero");
  251.                 value_ %= rhs.get();
  252.                 return *this;
  253.         }
  254.         template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
  255.         ROV_CXX14_CONSTEXPR rov_int_template& operator %=(U rhs) {
  256.                 if (rhs == 0)
  257.                         throw std::runtime_error("ERROR modulo by zero");
  258.                 value_ %= rhs;
  259.                 return *this;
  260.         }
  261. #else
  262.         ROV_MEMBER_COMPOUND_OP(/=)
  263.         ROV_MEMBER_COMPOUND_OP(%=)
  264. #endif /* ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO */
  265.         ROV_MEMBER_COMPOUND_OP(<<=)
  266.         ROV_MEMBER_COMPOUND_OP(>>=)
  267.         ROV_MEMBER_COMPOUND_OP(|=)
  268.         ROV_MEMBER_COMPOUND_OP(&=)
  269.         ROV_MEMBER_COMPOUND_OP(^=)
  270. #undef ROV_MEMBER_COMPOUND_OP
  271.  
  272. #ifdef ROV_HAS_SPACESHIP
  273.         template <typename U>
  274.         constexpr auto operator<=>(const rov_int_template<U>& rhs) const {
  275.                 return value_ <=> rhs.get();
  276.         }
  277.         template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
  278.         constexpr auto operator<=>(U rhs) const {
  279.                 return value_ <=> rhs;
  280.         }
  281.         template <typename U>
  282.         constexpr bool operator==(const rov_int_template<U>& rhs) const {
  283.                 return value_ == rhs.get();
  284.         }
  285.         template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type>
  286.         constexpr bool operator==(U rhs) const {
  287.                 return value_ == rhs;
  288.         }
  289. #else
  290. #define ROV_COMP_OP(OP) \
  291.         template <typename U> \
  292.                 constexpr bool operator OP(const rov_int_template<U>& rhs) const { return value_ OP rhs.get(); } \
  293.         template <typename U, typename = typename std::enable_if<std::is_integral<U>::value>::type> \
  294.                 constexpr bool operator OP(U rhs) const { return value_ OP rhs; }
  295.  
  296.         ROV_COMP_OP(==)
  297.         ROV_COMP_OP(!=)
  298.         ROV_COMP_OP(<)
  299.         ROV_COMP_OP(<=)
  300.         ROV_COMP_OP(>)
  301.         ROV_COMP_OP(>=)
  302.  
  303. #undef ROV_COMP_OP
  304. #endif /* ROV_HAS_SPACESHIP */
  305. };
  306.  
  307. #define ROV_NONMEMBER_BINOP(OP) \
  308.         template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type> \
  309.         constexpr rov_int_template<decltype(std::declval<U>() OP std::declval<T>())> operator OP(U lhs, const rov_int_template<T>& rhs) { \
  310.                 return rov_int_template<decltype(std::declval<U>() OP std::declval<T>())>(lhs OP rhs.get()); \
  311.         }
  312.  
  313.         ROV_NONMEMBER_BINOP(+)
  314.         ROV_NONMEMBER_BINOP(-)
  315.         ROV_NONMEMBER_BINOP(*)
  316. #ifdef ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO
  317.         /* Division operator */
  318.         template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type>
  319.         constexpr rov_int_template<decltype(std::declval<U>() / std::declval<T>())> operator /(U lhs, const rov_int_template<T>& rhs) {
  320.                 if (rhs.get() == 0)
  321.                         throw std::runtime_error("ERROR division by zero");
  322.                 return rov_int_template<decltype(std::declval<U>() / std::declval<T>())>(lhs / rhs.get());
  323.         }
  324.  
  325.         /* Modulo operator */
  326.         template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type>
  327.         constexpr rov_int_template<decltype(std::declval<U>() % std::declval<T>())> operator %(U lhs, const rov_int_template<T>& rhs) {
  328.                 if (rhs.get() == 0)
  329.                         throw std::runtime_error("ERROR modulo by zero");
  330.                 return rov_int_template<decltype(std::declval<U>() % std::declval<T>())>(lhs % rhs.get());
  331.         }
  332. #else
  333.         ROV_NONMEMBER_BINOP(/)
  334.         ROV_NONMEMBER_BINOP(%)
  335. #endif /* ROV_INT_BUILD_THROW_EXCEPTION_DIVMODULO_BY_ZERO */
  336.         ROV_NONMEMBER_BINOP(<<)
  337.         ROV_NONMEMBER_BINOP(>>)
  338.         ROV_NONMEMBER_BINOP(|)
  339.         ROV_NONMEMBER_BINOP(&)
  340.         ROV_NONMEMBER_BINOP(^)
  341.  
  342. #undef ROV_NONMEMBER_BINOP
  343.  
  344. #ifndef ROV_HAS_SPACESHIP
  345. #define ROV_NONMEMBER_COMP_OP(OP) \
  346.         template <typename U, typename T, typename = typename std::enable_if<std::is_integral<U>::value>::type> \
  347.                 constexpr bool operator OP(U lhs, const rov_int_template<T>& rhs) { return lhs OP rhs.get(); }
  348.  
  349.         ROV_NONMEMBER_COMP_OP(==)
  350.         ROV_NONMEMBER_COMP_OP(!=)
  351.         ROV_NONMEMBER_COMP_OP(<)
  352.         ROV_NONMEMBER_COMP_OP(<=)
  353.         ROV_NONMEMBER_COMP_OP(>)
  354.         ROV_NONMEMBER_COMP_OP(>=)
  355. #undef ROV_NONMEMBER_COMP_OP
  356. #endif /* !ROV_HAS_SPACESHIP */
  357.  
  358. #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