<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <title>p1751r0</title>
  <style type="text/css">
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
  </style>
  <style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
  { content: attr(title);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
  </style>
  <!--adapted from https://github.com/Thiht/markdown-viewer/blob/master/chrome/lib/sss/sss.css-->
  <style type="text/css">
  body {
      color: #333;
      font-family: 'Segoe UI', 'Lucida Grande', Helvetica, sans-serif;
      line-height: 1.5;
      margin: auto;
      max-width: 1000px;
  }
  
  h1, h2, h3, h4, h5, h6 {
      font-weight: normal;
      line-height: 1em;
      margin: 20px 0;
  }
  
  h1 {
      font-size: 2.25em;
  }
  
  h2 {
      font-size: 1.75em;
  }
  
  h3 {
      font-size: 1.5em;
  }
  
  h4, h5, h6 {
      font-size: 1.25em;
  }
  
  a {
      color: #08C;
      text-decoration: none;
  }
  
  a:hover, a:focus {
      text-decoration: underline;
  }
  
  a:visited {
      color: #058;
  }
  
  img {
      max-width: 100%;
  }
  
  li + li {
      margin-top: 3px;
  }
  
  dt {
      font-weight: bold;
  }
  
  code {
      background: #EEE;
      font-family: "Consolas", "Lucida Console", monospace;
      padding: 1px 5px;
  }
  
  pre {
      background: #EEE;
      padding: 5px 10px;
      white-space: pre-wrap;
  }
  
  pre code {
      padding: 0;
  }
  
  blockquote {
      border-left: 5px solid #EEE;
      margin: 0;
      padding: 0 10px;
  }
  
  table {
      border-collapse: collapse;
      width: 100%;
  }
  
  table + table {
      margin-top: 1em;
  }
  
  thead {
      background: #EEE;
      text-align: left;
  }
  
  th, td {
      border: 1px solid #EEE;
      padding: 5px 10px;
  }
  
  hr {
      background: #EEE;
      border: 0;
      height: 1px;
  }
  </style>
</head>
<body>
<p><strong>Document number</strong>: P1751R0<br />
<strong>Date</strong>: 2019-06-16<br />
<strong>Reply-to</strong>: John McFarlane, <a href="mailto:wg21@john.mcfarlane.name">wg21@john.mcfarlane.name</a><br />
<strong>Audience</strong>: SG6, LEWGI</p>
<h1>Numeric Type Families</h1>
<h2>Introduction</h2>
<p>This paper introduces the notion of numeric type families which play an important role in facilitating efficient, extensible, generic numeric code. It explains what they are, how they are used and proposes library facilities for accessing and manipulating them.</p>
<h2>Definition</h2>
<p>The two first paragraphs of [<a href="http://eel.is/c++draft/basic.types#basic.fundamental">basic.fundamental</a>] in [<a href="chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4810.pdf">N4810</a>] introduce the <em>signed integer types</em> and the <em>unsigned integer types</em> respectively. Together, these constitute the <em>fundamental integer type family</em>.</p>
<p>They are supported by optional library aliases (<code>int32_t</code> etc.) which provide width guarantees and by type traits (<code>is_signed</code>, <code>make_signed</code> and <code>make_unsigned</code>) which allow transformations between them.</p>
<p>Outside the standard, other numeric type families exist. A recurring pattern is is that their members vary in width and signedness. Some even exhibit a 1-to-1 mapping with the fundamental integer type family. For example, the <a href="https://docs.microsoft.com/en-us/cpp/safeint/safeint-class?view=vs-2019"><code>SafeInt</code></a> class is parameterised on a fundamental integer type:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb1-1" title="1">SafeInt&lt;<span class="dt">int</span>&gt; a{<span class="dv">42</span>};</a></code></pre></div>
<p>Other families have continuous ranges of widths. For example, <a href="https://www.boost.org/doc/libs/1_66_0/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html"><code>boost::multiprecision::number</code></a> has a width parameter:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb2-1" title="1">number&lt;cpp_int_backend&lt;<span class="dv">32</span>&gt;&gt; b{<span class="dv">42</span>};</a></code></pre></div>
<p>[<a href="https://godbolt.org/z/-NXgTn">example</a>]</p>
<h2>Applications</h2>
<h3>Example 1: Generic Arithmetic Functions</h3>
<p>There is an increasing demand to make numeric types easier to use in generic code. Consider a library which provides overflow-resistant arithmetic <a href="https://godbolt.org/z/CVHfa3">:</a></p>
<div class="sourceCode" id="cb3"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb3-1" title="1"><span class="kw">namespace</span> acme {</a>
<a class="sourceLine" id="cb3-2" title="2">    <span class="co">// avoids negative overflow when b&gt;a</span></a>
<a class="sourceLine" id="cb3-3" title="3">    <span class="kw">auto</span> minus(<span class="dt">uint32_t</span> a, <span class="dt">uint32_t</span> b) { </a>
<a class="sourceLine" id="cb3-4" title="4">        <span class="cf">return</span> <span class="dt">int64_t</span>{a}-b;</a>
<a class="sourceLine" id="cb3-5" title="5">    }</a>
<a class="sourceLine" id="cb3-6" title="6">    </a>
<a class="sourceLine" id="cb3-7" title="7">    <span class="co">// avoids positive overflow when product exceeds range of the operands</span></a>
<a class="sourceLine" id="cb3-8" title="8">    <span class="kw">auto</span> multiply(<span class="dt">uint32_t</span> a, <span class="dt">uint32_t</span> b) { </a>
<a class="sourceLine" id="cb3-9" title="9">        <span class="cf">return</span> <span class="dt">uint64_t</span>{a}*b;</a>
<a class="sourceLine" id="cb3-10" title="10">    }</a>
<a class="sourceLine" id="cb3-11" title="11">}</a></code></pre></div>
<p>Now consider all of overloads of the above functions necessary to cover the fundamental integers. Finally, consider the overloads necessary to cover third-party integers such as the SafeInt and Boost.Multiprecision types. Clearly, function templates are needed.</p>
<p>One facility which would cover the case for fundamental integers is parameterisation of width or digits. We already have <code>numeric_limits::digits</code> which is helpful in calculating the range of a number. A complementary setter is frequently requested as a standard library addition.</p>
<p>Boost provides <a href="https://www.boost.org/doc/libs/1_66_0/libs/integer/doc/html/boost_integer/integer.html">facilities</a> for chosing a fundamental signed or unsigned type given a number of bits, e.g.:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb4-1" title="1"><span class="co">//  signed</span></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="kw">template</span>&lt;<span class="dt">int</span> Bits&gt;</a>
<a class="sourceLine" id="cb4-3" title="3"><span class="kw">struct</span> <span class="dt">int_t</span></a>
<a class="sourceLine" id="cb4-4" title="4">{</a>
<a class="sourceLine" id="cb4-5" title="5">    <span class="co">/* Member exact may or may not be defined depending upon Bits */</span></a>
<a class="sourceLine" id="cb4-6" title="6">    <span class="kw">typedef</span> implementation-defined-type  exact;</a>
<a class="sourceLine" id="cb4-7" title="7">    <span class="kw">typedef</span> implementation-defined-type  least;</a>
<a class="sourceLine" id="cb4-8" title="8">    <span class="kw">typedef</span> <span class="dt">int_fast_t</span>&lt;least&gt;::fast      fast;</a>
<a class="sourceLine" id="cb4-9" title="9">};</a>
<a class="sourceLine" id="cb4-10" title="10"></a>
<a class="sourceLine" id="cb4-11" title="11"><span class="co">//  unsigned</span></a>
<a class="sourceLine" id="cb4-12" title="12"><span class="kw">template</span>&lt;<span class="dt">int</span> Bits&gt;</a>
<a class="sourceLine" id="cb4-13" title="13"><span class="kw">struct</span> <span class="dt">uint_t</span></a>
<a class="sourceLine" id="cb4-14" title="14">{</a>
<a class="sourceLine" id="cb4-15" title="15">  <span class="co">/* Member exact may or may not be defined depending upon Bits */</span></a>
<a class="sourceLine" id="cb4-16" title="16">  <span class="kw">typedef</span> implementation-defined-type  exact;</a>
<a class="sourceLine" id="cb4-17" title="17">  <span class="kw">typedef</span> implementation-defined-type  least;</a>
<a class="sourceLine" id="cb4-18" title="18">  <span class="kw">typedef</span> <span class="dt">int_fast_t</span>&lt;least&gt;::fast      fast;</a>
<a class="sourceLine" id="cb4-19" title="19">};</a></code></pre></div>
<p>This is a step in the right direction and helps out with the <code>minus</code> function in our library<a href="https://godbolt.org/z/0fvKtx">:</a></p>
<div class="sourceCode" id="cb5"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb5-1" title="1"><span class="kw">namespace</span> acme {</a>
<a class="sourceLine" id="cb5-2" title="2">    <span class="co">// avoids negative overflow when b&gt;a</span></a>
<a class="sourceLine" id="cb5-3" title="3">    <span class="kw">template</span>&lt;<span class="kw">class</span> Operand&gt;</a>
<a class="sourceLine" id="cb5-4" title="4">    <span class="kw">auto</span> minus(Operand a, Operand b) {</a>
<a class="sourceLine" id="cb5-5" title="5">        <span class="kw">using</span> result = <span class="ex">boost::</span>int_t&lt;numeric_limits&lt;Operand&gt;::digits+<span class="dv">1</span>&gt;::fast;</a>
<a class="sourceLine" id="cb5-6" title="6">        <span class="cf">return</span> result{a}-b;</a>
<a class="sourceLine" id="cb5-7" title="7">    }</a>
<a class="sourceLine" id="cb5-8" title="8">    </a>
<a class="sourceLine" id="cb5-9" title="9">    <span class="co">// avoids positive overflow when product exceeds range of the operands</span></a>
<a class="sourceLine" id="cb5-10" title="10">    <span class="kw">auto</span> multiply(<span class="dt">uint32_t</span> a, <span class="dt">uint32_t</span> b) { </a>
<a class="sourceLine" id="cb5-11" title="11">        <span class="cf">return</span> <span class="dt">uint64_t</span>{a}*b;</a>
<a class="sourceLine" id="cb5-12" title="12">    }</a>
<a class="sourceLine" id="cb5-13" title="13">}</a></code></pre></div>
<p>But <code>multiply</code> is more awkward: we need signed and unsigned overloads to make use of <code>boost::int_t</code> and <code>boost::uint_t</code>. And it still only works for fundamental integers.</p>
<p>[<a href="wg21.link/p0675">P0675</a>] proposes a user-customisable metafunction, <code>set_digits</code> which addresses both of these concerns with a single type parameter:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb6-1" title="1"><span class="kw">template</span>&lt;<span class="kw">class</span> T, <span class="dt">int</span> MinDigits&gt;</a>
<a class="sourceLine" id="cb6-2" title="2"><span class="kw">struct</span> set_digits;</a></code></pre></div>
<p>Common arguments to <code>T</code> are <code>signed</code> and <code>unsigned</code> <a href="https://godbolt.org/z/iX03YE">:</a></p>
<div class="sourceCode" id="cb7"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb7-1" title="1"><span class="dt">set_digits_t</span>&lt;<span class="dt">unsigned</span>, <span class="dv">5</span>&gt; a{<span class="dv">30</span>};  <span class="co">// an unsigned integer with at least 5 digits.</span></a></code></pre></div>
<p>Two things are worth noting here:</p>
<ol>
<li>The type returned by this metafunction is the same signedness and <strong>the same family</strong> as the input.</li>
<li>The terminology is <strong>digits, not bits or width</strong>. This is an important but subtle distinction: width includes the sign bit but digits does not.</li>
</ol>
<p>Including <code>set_digits</code>, [<a href="https://wg21.link/p0675">P0675</a>] proposes a full set of user-customizable metafunctions for transforming between types within a family:</p>
<ul>
<li><code>set_digits</code> - returns a type with at least the given number of digits</li>
<li><code>digits</code> - returns the number of digits (equivalent to <code>numeric_limits::digits</code>)</li>
<li><code>is_signed</code> - returns true iff <code>T</code> is signed (equivalent to <code>numeric_limits::is_signed</code>)</li>
<li><code>add_signedness</code> - returns a signed equivalent of <code>T</code> (like <code>make_signed</code> but user-customisable)</li>
<li><code>remove_signedness</code> - complement to <code>add_signedness</code></li>
</ul>
<p>Lets see how these helps our <code>multiply</code> function <a href="https://godbolt.org/z/1ozBgm">:</a></p>
<div class="sourceCode" id="cb8"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb8-1" title="1"><span class="kw">namespace</span> acme {</a>
<a class="sourceLine" id="cb8-2" title="2">    <span class="co">// avoids negative overflow when b&gt;a</span></a>
<a class="sourceLine" id="cb8-3" title="3">    <span class="kw">template</span>&lt;<span class="kw">class</span> Operand&gt;</a>
<a class="sourceLine" id="cb8-4" title="4">    <span class="kw">auto</span> minus(Operand a, Operand b) {</a>
<a class="sourceLine" id="cb8-5" title="5">        <span class="kw">constexpr</span> <span class="kw">auto</span> operand_digits = digits_v&lt;Operand&gt;;</a>
<a class="sourceLine" id="cb8-6" title="6">        <span class="kw">using</span> signed_operand = <span class="dt">add_signedness_t</span>&lt;Operand&gt;;</a>
<a class="sourceLine" id="cb8-7" title="7">        <span class="kw">using</span> result = <span class="dt">set_digits_t</span>&lt;signed_operand, operand_digits+<span class="dv">1</span>&gt;;</a>
<a class="sourceLine" id="cb8-8" title="8">        <span class="cf">return</span> result{a}-b;</a>
<a class="sourceLine" id="cb8-9" title="9">    }</a>
<a class="sourceLine" id="cb8-10" title="10"></a>
<a class="sourceLine" id="cb8-11" title="11">    <span class="co">// avoids positive overflow when product exceeds range of the operands</span></a>
<a class="sourceLine" id="cb8-12" title="12">    <span class="kw">template</span>&lt;<span class="kw">class</span> Operand&gt;</a>
<a class="sourceLine" id="cb8-13" title="13">    <span class="kw">auto</span> multiply(Operand a, Operand b) {</a>
<a class="sourceLine" id="cb8-14" title="14">        <span class="kw">constexpr</span> <span class="kw">auto</span> operand_digits = digits_v&lt;Operand&gt;;</a>
<a class="sourceLine" id="cb8-15" title="15">        <span class="kw">using</span> result = <span class="dt">set_digits_t</span>&lt;Operand, operand_digits*<span class="dv">2</span>&gt;;</a>
<a class="sourceLine" id="cb8-16" title="16">        <span class="cf">return</span> result{a}*b;</a>
<a class="sourceLine" id="cb8-17" title="17">    }</a>
<a class="sourceLine" id="cb8-18" title="18">}</a></code></pre></div>
<p>Now the functions work with all fundamental integers (except the widest ones, for which there are no valid return types). Better still, we can now provide <a href="https://godbolt.org/z/U0H4nU">a dab of glue</a> and pass Boost.Multiprecision types, among many others.</p>
<h3>Example 2: Generic Arithmetic Types</h3>
<p>The above example shows safe -- but tedious -- named functions which quickly becomes unreadable. [<a href="https://wg21.link/p0828">P0828</a>] proposes the same facility in the form of a numeric type, <code>elastic_integer</code>, with a full set of arithmetic operators:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb9-1" title="1"><span class="kw">template</span>&lt;<span class="dt">int</span> MaxDigits, <span class="kw">class</span> Narrowest&gt;</a>
<a class="sourceLine" id="cb9-2" title="2"><span class="kw">class</span> elastic_integer;</a></code></pre></div>
<p>This makes the same facility far more readable<a href="https://godbolt.org/z/qnDIIv">:</a></p>
<div class="sourceCode" id="cb10"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb10-1" title="1"><span class="co">// elastic_integer&lt;32, signed&gt;{-1}</span></a>
<a class="sourceLine" id="cb10-2" title="2"><span class="kw">auto</span> a{elastic_integer{<span class="dv">0</span><span class="bu">U</span>}-elastic_integer{<span class="dv">1</span><span class="bu">U</span>}};</a>
<a class="sourceLine" id="cb10-3" title="3"></a>
<a class="sourceLine" id="cb10-4" title="4"><span class="co">// elastic_integer&lt;64, unsigned&gt;{UINT_MAX*UINT_MAX}</span></a>
<a class="sourceLine" id="cb10-5" title="5"><span class="kw">auto</span> b{elastic_integer{UINT_MAX}*elastic_integer{UINT_MAX}};</a></code></pre></div>
<h3>Example 3: Composite Types</h3>
<p>In order to be generally useful, <code>elastic_integer</code> also specializes the family metafunctions, e.g.:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb11-1" title="1"><span class="kw">template</span>&lt;<span class="dt">int</span> Digits, <span class="kw">class</span> Narrowest, <span class="dt">int</span> MinNumBits&gt;</a>
<a class="sourceLine" id="cb11-2" title="2"><span class="kw">struct</span> set_digits&lt;elastic_integer&lt;Digits, Narrowest&gt;, MinNumBits&gt; {</a>
<a class="sourceLine" id="cb11-3" title="3">    <span class="kw">using</span> type = elastic_integer&lt;MinNumBits, Narrowest&gt;;</a>
<a class="sourceLine" id="cb11-4" title="4">};</a></code></pre></div>
<p>Now <code>elastic_integer</code> itself can start to become a piece in a larger system and we begin to build up a vocabulary for describing components and their interaction. For instance, we can use a 'safe integer' type to wrap -- not only fundamental types as SafeInt does but also -- all suitable class-based numeric types.</p>
<p>[<a href="http://wg21.link/p0554">P0554</a>] describes an entire system for numeric composition in which the notion of a family will become an essential notion. Introduced in that paper is a more generic alternative to SafeInt called <code>overflow_integer</code>:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb12-1" title="1"><span class="kw">template</span>&lt;<span class="kw">class</span> Rep, <span class="kw">class</span> OverflowTag = contract_overflow_tag&gt;</a>
<a class="sourceLine" id="cb12-2" title="2"><span class="kw">class</span> overflow_integer;</a></code></pre></div>
<p>Once <code>set_digits</code> and all the other family metafunctions have been specialized for <code>elastic_integer</code>, it becomes a family which can be plugged into <code>overflow_integer</code>:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode c++"><code class="sourceCode cpp"><a class="sourceLine" id="cb13-1" title="1"><span class="kw">template</span>&lt;</a>
<a class="sourceLine" id="cb13-2" title="2">        <span class="dt">int</span> MinDigits,</a>
<a class="sourceLine" id="cb13-3" title="3">        <span class="kw">class</span> Narrowest = <span class="dt">signed</span>,</a>
<a class="sourceLine" id="cb13-4" title="4">        <span class="kw">class</span> OverflowTag = contract_overflow_tag&gt;</a>
<a class="sourceLine" id="cb13-5" title="5"><span class="kw">using</span> safe_integer = </a>
<a class="sourceLine" id="cb13-6" title="6">    overflow_integer&lt;elastic_integer&lt;MinDigits, Narrowest&gt;, OverflowTag&gt;;</a></code></pre></div>
<p>Such a <strong>composite numeric type</strong> is hard to digest without some idea of the families involved:</p>
<ul>
<li><code>Narrowest</code> is -- by default -- a signed member of the fundamental integer family. The concrete storage for an instantiation of <code>safe_integer</code> will be either <code>int</code> or something wider than <code>int</code>. Swapping this out for <code>unsigned</code> would give equivalent unsigned behavior. Non-fundamental families are accepted but must have the family metafunctions specialized for them.</li>
<li><code>Rep</code> is the family wrapped by <code>overflow_integer</code> and in this case, the choice is <code>elastic_integer&lt;MinDigits, Narrowest&gt;</code>. Any change to the digits or signedness of <code>overflow_integer</code> will involve an equivalent change in the <code>elastic_integer</code> parameters.</li>
<li><code>safe_integer&lt;MinDigits, Narrowest, OverflowTag&gt;</code> is specialized to become a member of the outermost family. A member of that family might be, <code>safe_integer&lt;31&gt;</code> which would give it the same digits and signedness as <code>int32_t</code>. (To strain the family metaphore to its limits, if <code>int</code> were the matriarch of the fundamental integer family, her default <code>safe_integer</code> counterpart would be <code>safe_integer&lt;31&gt;</code>.)</li>
</ul>
<h2>Acknowledgements</h2>
<p>Special thanks to Davis Herring for extensive and invaluable input on this topic.</p>
</body>
</html>
