/* * Copyright 2015 - 2022 gary@drinkingtea.net * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once #include "types.hpp" namespace ox { struct BaseInteger { constexpr BaseInteger() noexcept = default; constexpr BaseInteger(const BaseInteger&) noexcept { } constexpr BaseInteger operator=(const BaseInteger&) noexcept { return *this; } }; /** * Integer is a strongly typed integer wrapper used to create strongly typed * integers. */ template class Integer: public Base { private: T m_i; public: constexpr Integer() noexcept = default; constexpr explicit Integer(T i) noexcept; constexpr Integer(const Integer &i) noexcept; constexpr Integer operator=(Integer i) noexcept; constexpr Integer operator==(Integer i) const noexcept; constexpr Integer operator!=(Integer i) const noexcept; constexpr Integer operator<(Integer i) const noexcept; constexpr Integer operator>(Integer i) const noexcept; constexpr Integer operator<=(Integer i) const noexcept; constexpr Integer operator>=(Integer i) const noexcept; constexpr Integer operator+(Integer i) const noexcept; constexpr Integer operator+=(Integer i) noexcept; constexpr Integer operator-(Integer i) const noexcept; constexpr Integer operator-=(Integer i) noexcept; constexpr Integer operator*(Integer i) const noexcept; constexpr Integer operator*=(Integer i) noexcept; constexpr Integer operator/(Integer i) const noexcept; constexpr Integer operator/=(Integer i) noexcept; constexpr Integer operator%(Integer i) const noexcept; constexpr Integer operator%=(Integer i) noexcept; constexpr Integer operator>>(int i) const noexcept; constexpr Integer operator>>=(int i) noexcept; constexpr Integer operator<<(int i) const noexcept; constexpr Integer operator<<=(int i) noexcept; constexpr Integer operator|(Integer i) const noexcept; constexpr Integer operator|=(Integer i) noexcept; constexpr Integer operator&(Integer i) const noexcept; constexpr Integer operator&=(Integer i) noexcept; constexpr Integer operator^(Integer i) const noexcept; constexpr Integer operator^=(Integer i) noexcept; constexpr Integer operator~() const noexcept; // Prefix increment constexpr Integer operator++() noexcept; // Postfix increment constexpr Integer operator++(int) noexcept; // Prefix decrement constexpr Integer operator--() noexcept; // Postfix decrement constexpr Integer operator--(int) noexcept; constexpr explicit operator T() const noexcept; constexpr operator bool() const noexcept; }; template constexpr Integer::Integer(T i) noexcept { m_i = i; } template constexpr Integer::Integer(const Integer &i) noexcept: Base(i), m_i(i.m_i) { } template constexpr Integer Integer::operator=(Integer i) noexcept { // needed in case T has nodiscard constexpr auto ignore = [](Base) {}; ignore(Base::operator=(i)); m_i = i.m_i; return *this; } template constexpr Integer Integer::operator==(Integer i) const noexcept { return Integer(m_i == i.m_i); } template constexpr Integer Integer::operator!=(Integer i) const noexcept { return Integer(m_i != i.m_i); } template constexpr Integer Integer::operator<(Integer i) const noexcept { return Integer(m_i < i.m_i); } template constexpr Integer Integer::operator>(Integer i) const noexcept { return Integer(m_i > i.m_i); } template constexpr Integer Integer::operator<=(Integer i) const noexcept { return Integer(m_i <= i.m_i); } template constexpr Integer Integer::operator>=(Integer i) const noexcept { return Integer(m_i >= i.m_i); } template constexpr Integer Integer::operator+(Integer i) const noexcept { return Integer(m_i + i.m_i); } template constexpr Integer Integer::operator+=(Integer i) noexcept { return Integer(m_i += i.m_i); } template constexpr Integer Integer::operator-(Integer i) const noexcept { return Integer(m_i - i.m_i); } template constexpr Integer Integer::operator-=(Integer i) noexcept { return Integer(m_i -= i.m_i); } template constexpr Integer Integer::operator*(Integer i) const noexcept { return Integer(m_i * i.m_i); } template constexpr Integer Integer::operator*=(Integer i) noexcept { return Integer(m_i *= i.m_i); } template constexpr Integer Integer::operator/(Integer i) const noexcept { return Integer(m_i / i.m_i); } template constexpr Integer Integer::operator/=(Integer i) noexcept { return Integer(m_i /= i.m_i); } template constexpr Integer Integer::operator%(Integer i) const noexcept { return Integer(m_i % i.m_i); } template constexpr Integer Integer::operator%=(Integer i) noexcept { return Integer(m_i %= i.m_i); } template constexpr Integer Integer::operator>>(int i) const noexcept { return Integer(m_i >> i); } template constexpr Integer Integer::operator>>=(int i) noexcept { return Integer(m_i >>= i); } template constexpr Integer Integer::operator<<(int i) const noexcept { return Integer(m_i << i); } template constexpr Integer Integer::operator<<=(int i) noexcept { return Integer(m_i <<= i); } template constexpr Integer Integer::operator|(Integer i) const noexcept { return Integer(m_i | i.m_i); } template constexpr Integer Integer::operator|=(Integer i) noexcept { return Integer(m_i |= i.m_i); } template constexpr Integer Integer::operator&(Integer i) const noexcept { return Integer(m_i & i.m_i); } template constexpr Integer Integer::operator&=(Integer i) noexcept { return Integer(m_i &= i.m_i); } template constexpr Integer Integer::operator^(Integer i) const noexcept { return Integer(m_i ^ i.m_i); } template constexpr Integer Integer::operator^=(Integer i) noexcept { return Integer(m_i ^= i.m_i); } template constexpr inline Integer Integer::operator~() const noexcept { return Integer(~m_i); } // Prefix increment template constexpr inline Integer Integer::operator++() noexcept { return Integer(++m_i); } // Postfix increment template constexpr inline Integer Integer::operator++(int) noexcept { return Integer(m_i++); } // Prefix decrement template constexpr inline Integer Integer::operator--() noexcept { return Integer(--m_i); } // Postfix decrement template constexpr inline Integer Integer::operator--(int) noexcept { return Integer(m_i--); } template constexpr Integer::operator T() const noexcept { return m_i; } template constexpr Integer::operator bool() const noexcept { return m_i; } using Int8 = Integer; using Int16 = Integer; using Int32 = Integer; using Int64 = Integer; using Uint8 = Integer; using Uint16 = Integer; using Uint32 = Integer; using Uint64 = Integer; }