#pragma once /////////////////////////////////////////////////////////////// // Distributed under the Boost Software License, Version 1.0. // (See at http://www.boost.org/LICENSE_1_0.txt) /////////////////////////////////////////////////////////////// /* Divide and multiply * * * Copyright (c) 2008 * Evan Teran * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appears in all copies and that both the * copyright notice and this permission notice appear in supporting * documentation, and that the same name not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. We make no representations about the * suitability this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include // CHAR_BIT #include #include #include #include namespace std { template class wide_integer; template struct common_type, wide_integer>; template struct common_type, Arithmetic>; template struct common_type>; template class wide_integer { public: using base_type = uint8_t; using signed_base_type = int8_t; // ctors wide_integer() = default; template constexpr wide_integer(T rhs) noexcept; template constexpr wide_integer(std::initializer_list il) noexcept; // assignment template constexpr wide_integer & operator=(const wide_integer & rhs) noexcept; template constexpr wide_integer & operator=(Arithmetic rhs) noexcept; template constexpr wide_integer & operator*=(const Arithmetic & rhs); template constexpr wide_integer & operator/=(const Arithmetic & rhs); template constexpr wide_integer & operator+=(const Arithmetic & rhs) noexcept(is_same::value); template constexpr wide_integer & operator-=(const Arithmetic & rhs) noexcept(is_same::value); template constexpr wide_integer & operator%=(const Integral & rhs); template constexpr wide_integer & operator&=(const Integral & rhs) noexcept; template constexpr wide_integer & operator|=(const Integral & rhs) noexcept; template constexpr wide_integer & operator^=(const Integral & rhs) noexcept; constexpr wide_integer & operator<<=(int n); constexpr wide_integer & operator>>=(int n) noexcept; constexpr wide_integer & operator++() noexcept(is_same::value); constexpr wide_integer operator++(int) noexcept(is_same::value); constexpr wide_integer & operator--() noexcept(is_same::value); constexpr wide_integer operator--(int) noexcept(is_same::value); // observers constexpr explicit operator bool() const noexcept; template using __integral_not_wide_integer_class = typename std::enable_if::value, T>::type; template > constexpr operator T() const noexcept; constexpr operator long double() const noexcept; constexpr operator double() const noexcept; constexpr operator float() const noexcept; struct _impl; private: template friend class wide_integer; friend class numeric_limits>; friend class numeric_limits>; base_type m_arr[_impl::arr_size]; }; template static constexpr bool ArithmeticConcept() noexcept; template using __only_arithmetic = typename std::enable_if() && ArithmeticConcept()>::type; template static constexpr bool IntegralConcept() noexcept; template using __only_integer = typename std::enable_if() && IntegralConcept()>::type; // Unary operators template constexpr wide_integer operator~(const wide_integer & lhs) noexcept; template constexpr wide_integer operator-(const wide_integer & lhs) noexcept(is_same::value); template constexpr wide_integer operator+(const wide_integer & lhs) noexcept(is_same::value); // Binary operators template std::common_type_t, wide_integer> constexpr operator*(const wide_integer & lhs, const wide_integer & rhs); template > std::common_type_t constexpr operator*(const Arithmetic & rhs, const Arithmetic2 & lhs); template std::common_type_t, wide_integer> constexpr operator/(const wide_integer & lhs, const wide_integer & rhs); template > std::common_type_t constexpr operator/(const Arithmetic & rhs, const Arithmetic2 & lhs); template std::common_type_t, wide_integer> constexpr operator+(const wide_integer & lhs, const wide_integer & rhs); template > std::common_type_t constexpr operator+(const Arithmetic & rhs, const Arithmetic2 & lhs); template std::common_type_t, wide_integer> constexpr operator-(const wide_integer & lhs, const wide_integer & rhs); template > std::common_type_t constexpr operator-(const Arithmetic & rhs, const Arithmetic2 & lhs); template std::common_type_t, wide_integer> constexpr operator%(const wide_integer & lhs, const wide_integer & rhs); template > std::common_type_t constexpr operator%(const Integral & rhs, const Integral2 & lhs); template std::common_type_t, wide_integer> constexpr operator&(const wide_integer & lhs, const wide_integer & rhs); template > std::common_type_t constexpr operator&(const Integral & rhs, const Integral2 & lhs); template std::common_type_t, wide_integer> constexpr operator|(const wide_integer & lhs, const wide_integer & rhs); template > std::common_type_t constexpr operator|(const Integral & rhs, const Integral2 & lhs); template std::common_type_t, wide_integer> constexpr operator^(const wide_integer & lhs, const wide_integer & rhs); template > std::common_type_t constexpr operator^(const Integral & rhs, const Integral2 & lhs); // TODO: Integral template constexpr wide_integer operator<<(const wide_integer & lhs, int n) noexcept; template constexpr wide_integer operator>>(const wide_integer & lhs, int n) noexcept; template >> constexpr wide_integer operator<<(const wide_integer & lhs, Int n) noexcept { return lhs << int(n); } template >> constexpr wide_integer operator>>(const wide_integer & lhs, Int n) noexcept { return lhs >> int(n); } template constexpr bool operator<(const wide_integer & lhs, const wide_integer & rhs); template > constexpr bool operator<(const Arithmetic & rhs, const Arithmetic2 & lhs); template constexpr bool operator>(const wide_integer & lhs, const wide_integer & rhs); template > constexpr bool operator>(const Arithmetic & rhs, const Arithmetic2 & lhs); template constexpr bool operator<=(const wide_integer & lhs, const wide_integer & rhs); template > constexpr bool operator<=(const Arithmetic & rhs, const Arithmetic2 & lhs); template constexpr bool operator>=(const wide_integer & lhs, const wide_integer & rhs); template > constexpr bool operator>=(const Arithmetic & rhs, const Arithmetic2 & lhs); template constexpr bool operator==(const wide_integer & lhs, const wide_integer & rhs); template > constexpr bool operator==(const Arithmetic & rhs, const Arithmetic2 & lhs); template constexpr bool operator!=(const wide_integer & lhs, const wide_integer & rhs); template > constexpr bool operator!=(const Arithmetic & rhs, const Arithmetic2 & lhs); template std::string to_string(const wide_integer & n); template struct hash>; } #include "wide_integer_impl.h"