.. _program_listing_file_src_rdf4cpp_util_CheckedInt.hpp: Program Listing for File CheckedInt.hpp ======================================= |exhale_lsh| :ref:`Return to documentation for file ` (``src/rdf4cpp/util/CheckedInt.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef RDF4CPP_CHECKEDINT_HPP #define RDF4CPP_CHECKEDINT_HPP namespace rdf4cpp::util { template struct CheckedIntegral { private: I value; bool invalid = false; public: constexpr CheckedIntegral(I value, bool invalid = false) noexcept : value(value), invalid(invalid) {} [[nodiscard]]constexpr bool is_invalid() const noexcept { return invalid; } [[nodiscard]]constexpr I get_value() const noexcept { return value; } constexpr std::partial_ordering operator<=>(const CheckedIntegral &other) const noexcept { if (this->invalid && other.invalid) return std::partial_ordering::equivalent; if (this->invalid != other.invalid) return std::partial_ordering::unordered; return this->value <=> other.value; } constexpr CheckedIntegral &operator+=(const CheckedIntegral &other) noexcept { this->invalid |= other.invalid; this->invalid |= __builtin_add_overflow(this->value, other.value, &this->value); return *this; } constexpr CheckedIntegral operator+(const CheckedIntegral &other) const noexcept { CheckedIntegral r = *this; r += other; return r; } constexpr CheckedIntegral &operator-=(const CheckedIntegral &other) noexcept { this->invalid |= other.invalid; this->invalid |= __builtin_sub_overflow(this->value, other.value, &this->value); return *this; } constexpr CheckedIntegral operator-(const CheckedIntegral &other) const noexcept { CheckedIntegral r = *this; r -= other; return r; } constexpr CheckedIntegral &operator*=(const CheckedIntegral &other) noexcept { this->invalid |= other.invalid; this->invalid |= __builtin_mul_overflow(this->value, other.value, &this->value); return *this; } constexpr CheckedIntegral operator*(const CheckedIntegral &other) const noexcept { CheckedIntegral r = *this; r *= other; return r; } constexpr CheckedIntegral &operator/=(const CheckedIntegral &other) noexcept { if (this->invalid || other.invalid || other.value == 0) { this->invalid = true; return *this; } this->value = this->value / other.value; return *this; } constexpr CheckedIntegral operator/(const CheckedIntegral &other) const noexcept { CheckedIntegral r = *this; r /= other; return r; } friend constexpr CheckedIntegral abs(CheckedIntegral const &val) noexcept { if constexpr (std::is_unsigned_v) { return val; } else { if (val.value >= 0) { return val; } CheckedIntegral ret{0, val.invalid}; ret.invalid |= __builtin_sub_overflow(0, val.value, &ret.value); return ret; } } }; } // namespace rdf4cpp::util #endif //RDF4CPP_CHECKEDINT_HPP