Botan 3.7.1
Crypto and TLS for C&
Botan::bitvector_base< AllocatorT > Class Template Referencefinal

#include <bitvector.h>

Classes

class  bitref
 
class  bitref< BlockT >
 

Public Types

using allocator_type = AllocatorT<block_type>
 
using block_type = uint8_t
 
using const_iterator = detail::bitvector_iterator<const bitvector_base<AllocatorT>>
 
using iterator = detail::bitvector_iterator<bitvector_base<AllocatorT>>
 
using size_type = size_t
 
using value_type = block_type
 

Public Member Functions

template<bitvectorish OutT>
OutT as () const
 
 bitvector_base ()
 
 bitvector_base (size_type bits)
 
 bitvector_base (std::initializer_list< block_type > blocks, std::optional< size_type > bits=std::nullopt)
 
 bitvector_base (std::span< const uint8_t > bytes, std::optional< size_type > bits=std::nullopt)
 
bool empty () const
 
template<bitvectorish OtherT>
bool equals (const OtherT &other) const noexcept
 
template<bitvectorish OtherT>
bool equals_vartime (const OtherT &other) const noexcept
 
size_type hamming_weight () const
 
CT::Choice has_odd_hamming_weight () const
 
size_type size () const
 
Serialization
void from_bytes (std::span< const uint8_t > bytes, std::optional< size_type > bits=std::nullopt)
 
template<concepts::resizable_byte_buffer OutT = std::conditional_t<uses_secure_allocator, secure_vector<uint8_t>, std::vector<uint8_t>>>
OutT to_bytes () const
 
void to_bytes (std::span< uint8_t > out) const
 
std::string to_string () const
 
Capacity Accessors and Modifiers
size_type capacity () const
 
void reserve (size_type bits)
 
void resize (size_type bits)
 
void push_back (bool bit)
 
void pop_back ()
 
Bitwise and Global Accessors and Modifiers
auto at (size_type pos)
 
auto at (size_type pos) const
 
auto front ()
 
auto front () const
 
auto back ()
 
auto back () const
 
bitvector_baseset (size_type pos)
 
bitvector_baseset ()
 
bitvector_baseunset (size_type pos)
 
bitvector_baseunset ()
 
bitvector_baseflip (size_type pos)
 
bitvector_baseflip ()
 
bool none_vartime () const
 
bool none () const
 
bool any_vartime () const
 
bool any () const
 
bool all_vartime () const
 
bool all () const
 
auto operator[] (size_type pos)
 
auto operator[] (size_type pos) const
 
Subvectors
template<bitvectorish OutT = bitvector_base<AllocatorT>>
auto subvector (size_type pos, std::optional< size_type > length=std::nullopt) const
 
template<typename OutT >
requires (std::unsigned_integral<strong_type_wrapped_type<OutT>> && !std::same_as<bool, strong_type_wrapped_type<OutT>>)
OutT subvector (size_type pos) const
 
template<typename InT >
requires (std::unsigned_integral<strong_type_wrapped_type<InT>> && !std::same_as<bool, InT>)
void subvector_replace (size_type pos, InT value)
 
Operators
auto operator~ ()
 
template<bitvectorish OtherT>
auto & operator|= (const OtherT &other)
 
template<bitvectorish OtherT>
auto & operator&= (const OtherT &other)
 
template<bitvectorish OtherT>
auto & operator^= (const OtherT &other)
 
Constant Time Operations
template<bitvectorish OtherT>
void ct_conditional_xor (CT::Choice condition, const OtherT &other)
 
constexpr void _const_time_poison () const
 
constexpr void _const_time_unpoison () const
 
Iterators
iterator begin () noexcept
 
const_iterator begin () const noexcept
 
const_iterator cbegin () const noexcept
 
iterator end () noexcept
 
const_iterator end () const noexcept
 
const_iterator cend () noexcept
 

Static Public Attributes

static constexpr size_type block_size_bits = block_size_bytes * 8
 
static constexpr size_type block_size_bytes = sizeof(block_type)
 
static constexpr bool uses_secure_allocator = std::is_same_v<allocator_type, secure_allocator<block_type>>
 

Friends

template<template< typename > typename FriendAllocatorT>
class bitvector_base
 

Detailed Description

template<template< typename > typename AllocatorT>
class Botan::bitvector_base< AllocatorT >

