<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
        <title>A Proposal to add wide_int Class</title>
        <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
        <meta http-equiv="Content-Language" content="en-us">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

        <style type="text/css">
            .addition { color: green; }
            .right { float:right; }
            pre { line-height: 1.2; font-size: 10pt; margin-top: 25px;}
            .desc { margin-left: 35px; margin-top: 10px; padding:0; white-space: normal; }
            body {max-width: 1024px; margin-left: 25px;}
            .cppkeyword { color: blue; }
            .cppcomment { color: green; }
            .cppcomment > .cppkeyword{ color: green; }
            .cpptext { color: #2E8B57; }
        </style>
    </head>
    <body bgcolor="#ffffff">
        <address>Document number: P0539R0</address>
        <address>Project: Programming Language C++</address>
        <address>Audience: SG6 Numerics</address>
        <address>&nbsp;</address>
        <address>Igor Klevanets &lt;<a href="mailto:cerevra@yandex.ru">cerevra@yandex.ru</a>&gt;, &lt;<a href="mailto:cerevra@yandex-team.ru">cerevra@yandex-team.ru</a>&gt;</address>
        <address>Antony Polukhin &lt;<a href="mailto:antoshkka@gmail.com">antoshkka@gmail.com</a>&gt;, &lt;<a href="mailto:antoshkka@yandex-team.ru">antoshkka@yandex-team.ru</a>&gt;</address>
        <address>&nbsp;</address>
        <address>Date: 2017-01-28</address>
        <h1>A Proposal to add wide_int Template Class</h1>

        <h2>I. Introduction and Motivation</h2>
        <p>Current standard provides signed and unsigned int8_t, int16_t, int32_t, int64_t. It is usually enough for every day tasks, but sometimes appears a need in big numbers: for cryptography, IPv6, very big counters etc. Non-standard type __int128 which is provided by gcc and clang illuminates this need. But there is no cross-platform solution and no way to satisfy future needs in even more big numbers.</p>
        <p>This is an attempt to solve the problem in a generic way on a library level and provide wording for <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0104r0.html">P0104R0: Multi-Word Integer Operations and Types</a>.</p>
        <p>A proof of concept implementation available at: <a href="https://github.com/cerevra/int/tree/master/v2">https://github.com/cerevra/int/tree/master/v2</a>.
        </p>

        <h2>II. P0104R0 and this proposal</h2>
        <p>Differences with P0104R0:</p>
        <ul>
            <li>Template parameters were changed, from <code>int words</code> to <code>size_t Bytes, bool Signed</code> in attempt to make the class less platform dependent (avoid description of "machine word" term and it's size) and in attept to minimize wording size by describing only one class, instead of two.</li>
            <li>Conversion to bool was made explicit to avoid user errors.</li>
            <li>Result of the arithmetic operations is a <code>common_type_t</code> of two types instead of a left-hand side type. This makes the <code>wide_int</code> class behave more close to the built-in types.</li>
        </ul>
        <p>Extensions to P0104R0:</p>
        <ul>
            <li>Added operators to interact with built-in arithmetic types to simplify <code>wide_int</code> class usage.</li>
            <li>Added conversion operators to built-in arithmetic types to simplify usage of the <code>wide_int</code> class with existing code.</li>
            <li>Added literals, hashing, type_traits, numeric_limits and some functions to integrate better with existing code.</li>
        </ul>


        <h2>III. Proposed wording</h2>

<h3>26.??.1 Header &lt;wide_int&gt; synopsis<span class="right">[wide_int.syn]</span></h3>
<pre>namespace std {

  // 26.??.2 class template wide_int
  template&lt;size_t Bytes, bool Signed&gt; class wide_int;

  // 26.??.?? type traits specializations
  template&lt;size_t Bytes, bool Signed&gt; struct is_scalar&lt;wide_int&lt;Bytes, Signed&gt;&gt;: true_type {};
  template&lt;size_t Bytes, bool Signed&gt; struct is_compound&lt;wide_int&lt;Bytes, Signed&gt;&gt;: true_type {};
  template&lt;size_t Bytes, bool Signed&gt; struct is_unsigned&lt;wide_int&lt;Bytes, Signed&gt;&gt;: bool_constant&lt;!Signed&gt; {};
  template&lt;size_t Bytes, bool Signed&gt; struct is_signed&lt;wide_int&lt;Bytes, Signed&gt;&gt;: bool_constant&lt;Signed&gt; {};

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  struct common_type&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;;

  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  struct common_type&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;;

  // 26.??.?? unary operations
  template&lt;size_t Bytes, bool Signed&gt; constexpr wide_int&lt;Bytes, Signed&gt; operator~(const wide_int&lt;Bytes, Signed&gt;&amp; val) noexcept;
  template&lt;size_t Bytes, bool Signed&gt; constexpr wide_int&lt;Bytes, Signed&gt; operator-(const wide_int&lt;Bytes, Signed&gt;&amp; val) noexcept(!Signed);
  template&lt;size_t Bytes, bool Signed&gt; constexpr wide_int&lt;Bytes, Signed&gt; operator+(const wide_int&lt;Bytes, Signed&gt;&amp; val) noexcept(!Signed);

  // 26.??.?? binary operations
  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
    constexpr operator*(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs);
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
    constexpr operator*(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs);
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
    constexpr operator*(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs);

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
    constexpr operator/(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs);
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
    constexpr operator/(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs);
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
    constexpr operator/(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs);

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
    constexpr operator+(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept(!Signed);
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
    constexpr operator+(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept(!Signed);
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
    constexpr operator+(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept(!Signed);

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
    constexpr operator-(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept(!Signed);
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
    constexpr operator-(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept(!Signed);
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
    constexpr operator-(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept(!Signed);

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
    constexpr operator%(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs);
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
    constexpr  operator%(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs);
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
    constexpr operator%(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs);

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
    constexpr operator&amp;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
    constexpr operator&amp;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
    constexpr operator&amp;(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
    constexpr operator|(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
    constexpr operator|(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
    constexpr operator|(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
    constexpr  operator^(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
    constexpr operator^(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
    constexpr operator^(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
    constexpr  operator&lt;&lt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs);
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    constexpr wide_int&lt;Bytes, Signed&gt; operator&lt;&lt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs);
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    constexpr Integral operator&lt;&lt;(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs);

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
    constexpr  operator&gt;&gt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    constexpr wide_int&lt;Bytes, Signed&gt; operator&gt;&gt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Integral&gt;
    constexpr Integral operator&gt;&gt;(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    constexpr bool operator&lt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator&lt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator&lt;(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    constexpr bool operator&gt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator&gt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator&gt;(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    constexpr bool operator&lt;=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator&lt;=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator&lt;=(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    constexpr bool operator&gt;=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator&gt;=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator&gt;=(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    constexpr bool operator==(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator==(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator==(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;

  template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
    constexpr bool operator!=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator!=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
  template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
    constexpr bool operator!=(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;

  // 26.??.?? numeric conversions
  template&lt;size_t Bytes, bool Signed&gt; std::string to_string(const wide_int&lt;Bytes, Signed&gt;&amp; val);
  template&lt;size_t Bytes, bool Signed&gt; std::wstring to_wstring(const wide_int&lt;Bytes, Signed&gt;&amp; val);

  // 26.??.?? iostream specializations
  template&lt;class Char, class Traits, size_t Bytes, bool Signed&gt;
  basic_ostream&lt;Char, Traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;Char, Traits&gt;&amp; os, const wide_int&lt;Bytes, Signed&gt;&amp; val);

  template&lt;class Char, class Traits, size_t Bytes, bool Signed&gt;
  basic_istream&lt;Char, Traits&gt;&amp; operator&gt;&gt;(basic_istream&lt;Char, Traits&gt;&amp; is, wide_int&lt;Bytes, Signed&gt;&amp; val);

  using int128_t  = wide_int&lt;128 / 8,true&gt;;
  using uint128_t = wide_int&lt;128 / 8,false&gt;;

  using int256_t  = wide_int&lt;256 / 8,true&gt;;
  using uint256_t = wide_int&lt;256 / 8,false&gt;;

  using int512_t  = wide_int&lt;512 / 8,true&gt;;
  using uint512_t = wide_int&lt;512 / 8,false&gt;;

  // 26.??.?? hash support
  template&lt;class T&gt; struct hash;
  template&lt;size_t Bytes, bool Signed&gt; struct hash&lt;wide_int&lt;Bytes, Signed&gt;&gt;;

  // 26.??.?? numeric_limits specialization
  template&lt;size_t Bytes, bool Signed&gt; struct numeric_limits&lt;wide_int&lt;Bytes, Signed&gt;&gt;;

  inline namespace literals {
  inline namespace wide_int_literals {

  constexpr int128_t operator &quot;&quot; _int128(const char*);
  constexpr int256_t operator &quot;&quot; _int256(const char*);
  constexpr int512_t operator &quot;&quot; _int512(const char*);
  constexpr uint128_t operator &quot;&quot; _uint128(const char*);
  constexpr uint256_t operator &quot;&quot; _uint256(const char*);
  constexpr uint512_t operator &quot;&quot; _uint512(const char*);

  } // namespace wide_int_literals
  } // namespace literals
}
</pre>
<p>The header &lt;wide_int&gt; defines class template <code>wide_int</code> and a set of operators for representing and manipulating integers of specified width.</p><pre>[Example:
    constexpr int128_t c = std::numeric_limits&lt;int128_t&gt;::min();
    static_assert(c == 0x80000000000000000000000000000000_uint128);

    int256_t a = 13;
    a += 0xFF;
    a *= 2.0;
    a -= 12_int128;
    assert(a &gt; 0);
]</pre>


<h3>26.??.2 Template class wide_int overview<span class="right">[wide_int.overview]</span></h3>
<pre>namespace std {
  template&lt;size_t Bytes, bool Signed&gt;
  class wide_int {
  public:
    // 26.??.2.?? construct:
    constexpr wide_int() noexcept = default;
    template&lt;typename Arithmetic&gt; constexpr wide_int(const Arithmetic&amp; other) noexcept;
    template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int(const wide_int&lt;Bytes2, Signed2&gt;&amp; other) noexcept;

    // 26.??.2.?? assignment:
    template&lt;typename Arithmetic&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator=(const Arithmetic&amp; other) noexcept;
    template&lt;size_t Bytes2, bool Signed2&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator=(const wide_int&lt;Bytes2, Signed2&gt;&amp; other) noexcept;

    // 26.??.2.?? compound assignment:
    template&lt;typename Arithmetic&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator*=(const Arithmetic&amp;);
    template&lt;size_t Bytes2, bool Signed2&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator*=(const wide_int&lt;Bytes2, Signed2&gt;&amp;);

    template&lt;typename Arithmetic&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator/=(const Arithmetic&amp;);
    template&lt;size_t Bytes2, bool Signed2&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator/=(const wide_int&lt;Bytes2, Signed2&gt;&amp;);

    template&lt;typename Arithmetic&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator+=(const Arithmetic&amp;) noexcept(!Signed);
    template&lt;size_t Bytes2, bool Signed2&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator+=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept(!Signed);

    template&lt;typename Arithmetic&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator-=(const Arithmetic&amp;) noexcept(!Signed);
    template&lt;size_t Bytes2, bool Signed2&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator-=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept(!Signed);

    template&lt;typename Integral&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator%=(const Integral&amp;);
    template&lt;size_t Bytes2, bool Signed2&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator%=(const wide_int&lt;Bytes2, Signed2&gt;&amp;);

    template&lt;typename Integral&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&amp;=(const Integral&amp;) noexcept;
    template&lt;size_t Bytes2, bool Signed2&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&amp;=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept;

    template&lt;typename Integral&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator|=(const Integral&amp;) noexcept;
    template&lt;size_t Bytes2, bool Signed2&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator|=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept;

    template&lt;typename Integral&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator^=(const Integral&amp;) noexcept;
    template&lt;size_t Bytes2, bool Signed2&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator^=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept;

    template&lt;typename Integral&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&lt;&lt;=(const Integral&amp;);
    template&lt;size_t Bytes2, bool Signed2&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&lt;&lt;=(const wide_int&lt;Bytes2, Signed2&gt;&amp;);

    template&lt;typename Integral&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&gt;&gt;=(const Integral&amp;) noexcept;
    template&lt;size_t Bytes2, bool Signed2&gt;
    constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&gt;&gt;=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept;

    // 26.??.2.?? observers:
    template &lt;typename Arithmetic&gt; constexpr operator Arithmetic() const noexcept;
    constexpr explicit operator bool() const noexcept;

  private:
    uint32_t data[Bytes / sizeof(uint32_t) + 1]; // exposition only
  };
}</pre>
<p>The class template <code>wide_int&lt;size_t Bytes, bool Signed&gt;</code> is a POD class that behaves as an integer type of a compile time specified width. Template parameter <code>Bytes</code> specifies significant bytes count to store the integer value. <i>[Note:</i> <code>sizeof(wide_int&lt;Bytes, true&gt;)</code> and <code>sizeof(wide_int&lt;Bytes, false&gt;)</code> are not requred to be equal to <code>Bytes</code>. <i>- end note]</i>  Template parameter <code>Signed</code> specifies signedness of the stored integer value.</p>


<h4>26.??.2.?? wide_int constructors <span class="right">[wide_int.cons]</span></h4>
<pre>constexpr wide_int() noexcept = default;</pre>
<div class="desc"><i>Effects:</i> A Constructs an object with undefined value.</div>

<pre>template&lt;typename Arithmetic&gt; constexpr wide_int(const Arithmetic&amp; other) noexcept;</pre>
<div class="desc"><i>Remarks:</i> This function shall not participate in overload resolution unless <code>is_arithmetic_v&lt;Arithmetic&gt;</code> is true.</div>
<div class="desc"><i>Effects:</i> Constructs an object from <code>other</code> using the integral conversion rules [conv.integral].</div>

<pre>template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int(const wide_int&lt;Bytes2, Signed2&gt;&amp; other) noexcept;</pre>
<div class="desc"><i>Effects:</i> Constructs an object from <code>other</code> using the integral conversion rules [conv.integral].</div>

<h4>26.??.2.?? wide_int assignments <span class="right">[wide_int.assign]</span></h4>
<pre>template&lt;typename Arithmetic&gt;
constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator=(const Arithmetic&amp; other) noexcept;</pre>
<div class="desc"><i>Remarks:</i> This function shall not participate in overload resolution unless <code>is_arithmetic_v&lt;Arithmetic&gt;</code> is true.</div>
<div class="desc"><i>Effects:</i> Constructs an object from <code>other</code> using the integral conversion rules [conv.integral].</div>

<pre>template&lt;size_t Bytes2, bool Signed2&gt;
constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator=(const wide_int&lt;Bytes2, Signed2&gt;&amp; other) noexcept;</pre>
<div class="desc"><i>Effects:</i> Constructs an object from <code>other</code> using the integral conversion rules [conv.integral].</div>

<h4>26.??.2.?? wide_int compound assignments <span class="right">[wide_int.cassign]</span></h4>
<pre>template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator*=(const wide_int&lt;Bytes2, Signed2&gt;&amp;);
template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator/=(const wide_int&lt;Bytes2, Signed2&gt;&amp;);
template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator+=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept(!Signed);
template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator-=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept(!Signed);
template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator%=(const wide_int&lt;Bytes2, Signed2&gt;&amp;);
template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&amp;=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept;
template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator|=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept;
template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator^=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept;
template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&lt;&lt;=(const wide_int&lt;Bytes2, Signed2&gt;&amp;);
template&lt;size_t Bytes2, bool Signed2&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&gt;&gt;=(const wide_int&lt;Bytes2, Signed2&gt;&amp;) noexcept;</pre>
<div class="desc"><i>Effects:</i> Behavior of these operators is similar to operators for built-in integral types.</div>

<pre>template&lt;typename Arithmetic&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator*=(const Arithmetic&amp;);
template&lt;typename Arithmetic&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator/=(const Arithmetic&amp;);
template&lt;typename Arithmetic&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator+=(const Arithmetic&amp;) noexcept(!Signed);
template&lt;typename Arithmetic&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator-=(const Arithmetic&amp;) noexcept(!Signed);</pre>
<div class="desc"><i>Remarks:</i> Functions shall not participate in overload resolution unless <code>is_arithmetic_v&lt;Arithmetic&gt;</code> is true.</div>
<div class="desc"><i>Effects:</i> As if an object <code>wi</code> of type <code>wide_int&lt;Bytes, Signed&gt;</code> was created from input value and the corresponding operator was called for <code>*this</code> and the <code>wi</code>.</div>

<pre>template&lt;typename Integral&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator%=(const Integral&amp;);
template&lt;typename Integral&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&amp;=(const Integral&amp;) noexcept;
template&lt;typename Integral&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator|=(const Integral&amp;) noexcept;
template&lt;typename Integral&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator^=(const Integral&amp;) noexcept;
template&lt;typename Integral&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&lt;&lt;=(const Integral&amp;);
template&lt;typename Integral&gt; constexpr wide_int&lt;Bytes, Signed&gt;&amp; operator&gt;&gt;=(const Integral&amp;) noexcept;</pre>
<div class="desc"><i>Remarks:</i> Functions shall not participate in overload resolution unless <code>is_integral_v&lt;Integral&gt;</code> is true.</div>
<div class="desc"><i>Effects:</i> As if an object <code>wi</code> of type <code>wide_int&lt;Bytes, Signed&gt;</code> was created from input value and the corresponding operator was called for <code>*this</code> and the <code>wi</code>.</div>


<h4>26.??.2.?? wide_int observers <span class="right">[wide_int.observers]</span></h4>
<pre>template &lt;typename Arithmetic&gt; constexpr operator Arithmetic() const noexcept;</pre>
<div class="desc"><i>Remarks:</i> This function shall not participate in overload resolution unless <code>is_arithmetic_v&lt;Arithmetic&gt;</code> is true.</div>
<div class="desc"><i>Returns:</i> If <code>Arithmetic</code> type is an integral type then it is constructed from <code>*this</code> using the integral conversion rules [conv.integral]. Otherwise <code>Arithmetic</code> is constructed from <code>*this</code> using the floating-integral conversion rules [conv.fpint].</div>

<pre>constexpr explicit operator bool() const noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>true</code> if <code>*this</code> is not equal to 0.</div>


<h3>26.??.?? Specializations of common_type <span class="right">[wide_int.traits.specializations]</span></h3>
<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
struct common_type&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt; {
  using type = wide_int&lt;max(Bytes, Bytes2), <i>see below</i>&gt;;
};</pre>

<p>The signed template parameter indicated by this specialization is following:</p>
<ul>
  <li><code>(Signed &amp;&amp; Signed2)</code> if <code>Bytes == Bytes2</code></li>
  <li><code>Signed</code> if <code>Bytes > Bytes2</code></li>
  <li><code>Signed2</code> otherwise</li>
</ul>

<pre>template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
struct common_type&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt; {
  using type = <i>see below</i>;
};</pre>

<p>The member typedef <code>type</code> is following:</p>
<ul>
  <li><code>Arithmetic</code> if <code>is_floating_point_v&lt;Arithmetic&gt;</code> is <code>true</code></li>
  <li><code>wide_int&lt;Bytes, Signed&gt;</code> if <code>Bytes &gt; sizeof(Arithmetic)</code></li>
  <li><code>Arithmetic</code> if <code>Bytes &lt; sizeof(Arithmetic)</code></li>
  <li><code>Arithmetic</code> if <code>Bytes == sizeof(Arithmetic) &amp;&amp; Signed</code> or <code>Bytes == sizeof(Arithmetic) &amp;&amp; Signed == is_signed_v&lt;Arithmetic&gt;</code></li>
  <li><code>wide_int&lt;Bytes, Signed&gt;</code> otherwise</li>
</ul>
<div class="desc"><i>Requires:</i> <code>is_arithmetic_v&lt;Arithmetic&gt;</code> is true.</div>


<h3>26.??.?? Unary operators <span class="right">[wide_int.unary_ops]</span></h3>
<pre>template&lt;size_t Bytes, bool Signed&gt; constexpr wide_int&lt;Bytes, Signed&gt; operator~(const wide_int&lt;Bytes, Signed&gt;&amp; val) noexcept;</pre>
<div class="desc"><i>Returns:</i> value with inverted significant bits of <code>val</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed&gt; constexpr wide_int&lt;Bytes, Signed&gt; operator-(const wide_int&lt;Bytes, Signed&gt;&amp; val) noexcept(!Signed);</pre>
<div class="desc"><i>Returns:</i> <code>val *= -1</code> if <code>Signed</code> is true, otherwise the result is unspecified.</div>

<pre>template&lt;size_t Bytes, bool Signed&gt; constexpr wide_int&lt;Bytes, Signed&gt; operator+(const wide_int&lt;Bytes, Signed&gt;&amp; val) noexcept(!Signed);</pre>
<div class="desc"><i>Returns:</i> <code>val</code>.</div>

<h3>26.??.?? Binary operators <span class="right">[wide_int.binary_ops]</span></h3>
<p>In the function descriptions that follow, <code>CT</code> represents <code>common_type_t&lt;A, B&gt;</code>, where <code>A</code> and <code>B</code> are the types of the two arguments to the function.</p>
<p>Functions that accept <code>Integral</code> parameter shall not participate in overload resolution unless <code>is_integral_v&lt;Integral&gt;</code> is true.</p>
<p>Functions that accept <code>Arithmetic</code> parameter shall not participate in overload resolution unless <code>is_arithmetic_v&lt;Arithmetic&gt;</code> is true.</p>
<p><i>[Note:</i> To reduce template instantinations count operators that accept <code>Integral</code> and <code>Arithmetic</code> parameter convert to common type first, as the common type may be a built-in type. <i>- end note]</i></p>

</p>
<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
  constexpr operator*(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) *= rhs</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
  constexpr operator*(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs);
template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
  constexpr operator*(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) * CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
  constexpr operator/(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) /= rhs</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
  constexpr operator/(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs);
template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
  constexpr operator/(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) / CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
  constexpr operator+(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept(!Signed);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) += rhs</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
  constexpr operator+(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept(!Signed);
template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
  constexpr operator+(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept(!Signed);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) + CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
  constexpr operator-(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept(!Signed);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) -= rhs</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
  constexpr operator-(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept(!Signed);
template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Arithmetic&gt;
  constexpr operator-(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept(!Signed);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) - CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
  constexpr operator%(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) %= rhs</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
  constexpr  operator%(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs);
template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
  constexpr operator%(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) % CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
  constexpr operator&amp;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) &amp;= rhs</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
  constexpr operator&amp;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs) noexcept;
template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
  constexpr operator&amp;(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) &amp; CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
  constexpr operator|(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) |= rhs</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
  constexpr operator|(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs) noexcept;
template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
  constexpr operator|(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) | CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
  constexpr  operator^(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) ^= rhs</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
  constexpr operator^(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs) noexcept;
template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, Integral&gt;
  constexpr operator^(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) ^ CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
  constexpr  operator&lt;&lt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) &lt;&lt;= rhs</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  constexpr wide_int&lt;Bytes, Signed&gt; operator&lt;&lt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs);</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) &lt;&lt; CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  constexpr Integral operator&lt;&lt;(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs);</pre>
<div class="desc"><i>Returns:</i> <code>lhs &lt;&lt; Integral(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  common_type_t&lt;wide_int&lt;Bytes, Signed&gt;, wide_int&lt;Bytes2, Signed2&gt;&gt;
  constexpr  operator&gt;&gt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) &gt;&gt;= rhs</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  constexpr wide_int&lt;Bytes, Signed&gt; operator&gt;&gt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Integral&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) &gt;&gt; CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Integral&gt;
  constexpr Integral operator&gt;&gt;(const Integral&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>lhs &gt;&gt; Integral(rhs)</code>.</div>




<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  constexpr bool operator&lt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>true</code> if value of <code>CT(lhs)</code> is less than the value of <code>CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator&lt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator&lt;(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) &lt; CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  constexpr bool operator&gt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>true</code> if value of <code>CT(lhs)</code> is greater than the value of <code>CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator&gt;(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator&gt;(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) &gt; CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  constexpr bool operator&lt;=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>true</code> if value of <code>CT(lhs)</code> is equal or less than the value of <code>CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator&lt;=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator&lt;=(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) &lt;= CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  constexpr bool operator&gt;=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>true</code> if value of <code>CT(lhs)</code> is equal or greater than the value of <code>CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator&gt;=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator&gt;=(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) &gt;= CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  constexpr bool operator==(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>true</code> if significant bits of <code>CT(lhs)</code> and <code>CT(rhs)</code> are the same.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator==(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator==(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) == CT(rhs)</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, size_t Bytes2, bool Signed2&gt;
  constexpr bool operator!=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const wide_int&lt;Bytes2, Signed2&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>!(CT(lhs) == CT(rhs))</code>.</div>

<pre>template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator!=(const wide_int&lt;Bytes, Signed&gt;&amp; lhs, const Arithmetic&amp; rhs) noexcept;
template&lt;size_t Bytes, bool Signed, typename Arithmetic&gt;
  constexpr bool operator!=(const Arithmetic&amp; lhs, const wide_int&lt;Bytes, Signed&gt;&amp; rhs) noexcept;</pre>
<div class="desc"><i>Returns:</i> <code>CT(lhs) != CT(rhs)</code>.</div>


<h3>26.??.?? Numeric conversions <span class="right">[wide_int.conversions]</span></h3>
<pre>template&lt;size_t Bytes, bool Signed&gt; std::string to_string(const wide_int&lt;Bytes, Signed&gt;&amp; val);
template&lt;size_t Bytes, bool Signed&gt; std::wstring to_wstring(const wide_int&lt;Bytes, Signed&gt;&amp; val);</pre>
<div class="desc"><i>Returns:</i> Each function returns an object holding the character representation of the value of its argument. All the significant bits of the argument are outputed as a signed decimal in the style <code>[-]dddd</code>.</div>

<h3>26.??.?? iostream specializations <span class="right">[wide_int.io]</span></h3>
<pre>template&lt;class Char, class Traits, size_t Bytes, bool Signed&gt;
basic_ostream&lt;Char, Traits&gt;&amp; operator&lt;&lt;(basic_ostream&lt;Char, Traits&gt;&amp; os, const wide_int&lt;Bytes, Signed&gt;&amp; val);</pre>
<div class="desc"><i>Effects:</i> As if by: <code>os &lt;&lt; to_string(val)</code>.</div>
<div class="desc"><i>Returns:</i> <code>os</code>.</div>


<pre>template&lt;class Char, class Traits, size_t Bytes, bool Signed&gt;
basic_istream&lt;Char, Traits&gt;&amp; operator&gt;&gt;(basic_istream&lt;Char, Traits&gt;&amp; is, wide_int&lt;Bytes, Signed&gt;&amp; val);</pre>
<div class="desc"><i>Effects:</i> Extracts a <code>wide_int</code> that is represented as a decimal number in the <code>is</code>. If bad input is encountered, calls <code>is.setstate(ios_base::failbit)</code> (which may throw <code>ios::failure</code> ([iostate.flags])).</div>
<div class="desc"><i>Returns:</i> <code>is</code>.</div>


<h3>26.??.?? Hash support <span class="right">[wide_int.hash]</span></h3>
<pre>template&lt;size_t Bytes, bool Signed&gt; struct hash&lt;wide_int&lt;Bytes, Signed&gt;&gt;;</pre>
<p>The specialization is enabled (20.14.14). If there is a built-in integral type <code>Integral</code> that has the same signedness and width as <code>wide_int&lt;Bytes, Signed&gt;</code>, and <code>wi</code> is an object of type <code>wide_int&lt;Bytes, Signed&gt;</code>, then <code>hash&lt;wide_int&lt;Bytes, Signed&gt;&gt;()(wi) == hash&lt;Integral&gt;()(Integral(wi))</code>.</p>


<h3>26.??.?? numeric_limits specialization <span class="right">[wide_int.numeric_limits]</span></h3>
<pre>template&lt;size_t Bytes, bool Signed&gt; struct numeric_limits&lt;wide_int&lt;Bytes, Signed&gt;&gt;;</pre>
<p>Specialization follows the rules described in [numeric.limits.members]. If there is a built-in integral type <code>Integral</code> that has the same signedness and width as <code>wide_int&lt;Bytes, Signed&gt;</code>, then <code>numeric_limits&lt;wide_int&lt;Bytes, Signed&gt;&gt;</code> specialized in the same way as <code>numeric_limits&lt;Integral&gt;</code>.</p>

        <h2>IV. Feature-testing macro</h2>
        <p>For the purposes of SG10 it is sufficient to check for header <code>&lt;wide_int&gt;</code> using <code>__has_include</code>.</p>

        <script type="text/javascript">
            function colorize_texts(texts) {
                for (var i = 0; i < texts.length; ++i) {
                    var text = texts[i].innerHTML;
                    text = text.replace(/namespace|enum|void|using |template|class|struct|auto|const |typename|explicit|public|private|operator|#include|char|typedef|static_assert|static_cast|static/g,"<span class='cppkeyword'>$&</span>");
                    text = text.replace(/\/\/[\s\S]+?\n/g,"<span class='cppcomment'>$&</span>");
                    text = text.replace(/\"[\s\S]*?\"/g,"<span class='cpptext'>$&</span>");
                    texts[i].innerHTML = text;
                }
            }

            colorize_texts(document.getElementsByTagName("pre"));
            colorize_texts(document.getElementsByTagName("code"));
        </script>
</body></html>
