Skip to content
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,
Date: 2019-07-16
Repository: slurps-mad-rips/byteswap
!Current Render: <a href="">D1272R3</a>
!Current Source: <a href="">slurps-mad-rips/papers/proposals/</a>
!Implementation: <a href="">slurps-mad-rips/byteswap</a>
ins {background-color: #CCFFCC; text-decoration: underline;}
del {background-color: #FFCACA; text-decoration: line-through;}
tr.insert { background-color: #CCFFCC; text-decoration: underline; }
# 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:
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**]:
<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;
<em>// 25.5.4, byteswap</em>
template &lt;class IntegerType&gt;
constexpr IntegerType byteswap (IntegerType value) noexcept;
template &lt;class T&gt;
constexpr bool ispow2(T x) noexcept;
template &lt;class T&gt;
constexpr T ceil2(T x) noexcept;
The following is to be placed *before* the current subclause 25.5.4 [**bit.pow.two**] into [**bit.byteswap**]:
template <class IntegerType>
constexpr IntegerType byteswap (IntegerType value) noexcept;
<sup>1</sup> *Constraints*: `std::is_integral_v<IntegerType>` is `true`.
<sup>2</sup> *Mandates*: `IntegerType` does not have padding bits.
<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`.
The following modification in 26.5.3 [**bit.cast**]:
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>
## 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:
<th>Macro Name<br></th>
<tr class="insert">
&lt;atomic&gt; &lt;filesystem&gt;
&lt;istream&gt; &lt;limits&gt; &lt;locale&gt;
&lt;ostream&gt; &lt;string&gt;
# Acknowledgement # {#acknowledgement}
Thanks to Nicole Muzzuca for feedback on writing this proposal.
You can’t perform that action at this time.