<html>
<head>
<title>P0556R3: Integral power-of-2 operations</title>

<style type="text/css">
  ins { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .new { text-decoration:none; font-weight:bold; background-color:#D0FFD0 }
  del { text-decoration:line-through; background-color:#FFA0A0 }  
  strong { font-weight: inherit; color: #2020ff }
  table, td, th { border: 1px solid black; border-collapse:collapse; padding: 5px }
</style>
</head>

<body>
ISO/IEC JTC1 SC22 WG21 P0556R3<br/>
Jens Maurer &lt;Jens.Maurer@gmx.net><br/>
Target audience: LWG<br/>
2018-06-06<br/>

<h1>P0556R3: Integral power-of-2 operations</h1>

<h2>Introduction</h2>

<p>

This paper proposes to add simple free functions for operations
related to integral powers of 2 on all unsigned integer types.

<p>
A previous proposal was in "N3864: A constexpr bitwise operations
library for C++" by Matthew Fioravante.

<p>
The foundation for digital computers are binary digits (also called "bits"), and as such
operating with a base-2 representation of data is often most natural
or most efficient.

<p>
It is expected that the functions provided with this proposal will be,
at some later time, overloaded for <code>std::datapar<T></code>, the
nascent SIMD data type (see P0214R3: "Data-Parallel Vector Types &
Operations" by Matthias Kretz).
</p>

<h2>Changes</h2>

P0556R0 was favorably reviewed by SG6 and passed to LEWG with the
following changes:

<ul>
  <li>Provide wide-contract log2p1 instead of narrow-contract log2.</li>
  <li>Rename ceilpow2 to ceil2 and floorpow2 to floor2.</li>
</ul>

P0556R1 was favorably reviewed by LEWG with the following changes:

<ul>
  <li>Make ceil2 return an unspecified value for out-of-bounds arguments.</li>
  <li>Change to header &lt;bit></li>
</ul>

<h2>Design considerations</h2>

The functions are provided for unsigned operands only, since the
domain of the proposed functions is positive.
<p>
This proposal uses readable English names for the operations, using
the established abbreviations <code>pow</code> and <code>ceil</code>.
<p>
It is conceivable to add these functions to the
header <code>&lt;cstdlib></code> (<code>abs</code> and <code>div</code>
are already there), although a new header such as <code>&lt;pow2></code> seems more
focused.  The wording below adds a new header.
<p>
Per prevailing LWG convention, only those functions are marked
<code>noexcept</code> that have a wide <strong>contract</strong>, i.e. no restrictions
on the values of the function arguments.
<p>
All functions are mathematically pure, i.e. do not access or modify
data other than the argument values, and thus are
marked <code>constexpr</code>.

<h2>Wording</h2>

Add the header <code>&lt;bit></code> to the table in 17.5.1.2 [headers].
<p>
Append a new subsection to clause 29 [numerics] with the following content:

<blockquote class="new">
<h2>29.10 Integral powers of 2 [numerics.pow.two]</h2>

<h3>29.10.1 Header <code>&lt;bit></code> synopsis [bit.syn]</h3>

  <pre>
namespace std {
  template &lt;class T>
    constexpr bool ispow2(T x) noexcept;
  template &lt;class T>
    constexpr T ceil2(T x) noexcept;
  template &lt;class T>
    constexpr T floor2(T x) noexcept;
  template &lt;class T>
    constexpr T log2p1(T x) noexcept;
}
  </pre>

<h3>29.10.1 Operations [numerics.pow.two.ops]</h3>

<pre>
  template &lt;class T>
    constexpr bool ispow2(T x) noexcept;
</pre>

<em>Returns:</em> <code>true</code> if x is <strong>an integral</strong> power
of two; <strong><code>false</code> otherwise</strong>.
<p>
<em>Remarks:</em> <strong>This function shall not participate in overload
resolution unless</strong> T is an unsigned integer type
(3.9.1 [basic.fundamental]).

<pre>
  template &lt;class T>
    constexpr T ceil2(T x) noexcept;
</pre>

<em>Returns:</em> The minimal value <code>y</code> such
that <code>ispow2(y)</code> is <code>true</code> and <code>y >=
x</code>; if <code>y</code> is not representable as a value of
type T, the result is an unspecified value.
<p>
  <em>Remarks:</em> <strong>This function shall not participate in overload
    resolution unless</strong> T is an
unsigned integer type (3.9.1 [basic.fundamental]).

<pre>
  template &lt;class T>
    constexpr T floor2(T x) noexcept;
</pre>
<em>Returns:</em> If <code>x == 0</code>, 0; otherwise the maximal
value <code>y</code> such that <code>ispow2(y)</code>
is <code>true</code> and <code>y &lt;= x</code>.
<p>
  <em>Remarks:</em> <strong>This function shall not participate in overload
    resolution unless</strong> T is an
unsigned integer type (3.9.1 [basic.fundamental]).

<pre>
  template &lt;class T>
    constexpr T log2p1(T x) noexcept;
</pre>
<em>Returns:</em> If <code>x == 0</code>, 0; otherwise one
plus the base-2 logarithm of x, with any fractional part
discarded.
<p>
  <em>Remarks:</em> <strong>This function shall not participate in overload
    resolution unless</strong> T is an unsigned
integer type (3.9.1 [basic.fundamental]).

</blockquote>

<h2>References</h2>
<ul>
  <li>ISO/IEC JTC1 SC22 WG21 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3864.html">N3864</a>: "A constexpr bitwise operations library for C++" by Matthew Fioravante</li>
  <li>ISO/IEC JTC1 SC22 WG21 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0214r2.pdf">P0214R3</a>: "Data-Parallel Vector Types & Operations" by Matthias Kretz</li>
  <li><a href="http://infocenter.arm.com/help/topic/com.arm.doc.dui0801g/DUI0801
G_armasm_user_guide.pdf">ARM Compiler User Guide</a> [large PDF]</li>
  <li><a href="http://www.intel.com/content/dam/www/public/us/en/documents/manua
ls/64-ia-32-architectures-software-developer-instruction-set-reference-manual-32
5383.pdf">Intel x86 Instruction Set Reference</a> [large PDF]</li>
  <li>PowerPC Architecture Book, Version 2.02: <a href="http://public.dhe.ibm.com/software/dw/library/es-ppcbook1.zip">Book I: PowerPC User Instruction Set Architecture</a> [large PDF inside ZIP]</li>
</ul>

</body>
</html>
