Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
308 lines (240 sloc) 7.96 KB
<pre class='metadata'>
Markup Shorthands: markdown yes
No Abstract: yes
Toggle Diffs: yes
Group: WG21
Status: P
Shortname: P1280
Revision: 2
Audience: LEWG
Title: Integer Width Literals
Editor: Isabella Muerte, https://twitter.com/slurpsmadrips
Date: 2019-06-12
URL: https://wg21.link/P1280R1
!Current Render: <a href="https://api.csswg.org/bikeshed/?force=1&url=https://git.io/fx3gF">P1280R1</a>
!Current Source: <a href="https://git.io/fx3gX">slurps-mad-rips/papers/proposals/integer-width-literals.bs</a>
</pre>
<style>
ins {background-color: #CCFFCC; text-decoration: underline;}
del {background-color: #FFCACA; text-decoration: line-through;}
</style>
# Revision History # {#changelog}
## Revision 2 ## {#r2}
* Make all functions `consteval` instead of `constexpr` at the recommendation
of Alisdair Meredith.
## Revision 1 ## {#r1}
* Modify return types to actually be `[u]int_leastXX_t` and friends. This is
to make sure that we are actually replacing the `[U]INTxx_C` macros, as
these return a `[u]int_leastXX_t`
## Revision 0 ## {#r0}
Initial Release 🎉
# Motivation # {#motivation}
Proposal [[p0330r2]] proposes literal suffixes for `ptrdiff_t` and `size_t`. In
it, the question [[p0330r2#design-std-ints|
What about the fixed/least/max (unsigned) int types?]] is given regarding the
fixed/least/max integer types provided by `<cstdint>`. As that paper has
decided to focus exclusively on `ptrdiff_t` and `size_t`, this proposal will
instead focus on the *fixed* width integer literals. The problem of least/max
literals is left for another time and paper. The primary goal of this paper is
to replace the `UINTxx_C`/`INTxx_C` macros found in `<cstdint>` with user
defined literal suffixes.
As an example, one can see the results of the compiler results on
<a href="https://gcc.godbolt.org/z/CzOF2m">godbolt</a>.
```c++
#include <cstdint>
void foo(uint32_t);
void foo(uint64_t);
void test()
{
// change this to 10ul and it fails to compile on MSVC
// change this to 10ull and it fails to compile on GCC and Clang
// The only safe thing to do is to use the UINTXX_C macros.
auto x = 10;
foo(x);
}
```
Note: The author is more than willing to extend this paper's scope for the
least and max integer types, however the fixed width integer literals show
promise of the least complex changes. Also we get to deprecate some C macros in
the process and that's always a good thing.
# Design # {#design}
The design for these literals suffixes is to permit explicitly sized
expressions when writing integer literals (e.g., `123i32 + 12i16`).
These operators are declared in the namespace `std::literals::integer_literals`
where both `literals` and `integer_literals` are inline namespaces. Access to
these operators can be gained with:
* `using namespace std::literals`
* `using namespace integer_literals`
* `using namespace std::literals::integer_literals`.
It is intended that these operators be placed into the `<cstdint>` header.
## Synopsis ## {#design-synopsis}
The operator's full specification is:
```c++
namespace std::inline literals::inline integer_literals {
consteval uint_least64_t operator ""u64 (unsigned long long arg);
consteval uint_least32_t operator ""u32 (unsigned long long arg);
consteval uint_least16_t operator ""u16 (unsigned long long arg);
consteval uint_least8_t operator ""u8 (unsigned long long arg);
consteval int_least64_t operator ""i64 (unsigned long long arg);
consteval int_least32_t operator ""i32 (unsigned long long arg);
consteval int_least16_t operator ""i16 (unsigned long long arg);
consteval int_least8_t operator ""i8 (unsigned long long arg);
}
```
# Examples # {#examples}
A small code example is presented below to show how the suffix can be
used in code. (This code sample assumes that [[P0645]] has been added to the
standard. Additionally as the author of [[P1276]], we use that here as well)
Note: This code sample does not attempt to solve the previously shown code
in [[#motivation]], as this is easily solved elsewhere.
```cpp
template <class... Args>
void println (Args&&... args) {
std::puts(std::format(std::forward<Args>(args)...).c_str());
}
void main () {
using namespace std::literals;
println("1 + 2 = {}", 1u32 + 2);
println("1 - 2 = {}", 1i32 - 2);
println("0011 AND 0101 is {:04b}", 0b0011u32 & 0b0101);
println("0011 XOR 0101 is {:04b}", 0b0011u32 ^ 0b0101);
println("0011 OR 0101 is {:04b}", 0b0011u32 | 0b0101);
println("One million is written as {}", 1'000'000u32)
}
```
# Wording # {#wording}
The following is wording for the library section.
<ins>
<!-- u64 -->
<xmp highlight="c++">
namespace std::inline literals::inline integer_literals {
consteval uint_least64_t operator ""u64 (unsigned long long arg);
}
</xmp>
<ol>
<li>*Constraints*
`arg` must fit in the range `arg <= numeric_limits<uint_least64_t>::max()`
</li>
<li>*Returns*
An integer of type `uint_least64_t` with the value given in `arg`
</li>
</ol>
<!-- u32 -->
<xmp highlight="c++">
namespace std::inline literals::inline integer_literals {
consteval uint_least32_t operator ""u32 (unsigned long long arg);
}
</xmp>
<ol>
<li>*Constraints*
`arg` must fit in the range `arg <= numeric_limits<uint_least32_t>::max()`
</li>
<li>*Returns*
An integer of type `uint_least32_t` with the value given in `arg`
</li>
</ol>
<!-- u16 -->
<xmp highlight="c++">
namespace std::inline literals::inline integer_literals {
consteval uint_least16_t operator ""u16 (unsigned long long arg);
}
</xmp>
<ol>
<li>*Constraints*
`arg` must fit in the range `arg <= numeric_limits<uint_least16_t>::max()`
</li>
<li>*Returns*
An integer of type `uint_least16_t` with the value given in `arg`
</li>
</ol>
<!-- u8 -->
<xmp highlight="c++">
namespace std::inline literals::inline integer_literals {
consteval uint_least8_t operator ""u8 (unsigned long long arg);
}
</xmp>
<ol>
<li>*Constraints*
`arg` must fit in the range `arg <= numeric_limits<uint_least8_t>::max()`
</li>
<li>*Returns*
An integer of type `uint_least8_t` with the value given in `arg`
</li>
</ol>
<xmp highlight="c++">
namespace std::inline literals::inline integer_literals {
consteval int_least64_t operator ""i64 (unsigned long long arg);
}
</xmp>
<ol>
<li>*Constraints*
`arg` must fit in the range `arg <= numeric_limits<int_least64_t>::max()`
</li>
<li>*Returns*
An integer of type `int_least64_t` with the value given in `arg`
</li>
</ol>
<xmp highlight="c++">
namespace std::inline literals::inline integer_literals {
consteval int_least32_t operator ""i32 (unsigned long long arg);
}
</xmp>
<ol>
<li>*Constraints*
`arg` must fit in the range `arg <= numeric_limits<int_least32_t>::max()`
</li>
<li>*Returns*
An integer of type `int_least32_t` with the value given in `arg`
</li>
</ol>
<xmp highlight="c++">
namespace std::inline literals::inline integer_literals {
consteval int_least16_t operator ""i16 (unsigned long long arg);
}
</xmp>
<ol>
<li>*Constraints*
`arg` must fit in the range `arg <= numeric_limits<int_least16_t>::max()`
</li>
<li>*Returns*
An integer of type `int_least16_t` with the value given in `arg`
</li>
</ol>
<xmp highlight="c++">
namespace std::inline literals::inline integer_literals {
consteval int_least8_t operator ""i8 (unsigned long long arg);
}
</xmp>
<ol>
<li>*Constraints*
`arg` must fit in the range `arg <= numeric_limits<int_least8_t>::max()`
</li>
<li>*Returns*
An integer of type `int_least8_t` with the value given in `arg`
</li>
</ol>
</ins>
## Feature Testing ## {#feature-test}
The `__cpp_lib_integer_literals` feature test macro should be added.
<pre class=biblio>
{
"p0330r2": {
"authors": [
"JeanHeyd Meneide",
"Rein Halbersma"
],
"href": "https://wg21.link/p0330r2",
"title": "Literal Suffixes for ptrdiff_t and size_t"
},
"P1276": {
"authors": "Isabella Muerte",
"href": "https://wg21.link/p1276r0",
"title": "Void Main"
},
"P0645": {
"authors": "Victor Zverovich",
"href": "https://wg21.link/p0645r3",
"title": "Text Formatting"
}
}
</pre>
You can’t perform that action at this time.