<xstd/bits/bit/bit_convert.hpp>¶
xstd::bit_convert¶
template<class To, class From>
requires see below
constexpr auto bit_convert(From&& from) noexcept(see below) -> remove_cv_t<To>;
Maps positions across bit storages: position i of the source is position i of the result, where bit_cast
reinterprets an object.
Terms¶
Let F be remove_cvref_t<From> and T be remove_cv_t<To>.
- A fixed width is a type that fixes in its type how many positions it has, its width
W:- an owner of ours whose storage fixes its width, as
basic_bit_array,basic_bit_fixed_setandbasic_bit_fixed_valarraydo; - a whole view whose storage fixes its width,
Wbeing the storage's, as forbit_set_view<uint64_t>andbit_span<array<uint8_t, 3>>; - a block, an
arrayof blocks or a built-in array of blocks,Wbeing theirbit_blocks_extent_v; - and, on a little-endian target,
bitset<N>, whoseWisN.
- an owner of ours whose storage fixes its width, as
- A fixed target is a fixed width that is neither a view nor a built-in array.
- A run-time target is an owner of ours that stores its width, a capacity included: the vectors, the run-time and inplace sets and valarrays, and the Boost extension's small owners.
- A source is a fixed width, an owner of ours, a whole view of ours of run-time width, or a window.
Conversions¶
T |
F |
Result |
|---|---|---|
| a fixed target | a fixed width of W(F) <= W(T) |
the W(F) positions, the positions [W(F), W(T)) clear |
| a fixed target | a source that is no fixed width | its positions below W(T), zero-extended; a position at or past W(T) throws |
| a run-time target | a source | the source's positions at the source's width, as under Return value |
| a type an extension makes a target | a source the extension admits | as the extension specifies |
Template parameters¶
| Parameter | Meaning |
|---|---|
To |
The target type. Its cv is dropped, as a cast's scalar prvalue drops it. |
From |
The source type, deduced. |
Parameters¶
| Parameter | Meaning |
|---|---|
from |
the source |
Return value¶
The object of type T holding the source's positions. Where remove_reference_t<From> is a volatile scalar, it
is read once and the result is bit_convert<T>(static_cast<F>(from)). Into a run-time target:
- A sequence target takes the source's width: a sequence's size, a window's size, a fixed width's
W, and a set's universe, its whole blocks up to itsmax_size(). A set target covers that width in whole blocks of its own, capped at its capacity where it has one. The positions past the source's width are clear. - Where
Fromis a non-constrvalue whoseextract()yields a containerC,bit_constructible_from<T, C>holds, andT's capacity, where it has one, is every bit ofC, the blocks move:Cis extracted into thefrom_blocksconstructor without copying a block, a sequence target then takes the source's width, and the source is left at width zero. The extracted container's type carries its allocator, so another allocator is anotherC. - Otherwise the positions are copied, and the source is unchanged.
Exceptions¶
overflow_errorwhereTis a fixed target,Fis no fixed width, and a position at or pastW(T)is set, asbitset::to_ulongthrows in [bitset.members].bad_allocwhereTis an inplace sequence whose capacity is short of the source's width, or a set target capped at its capacity would lose a key, which is what the target's own growth throws, before a block is written.- Any exception the target's allocator throws.
The exception specification is fixed-width<T> and fixed-width<F>: nothing throws between two fixed widths, and a
run-time end can allocate, refuse a capacity or throw overflow_error.
Remarks¶
- Constraints:
FandTmeet one of the conversions, andremove_reference_t<From>is notvolatileunless it is a scalar type. - It is usable in a constant expression. There the copy is made by shifts, and outside one by a single copy of the bytes where both block types are built-ins without padding on a little-endian target.
Tois never a view, which would write bits it does not own, nor a built-in array, which no function returns. Aspanof blocks lends its width rather than having it, so it is neither end; abit_spanover it converts.- A
bitsetis read and written through its object on the termsbit_castreads one, so it converts on a little-endian target only. Itsto_string()writes position 0 last, so its text reads reversed against the positions written first to last.
Notes¶
bit_convert<uint64_t>(bit_fixed_set<64>{0, 5, 63})is(1ULL << 63) | (1ULL << 5) | 1, andbit_convert<uint8_t>(bit_array<5>)is whatto_ulonggives for abitset<5>of the same positions.bit_convert<array<uint64_t, 2>>(bit_fixed_set<100>{0, 63, 64, 99})is{(1ULL << 63) | 1, (1ULL << 35) | 1}, whichbit_castreads from the set's object too.bit_convert<bit_fixed_set<10>>(bit_set{3, 9})holds{3, 9}, andbit_convert<bit_fixed_set<10>>(bit_set{3, 10})throwsoverflow_error.bit_convert<bitset<0>>(bit_set())converts, andbit_set{0}throws.bit_convert<bit_vector>(bit_set{3, 64, 129})has the set's whole blocks as its size, 192 over 64-bit blocks, andbit_convert<bit_vector>(bit_fixed_set<100>{99})has 100. Abit_vectorof 70 converts to a set over 72 positions inuint8_tblocks.bit_convert<bit_vector>(std::move(s))for abit_set stakess's blocks, andsis then empty; from abasic_bit_set<size_t, vector<uint8_t>>it copies, and the source keeps its bits.
See also¶
| Entity | Relation |
|---|---|
bit_convert with boost::dynamic_bitset |
the extension that makes boost::dynamic_bitset either end |
from_blocks |
the tag through which an owner reads blocks it takes as they are |
bit_blocks_extent_v |
the width of a block or an array of them |
std::bit_cast |
the standard's reinterpretation of an object, whose role this function takes across bit storages |