Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
170 lines (140 sloc) 6.05 KB
<pre class='metadata'>
Markup Shorthands: markdown yes
No Abstract: yes
Toggle Diffs: yes
Group: WG21
Status: P
Shortname: P1272
Revision: 3
Audience: LWG
Title: Byteswapping for fun&&nuf
Editor: Isabella Muerte, https://twitter.com/slurpsmadrips
Date: 2019-07-16
Repository: slurps-mad-rips/byteswap
URL: https://wg21.link/P1272R3
!Current Render: <a href="https://api.csswg.org/bikeshed/?force=1&url=https://git.io/fx3lR">D1272R3</a>
!Current Source: <a href="https://git.io/fx3l0">slurps-mad-rips/papers/proposals/byteswap.bs</a>
!Implementation: <a href="https://git.io/fAvWz">slurps-mad-rips/byteswap</a>
</pre>
<style>
ins {background-color: #CCFFCC; text-decoration: underline;}
del {background-color: #FFCACA; text-decoration: line-through;}
tr.insert { background-color: #CCFFCC; text-decoration: underline; }
</style>
# Revision History # {#changelog}
## Revision 2 ## {#r2}
* Add missing remarks of undefined behavior in cases such as byteswapping an `IntegerType` such as a bitfield.
* Update feature macro value for the Cologne 2019 meeting
## Revision 1 ## {#r1}
* Update wording based on feedback from CWG regarding the representation of the "reversed" object.
* Update wording based on feedback from LWG subclause location and grammatical changes
* Readjust wording to use [[N4820]] library wording constructs instead of [[N4672]]
## Revision 0 ## {#r0}
Initial release. 🎉
# Motivation # {#motivation}
Proposal [[P0553r2]] gives several bit operations to perform on integer types,
such as popcount, or bit rotation. Despite these new operations provided to
C++ developers, we still cannot swap (i.e., reverse) the bytes of builtin
integer types in a performant way (i.e., one instruction or less) without
resorting to compiler intrinsics. Currently, most CPU architectures provide
single instructions for a byte swap. For those that don't, falling back on
existing operations is more than amenable. We should, however, endeavor to
standardize existing practice.
Note: The phrase one instruction or less refers to compilers inserting at
most one instruction, and at the very least removing any instructions
due to optimizations.
# Design Considerations # {#design}
The design for the byteswap free function is quite simple. It takes any
integer type and swaps its byteorder to the reverse of its current state.
Additionally, it *only* takes integer types, requiring users to openly
`bit_cast` their non-integers to integers in blatant heresy to the Worm-Seethe.
How utterly disgraceful.
Note: It is intended that the byteswap function, despite swapping bytes, be
placed into the `<bit>` header.
## Synopsis ## {#design-synopsis}
The function's full specification is:
```c++
namespace std {
template <class IntegerType>
constexpr IntegerType byteswap (IntegerType value) noexcept;
}
```
Where `std::is_integral_v<IntegerType>` is `true`.
# Wording # {#wording}
The following synopsis is to be added to subclause 25.5.2 <em>Header `<bit>`
Synopsis</em> [**bit.syn**]:
<blockquote>
<pre highlight="c++">
<em>// 25.5.3, bit_cast</em>
template &lt;typename To, typename From&gt;
constexpr To bit_cast (const From& from) noexcept;
<ins>
<em>// 25.5.4, byteswap</em>
template &lt;class IntegerType&gt;
constexpr IntegerType byteswap (IntegerType value) noexcept;
</ins>
template &lt;class T&gt;
constexpr bool ispow2(T x) noexcept;
template &lt;class T&gt;
constexpr T ceil2(T x) noexcept;
...
</pre>
</blockquote>
The following is to be placed *before* the current subclause 25.5.4 [**bit.pow.two**] into [**bit.byteswap**]:
<blockquote>
<ins>
```cpp
template <class IntegerType>
constexpr IntegerType byteswap (IntegerType value) noexcept;
```
<sup>1</sup> *Constraints*: `std::is_integral_v<IntegerType>` is `true`.
<br>
<sup>2</sup> *Mandates*: `IntegerType` does not have padding bits.
<br>
<sup>3</sup> *Returns*: An object of type `IntegerType`. Let the sequence `R` comprise the bytes of the object representation of `value` in reverse order. Each byte in the object representation of the result is equal to the byte in the corresponding position in `R`.
<br>
</ins>
</blockquote>
The following modification in 26.5.3 [**bit.cast**]:
<blockquote>
```cpp
template<typename To, typename From>
constexpr To bit_cast(const From& from) noexcept;
```
*Returns*: An object of type `To`. Each bit of the value representation of the result is equal to the corresponding bit in the object representation of `from`. Padding bits of the `To` object are unspecified. If there is no value of type `To` corresponding to the value representation produced, the behavior is undefined. If there are multiple such values, which value is produced is unspecified. <ins>A bit in the value representation of the result is indeterminate if does not correspond to a bit in the value representation of `from` or corresponds to a bit of an object that is not within its lifetime or has an indeterminate value ([basic.indet]). For each bit in the value representation of the result that is indeterminate, the smallest object containing that bit has an indeterminate value; the behavior is undefined unless that object is of unsigned ordinary character type or `std::byte` type. The result does not otherwise contain any indeterminate values.</ins>
</blockquote>
## Feature Testing ## {#feature-test}
In 16.3.1 [**support.limits.general**], Table 36, add a new row below
`__cpp_lib_byte` with the following content:
<table>
<tr>
<th>Macro Name<br></th>
<th>Value</th>
<th>Header(s)<br></th>
</tr>
<tr>
<td>__cpp_lib_byte<br></td>
<td>201603L</td>
<td>&lt;cstddef&gt;</td>
</tr>
<tr class="insert">
<td>**__cpp_lib_byteswap**</td>
<td>**??????L**</td>
<td>**&lt;bit&gt;**</td>
</tr>
<tr>
<td>__cpp_lib_char8_t</td>
<td>201811L</td>
<td>
&lt;atomic&gt; &lt;filesystem&gt;
<br>
&lt;istream&gt; &lt;limits&gt; &lt;locale&gt;
<br>
&lt;ostream&gt; &lt;string&gt;
<br>
&lt;string_view&gt;
</td>
</tr>
</table>
# Acknowledgement # {#acknowledgement}
Thanks to Nicole Muzzuca for feedback on writing this proposal.
You can’t perform that action at this time.