An arbitrarily large bitvector with typical bit manipulation and convenient bitwise access methods. Don't use bitvector_base directly, but the type aliases::

  • bitvector - with a standard allocator
  • secure_bitvector - with a secure allocator that auto-scrubs the memory

Definition at line 231 of file bitvector.h.

Member Typedef Documentation

◆ allocator_type

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::allocator_type = AllocatorT<block_type>

Definition at line 235 of file bitvector.h.

◆ block_type

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::block_type = uint8_t

Definition at line 233 of file bitvector.h.

◆ const_iterator

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::const_iterator = detail::bitvector_iterator<const bitvector_base<AllocatorT>>

Definition at line 238 of file bitvector.h.

◆ iterator

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::iterator = detail::bitvector_iterator<bitvector_base<AllocatorT>>

Definition at line 237 of file bitvector.h.

◆ size_type

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::size_type = size_t

Definition at line 234 of file bitvector.h.

◆ value_type

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::value_type = block_type

Definition at line 236 of file bitvector.h.

Constructor & Destructor Documentation

◆ bitvector_base() [1/4]

template<template< typename > typename AllocatorT>
Botan::bitvector_base< AllocatorT >::bitvector_base ( )
inline

Definition at line 373 of file bitvector.h.

373: m_bits(0) {}

◆ bitvector_base() [2/4]

template<template< typename > typename AllocatorT>
Botan::bitvector_base< AllocatorT >::bitvector_base ( size_type bits)
inline

Definition at line 375 of file bitvector.h.

375: m_bits(bits), m_blocks(ceil_toblocks(bits)) {}

◆ bitvector_base() [3/4]

template<template< typename > typename AllocatorT>
Botan::bitvector_base< AllocatorT >::bitvector_base ( std::span< const uint8_t > bytes,
std::optional< size_type > bits = std::nullopt )
inline

Initialize the bitvector from a byte-array. Bits are taken byte-wise from least significant to most significant. Example::

bitvector[0] -> LSB(Byte[0]) bitvector[1] -> LSB+1(Byte[0]) ... bitvector[8] -> LSB(Byte[1])

Parameters
bytesThe byte vector to be loaded
bitsThe number of bits to be loaded. This must not be more than the number of bytes in bytes.

Definition at line 390 of file bitvector.h.

390 {
391 from_bytes(bytes, bits);
392 }
void from_bytes(std::span< const uint8_t > bytes, std::optional< size_type > bits=std::nullopt)
Definition bitvector.h:463

References Botan::bitvector_base< AllocatorT >::from_bytes().

◆ bitvector_base() [4/4]

template<template< typename > typename AllocatorT>
Botan::bitvector_base< AllocatorT >::bitvector_base ( std::initializer_list< block_type > blocks,
std::optional< size_type > bits = std::nullopt )
inline

Definition at line 394 of file bitvector.h.

394 :
395 m_bits(bits.value_or(blocks.size() * block_size_bits)), m_blocks(blocks.begin(), blocks.end()) {}
static constexpr size_type block_size_bits
Definition bitvector.h:241

Member Function Documentation

◆ _const_time_poison()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::_const_time_poison ( ) const
inlineconstexpr

Definition at line 875 of file bitvector.h.

875{ CT::poison(m_blocks); }
constexpr void poison(const T *p, size_t n)
Definition ct_utils.h:53

References Botan::CT::poison().

◆ _const_time_unpoison()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::_const_time_unpoison ( ) const
inlineconstexpr

Definition at line 877 of file bitvector.h.

877{ CT::unpoison(m_blocks); }
constexpr void unpoison(const T *p, size_t n)
Definition ct_utils.h:64

References Botan::CT::unpoison().

◆ all()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::all ( ) const
inline
Returns
true iff all bits are set in constant time

Definition at line 680 of file bitvector.h.

680{ return hamming_weight() == m_bits; }
size_type hamming_weight() const
Definition bitvector.h:419

References Botan::bitvector_base< AllocatorT >::hamming_weight().

◆ all_vartime()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::all_vartime ( ) const
inline
Returns
true iff all bits are set

Definition at line 672 of file bitvector.h.

672 {
673 return full_range_operation(
674 []<std::unsigned_integral BlockT>(BlockT block, BlockT mask) { return block == mask; }, *this);
675 }

