Reference¶
Each public entity of xstd-bits is specified here the way the standard specifies the library: a synopsis per
header, then for each entity the elements of
[structure.specifications] that apply. The library compiles as
C++23, but its interfaces are measured against the current
working draft, and every clause cited here is the draft's. A name with no namespace is in
std.
The synopses leave out [[nodiscard]], as the standard's own have since P2422R1, which
made it a recommended practice rather than part of a library's specification. The code carries it on every function
that returns a value, but for a reference returned for chaining, as operator&= returns one, and for a by-product a
caller may ignore: postfix ++ and --, insert, insert_range, emplace, emplace_hint, erase, the free
erase and erase_if, the reference push_back and emplace_back return, and the try_ and unchecked_ doors.
It carries it on every constructor but basic_bit_array's from an initializer_list.
The library's own terms are used throughout:
- A block is an unsigned integer holding bits. Position
iis biti % Dof blocki / D, whereDis the block'snumeric_limits<Block>::digits. - The storage holds the blocks: fixed, the width the type's; inplace, a run-time width within a capacity the
type carries, the blocks held inline; or dynamic, on the heap. Each has a standard backend:
array,inplace_vectorandvector. Any other container is abit_storageargument; the aliases over other libraries' containers, such as Boost'ssmall_vector, are underext/and are not related here. - An owner holds its storage, and a view refers to storage another object holds.
- A reading is what the bits mean: a sequence of
bool, a set of keys, or a valarray, the sequence read elementwise.
Each container answers a standard counterpart's synopsis, and is specified as that counterpart with what the
packing changes. Members named adaptor_type, adapted_type, derived_type, reads_as, owns_storage,
is_windowed and static_extent answer the library's own traits and are not specified here.
Each umbrella has a page of its own, with its synopsis and its headers, and each header a page beneath it:
<xstd/bits/bit.hpp><xstd/bits/bit_algorithm.hpp><xstd/bits/bit_array.hpp><xstd/bits/bit_concepts.hpp><xstd/bits/bit_functional.hpp><xstd/bits/bit_inplace_vector.hpp><xstd/bits/bit_iterator.hpp><xstd/bits/bit_ranges.hpp><xstd/bits/bit_set.hpp><xstd/bits/bit_span.hpp><xstd/bits/bit_type_traits.hpp><xstd/bits/bit_valarray.hpp><xstd/bits/bit_vector.hpp><xstd/bits/ext/boost.hpp><xstd/bits/ext/boost/dynamic_bitset.hpp>
Relation to the standard library¶
Each entity is one of five kinds, as across the xstd libraries: - Copied: the standard's own exposition-only wording, word for word, under a name users can spell. - Extends: a standard facility under its own name, giving the standard's answer wherever the standard gives one, with overloads or specializations for more types. - Generalizes: the job of a standard facility, done for more types through an interface of its own. - Spells: a portable spelling of a standard attribute or macro. - Proposed or new: no counterpart in the standard. A proposed entity follows a WG21 paper; a new one follows none.
Nothing here is copied or spelled: the containers, views and algorithms generalize, the specializations of standard templates extend, and the templates that choose a container's block type, storage and allocator, like what the standard has no word for, are new.
The Counterpart column leads with the clause of the working draft each entity answers, then says how it extends or generalizes what that clause specifies. The rows follow the draft's order of those clauses, and the names within a row the draft's order of their counterparts. A row with no counterpart sits beside its nearest kin, citing the kin's clause where one is shared.
| Entity | Kind | Counterpart |
|---|---|---|
indeterminateindeterminate_arrayindeterminate_t |
New | [dcl.attr.indet] as a constructor tag: a fixed set's blocks left unwritten, as the attribute leaves a variable's storage |
bit_flag_set |
Generalizes | [bitmask.types] as the set of a bitmask type's one-bit values |
bit_enum_set |
New | none: the standard has no set of an enumeration's values |
least_block_tfast_block_t |
Generalizes | [cstdint.syn] chosen by a width rather than named by one |
bit_blocksbit_constructible_frombit_convertible_tobit_index_mappingbit_mask_mappingsized_bit_index_mapping |
New | none |
bit_alignbit_blocks_extent_vbit_fastbit_leastbit_underlyingunderlying_block_t |
New | none |
bit_storage_rebind |
New | [allocator.traits.types] as rebind_alloc rebinds an allocator, for a storage's block and its count of blocks |
bit_compare_three_waybit_equal_tobit_not_equal_tobit_greaterbit_lessbit_greater_equalbit_less_equal |
Generalizes | [comparisons.three.way] [range.cmp] across block types and storages |
hash |
Extends | [unord.hash] specializations for every owner but the valarrays, and for the set view |
bit_hash |
Generalizes | [unord.hash] of the packed bits rather than the model's value, under a Boost.Hash2 algorithm the caller names |
bit_hash_append |
New | none in the standard: a Boost.Hash2 hash_append, after N3980 |
bit_digest |
Proposed | N3980's uhash, returning the algorithm's whole result |
is_rangeis_tuple_like |
New | none in the standard: specializations of Boost.ContainerHash's traits |
bit_convert |
Generalizes | [bit.cast] from P0476R2: position for position across widths and readings, rather than byte for byte at one size |
bit_convert with boost::dynamic_bitset |
New | none in the standard: conversion to and from Boost.DynamicBitset |
shlshr |
Proposed | P3793R2's total shifts, beside [bit.rotate]: a set's keys moved by any count, where the set's own << and >> take a count below a static width as their precondition |
bit_array |
Generalizes | [array] of bool, packed |
basic_bit_array |
New | [array] customizing the block type |
to_bit_array |
Generalizes | [array.creation] returning a bit_array |
tuple_sizetuple_elementget |
Extends | [array.tuple] specializations and an overload for basic_bit_array |
eraseerase_if |
Generalizes | [vector.erasure] [inplace.vector.erasure] [set.erasure] for the packed sequences and sets |
bit_vector |
Generalizes | [vector.bool] packed into blocks, which vector<bool> leaves to the implementation |
basic_bit_vector |
New | [vector.bool] customizing the storage, and with it the block type and the allocator, and capping the width |
bit_inplace_vector |
Generalizes | [inplace.vector] of bool, packed |
basic_bit_inplace_vector |
New | [inplace.vector] customizing the block type, as basic_bit_vector over inline blocks |
bit_set |
Generalizes | [set] of positions, one bit per possible key, packed into blocks |
basic_bit_setbasic_bit_fixed_setbasic_bit_inplace_setbit_fixed_setbit_inplace_set |
New | [set] customizing the key mapping and the storage, and with it the block type and the allocator: at a fixed width or within an inline capacity |
bit_set_view |
New | none: no standard view reads a range as a set |
bit_find_mappingbit_flag_mappingbit_key_mappingbit_range_mappingenum_traits |
New | none; bit_key_mapping is specialized per key as char_traits is, [char.traits] |
bit_storage |
New | [flat.set.overview] as flat_set constrains its KeyContainer, for the blocks an owner keeps |
bit_span |
Generalizes | [views.span] over blocks read as a sequence of bool |
bit_subspan |
Generalizes | [span.sub] at any bit offset |
bit_advancebit_distancebit_nextbit_prev |
Generalizes | [range.iter.ops] a block at a time over a set |
from_blocks_tfrom_blocks |
Generalizes | [ranges.syn] from P1206R7: reading an argument's blocks as bits, where from_range reads its elements as values |
bit_all_ofbit_any_ofbit_none_ofbit_for_eachbit_findbit_find_lastbit_countbit_mismatchbit_equal |
Generalizes | [alg.nonmodifying] a block at a time, without the projections and predicates a range of bits has no use for |
bit_copybit_copy_backwardbit_movebit_swap_rangesbit_transformbit_fillbit_reversebit_reverse_copybit_rotatebit_rotate_copybit_shift_leftbit_shift_right |
Generalizes | [alg.modifying.operations] a block at a time, without the projections a range of bits has no use for |
bit_sortbit_is_sortedbit_is_partitionedbit_partitionbit_partition_point |
Generalizes | [alg.sorting] a block at a time, without the projections, predicates and comparators a range of bits has no use for |
bit_includesbit_set_unionbit_set_intersectionbit_set_differencebit_set_symmetric_difference |
Generalizes | [alg.set.operations] returning a set where the standard writes through an output iterator |
bit_intersectsbit_disjoint |
New | [alg.set.operations] none: the standard has no test of whether two sets share an element |
bit_lexicographical_compare_three_way |
Proposed | [alg.three.way] over two ranges, as P2022R3 proposes ranges::lexicographical_compare_three_way |
bit_valarraybit_slicebit_slice_arraybit_gslicebit_gslice_arraybit_mask_arraybit_indirect_array |
Generalizes | [numarray] of bool, packed, with the slices and helper arrays that select from it |
basic_bit_valarraybasic_bit_fixed_valarraybasic_bit_inplace_valarraybit_fixed_valarraybit_inplace_valarray |
New | [numarray] customizing the storage, and with it the block type and the allocator: at a fixed width or within an inline capacity |
bit_rebindbit_resize |
Generalizes | [simd.traits] from P1928R15, for owners rather than simd types |
Prior work¶
What each entity builds on in C++, and, for an entity that introduces a name or a concept of its own, its counterpart
in another language where that counterpart shares its purpose. A container that generalizes bitset or
vector<bool> cites no other language. Papers are linked through wg21.link.
- The containers, and
bitset:- Chuck Allison's
N0075
(1991) and
N0128
(1992), the proposals that became
bitset, which named both of its readings, an array of bits and a set of integers. - P0125R0, std::bitset inclusion test methods (Vittorio Romeo), the subset test
bit_includesanswers. - P0161R0, Bitset Iterators, Masks, and Container Operations (Nathan Myers), which
iterates a
bitsetas the sets iterate their keys. - P2417R2, A more constexpr bitset (Daniil Goncharov), and P3103R2, More bitset operations (Jan Schultke).
- Chuck Allison's
N0075
(1991) and
N0128
(1992), the proposals that became
bit_vector, andvector<bool>: the SGI STL'sbit_vector, a class of its own for want of partial specialization, and N1847, vector: More Problems, Better Solutions (Herb Sutter).- The dynamic storage, and the containers under
ext/:boost::dynamic_bitset, and N2050, Proposal to Add a Dynamically Sizeable Bitset to the Standard Library Technical Report Revision 1 (J. Allsop, A. Meredith, G. Prota), which proposed it for the standard.- LLVM's
BitVectorandSmallBitVector, EASTL'sbitvectorand Qt'sQBitArray. - Boost.Container's
small_vector, whichext/boost/'s small aliases adopt, andstatic_vector, which holds the inplace storage below C++26.
bit_inplace_vector,bit_inplace_set,bit_inplace_valarray: P0843R14, inplace_vector (Gonzalo Brito Gadeschi, Timur Doumler, Nevin Liber, David Sankel).bit_span,bit_subspanand the proxies:- P0237R10, Wording for fundamental bit manipulation utilities (Vincent Reverdy,
Robert J. Brunner), whose
bit_referenceandbit_iteratoraddress a bit at any offset. - itsy_bitsy's
bit_viewandbit_sequence, a view and a container of bits over a range of words. - P0122R7, span: bounds-safe views for sequences of objects (Neil MacIntosh, Stephan T. Lavavej).
- P0237R10, Wording for fundamental bit manipulation utilities (Vincent Reverdy,
Robert J. Brunner), whose
bit_flag_set,bit_enum_setand the key mappings:- C++: N3110, Problems with bitmask types in the library (Jonathan Wakely);
N4202, Strongly Typed Bitset (Matthew Fioravante); and
P4313R1, Bitmask operations for enums (Iliya Guterman, Anthony Williams), whose
operators
bit_flag_settakes as they are. Mozilla'sEnumSet, whose default word isbit_underlying's, Chromium'sEnumSet, type_safe'sflag_setand Qt'sQFlags. - Java's
EnumSetisbit_enum_set's counterpart: a set of one enumeration's values, represented internally as a bit vector.
- C++: N3110, Problems with bitmask types in the library (Jonathan Wakely);
N4202, Strongly Typed Bitset (Matthew Fioravante); and
P4313R1, Bitmask operations for enums (Iliya Guterman, Anthony Williams), whose
operators
- The algorithms and iterator operations:
- P2022R3, Rangified version of lexicographical_compare_three_way (Ran Regev, Alex
Dathskovsky), whose signature
bit_lexicographical_compare_three_waytakes. - range-v3's set views, which return their result as the four set operations here do rather than writing it through an output iterator.
- SDSL's
rank_support_vandselect_support_mcl, the rank and select thatbit_distanceandbit_advancecompute over a set a block at a time.
- P2022R3, Rangified version of lexicographical_compare_three_way (Ran Regev, Alex
Dathskovsky), whose signature
bit_rebind,bit_resize: P1928R15, std::simd - Merge data-parallel types from the Parallelism TS 2 (Matthias Kretz), whoserebind_tandresize_tthey mirror.bit_hash,bit_hash_append,bit_digest: N3980, Types Don't Know # (Howard Hinnant, Vinnie Falco, John Bytheway), Boost.Hash2 and Boost.ContainerHash.from_blocks: P1206R7, Conversions from ranges to containers (Corentin Jabot, Eric Niebler, Casey Carter), whosefrom_rangetag it mirrors. itsy_bitsy'sbit_sequencetakes its storage throughstd::in_placeinstead.indeterminate: P2795R5, Erroneous behaviour for uninitialized reads (Thomas Köppe), whose[[indeterminate]]the tag mirrors; P1020R1, Smart pointer creation with default initialization (Glen Fernandes, Peter Dimov), the standard'sfor_overwrite; and Boost.Container'sdefault_init_t.bit_convert: P0476R2, Bit-casting object representations (JF Bastien).