This documentation is automatically generated by online-judge-tools/verification-helper
#include "src/algebra/extended.hpp"
#pragma once
/**
* @file extended.hpp
* @brief Extended Numeric Type
*/
#include <cstdint>
#include <type_traits>
#include "lib/cxx17"
namespace workspace {
template <class _Tp> constexpr auto sign_of(const _Tp &__x) noexcept {
return __x != _Tp(0) ? (__x > _Tp(0) ? +1 : -1) : 0;
}
// Extended numeric type.
template <class _Tp> class extended {
bool infinite{};
int_least8_t sign{}; // in {0, +1, -1}
_Tp value{}; // is 0 if infinite
template <class _Os>
friend _Os &operator<<(_Os &__os, const extended &__x) noexcept {
return __x.infinite ? __os << (__x.sign > 0 ? '+' : '-') << "infinity"
: __os << __x.value;
}
friend std::istream &operator>>(std::istream &__is, extended &__x) noexcept {
__x.infinite = false;
__is >> __x.value;
__x.sign = sign_of(__x.value);
return __is;
}
constexpr extended(bool __x, int_least8_t __y, const _Tp &__z) noexcept
: infinite(__x), sign(__y), value(__z) {}
public:
constexpr static extended infinity{true, +1, 0};
constexpr extended() noexcept {}
constexpr extended(const _Tp &__x) noexcept
: sign(sign_of(__x)), value(__x) {}
constexpr std::enable_if_t<std::is_swappable<_Tp>::value> swap(
extended &__x) noexcept {
std::swap(infinite, __x.infinite);
std::swap(sign, __x.sign);
std::swap(value, __x.value);
}
template <class _U> constexpr operator _U const &() const noexcept {
if _CXX17_CONSTEXPR (std::is_same_v<_U, bool>) return sign;
return value;
}
template <class _U> constexpr operator _U() const noexcept {
if _CXX17_CONSTEXPR (std::is_same_v<_U, bool>) return sign;
return value;
}
constexpr extended operator+() const noexcept { return *this; }
constexpr extended operator-() const noexcept {
return extended(infinite, -sign, -value);
}
constexpr extended &operator+=(const extended &__x) noexcept {
if (__x.infinite) return *this = __x;
return operator+=(__x.value);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended &>
operator+=(const _U &__x) noexcept {
if (!infinite) sign = sign_of(value += __x);
return *this;
}
constexpr extended &operator-=(const extended &__x) noexcept {
return operator+=(-__x);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended &>
operator-=(const _U &__x) noexcept {
return operator+=(-__x);
}
constexpr extended &operator*=(const extended &__x) noexcept {
if (sign *= __x.sign)
infinite = infinite || __x.infinite, value *= __x.value;
else
infinite = false, value = 0;
return *this;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended &>
operator*=(const _U &__x) noexcept {
if (sign *= sign_of(__x))
value *= __x;
else
infinite = false, value = 0;
return *this;
}
constexpr extended &operator/=(const extended &__x) noexcept {
if (__x.infinite)
infinite = false, sign = 0, value = 0;
else if (__x.sign)
(value /= __x.value) ? sign *= __x.sign : sign = 0;
else
infinite = true, value = 0;
return *this;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended &>
operator/=(const _U &__x) noexcept {
auto __s = sign_of(__x);
if (__s)
(value /= __x) ? sign *= __s : sign = 0;
else
infinite = true, value = 0;
return *this;
}
constexpr extended &operator%=(const extended &__x) noexcept {
if (!__x.infinite) sign = sign_of(value %= __x);
return *this;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended &>
operator%=(const _U &__x) noexcept {
sign = sign_of(value %= __x);
return *this;
}
constexpr extended operator+(const extended &__x) const noexcept {
return extended(*this) += __x;
}
constexpr extended operator-(const extended &__x) const noexcept {
return extended(*this) -= __x;
}
constexpr extended operator*(const extended &__x) const noexcept {
return extended(*this) *= __x;
}
constexpr extended operator/(const extended &__x) const noexcept {
return extended(*this) /= __x;
}
constexpr extended operator%(const extended &__x) const noexcept {
return extended(*this) %= __x;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended>
operator+(const _U &__x) const noexcept {
return extended(*this) += __x;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended>
operator-(const _U &__x) const noexcept {
return extended(*this) -= __x;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended>
operator*(const _U &__x) const noexcept {
return extended(*this) *= __x;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended>
operator/(const _U &__x) const noexcept {
return extended(*this) /= __x;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended>
operator%(const _U &__x) const noexcept {
return extended(*this) %= __x;
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value,
extended>
operator+(const _U &__x, const extended &__y) noexcept {
return extended(__x) += __y;
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value,
extended>
operator-(const _U &__x, const extended &__y) noexcept {
return extended(__x) -= __y;
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value,
extended>
operator*(const _U &__x, const extended &__y) noexcept {
return extended(__x) *= __y;
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value,
extended>
operator/(const _U &__x, const extended &__y) noexcept {
return extended(__x) /= __y;
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value,
extended>
operator%(const _U &__x, const extended &__y) noexcept {
return extended(__x) %= __y;
}
constexpr bool operator==(const extended &__x) const noexcept {
return infinite == __x.infinite && sign == __x.sign && value == __x.value;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator==(const _U &__x) const noexcept {
return !infinite && value == static_cast<_Tp>(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator==(const _U &__x, const extended &__y) noexcept {
return __y.operator==(__x);
}
constexpr bool operator!=(const extended &__x) const noexcept {
return !operator==(__x);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator!=(const _U &__x) const noexcept {
return !operator==(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator!=(const _U &__x, const extended &__y) noexcept {
return __y.operator!=(__x);
}
constexpr bool operator<(const extended &__x) const noexcept {
auto __l = sign * infinite, __r = __x.sign * __x.infinite;
return __l != __r ? __l < __r : value < __x.value;
}
constexpr bool operator<=(const extended &__x) const noexcept {
auto __l = sign * infinite, __r = __x.sign * __x.infinite;
return __l != __r ? __l < __r : value <= __x.value;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator<(const _U &__x) const noexcept {
return infinite ? sign < 0 : value < static_cast<_Tp>(__x);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator<=(const _U &__x) const noexcept {
return infinite ? sign < 0 : value <= static_cast<_Tp>(__x);
}
constexpr bool operator>(const extended &__x) const noexcept {
return __x.operator<(*this);
}
constexpr bool operator>=(const extended &__x) const noexcept {
return __x.operator<=(*this);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator>(const _U &__x) const noexcept {
return infinite ? sign > 0 : value > static_cast<_Tp>(__x);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator>=(const _U &__x) const noexcept {
return infinite ? sign > 0 : value >= static_cast<_Tp>(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator<(const _U &__x, const extended &__y) noexcept {
return __y.operator>(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator>(const _U &__x, const extended &__y) noexcept {
return __y.operator<(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator<=(const _U &__x, const extended &__y) noexcept {
return __y.operator>=(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator>=(const _U &__x, const extended &__y) noexcept {
return __y.operator<=(__x);
}
};
} // namespace workspace
#line 2 "src/algebra/extended.hpp"
/**
* @file extended.hpp
* @brief Extended Numeric Type
*/
#include <cstdint>
#include <type_traits>
#line 2 "lib/cxx17"
#line 2 "lib/cxx14"
#ifndef _CXX14_CONSTEXPR
#if __cplusplus >= 201402L
#define _CXX14_CONSTEXPR constexpr
#else
#define _CXX14_CONSTEXPR
#endif
#endif
#line 4 "lib/cxx17"
#ifndef _CXX17_CONSTEXPR
#if __cplusplus >= 201703L
#define _CXX17_CONSTEXPR constexpr
#else
#define _CXX17_CONSTEXPR
#endif
#endif
#ifndef _CXX17_STATIC_ASSERT
#if __cplusplus >= 201703L
#define _CXX17_STATIC_ASSERT static_assert
#else
#define _CXX17_STATIC_ASSERT assert
#endif
#endif
#include <iterator>
#if __cplusplus < 201703L
namespace std {
/**
* @brief Return the size of a container.
* @param __cont Container.
*/
template <typename _Container>
constexpr auto size(const _Container& __cont) noexcept(noexcept(__cont.size()))
-> decltype(__cont.size()) {
return __cont.size();
}
/**
* @brief Return the size of an array.
*/
template <typename _Tp, size_t _Nm>
constexpr size_t size(const _Tp (&)[_Nm]) noexcept {
return _Nm;
}
/**
* @brief Return whether a container is empty.
* @param __cont Container.
*/
template <typename _Container>
[[nodiscard]] constexpr auto empty(const _Container& __cont) noexcept(
noexcept(__cont.empty())) -> decltype(__cont.empty()) {
return __cont.empty();
}
/**
* @brief Return whether an array is empty (always false).
*/
template <typename _Tp, size_t _Nm>
[[nodiscard]] constexpr bool empty(const _Tp (&)[_Nm]) noexcept {
return false;
}
/**
* @brief Return whether an initializer_list is empty.
* @param __il Initializer list.
*/
template <typename _Tp>
[[nodiscard]] constexpr bool empty(initializer_list<_Tp> __il) noexcept {
return __il.size() == 0;
}
struct monostate {};
} // namespace std
#else
#include <variant>
#endif
#line 12 "src/algebra/extended.hpp"
namespace workspace {
template <class _Tp> constexpr auto sign_of(const _Tp &__x) noexcept {
return __x != _Tp(0) ? (__x > _Tp(0) ? +1 : -1) : 0;
}
// Extended numeric type.
template <class _Tp> class extended {
bool infinite{};
int_least8_t sign{}; // in {0, +1, -1}
_Tp value{}; // is 0 if infinite
template <class _Os>
friend _Os &operator<<(_Os &__os, const extended &__x) noexcept {
return __x.infinite ? __os << (__x.sign > 0 ? '+' : '-') << "infinity"
: __os << __x.value;
}
friend std::istream &operator>>(std::istream &__is, extended &__x) noexcept {
__x.infinite = false;
__is >> __x.value;
__x.sign = sign_of(__x.value);
return __is;
}
constexpr extended(bool __x, int_least8_t __y, const _Tp &__z) noexcept
: infinite(__x), sign(__y), value(__z) {}
public:
constexpr static extended infinity{true, +1, 0};
constexpr extended() noexcept {}
constexpr extended(const _Tp &__x) noexcept
: sign(sign_of(__x)), value(__x) {}
constexpr std::enable_if_t<std::is_swappable<_Tp>::value> swap(
extended &__x) noexcept {
std::swap(infinite, __x.infinite);
std::swap(sign, __x.sign);
std::swap(value, __x.value);
}
template <class _U> constexpr operator _U const &() const noexcept {
if _CXX17_CONSTEXPR (std::is_same_v<_U, bool>) return sign;
return value;
}
template <class _U> constexpr operator _U() const noexcept {
if _CXX17_CONSTEXPR (std::is_same_v<_U, bool>) return sign;
return value;
}
constexpr extended operator+() const noexcept { return *this; }
constexpr extended operator-() const noexcept {
return extended(infinite, -sign, -value);
}
constexpr extended &operator+=(const extended &__x) noexcept {
if (__x.infinite) return *this = __x;
return operator+=(__x.value);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended &>
operator+=(const _U &__x) noexcept {
if (!infinite) sign = sign_of(value += __x);
return *this;
}
constexpr extended &operator-=(const extended &__x) noexcept {
return operator+=(-__x);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended &>
operator-=(const _U &__x) noexcept {
return operator+=(-__x);
}
constexpr extended &operator*=(const extended &__x) noexcept {
if (sign *= __x.sign)
infinite = infinite || __x.infinite, value *= __x.value;
else
infinite = false, value = 0;
return *this;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended &>
operator*=(const _U &__x) noexcept {
if (sign *= sign_of(__x))
value *= __x;
else
infinite = false, value = 0;
return *this;
}
constexpr extended &operator/=(const extended &__x) noexcept {
if (__x.infinite)
infinite = false, sign = 0, value = 0;
else if (__x.sign)
(value /= __x.value) ? sign *= __x.sign : sign = 0;
else
infinite = true, value = 0;
return *this;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended &>
operator/=(const _U &__x) noexcept {
auto __s = sign_of(__x);
if (__s)
(value /= __x) ? sign *= __s : sign = 0;
else
infinite = true, value = 0;
return *this;
}
constexpr extended &operator%=(const extended &__x) noexcept {
if (!__x.infinite) sign = sign_of(value %= __x);
return *this;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended &>
operator%=(const _U &__x) noexcept {
sign = sign_of(value %= __x);
return *this;
}
constexpr extended operator+(const extended &__x) const noexcept {
return extended(*this) += __x;
}
constexpr extended operator-(const extended &__x) const noexcept {
return extended(*this) -= __x;
}
constexpr extended operator*(const extended &__x) const noexcept {
return extended(*this) *= __x;
}
constexpr extended operator/(const extended &__x) const noexcept {
return extended(*this) /= __x;
}
constexpr extended operator%(const extended &__x) const noexcept {
return extended(*this) %= __x;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended>
operator+(const _U &__x) const noexcept {
return extended(*this) += __x;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended>
operator-(const _U &__x) const noexcept {
return extended(*this) -= __x;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended>
operator*(const _U &__x) const noexcept {
return extended(*this) *= __x;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended>
operator/(const _U &__x) const noexcept {
return extended(*this) /= __x;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, extended>
operator%(const _U &__x) const noexcept {
return extended(*this) %= __x;
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value,
extended>
operator+(const _U &__x, const extended &__y) noexcept {
return extended(__x) += __y;
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value,
extended>
operator-(const _U &__x, const extended &__y) noexcept {
return extended(__x) -= __y;
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value,
extended>
operator*(const _U &__x, const extended &__y) noexcept {
return extended(__x) *= __y;
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value,
extended>
operator/(const _U &__x, const extended &__y) noexcept {
return extended(__x) /= __y;
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value,
extended>
operator%(const _U &__x, const extended &__y) noexcept {
return extended(__x) %= __y;
}
constexpr bool operator==(const extended &__x) const noexcept {
return infinite == __x.infinite && sign == __x.sign && value == __x.value;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator==(const _U &__x) const noexcept {
return !infinite && value == static_cast<_Tp>(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator==(const _U &__x, const extended &__y) noexcept {
return __y.operator==(__x);
}
constexpr bool operator!=(const extended &__x) const noexcept {
return !operator==(__x);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator!=(const _U &__x) const noexcept {
return !operator==(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator!=(const _U &__x, const extended &__y) noexcept {
return __y.operator!=(__x);
}
constexpr bool operator<(const extended &__x) const noexcept {
auto __l = sign * infinite, __r = __x.sign * __x.infinite;
return __l != __r ? __l < __r : value < __x.value;
}
constexpr bool operator<=(const extended &__x) const noexcept {
auto __l = sign * infinite, __r = __x.sign * __x.infinite;
return __l != __r ? __l < __r : value <= __x.value;
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator<(const _U &__x) const noexcept {
return infinite ? sign < 0 : value < static_cast<_Tp>(__x);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator<=(const _U &__x) const noexcept {
return infinite ? sign < 0 : value <= static_cast<_Tp>(__x);
}
constexpr bool operator>(const extended &__x) const noexcept {
return __x.operator<(*this);
}
constexpr bool operator>=(const extended &__x) const noexcept {
return __x.operator<=(*this);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator>(const _U &__x) const noexcept {
return infinite ? sign > 0 : value > static_cast<_Tp>(__x);
}
template <class _U>
constexpr std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator>=(const _U &__x) const noexcept {
return infinite ? sign > 0 : value >= static_cast<_Tp>(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator<(const _U &__x, const extended &__y) noexcept {
return __y.operator>(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator>(const _U &__x, const extended &__y) noexcept {
return __y.operator<(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator<=(const _U &__x, const extended &__y) noexcept {
return __y.operator>=(__x);
}
template <class _U>
constexpr friend std::enable_if_t<std::is_convertible<_U, _Tp>::value, bool>
operator>=(const _U &__x, const extended &__y) noexcept {
return __y.operator<=(__x);
}
};
} // namespace workspace