◆ any()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::any ( ) const
inline
Returns
true iff at least one bit is set in constant time

Definition at line 667 of file bitvector.h.

667{ return !none(); }
bool none() const
Definition bitvector.h:657

References Botan::bitvector_base< AllocatorT >::none().

◆ any_vartime()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::any_vartime ( ) const
inline
Returns
true iff at least one bit is set

Definition at line 662 of file bitvector.h.

662{ return !none_vartime(); }
bool none_vartime() const
Definition bitvector.h:650

References Botan::bitvector_base< AllocatorT >::none_vartime().

◆ as()

template<template< typename > typename AllocatorT>
template<bitvectorish OutT>
OutT Botan::bitvector_base< AllocatorT >::as ( ) const
inline
Returns
copies this bitvector into a new bitvector of type OutT

Definition at line 429 of file bitvector.h.

429 {
430 return subvector<OutT>(0, size());
431 }
auto subvector(size_type pos, std::optional< size_type > length=std::nullopt) const
Definition bitvector.h:697
size_type size() const
Definition bitvector.h:399

References Botan::bitvector_base< AllocatorT >::size(), and Botan::bitvector_base< AllocatorT >::subvector().

Referenced by Botan::bitvector_base< AllocatorT >::to_bytes().

◆ at() [1/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::at ( size_type pos)
inline

Definition at line 566 of file bitvector.h.

566 {
567 check_offset(pos);
568 return ref(pos);
569 }

◆ at() [2/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::at ( size_type pos) const
inline

Definition at line 572 of file bitvector.h.

572 {
573 check_offset(pos);
574 return ref(pos);
575 }

◆ back() [1/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::back ( )
inline

Definition at line 582 of file bitvector.h.

582{ return ref(size() - 1); }

References Botan::bitvector_base< AllocatorT >::size().

◆ back() [2/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::back ( ) const
inline

Definition at line 585 of file bitvector.h.

585{ return ref(size() - 1); }

References Botan::bitvector_base< AllocatorT >::size().

◆ begin() [1/2]

template<template< typename > typename AllocatorT>
const_iterator Botan::bitvector_base< AllocatorT >::begin ( ) const
inlinenoexcept

Definition at line 887 of file bitvector.h.

887{ return const_iterator(this, 0); }
detail::bitvector_iterator< const bitvector_base< AllocatorT > > const_iterator
Definition bitvector.h:238

◆ begin() [2/2]

template<template< typename > typename AllocatorT>
iterator Botan::bitvector_base< AllocatorT >::begin ( )
inlinenoexcept

Definition at line 885 of file bitvector.h.

885{ return iterator(this, 0); }
detail::bitvector_iterator< bitvector_base< AllocatorT > > iterator
Definition bitvector.h:237

◆ capacity()

template<template< typename > typename AllocatorT>
size_type Botan::bitvector_base< AllocatorT >::capacity ( ) const
inline

Definition at line 535 of file bitvector.h.

535{ return m_blocks.capacity() * block_size_bits; }

References Botan::bitvector_base< AllocatorT >::block_size_bits.

◆ cbegin()

template<template< typename > typename AllocatorT>
const_iterator Botan::bitvector_base< AllocatorT >::cbegin ( ) const
inlinenoexcept

Definition at line 889 of file bitvector.h.

889{ return const_iterator(this, 0); }

◆ cend()

template<template< typename > typename AllocatorT>
const_iterator Botan::bitvector_base< AllocatorT >::cend ( )
inlinenoexcept

Definition at line 895 of file bitvector.h.

895{ return const_iterator(this, size()); }

References Botan::bitvector_base< AllocatorT >::size().

◆ ct_conditional_xor()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
void Botan::bitvector_base< AllocatorT >::ct_conditional_xor ( CT::Choice condition,
const OtherT & other )
inline

Implements::

if(condition) { *this ^= other; }

omitting runtime dependence on any of the parameters.

Definition at line 853 of file bitvector.h.

853 {
854 BOTAN_ASSERT_NOMSG(m_bits == other.m_bits);
855 BOTAN_ASSERT_NOMSG(m_blocks.size() == other.m_blocks.size());
856
857 auto maybe_xor = overloaded{
858 [m = CT::Mask<uint64_t>::from_choice(condition)](uint64_t lhs, uint64_t rhs) -> uint64_t {
859 return lhs ^ m.if_set_return(rhs);
860 },
861 [m = CT::Mask<uint32_t>::from_choice(condition)](uint32_t lhs, uint32_t rhs) -> uint32_t {
862 return lhs ^ m.if_set_return(rhs);
863 },
864 [m = CT::Mask<uint16_t>::from_choice(condition)](uint16_t lhs, uint16_t rhs) -> uint16_t {
865 return lhs ^ m.if_set_return(rhs);
866 },
867 [m = CT::Mask<uint8_t>::from_choice(condition)](uint8_t lhs, uint8_t rhs) -> uint8_t {
868 return lhs ^ m.if_set_return(rhs);
869 },
870 };
871
872 full_range_operation(maybe_xor, *this, unwrap_strong_type(other));
873 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
static constexpr Mask< T > from_choice(Choice c)
Definition ct_utils.h:413
constexpr decltype(auto) unwrap_strong_type(T &&t)
Generically unwraps a strong type to its underlying type.
overloaded(Ts...) -> overloaded< Ts... >

References BOTAN_ASSERT_NOMSG, Botan::CT::Mask< T >::from_choice(), and Botan::unwrap_strong_type().

◆ empty()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::empty ( ) const
inline

Definition at line 397 of file bitvector.h.

397{ return m_bits == 0; }

Referenced by Botan::bitvector_base< AllocatorT >::pop_back().

◆ end() [1/2]

template<template< typename > typename AllocatorT>
const_iterator Botan::bitvector_base< AllocatorT >::end ( ) const
inlinenoexcept

Definition at line 893 of file bitvector.h.

893{ return const_iterator(this, size()); }

References Botan::bitvector_base< AllocatorT >::size().

◆ end() [2/2]

template<template< typename > typename AllocatorT>
iterator Botan::bitvector_base< AllocatorT >::end ( )
inlinenoexcept

Definition at line 891 of file bitvector.h.

891{ return iterator(this, size()); }

References Botan::bitvector_base< AllocatorT >::size().

◆ equals()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
bool Botan::bitvector_base< AllocatorT >::equals ( const OtherT & other) const
inlinenoexcept
Returns
true if other contains the same bit pattern as this

Definition at line 448 of file bitvector.h.

448 {
449 return (*this ^ other).none();
450 }

◆ equals_vartime()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
bool Botan::bitvector_base< AllocatorT >::equals_vartime ( const OtherT & other) const
inlinenoexcept
Returns
true if other contains the same bit pattern as this

Definition at line 437 of file bitvector.h.

437 {
438 return size() == other.size() &&
439 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) { return lhs == rhs; },
440 *this,
441 unwrap_strong_type(other));
442 }

References Botan::bitvector_base< AllocatorT >::size(), and Botan::unwrap_strong_type().

◆ flip() [1/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::flip ( )
inline

Flips all currently allocated bits.

Definition at line 641 of file bitvector.h.

641 {
642 full_range_operation([](std::unsigned_integral auto block) -> decltype(block) { return ~block; }, *this);
643 zero_unused_bits();
644 return *this;
645 }

◆ flip() [2/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::flip ( size_type pos)
inline

Flips the bit at position pos.

Exceptions
Botan::Invalid_Argumentif pos is out of range

Definition at line 632 of file bitvector.h.

632 {
633 check_offset(pos);
634 ref(pos).flip();
635 return *this;
636 }

◆ from_bytes()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::from_bytes ( std::span< const uint8_t > bytes,
std::optional< size_type > bits = std::nullopt )
inline

Re-initialize the bitvector with the given bytes. See the respective constructor for details. This should be used only when trying to save allocations. Otherwise, use the constructor.

Parameters
bytesthe byte range to load bits from
bits(optional) if not all bytes should be loaded in full

Definition at line 463 of file bitvector.h.

463 {
464 m_bits = bits.value_or(bytes.size_bytes() * 8);
465 BOTAN_ARG_CHECK(m_bits <= bytes.size_bytes() * 8, "not enough data to load so many bits");
466 resize(m_bits);
467
468 // load as much aligned data as possible
469 const auto verbatim_blocks = m_bits / block_size_bits;
470 const auto verbatim_bytes = verbatim_blocks * block_size_bytes;
471 if(verbatim_blocks > 0) {
472 typecast_copy(std::span{m_blocks}.first(verbatim_blocks), bytes.first(verbatim_bytes));
473 }
474
475 // load remaining unaligned data
476 for(size_type i = verbatim_bytes * 8; i < m_bits; ++i) {
477 ref(i) = ((bytes[i >> 3] & (uint8_t(1) << (i & 7))) != 0);
478 }
479 }
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29
static constexpr size_type block_size_bytes
Definition bitvector.h:240
void resize(size_type bits)
Definition bitvector.h:539
constexpr void typecast_copy(ToR &&out, FromR &&in)
Definition mem_ops.h:179

References Botan::bitvector_base< AllocatorT >::block_size_bits, Botan::bitvector_base< AllocatorT >::block_size_bytes, BOTAN_ARG_CHECK, Botan::bitvector_base< AllocatorT >::resize(), and Botan::typecast_copy().

Referenced by Botan::bitvector_base< AllocatorT >::bitvector_base().

◆ front() [1/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::front ( )
inline

Definition at line 577 of file bitvector.h.

577{ return ref(0); }

◆ front() [2/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::front ( ) const
inline

Definition at line 580 of file bitvector.h.

580{ return ref(0); }

◆ hamming_weight()

template<template< typename > typename AllocatorT>
size_type Botan::bitvector_base< AllocatorT >::hamming_weight ( ) const
inline

Counts the number of 1-bits in the bitvector in constant time.

Returns
the "population count" (or hamming weight) of the bitvector

Definition at line 419 of file bitvector.h.

419 {
420 size_type acc = 0;
421 full_range_operation([&](std::unsigned_integral auto block) { acc += ct_popcount(block); }, *this);
422 return acc;
423 }
constexpr uint8_t ct_popcount(T x)
Definition bit_ops.h:261

References Botan::ct_popcount().

Referenced by Botan::bitvector_base< AllocatorT >::all(), and Botan::bitvector_base< AllocatorT >::none().

◆ has_odd_hamming_weight()

template<template< typename > typename AllocatorT>
CT::Choice Botan::bitvector_base< AllocatorT >::has_odd_hamming_weight ( ) const
inline
Returns
true iff the number of 1-bits in this is odd, false otherwise (constant time)

Definition at line 404 of file bitvector.h.

404 {
405 uint64_t acc = 0;
406 full_range_operation([&](std::unsigned_integral auto block) { acc ^= block; }, *this);
407
408 for(size_t i = (sizeof(acc) * 8) >> 1; i > 0; i >>= 1) {
409 acc ^= acc >> i;
410 }
411
412 return CT::Choice::from_int(acc & one);
413 }
static constexpr Choice from_int(T v)
Definition ct_utils.h:311

References Botan::CT::Choice::from_int().

◆ none()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::none ( ) const
inline
Returns
true iff no bit is set in constant time

Definition at line 657 of file bitvector.h.

657{ return hamming_weight() == 0; }

References Botan::bitvector_base< AllocatorT >::hamming_weight().

Referenced by Botan::bitvector_base< AllocatorT >::any().

◆ none_vartime()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::none_vartime ( ) const
inline
Returns
true iff no bit is set

Definition at line 650 of file bitvector.h.

650 {
651 return full_range_operation([](std::unsigned_integral auto block) { return block == 0; }, *this);
652 }

Referenced by Botan::bitvector_base< AllocatorT >::any_vartime().

◆ operator&=()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
auto & Botan::bitvector_base< AllocatorT >::operator&= ( const OtherT & other)
inline

Definition at line 822 of file bitvector.h.

822 {
823 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs & rhs; },
824 *this,
825 unwrap_strong_type(other));
826 return *this;
827 }

References Botan::unwrap_strong_type().

◆ operator[]() [1/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::operator[] ( size_type pos)
inline

Definition at line 682 of file bitvector.h.

682{ return ref(pos); }

◆ operator[]() [2/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::operator[] ( size_type pos) const
inline

Definition at line 685 of file bitvector.h.

685{ return ref(pos); }

◆ operator^=()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
auto & Botan::bitvector_base< AllocatorT >::operator^= ( const OtherT & other)
inline

Definition at line 830 of file bitvector.h.

830 {
831 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs ^ rhs; },
832 *this,
833 unwrap_strong_type(other));
834 return *this;
835 }

References Botan::unwrap_strong_type().

◆ operator|=()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
auto & Botan::bitvector_base< AllocatorT >::operator|= ( const OtherT & other)
inline

Definition at line 814 of file bitvector.h.

814 {
815 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs | rhs; },
816 *this,
817 unwrap_strong_type(other));
818 return *this;
819 }

References Botan::unwrap_strong_type().

◆ operator~()

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::operator~ ( )
inline

Definition at line 807 of file bitvector.h.

807 {
808 auto newbv = *this;
809 newbv.flip();
810 return newbv;
811 }

◆ pop_back()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::pop_back ( )
inline

◆ push_back()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::push_back ( bool bit)
inline

Definition at line 549 of file bitvector.h.

549 {
550 const auto i = size();
551 resize(i + 1);
552 ref(i) = bit;
553 }

References Botan::bitvector_base< AllocatorT >::resize(), and Botan::bitvector_base< AllocatorT >::size().

◆ reserve()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::reserve ( size_type bits)
inline

Definition at line 537 of file bitvector.h.

537{ m_blocks.reserve(ceil_toblocks(bits)); }

◆ resize()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::resize ( size_type bits)
inline

Definition at line 539 of file bitvector.h.

539 {
540 const auto new_number_of_blocks = ceil_toblocks(bits);
541 if(new_number_of_blocks != m_blocks.size()) {
542 m_blocks.resize(new_number_of_blocks);
543 }
544
545 m_bits = bits;
546 zero_unused_bits();
547 }

Referenced by Botan::bitvector_base< AllocatorT >::from_bytes(), Botan::bitvector_base< AllocatorT >::pop_back(), and Botan::bitvector_base< AllocatorT >::push_back().

◆ set() [1/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::set ( )
inline

Sets all currently allocated bits.

Definition at line 600 of file bitvector.h.

600 {
601 full_range_operation(
602 [](std::unsigned_integral auto block) -> decltype(block) { return static_cast<decltype(block)>(~0); },
603 *this);
604 zero_unused_bits();
605 return *this;
606 }

◆ set() [2/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::set ( size_type pos)
inline

Sets the bit at position pos.

Exceptions
Botan::Invalid_Argumentif pos is out of range

Definition at line 591 of file bitvector.h.

591 {
592 check_offset(pos);
593 ref(pos).set();
594 return *this;
595 }

◆ size()

◆ subvector() [1/2]

template<template< typename > typename AllocatorT>
template<typename OutT >
requires (std::unsigned_integral<strong_type_wrapped_type<OutT>> && !std::same_as<bool, strong_type_wrapped_type<OutT>>)
OutT Botan::bitvector_base< AllocatorT >::subvector ( size_type pos) const
inline

Extracts a subvector of bits as an unsigned integral type OutT starting from bit pos and copying exactly sizeof(OutT)*8 bits.

Hint: The bits are in big-endian order, i.e. the least significant bit is the 0th bit and the most significant bit it the n-th. Hence, addressing the bits with bitwise operations is done like so: bool bit = (out_int >> pos) & 1;

Definition at line 737 of file bitvector.h.

737 {
738 using result_t = strong_type_wrapped_type<OutT>;
739 constexpr size_t bits = sizeof(result_t) * 8;
740 BOTAN_ARG_CHECK(pos + bits <= size(), "Not enough bits to copy");
741 result_t out = 0;
742
743 if(pos % 8 == 0) {
744 out = load_le<result_t>(std::span{m_blocks}.subspan(block_index(pos)).template first<sizeof(result_t)>());
745 } else {
746 BitRangeOperator<const bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> op(*this, pos, bits);
747 range_operation(
748 [&](std::unsigned_integral auto integer) {
749 if constexpr(std::same_as<result_t, decltype(integer)>) {
750 out = integer;
751 }
752 },
753 op);
754 }
755
756 return wrap_strong_type<OutT>(out);
757 }
typename detail::wrapped_type_helper< std::remove_cvref_t< T > >::type strong_type_wrapped_type
Extracts the wrapped type from a strong type.
constexpr decltype(auto) wrap_strong_type(ParamT &&t)
Wraps a value into a caller-defined (strong) type.
constexpr auto load_le(ParamTs &&... params)
Definition loadstor.h:521

References BOTAN_ARG_CHECK, Botan::load_le(), Botan::bitvector_base< AllocatorT >::size(), and Botan::wrap_strong_type().

◆ subvector() [2/2]

template<template< typename > typename AllocatorT>
template<bitvectorish OutT = bitvector_base<AllocatorT>>
auto Botan::bitvector_base< AllocatorT >::subvector ( size_type pos,
std::optional< size_type > length = std::nullopt ) const
inline

Creates a new bitvector with a subsection of this bitvector starting at pos copying exactly length bits.

Definition at line 697 of file bitvector.h.

697 {
698 size_type bitlen = length.value_or(size() - pos);
699 BOTAN_ARG_CHECK(pos + bitlen <= size(), "Not enough bits to copy");
700
701 OutT newvector(bitlen);
702
703 // Handle bitvectors that are wrapped in strong types
704 auto& newvector_unwrapped = unwrap_strong_type(newvector);
705
706 if(bitlen > 0) {
707 if(pos % 8 == 0) {
708 copy_mem(
709 newvector_unwrapped.m_blocks,
710 std::span{m_blocks}.subspan(block_index(pos), block_index(pos + bitlen - 1) - block_index(pos) + 1));
711 } else {
712 BitRangeOperator<const bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> from_op(
713 *this, pos, bitlen);
714 BitRangeOperator<strong_type_wrapped_type<OutT>> to_op(
715 unwrap_strong_type(newvector_unwrapped), 0, bitlen);
716 range_operation([](auto /* to */, auto from) { return from; }, to_op, from_op);
717 }
718
719 newvector_unwrapped.zero_unused_bits();
720 }
721
722 return newvector;
723 }
constexpr auto bitlen(size_t x)
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:147

References Botan::bitlen(), BOTAN_ARG_CHECK, Botan::copy_mem(), Botan::bitvector_base< AllocatorT >::size(), and Botan::unwrap_strong_type().

Referenced by Botan::bitvector_base< AllocatorT >::as().

◆ subvector_replace()

template<template< typename > typename AllocatorT>
template<typename InT >
requires (std::unsigned_integral<strong_type_wrapped_type<InT>> && !std::same_as<bool, InT>)
void Botan::bitvector_base< AllocatorT >::subvector_replace ( size_type pos,
InT value )
inline

Replaces a subvector of bits with the bits of another bitvector value starting at bit pos. The number of bits to replace is determined by the size of value.

Note
This is currently supported for byte-aligned pos only.
Exceptions
Not_Implementedwhen called with pos not divisible by 8.
Parameters
posthe position to start replacing bits
valuethe bitvector to copy bits from

Definition at line 773 of file bitvector.h.

773 {
775 constexpr size_t bits = sizeof(in_t) * 8;
776 BOTAN_ARG_CHECK(pos + bits <= size(), "Not enough bits to replace");
777
778 if(pos % 8 == 0) {
779 store_le(std::span{m_blocks}.subspan(block_index(pos)).template first<sizeof(in_t)>(),
780 unwrap_strong_type(value));
781 } else {
782 BitRangeOperator<bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> op(*this, pos, bits);
783 range_operation(
784 [&]<std::unsigned_integral BlockT>(BlockT block) -> BlockT {
785 if constexpr(std::same_as<in_t, BlockT>) {
786 return unwrap_strong_type(value);
787 } else {
788 // This should never be reached. BOTAN_ASSERT_UNREACHABLE()
789 // caused warning "unreachable code" on MSVC, though. You
790 // don't say!
791 //
792 // Returning the given block back, is the most reasonable
793 // thing to do in this case, though.
794 return block;
795 }
796 },
797 op);
798 }
799 }
constexpr auto store_le(ParamTs &&... params)
Definition loadstor.h:764

References BOTAN_ARG_CHECK, Botan::bitvector_base< AllocatorT >::size(), Botan::store_le(), and Botan::unwrap_strong_type().

◆ to_bytes() [1/2]

template<template< typename > typename AllocatorT>
template<concepts::resizable_byte_buffer OutT = std::conditional_t<uses_secure_allocator, secure_vector<uint8_t>, std::vector<uint8_t>>>
OutT Botan::bitvector_base< AllocatorT >::to_bytes ( ) const
inline

Renders the bitvector into a byte array. By default, this will use std::vector<uint8_t> or Botan::secure_vector<uint8_t>, depending on the allocator used by the bitvector. The rendering is compatible with the bit layout explained in the respective constructor.

Definition at line 489 of file bitvector.h.

489 {
490 OutT out(ceil_tobytes(m_bits));
491 to_bytes(out);
492 return out;
493 }
OutT to_bytes() const
Definition bitvector.h:489
constexpr T ceil_tobytes(T bits)
Definition bit_ops.h:168

References Botan::ceil_tobytes(), and Botan::bitvector_base< AllocatorT >::to_bytes().

Referenced by Botan::Classic_McEliece_PrivateKeyInternal::serialize(), and Botan::bitvector_base< AllocatorT >::to_bytes().

◆ to_bytes() [2/2]

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::to_bytes ( std::span< uint8_t > out) const
inline

Renders the bitvector into a properly sized byte range.

Parameters
outa byte range that has a length of at least ceil_tobytes(size()).

Definition at line 500 of file bitvector.h.

500 {
501 const auto bytes_needed = ceil_tobytes(m_bits);
502 BOTAN_ARG_CHECK(bytes_needed <= out.size_bytes(), "Not enough space to render bitvector");
503
504 // copy as much aligned data as possible
505 const auto verbatim_blocks = m_bits / block_size_bits;
506 const auto verbatim_bytes = verbatim_blocks * block_size_bytes;
507 if(verbatim_blocks > 0) {
508 typecast_copy(out.first(verbatim_bytes), std::span{m_blocks}.first(verbatim_blocks));
509 }
510
511 // copy remaining unaligned data
512 clear_mem(out.subspan(verbatim_bytes));
513 for(size_type i = verbatim_bytes * 8; i < m_bits; ++i) {
514 out[i >> 3] |= ref(i).template as<uint8_t>() << (i & 7);
515 }
516 }
constexpr void clear_mem(T *ptr, size_t n)
Definition mem_ops.h:121

References Botan::bitvector_base< AllocatorT >::as(), Botan::bitvector_base< AllocatorT >::block_size_bits, Botan::bitvector_base< AllocatorT >::block_size_bytes, BOTAN_ARG_CHECK, Botan::ceil_tobytes(), Botan::clear_mem(), and Botan::typecast_copy().

◆ to_string()

template<template< typename > typename AllocatorT>
std::string Botan::bitvector_base< AllocatorT >::to_string ( ) const
inline

Renders this bitvector into a sequence of "0"s and "1"s. This is meant for debugging purposes and is not efficient.

Definition at line 522 of file bitvector.h.

522 {
523 std::stringstream ss;
524 for(size_type i = 0; i < size(); ++i) {
525 ss << ref(i);
526 }
527 return ss.str();
528 }

References Botan::bitvector_base< AllocatorT >::size().

◆ unset() [1/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::unset ( )
inline

Unsets all currently allocated bits.

Definition at line 621 of file bitvector.h.

621 {
622 full_range_operation(
623 [](std::unsigned_integral auto block) -> decltype(block) { return static_cast<decltype(block)>(0); },
624 *this);
625 return *this;
626 }

◆ unset() [2/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::unset ( size_type pos)
inline

Unsets the bit at position pos.

Exceptions
Botan::Invalid_Argumentif pos is out of range

Definition at line 612 of file bitvector.h.

612 {
613 check_offset(pos);
614 ref(pos).unset();
615 return *this;
616 }

Friends And Related Symbol Documentation

◆ bitvector_base

template<template< typename > typename AllocatorT>
template<template< typename > typename FriendAllocatorT>
friend class bitvector_base
friend

Definition at line 246 of file bitvector.h.

Member Data Documentation

◆ block_size_bits

template<template< typename > typename AllocatorT>
size_type Botan::bitvector_base< AllocatorT >::block_size_bits = block_size_bytes * 8
staticconstexpr

◆ block_size_bytes

template<template< typename > typename AllocatorT>
size_type Botan::bitvector_base< AllocatorT >::block_size_bytes = sizeof(block_type)
staticconstexpr

◆ uses_secure_allocator

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::uses_secure_allocator = std::is_same_v<allocator_type, secure_allocator<block_type>>
staticconstexpr

Definition at line 242 of file bitvector.h.


The documentation for this class was generated from the following file: