Coverage Report

Created: 2025-04-11 06:34

/src/botan/build/include/internal/botan/internal/bitvector.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * An abstraction for an arbitrarily large bitvector that can
3
 * optionally use the secure_allocator. All bitwise accesses and all
4
 * constructors are implemented in constant time. Otherwise, only methods
5
 * with the "ct_" pre-fix run in constant time.
6
 *
7
 * (C) 2023-2024 Jack Lloyd
8
 * (C) 2023-2024 René Meusel, Rohde & Schwarz Cybersecurity
9
 *
10
 * Botan is released under the Simplified BSD License (see license.txt)
11
 */
12
13
#ifndef BOTAN_BIT_VECTOR_H_
14
#define BOTAN_BIT_VECTOR_H_
15
16
#include <botan/concepts.h>
17
#include <botan/exceptn.h>
18
#include <botan/mem_ops.h>
19
#include <botan/secmem.h>
20
#include <botan/strong_type.h>
21
#include <botan/internal/bit_ops.h>
22
#include <botan/internal/ct_utils.h>
23
#include <botan/internal/loadstor.h>
24
#include <botan/internal/stl_util.h>
25
26
#include <memory>
27
#include <optional>
28
#include <span>
29
#include <sstream>
30
#include <string>
31
#include <utility>
32
#include <vector>
33
34
namespace Botan {
35
36
template <template <typename> typename AllocatorT>
37
class bitvector_base;
38
39
template <typename T>
40
struct is_bitvector : std::false_type {};
41
42
template <template <typename> typename T>
43
struct is_bitvector<bitvector_base<T>> : std::true_type {};
44
45
template <typename T>
46
constexpr static bool is_bitvector_v = is_bitvector<T>::value;
47
48
template <typename T>
49
concept bitvectorish = is_bitvector_v<strong_type_wrapped_type<T>>;
50
51
namespace detail {
52
53
template <typename T0, typename... Ts>
54
struct first_type {
55
      using type = T0;
56
};
57
58
// get the first type from a parameter pack
59
// TODO: C++26 will bring Parameter Pack indexing:
60
//       using first_t = Ts...[0];
61
template <typename... Ts>
62
   requires(sizeof...(Ts) > 0)
63
using first_t = typename first_type<Ts...>::type;
64
65
// get the first object from a parameter pack
66
// TODO: C++26 will bring Parameter Pack indexing:
67
//       auto first = s...[0];
68
template <typename T0, typename... Ts>
69
0
constexpr static first_t<T0, Ts...> first(T0&& t, Ts&&...) {
70
0
   return std::forward<T0>(t);
71
0
}
Unexecuted instantiation: cmce_decaps.cpp:Botan::detail::first_type<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&>::type Botan::detail::first<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&)
Unexecuted instantiation: cmce_decaps.cpp:Botan::detail::first_type<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&>::type Botan::detail::first<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&)
Unexecuted instantiation: cmce_decaps.cpp:Botan::detail::first_type<std::__1::span<unsigned long const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned long const, 18446744073709551615ul>&>(std::__1::span<unsigned long const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_decaps.cpp:Botan::detail::first_type<std::__1::span<unsigned int const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned int const, 18446744073709551615ul>&>(std::__1::span<unsigned int const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_decaps.cpp:Botan::detail::first_type<std::__1::span<unsigned short const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned short const, 18446744073709551615ul>&>(std::__1::span<unsigned short const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_keys_internal.cpp:Botan::detail::first_type<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&>::type Botan::detail::first<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&)
Unexecuted instantiation: cmce_keys_internal.cpp:Botan::detail::first_type<std::__1::span<unsigned long const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned long const, 18446744073709551615ul>&>(std::__1::span<unsigned long const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_keys_internal.cpp:Botan::detail::first_type<std::__1::span<unsigned int const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned int const, 18446744073709551615ul>&>(std::__1::span<unsigned int const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_keys_internal.cpp:Botan::detail::first_type<std::__1::span<unsigned short const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned short const, 18446744073709551615ul>&>(std::__1::span<unsigned short const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_keys_internal.cpp:Botan::detail::first_type<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&>::type Botan::detail::first<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&)
Unexecuted instantiation: cmce_keys_internal.cpp:Botan::detail::first_type<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&>::type Botan::detail::first<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&)
Unexecuted instantiation: cmce_keys_internal.cpp:Botan::detail::first_type<std::__1::span<unsigned long, 18446744073709551615ul>&, std::__1::span<unsigned long const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned long, 18446744073709551615ul>&, std::__1::span<unsigned long const, 18446744073709551615ul>&>(std::__1::span<unsigned long, 18446744073709551615ul>&, std::__1::span<unsigned long const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_keys_internal.cpp:Botan::detail::first_type<std::__1::span<unsigned int, 18446744073709551615ul>&, std::__1::span<unsigned int const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned int, 18446744073709551615ul>&, std::__1::span<unsigned int const, 18446744073709551615ul>&>(std::__1::span<unsigned int, 18446744073709551615ul>&, std::__1::span<unsigned int const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_keys_internal.cpp:Botan::detail::first_type<std::__1::span<unsigned short, 18446744073709551615ul>&, std::__1::span<unsigned short const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned short, 18446744073709551615ul>&, std::__1::span<unsigned short const, 18446744073709551615ul>&>(std::__1::span<unsigned short, 18446744073709551615ul>&, std::__1::span<unsigned short const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_matrix.cpp:Botan::detail::first_type<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&>::type Botan::detail::first<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&)
Unexecuted instantiation: cmce_matrix.cpp:Botan::detail::first_type<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&>::type Botan::detail::first<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&)
Unexecuted instantiation: cmce_matrix.cpp:Botan::detail::first_type<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&>::type Botan::detail::first<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&)
Unexecuted instantiation: cmce_matrix.cpp:Botan::detail::first_type<std::__1::span<unsigned long, 18446744073709551615ul>&, std::__1::span<unsigned long const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned long, 18446744073709551615ul>&, std::__1::span<unsigned long const, 18446744073709551615ul>&>(std::__1::span<unsigned long, 18446744073709551615ul>&, std::__1::span<unsigned long const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_matrix.cpp:Botan::detail::first_type<std::__1::span<unsigned int, 18446744073709551615ul>&, std::__1::span<unsigned int const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned int, 18446744073709551615ul>&, std::__1::span<unsigned int const, 18446744073709551615ul>&>(std::__1::span<unsigned int, 18446744073709551615ul>&, std::__1::span<unsigned int const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_matrix.cpp:Botan::detail::first_type<std::__1::span<unsigned short, 18446744073709551615ul>&, std::__1::span<unsigned short const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned short, 18446744073709551615ul>&, std::__1::span<unsigned short const, 18446744073709551615ul>&>(std::__1::span<unsigned short, 18446744073709551615ul>&, std::__1::span<unsigned short const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_matrix.cpp:Botan::detail::first_type<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&>::type Botan::detail::first<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>&)
Unexecuted instantiation: cmce_matrix.cpp:Botan::detail::first_type<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&>::type Botan::detail::first<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>&)
Unexecuted instantiation: cmce_matrix.cpp:Botan::detail::first_type<std::__1::span<unsigned long const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned long const, 18446744073709551615ul>&>(std::__1::span<unsigned long const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_matrix.cpp:Botan::detail::first_type<std::__1::span<unsigned int const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned int const, 18446744073709551615ul>&>(std::__1::span<unsigned int const, 18446744073709551615ul>&)
Unexecuted instantiation: cmce_matrix.cpp:Botan::detail::first_type<std::__1::span<unsigned short const, 18446744073709551615ul>&>::type Botan::detail::first<std::__1::span<unsigned short const, 18446744073709551615ul>&>(std::__1::span<unsigned short const, 18446744073709551615ul>&)
72
73
template <typename OutT, typename>
74
using as = OutT;
75
76
template <typename FnT, std::unsigned_integral BlockT, typename... ParamTs>
77
using blockwise_processing_callback_return_type = std::invoke_result_t<FnT, as<BlockT, ParamTs>...>;
78
79
template <typename FnT, typename BlockT, typename... ParamTs>
80
concept is_blockwise_processing_callback_return_type =
81
   std::unsigned_integral<BlockT> &&
82
   (std::same_as<BlockT, blockwise_processing_callback_return_type<FnT, BlockT, ParamTs...>> ||
83
    std::same_as<bool, blockwise_processing_callback_return_type<FnT, BlockT, ParamTs...>> ||
84
    std::same_as<void, blockwise_processing_callback_return_type<FnT, BlockT, ParamTs...>>);
85
86
template <typename FnT, typename... ParamTs>
87
concept blockwise_processing_callback_without_mask =
88
   is_blockwise_processing_callback_return_type<FnT, uint8_t, ParamTs...> &&
89
   is_blockwise_processing_callback_return_type<FnT, uint16_t, ParamTs...> &&
90
   is_blockwise_processing_callback_return_type<FnT, uint32_t, ParamTs...> &&
91
   is_blockwise_processing_callback_return_type<FnT, uint64_t, ParamTs...>;
92
93
template <typename FnT, typename... ParamTs>
94
concept blockwise_processing_callback_with_mask =
95
   is_blockwise_processing_callback_return_type<FnT, uint8_t, ParamTs..., uint8_t /* mask */> &&
96
   is_blockwise_processing_callback_return_type<FnT, uint16_t, ParamTs..., uint16_t /* mask */> &&
97
   is_blockwise_processing_callback_return_type<FnT, uint32_t, ParamTs..., uint32_t /* mask */> &&
98
   is_blockwise_processing_callback_return_type<FnT, uint64_t, ParamTs..., uint64_t /* mask */>;
99
100
/**
101
 * Defines the callback constraints for the BitRangeOperator. For further
102
 * details, see bitvector_base::range_operation().
103
 */
104
template <typename FnT, typename... ParamTs>
105
concept blockwise_processing_callback = blockwise_processing_callback_with_mask<FnT, ParamTs...> ||
106
                                        blockwise_processing_callback_without_mask<FnT, ParamTs...>;
107
108
template <typename FnT, typename... ParamTs>
109
concept manipulating_blockwise_processing_callback =
110
   (blockwise_processing_callback_without_mask<FnT, ParamTs...> &&
111
    std::same_as<uint32_t, blockwise_processing_callback_return_type<FnT, uint32_t, ParamTs...>>) ||
112
   (blockwise_processing_callback_with_mask<FnT, ParamTs...> &&
113
    std::same_as<uint32_t, blockwise_processing_callback_return_type<FnT, uint32_t, ParamTs..., first_t<ParamTs...>>>);
114
115
template <typename FnT, typename... ParamTs>
116
concept predicate_blockwise_processing_callback =
117
   (blockwise_processing_callback_without_mask<FnT, ParamTs...> &&
118
    std::same_as<bool, blockwise_processing_callback_return_type<FnT, uint32_t, ParamTs...>>) ||
119
   (blockwise_processing_callback_with_mask<FnT, ParamTs...> &&
120
    std::same_as<bool, blockwise_processing_callback_return_type<FnT, uint32_t, ParamTs..., first_t<ParamTs...>>>);
121
122
template <typename T>
123
class bitvector_iterator {
124
   private:
125
      using size_type = typename T::size_type;
126
127
   public:
128
      using difference_type = std::make_signed_t<size_type>;
129
      using value_type = std::remove_const_t<decltype(std::declval<T>().at(0))>;
130
      using pointer = value_type*;
131
      using reference = value_type&;
132
133
      // TODO: technically, this could be a random access iterator
134
      using iterator_category = std::bidirectional_iterator_tag;
135
136
   public:
137
      bitvector_iterator() = default;
138
      ~bitvector_iterator() = default;
139
140
      bitvector_iterator(T* bitvector, size_t offset) : m_bitvector(bitvector) { update(offset); }
141
142
      bitvector_iterator(const bitvector_iterator& other) noexcept : m_bitvector(other.m_bitvector) {
143
         update(other.m_offset);
144
      }
145
146
      bitvector_iterator(bitvector_iterator&& other) noexcept : m_bitvector(other.m_bitvector) {
147
         update(other.m_offset);
148
      }
149
150
      bitvector_iterator& operator=(const bitvector_iterator& other) noexcept {
151
         if(this != &other) {
152
            m_bitvector = other.m_bitvector;
153
            update(other.m_offset);
154
         }
155
         return *this;
156
      }
157
158
      bitvector_iterator& operator=(bitvector_iterator&& other) noexcept {
159
         m_bitvector = other.m_bitvector;
160
         update(other.m_offset);
161
         return *this;
162
      }
163
164
      bitvector_iterator& operator++() noexcept {
165
         update(signed_offset() + 1);
166
         return *this;
167
      }
168
169
      bitvector_iterator operator++(int) noexcept {
170
         auto copy = *this;
171
         update(signed_offset() + 1);
172
         return copy;
173
      }
174
175
      bitvector_iterator& operator--() noexcept {
176
         update(signed_offset() - 1);
177
         return *this;
178
      }
179
180
      bitvector_iterator operator--(int) noexcept {
181
         auto copy = *this;
182
         update(signed_offset() - 1);
183
         return copy;
184
      }
185
186
      std::partial_ordering operator<=>(const bitvector_iterator& other) const noexcept {
187
         if(m_bitvector == other.m_bitvector) {
188
            return m_offset <=> other.m_offset;
189
         } else {
190
            return std::partial_ordering::unordered;
191
         }
192
      }
193
194
      bool operator==(const bitvector_iterator& other) const noexcept {
195
         return m_bitvector == other.m_bitvector && m_offset == other.m_offset;
196
      }
197
198
      reference operator*() const { return m_bitref.value(); }
199
200
      pointer operator->() const { return &(m_bitref.value()); }
201
202
   private:
203
0
      void update(size_type new_offset) {
204
0
         m_offset = new_offset;
205
0
         if(m_offset < m_bitvector->size()) {
206
0
            m_bitref.emplace((*m_bitvector)[m_offset]);
207
0
         } else {
208
0
            // end() iterator
209
0
            m_bitref.reset();
210
0
         }
211
0
      }
Unexecuted instantiation: Botan::detail::bitvector_iterator<Botan::bitvector_base<Botan::secure_allocator> >::update(unsigned long)
Unexecuted instantiation: Botan::detail::bitvector_iterator<Botan::bitvector_base<Botan::secure_allocator> const>::update(unsigned long)
212
213
      difference_type signed_offset() const { return static_cast<difference_type>(m_offset); }
214
215
   private:
216
      T* m_bitvector;
217
      size_type m_offset;
218
      mutable std::optional<value_type> m_bitref;
219
};
220
221
}  // namespace detail
222
223
/**
224
 * An arbitrarily large bitvector with typical bit manipulation and convenient
225
 * bitwise access methods. Don't use `bitvector_base` directly, but the type
226
 * aliases::
227
 *
228
 *    * bitvector         - with a standard allocator
229
 *    * secure_bitvector  - with a secure allocator that auto-scrubs the memory
230
 */
231
template <template <typename> typename AllocatorT>
232
class bitvector_base final {
233
   public:
234
      using block_type = uint8_t;
235
      using size_type = size_t;
236
      using allocator_type = AllocatorT<block_type>;
237
      using value_type = block_type;
238
      using iterator = detail::bitvector_iterator<bitvector_base<AllocatorT>>;
239
      using const_iterator = detail::bitvector_iterator<const bitvector_base<AllocatorT>>;
240
241
      static constexpr size_type block_size_bytes = sizeof(block_type);
242
      static constexpr size_type block_size_bits = block_size_bytes * 8;
243
      static constexpr bool uses_secure_allocator = std::is_same_v<allocator_type, secure_allocator<block_type>>;
244
245
   private:
246
      template <template <typename> typename FriendAllocatorT>
247
      friend class bitvector_base;
248
249
      static constexpr block_type one = block_type(1);
250
251
      static constexpr size_type block_offset_shift = size_type(3) + ceil_log2(block_size_bytes);
252
      static constexpr size_type block_index_mask = (one << block_offset_shift) - 1;
253
254
0
      static constexpr size_type block_index(size_type pos) { return pos >> block_offset_shift; }
255
256
0
      static constexpr size_type block_offset(size_type pos) { return pos & block_index_mask; }
257
258
   private:
259
      /**
260
       * Internal helper to wrap a single bit in the bitvector and provide
261
       * certain convenience access methods.
262
       */
263
      template <typename BlockT>
264
         requires std::same_as<block_type, std::remove_cv_t<BlockT>>
265
      class bitref_base {
266
         private:
267
            friend class bitvector_base<AllocatorT>;
268
269
            constexpr bitref_base(std::span<BlockT> blocks, size_type pos) noexcept :
270
0
                  m_block(blocks[block_index(pos)]), m_mask(one << block_offset(pos)) {}
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::bitref_base<unsigned char const>::bitref_base(std::__1::span<unsigned char const, 18446744073709551615ul>, unsigned long)
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::bitref_base<unsigned char>::bitref_base(std::__1::span<unsigned char, 18446744073709551615ul>, unsigned long)
271
272
         public:
273
            bitref_base() = delete;
274
            bitref_base(const bitref_base&) noexcept = default;
275
            bitref_base(bitref_base&&) noexcept = default;
276
            bitref_base& operator=(const bitref_base&) = delete;
277
            bitref_base& operator=(bitref_base&&) = delete;
278
279
            ~bitref_base() = default;
280
281
         public:
282
0
            constexpr operator bool() const noexcept { return is_set(); }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::bitref_base<unsigned char const>::operator bool() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::bitref_base<unsigned char>::operator bool() const
283
284
0
            constexpr bool is_set() const noexcept { return (m_block & m_mask) > 0; }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::bitref_base<unsigned char const>::is_set() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::bitref_base<unsigned char>::is_set() const
285
286
            template <std::integral T>
287
0
            constexpr T as() const noexcept {
288
0
               return static_cast<T>(is_set());
289
0
            }
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE11bitref_baseIKhE2asITkNSt3__18integralEhEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE11bitref_baseIhE2asITkNSt3__18integralEmEET_v
290
291
0
            constexpr CT::Choice as_choice() const noexcept {
292
0
               return CT::Choice::from_int(static_cast<BlockT>(m_block & m_mask));
293
0
            }
294
295
         protected:
296
            BlockT& m_block;  // NOLINT(*-non-private-member-variables-in-classes)
297
            BlockT m_mask;    // NOLINT(*-non-private-member-variables-in-classes)
298
      };
299
300
   public:
301
      /**
302
       * Wraps a constant reference into the bitvector. Bit can be accessed
303
       * but not modified.
304
       */
305
      template <typename BlockT>
306
      class bitref final : public bitref_base<BlockT> {
307
         public:
308
            using bitref_base<BlockT>::bitref_base;
309
      };
310
311
      /**
312
       * Wraps a modifiable reference into the bitvector. Bit may be accessed
313
       * and modified (e.g. flipped or XOR'ed).
314
       *
315
       * Constant-time operations are used for the bit manipulations. The
316
       * location of the bit in the bit vector may be leaked, though.
317
       */
318
      template <typename BlockT>
319
         requires(!std::is_const_v<BlockT>)
320
      class bitref<BlockT> : public bitref_base<BlockT> {
321
         public:
322
            using bitref_base<BlockT>::bitref_base;
323
324
            ~bitref() = default;
325
            bitref(const bitref&) noexcept = default;
326
            bitref(bitref&&) noexcept = default;
327
328
            constexpr bitref& set() noexcept {
329
               this->m_block |= this->m_mask;
330
               return *this;
331
            }
332
333
            constexpr bitref& unset() noexcept {
334
               this->m_block &= ~this->m_mask;
335
               return *this;
336
            }
337
338
            constexpr bitref& flip() noexcept {
339
               this->m_block ^= this->m_mask;
340
               return *this;
341
            }
342
343
            // NOLINTBEGIN
344
345
0
            constexpr bitref& operator=(bool bit) noexcept {
346
0
               this->m_block =
347
0
                  CT::Mask<BlockT>::expand(bit).select(this->m_mask | this->m_block, this->m_block & ~this->m_mask);
348
0
               return *this;
349
0
            }
350
351
            constexpr bitref& operator=(const bitref& bit) noexcept { return *this = bit.is_set(); }
352
353
            constexpr bitref& operator=(bitref&& bit) noexcept { return *this = bit.is_set(); }
354
355
            // NOLINTEND
356
357
            constexpr bitref& operator&=(bool other) noexcept {
358
               this->m_block &= ~CT::Mask<BlockT>::expand(other).if_not_set_return(this->m_mask);
359
               return *this;
360
            }
361
362
            constexpr bitref& operator|=(bool other) noexcept {
363
               this->m_block |= CT::Mask<BlockT>::expand(other).if_set_return(this->m_mask);
364
               return *this;
365
            }
366
367
0
            constexpr bitref& operator^=(bool other) noexcept {
368
0
               this->m_block ^= CT::Mask<BlockT>::expand(other).if_set_return(this->m_mask);
369
0
               return *this;
370
0
            }
371
      };
372
373
   public:
374
0
      bitvector_base() : m_bits(0) {}
375
376
0
      bitvector_base(size_type bits) : m_bits(bits), m_blocks(ceil_toblocks(bits)) {}
377
378
      /**
379
       * Initialize the bitvector from a byte-array. Bits are taken byte-wise
380
       * from least significant to most significant. Example::
381
       *
382
       *    bitvector[0] -> LSB(Byte[0])
383
       *    bitvector[1] -> LSB+1(Byte[0])
384
       *    ...
385
       *    bitvector[8] -> LSB(Byte[1])
386
       *
387
       * @param bytes The byte vector to be loaded
388
       * @param bits  The number of bits to be loaded. This must not be more
389
       *              than the number of bytes in @p bytes.
390
       */
391
0
      bitvector_base(std::span<const uint8_t> bytes, std::optional<size_type> bits = std::nullopt) {
392
0
         from_bytes(bytes, bits);
393
0
      }
394
395
      bitvector_base(std::initializer_list<block_type> blocks, std::optional<size_type> bits = std::nullopt) :
396
0
            m_bits(bits.value_or(blocks.size() * block_size_bits)), m_blocks(blocks.begin(), blocks.end()) {}
Unexecuted instantiation: Botan::bitvector_base<std::__1::allocator>::bitvector_base(std::initializer_list<unsigned char>, std::__1::optional<unsigned long>)
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::bitvector_base(std::initializer_list<unsigned char>, std::__1::optional<unsigned long>)
397
398
      bool empty() const { return m_bits == 0; }
399
400
0
      size_type size() const { return m_bits; }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::size() const
Unexecuted instantiation: Botan::bitvector_base<std::__1::allocator>::size() const
401
402
      /**
403
       * @returns true iff the number of 1-bits in this is odd, false otherwise (constant time)
404
       */
405
0
      CT::Choice has_odd_hamming_weight() const {
406
0
         uint64_t acc = 0;
407
0
         full_range_operation([&](std::unsigned_integral auto block) { acc ^= block; }, *this);
Unexecuted instantiation: auto Botan::bitvector_base<Botan::secure_allocator>::has_odd_hamming_weight() const::{lambda(auto:1)#1}::operator()<unsigned long>(unsigned long) const
Unexecuted instantiation: auto Botan::bitvector_base<Botan::secure_allocator>::has_odd_hamming_weight() const::{lambda(auto:1)#1}::operator()<unsigned int>(unsigned int) const
Unexecuted instantiation: auto Botan::bitvector_base<Botan::secure_allocator>::has_odd_hamming_weight() const::{lambda(auto:1)#1}::operator()<unsigned short>(unsigned short) const
Unexecuted instantiation: auto Botan::bitvector_base<Botan::secure_allocator>::has_odd_hamming_weight() const::{lambda(auto:1)#1}::operator()<unsigned char>(unsigned char) const
408
409
0
         for(size_t i = (sizeof(acc) * 8) >> 1; i > 0; i >>= 1) {
410
0
            acc ^= acc >> i;
411
0
         }
412
413
0
         return CT::Choice::from_int(acc & one);
414
0
      }
415
416
      /**
417
       * Counts the number of 1-bits in the bitvector in constant time.
418
       * @returns the "population count" (or hamming weight) of the bitvector
419
       */
420
0
      size_type hamming_weight() const {
421
0
         size_type acc = 0;
422
0
         full_range_operation([&](std::unsigned_integral auto block) { acc += ct_popcount(block); }, *this);
Unexecuted instantiation: auto Botan::bitvector_base<Botan::secure_allocator>::hamming_weight() const::{lambda(auto:1)#1}::operator()<unsigned long>(unsigned long) const
Unexecuted instantiation: auto Botan::bitvector_base<Botan::secure_allocator>::hamming_weight() const::{lambda(auto:1)#1}::operator()<unsigned int>(unsigned int) const
Unexecuted instantiation: auto Botan::bitvector_base<Botan::secure_allocator>::hamming_weight() const::{lambda(auto:1)#1}::operator()<unsigned short>(unsigned short) const
Unexecuted instantiation: auto Botan::bitvector_base<Botan::secure_allocator>::hamming_weight() const::{lambda(auto:1)#1}::operator()<unsigned char>(unsigned char) const
423
0
         return acc;
424
0
      }
425
426
      /**
427
       * @returns copies this bitvector into a new bitvector of type @p OutT
428
       */
429
      template <bitvectorish OutT>
430
0
      OutT as() const {
431
0
         return subvector<OutT>(0, size());
432
0
      }
433
434
      /**
435
       * @returns true if @p other contains the same bit pattern as this
436
       */
437
      template <bitvectorish OtherT>
438
      bool equals_vartime(const OtherT& other) const noexcept {
439
         return size() == other.size() &&
440
                full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) { return lhs == rhs; },
441
                                     *this,
442
                                     unwrap_strong_type(other));
443
      }
444
445
      /**
446
       * @returns true if @p other contains the same bit pattern as this
447
       */
448
      template <bitvectorish OtherT>
449
0
      bool equals(const OtherT& other) const noexcept {
450
0
         return (*this ^ other).none();
451
0
      }
452
453
      /// @name Serialization
454
      /// @{
455
456
      /**
457
       * Re-initialize the bitvector with the given bytes. See the respective
458
       * constructor for details. This should be used only when trying to save
459
       * allocations. Otherwise, use the constructor.
460
       *
461
       * @param bytes  the byte range to load bits from
462
       * @param bits   (optional) if not all @p bytes should be loaded in full
463
       */
464
0
      void from_bytes(std::span<const uint8_t> bytes, std::optional<size_type> bits = std::nullopt) {
465
0
         m_bits = bits.value_or(bytes.size_bytes() * 8);
466
0
         BOTAN_ARG_CHECK(m_bits <= bytes.size_bytes() * 8, "not enough data to load so many bits");
467
0
         resize(m_bits);
468
469
         // load as much aligned data as possible
470
0
         const auto verbatim_blocks = m_bits / block_size_bits;
471
0
         const auto verbatim_bytes = verbatim_blocks * block_size_bytes;
472
0
         if(verbatim_blocks > 0) {
473
0
            typecast_copy(std::span{m_blocks}.first(verbatim_blocks), bytes.first(verbatim_bytes));
474
0
         }
475
476
         // load remaining unaligned data
477
0
         for(size_type i = verbatim_bytes * 8; i < m_bits; ++i) {
478
0
            ref(i) = ((bytes[i >> 3] & (uint8_t(1) << (i & 7))) != 0);
479
0
         }
480
0
      }
481
482
      /**
483
       * Renders the bitvector into a byte array. By default, this will use
484
       * `std::vector<uint8_t>` or `Botan::secure_vector<uint8_t>`, depending on
485
       * the allocator used by the bitvector. The rendering is compatible with
486
       * the bit layout explained in the respective constructor.
487
       */
488
      template <concepts::resizable_byte_buffer OutT =
489
                   std::conditional_t<uses_secure_allocator, secure_vector<uint8_t>, std::vector<uint8_t>>>
490
0
      OutT to_bytes() const {
491
0
         OutT out(ceil_tobytes(m_bits));
492
0
         to_bytes(out);
493
0
         return out;
494
0
      }
495
496
      /**
497
       * Renders the bitvector into a properly sized byte range.
498
       *
499
       * @param out  a byte range that has a length of at least `ceil_tobytes(size())`.
500
       */
501
0
      void to_bytes(std::span<uint8_t> out) const {
502
0
         const auto bytes_needed = ceil_tobytes(m_bits);
503
0
         BOTAN_ARG_CHECK(bytes_needed <= out.size_bytes(), "Not enough space to render bitvector");
504
505
         // copy as much aligned data as possible
506
0
         const auto verbatim_blocks = m_bits / block_size_bits;
507
0
         const auto verbatim_bytes = verbatim_blocks * block_size_bytes;
508
0
         if(verbatim_blocks > 0) {
509
0
            typecast_copy(out.first(verbatim_bytes), std::span{m_blocks}.first(verbatim_blocks));
510
0
         }
511
512
         // copy remaining unaligned data
513
0
         clear_mem(out.subspan(verbatim_bytes));
514
0
         for(size_type i = verbatim_bytes * 8; i < m_bits; ++i) {
515
0
            out[i >> 3] |= ref(i).template as<uint8_t>() << (i & 7);
516
0
         }
517
0
      }
518
519
      /**
520
       * Renders this bitvector into a sequence of "0"s and "1"s.
521
       * This is meant for debugging purposes and is not efficient.
522
       */
523
      std::string to_string() const {
524
         std::stringstream ss;
525
         for(size_type i = 0; i < size(); ++i) {
526
            ss << ref(i);
527
         }
528
         return ss.str();
529
      }
530
531
      /// @}
532
533
      /// @name Capacity Accessors and Modifiers
534
      /// @{
535
536
      size_type capacity() const { return m_blocks.capacity() * block_size_bits; }
537
538
0
      void reserve(size_type bits) { m_blocks.reserve(ceil_toblocks(bits)); }
539
540
0
      void resize(size_type bits) {
541
0
         const auto new_number_of_blocks = ceil_toblocks(bits);
542
0
         if(new_number_of_blocks != m_blocks.size()) {
543
0
            m_blocks.resize(new_number_of_blocks);
544
0
         }
545
546
0
         m_bits = bits;
547
0
         zero_unused_bits();
548
0
      }
549
550
0
      void push_back(bool bit) {
551
0
         const auto i = size();
552
0
         resize(i + 1);
553
0
         ref(i) = bit;
554
0
      }
555
556
      void pop_back() {
557
         if(!empty()) {
558
            resize(size() - 1);
559
         }
560
      }
561
562
      /// @}
563
564
      /// @name Bitwise and Global Accessors and Modifiers
565
      /// @{
566
567
0
      auto at(size_type pos) {
568
0
         check_offset(pos);
569
0
         return ref(pos);
570
0
      }
571
572
      // TODO C++23: deducing this
573
0
      auto at(size_type pos) const {
574
0
         check_offset(pos);
575
0
         return ref(pos);
576
0
      }
577
578
      auto front() { return ref(0); }
579
580
      // TODO C++23: deducing this
581
      auto front() const { return ref(0); }
582
583
      auto back() { return ref(size() - 1); }
584
585
      // TODO C++23: deducing this
586
      auto back() const { return ref(size() - 1); }
587
588
      /**
589
       * Sets the bit at position @p pos.
590
       * @throws Botan::Invalid_Argument if @p pos is out of range
591
       */
592
      bitvector_base& set(size_type pos) {
593
         check_offset(pos);
594
         ref(pos).set();
595
         return *this;
596
      }
597
598
      /**
599
       * Sets all currently allocated bits.
600
       */
601
      bitvector_base& set() {
602
         full_range_operation(
603
            [](std::unsigned_integral auto block) -> decltype(block) { return static_cast<decltype(block)>(~0); },
604
            *this);
605
         zero_unused_bits();
606
         return *this;
607
      }
608
609
      /**
610
       * Unsets the bit at position @p pos.
611
       * @throws Botan::Invalid_Argument if @p pos is out of range
612
       */
613
      bitvector_base& unset(size_type pos) {
614
         check_offset(pos);
615
         ref(pos).unset();
616
         return *this;
617
      }
618
619
      /**
620
       * Unsets all currently allocated bits.
621
       */
622
      bitvector_base& unset() {
623
         full_range_operation(
624
            [](std::unsigned_integral auto block) -> decltype(block) { return static_cast<decltype(block)>(0); },
625
            *this);
626
         return *this;
627
      }
628
629
      /**
630
       * Flips the bit at position @p pos.
631
       * @throws Botan::Invalid_Argument if @p pos is out of range
632
       */
633
      bitvector_base& flip(size_type pos) {
634
         check_offset(pos);
635
         ref(pos).flip();
636
         return *this;
637
      }
638
639
      /**
640
       * Flips all currently allocated bits.
641
       */
642
      bitvector_base& flip() {
643
         full_range_operation([](std::unsigned_integral auto block) -> decltype(block) { return ~block; }, *this);
644
         zero_unused_bits();
645
         return *this;
646
      }
647
648
      /**
649
       * @returns true iff no bit is set
650
       */
651
      bool none_vartime() const {
652
         return full_range_operation([](std::unsigned_integral auto block) { return block == 0; }, *this);
653
      }
654
655
      /**
656
       * @returns true iff no bit is set in constant time
657
       */
658
0
      bool none() const { return hamming_weight() == 0; }
659
660
      /**
661
       * @returns true iff at least one bit is set
662
       */
663
      bool any_vartime() const { return !none_vartime(); }
664
665
      /**
666
       * @returns true iff at least one bit is set in constant time
667
       */
668
      bool any() const { return !none(); }
669
670
      /**
671
       * @returns true iff all bits are set
672
       */
673
      bool all_vartime() const {
674
         return full_range_operation(
675
            []<std::unsigned_integral BlockT>(BlockT block, BlockT mask) { return block == mask; }, *this);
676
      }
677
678
      /**
679
       * @returns true iff all bits are set in constant time
680
       */
681
      bool all() const { return hamming_weight() == m_bits; }
682
683
0
      auto operator[](size_type pos) { return ref(pos); }
684
685
      // TODO C++23: deducing this
686
0
      auto operator[](size_type pos) const { return ref(pos); }
687
688
      /// @}
689
690
      /// @name Subvectors
691
      /// @{
692
693
      /**
694
       * Creates a new bitvector with a subsection of this bitvector starting at
695
       * @p pos copying exactly @p length bits.
696
       */
697
      template <bitvectorish OutT = bitvector_base<AllocatorT>>
698
0
      auto subvector(size_type pos, std::optional<size_type> length = std::nullopt) const {
699
0
         size_type bitlen = length.value_or(size() - pos);
700
0
         BOTAN_ARG_CHECK(pos + bitlen <= size(), "Not enough bits to copy");
701
702
0
         OutT newvector(bitlen);
703
704
         // Handle bitvectors that are wrapped in strong types
705
0
         auto& newvector_unwrapped = unwrap_strong_type(newvector);
706
707
0
         if(bitlen > 0) {
708
0
            if(pos % 8 == 0) {
709
0
               copy_mem(
710
0
                  newvector_unwrapped.m_blocks,
711
0
                  std::span{m_blocks}.subspan(block_index(pos), block_index(pos + bitlen - 1) - block_index(pos) + 1));
712
0
            } else {
713
0
               BitRangeOperator<const bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> from_op(
714
0
                  *this, pos, bitlen);
715
0
               BitRangeOperator<strong_type_wrapped_type<OutT>> to_op(
716
0
                  unwrap_strong_type(newvector_unwrapped), 0, bitlen);
717
0
               range_operation([](auto /* to */, auto from) { return from; }, to_op, from_op);
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEENKUlT_T0_E_clImmEEDaS7_S8_
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEENKUlT_T0_E_clIjjEEDaS7_S8_
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEENKUlT_T0_E_clIttEEDaS7_S8_
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEENKUlT_T0_E_clIhhEEDaS7_S8_
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEENKUlT_T0_E_clImmEEDaSA_SB_
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEENKUlT_T0_E_clIjjEEDaSA_SB_
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEENKUlT_T0_E_clIttEEDaSA_SB_
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEENKUlT_T0_E_clIhhEEDaSA_SB_
718
0
            }
719
720
0
            newvector_unwrapped.zero_unused_bits();
721
0
         }
722
723
0
         return newvector;
724
0
      }
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEE
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEE
725
726
      /**
727
       * Extracts a subvector of bits as an unsigned integral type @p OutT
728
       * starting from bit @p pos and copying exactly sizeof(OutT)*8 bits.
729
       *
730
       * Hint: The bits are in big-endian order, i.e. the least significant bit
731
       *       is the 0th bit and the most significant bit it the n-th. Hence,
732
       *       addressing the bits with bitwise operations is done like so:
733
       *       bool bit = (out_int >> pos) & 1;
734
       */
735
      template <typename OutT>
736
         requires(std::unsigned_integral<strong_type_wrapped_type<OutT>> &&
737
                  !std::same_as<bool, strong_type_wrapped_type<OutT>>)
738
0
      OutT subvector(size_type pos) const {
739
0
         using result_t = strong_type_wrapped_type<OutT>;
740
0
         constexpr size_t bits = sizeof(result_t) * 8;
741
0
         BOTAN_ARG_CHECK(pos + bits <= size(), "Not enough bits to copy");
742
0
         result_t out = 0;
743
744
0
         if(pos % 8 == 0) {
745
0
            out = load_le<result_t>(std::span{m_blocks}.subspan(block_index(pos)).template first<sizeof(result_t)>());
746
0
         } else {
747
0
            BitRangeOperator<const bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> op(*this, pos, bits);
748
0
            range_operation(
749
0
               [&](std::unsigned_integral auto integer) {
750
0
                  if constexpr(std::same_as<result_t, decltype(integer)>) {
751
0
                     out = integer;
752
0
                  }
753
0
               },
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS9_EEET_mENKUlSA_E_clImEEDaSA_
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS9_EEET_mENKUlSA_E_clIjEEDaSA_
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS9_EEET_mENKUlSA_E_clItEEDaSA_
Unexecuted instantiation: _ZZNK5Botan14bitvector_baseINS_16secure_allocatorEE9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS9_EEET_mENKUlSA_E_clIhEEDaSA_
754
0
               op);
755
0
         }
756
757
0
         return wrap_strong_type<OutT>(out);
758
0
      }
759
760
      /**
761
       * Replaces a subvector of bits with the bits of another bitvector @p value
762
       * starting at bit @p pos. The number of bits to replace is determined by
763
       * the size of @p value.
764
       *
765
       * @note This is currently supported for byte-aligned @p pos only.
766
       *
767
       * @throws Not_Implemented when called with @p pos not divisible by 8.
768
       *
769
       * @param pos    the position to start replacing bits
770
       * @param value  the bitvector to copy bits from
771
       */
772
      template <typename InT>
773
         requires(std::unsigned_integral<strong_type_wrapped_type<InT>> && !std::same_as<bool, InT>)
774
0
      void subvector_replace(size_type pos, InT value) {
775
0
         using in_t = strong_type_wrapped_type<InT>;
776
0
         constexpr size_t bits = sizeof(in_t) * 8;
777
0
         BOTAN_ARG_CHECK(pos + bits <= size(), "Not enough bits to replace");
778
779
0
         if(pos % 8 == 0) {
780
0
            store_le(std::span{m_blocks}.subspan(block_index(pos)).template first<sizeof(in_t)>(),
781
0
                     unwrap_strong_type(value));
782
0
         } else {
783
0
            BitRangeOperator<bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> op(*this, pos, bits);
784
0
            range_operation(
785
0
               [&]<std::unsigned_integral BlockT>(BlockT block) -> BlockT {
786
0
                  if constexpr(std::same_as<in_t, BlockT>) {
787
0
                     return unwrap_strong_type(value);
788
0
                  } else {
789
                     // This should never be reached. BOTAN_ASSERT_UNREACHABLE()
790
                     // caused warning "unreachable code" on MSVC, though. You
791
                     // don't say!
792
                     //
793
                     // Returning the given block back, is the most reasonable
794
                     // thing to do in this case, though.
795
0
                     return block;
796
0
                  }
797
0
               },
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEE17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS6_EEEvmT_ENKUlTkNSt3__117unsigned_integralESA_E_clImEESA_SA_
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEE17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS6_EEEvmT_ENKUlTkNSt3__117unsigned_integralESA_E_clIjEESA_SA_
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEE17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS6_EEEvmT_ENKUlTkNSt3__117unsigned_integralESA_E_clItEESA_SA_
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEE17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS6_EEEvmT_ENKUlTkNSt3__117unsigned_integralESA_E_clIhEESA_SA_
798
0
               op);
799
0
         }
800
0
      }
801
802
      /// @}
803
804
      /// @name Operators
805
      ///
806
      /// @{
807
808
      auto operator~() {
809
         auto newbv = *this;
810
         newbv.flip();
811
         return newbv;
812
      }
813
814
      template <bitvectorish OtherT>
815
      auto& operator|=(const OtherT& other) {
816
         full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs | rhs; },
817
                              *this,
818
                              unwrap_strong_type(other));
819
         return *this;
820
      }
821
822
      template <bitvectorish OtherT>
823
0
      auto& operator&=(const OtherT& other) {
824
0
         full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs & rhs; },
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEEaNITkNS_12bitvectorishES2_EERDaRKT_ENKUlTkNSt3__117unsigned_integralES5_S5_E_clImEES5_S5_S5_
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEEaNITkNS_12bitvectorishES2_EERDaRKT_ENKUlTkNSt3__117unsigned_integralES5_S5_E_clIjEES5_S5_S5_
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEEaNITkNS_12bitvectorishES2_EERDaRKT_ENKUlTkNSt3__117unsigned_integralES5_S5_E_clItEES5_S5_S5_
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEEaNITkNS_12bitvectorishES2_EERDaRKT_ENKUlTkNSt3__117unsigned_integralES5_S5_E_clIhEES5_S5_S5_
825
0
                              *this,
826
0
                              unwrap_strong_type(other));
827
0
         return *this;
828
0
      }
829
830
      template <bitvectorish OtherT>
831
0
      auto& operator^=(const OtherT& other) {
832
0
         full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs ^ rhs; },
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEEeOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_ENKUlTkNS4_17unsigned_integralES8_S8_E_clImEES8_S8_S8_
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEEeOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_ENKUlTkNS4_17unsigned_integralES8_S8_E_clIjEES8_S8_S8_
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEEeOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_ENKUlTkNS4_17unsigned_integralES8_S8_E_clItEES8_S8_S8_
Unexecuted instantiation: _ZZN5Botan14bitvector_baseINS_16secure_allocatorEEeOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_ENKUlTkNS4_17unsigned_integralES8_S8_E_clIhEES8_S8_S8_
833
0
                              *this,
834
0
                              unwrap_strong_type(other));
835
0
         return *this;
836
0
      }
837
838
      /// @}
839
840
      /// @name Constant Time Operations
841
      ///
842
      /// @{
843
844
      /**
845
       * Implements::
846
       *
847
       *    if(condition) {
848
       *       *this ^= other;
849
       *    }
850
       *
851
       * omitting runtime dependence on any of the parameters.
852
       */
853
      template <bitvectorish OtherT>
854
0
      void ct_conditional_xor(CT::Choice condition, const OtherT& other) {
855
0
         BOTAN_ASSERT_NOMSG(m_bits == other.m_bits);
856
0
         BOTAN_ASSERT_NOMSG(m_blocks.size() == other.m_blocks.size());
857
858
0
         auto maybe_xor = overloaded{
859
0
            [m = CT::Mask<uint64_t>::from_choice(condition)](uint64_t lhs, uint64_t rhs) -> uint64_t {
860
0
               return lhs ^ m.if_set_return(rhs);
861
0
            },
862
0
            [m = CT::Mask<uint32_t>::from_choice(condition)](uint32_t lhs, uint32_t rhs) -> uint32_t {
863
0
               return lhs ^ m.if_set_return(rhs);
864
0
            },
865
0
            [m = CT::Mask<uint16_t>::from_choice(condition)](uint16_t lhs, uint16_t rhs) -> uint16_t {
866
0
               return lhs ^ m.if_set_return(rhs);
867
0
            },
868
0
            [m = CT::Mask<uint8_t>::from_choice(condition)](uint8_t lhs, uint8_t rhs) -> uint8_t {
869
0
               return lhs ^ m.if_set_return(rhs);
870
0
            },
871
0
         };
872
873
0
         full_range_operation(maybe_xor, *this, unwrap_strong_type(other));
874
0
      }
875
876
0
      constexpr void _const_time_poison() const { CT::poison(m_blocks); }
877
878
0
      constexpr void _const_time_unpoison() const { CT::unpoison(m_blocks); }
879
880
      /// @}
881
882
      /// @name Iterators
883
      ///
884
      /// @{
885
886
0
      iterator begin() noexcept { return iterator(this, 0); }
887
888
0
      const_iterator begin() const noexcept { return const_iterator(this, 0); }
889
890
      const_iterator cbegin() const noexcept { return const_iterator(this, 0); }
891
892
0
      iterator end() noexcept { return iterator(this, size()); }
893
894
0
      const_iterator end() const noexcept { return const_iterator(this, size()); }
895
896
      const_iterator cend() noexcept { return const_iterator(this, size()); }
897
898
      /// @}
899
900
   private:
901
0
      void check_offset(size_type pos) const {
902
         // BOTAN_ASSERT_NOMSG(!CT::is_poisoned(&m_bits, sizeof(m_bits)));
903
         // BOTAN_ASSERT_NOMSG(!CT::is_poisoned(&pos, sizeof(pos)));
904
0
         BOTAN_ARG_CHECK(pos < m_bits, "Out of range");
905
0
      }
906
907
0
      void zero_unused_bits() {
908
0
         const auto first_unused_bit = size();
909
910
         // Zero out any unused bits in the last block
911
0
         if(first_unused_bit % block_size_bits != 0) {
912
0
            const block_type mask = (one << block_offset(first_unused_bit)) - one;
913
0
            m_blocks[block_index(first_unused_bit)] &= mask;
914
0
         }
915
0
      }
916
917
0
      static constexpr size_type ceil_toblocks(size_type bits) {
918
0
         return (bits + block_size_bits - 1) / block_size_bits;
919
0
      }
920
921
0
      auto ref(size_type pos) const { return bitref<const block_type>(m_blocks, pos); }
922
923
0
      auto ref(size_type pos) { return bitref<block_type>(m_blocks, pos); }
924
925
   private:
926
      enum class BitRangeAlignment { byte_aligned, no_alignment };
927
928
      /**
929
       * Helper construction to implement bit range operations on the bitvector.
930
       * It basically implements an iterator to read and write blocks of bits
931
       * from the underlying bitvector. Where "blocks of bits" are unsigned
932
       * integers of varying bit lengths.
933
       *
934
       * If the iteration starts at a byte boundary in the underlying bitvector,
935
       * this applies certain optimizations (i.e. loading blocks of bits straight
936
       * from the underlying byte buffer). The optimizations are enabled at
937
       * compile time (with the template parameter `alignment`).
938
       */
939
      template <typename BitvectorT, auto alignment = BitRangeAlignment::byte_aligned>
940
         requires is_bitvector_v<std::remove_cvref_t<BitvectorT>>
941
      class BitRangeOperator {
942
         private:
943
0
            constexpr static bool is_const() { return std::is_const_v<BitvectorT>; }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::is_const()
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::is_const()
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::is_const()
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::is_const()
944
945
            struct UnalignedDataHelper {
946
                  const uint8_t padding_bits;
947
                  const uint8_t bits_to_byte_alignment;
948
            };
949
950
         public:
951
            BitRangeOperator(BitvectorT& source, size_type start_bitoffset, size_type bitlength) :
952
0
                  m_source(source),
953
0
                  m_start_bitoffset(start_bitoffset),
954
0
                  m_bitlength(bitlength),
955
0
                  m_unaligned_helper({.padding_bits = static_cast<uint8_t>(start_bitoffset % 8),
956
0
                                      .bits_to_byte_alignment = static_cast<uint8_t>(8 - (start_bitoffset % 8))}),
957
0
                  m_read_bitpos(start_bitoffset),
958
0
                  m_write_bitpos(start_bitoffset) {
959
0
               BOTAN_ASSERT(is_byte_aligned() == (m_start_bitoffset % 8 == 0), "byte alignment guarantee");
960
0
               BOTAN_ASSERT(m_source.size() >= m_start_bitoffset + m_bitlength, "enough bytes in underlying source");
961
0
            }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::BitRangeOperator(Botan::bitvector_base<Botan::secure_allocator> const&, unsigned long, unsigned long)
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::BitRangeOperator(Botan::bitvector_base<Botan::secure_allocator>&, unsigned long, unsigned long)
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::BitRangeOperator(Botan::bitvector_base<Botan::secure_allocator> const&, unsigned long, unsigned long)
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::BitRangeOperator(Botan::bitvector_base<std::__1::allocator> const&, unsigned long, unsigned long)
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::BitRangeOperator(Botan::bitvector_base<Botan::secure_allocator>&, unsigned long, unsigned long)
962
963
0
            BitRangeOperator(BitvectorT& source) : BitRangeOperator(source, 0, source.size()) {}
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::BitRangeOperator(Botan::bitvector_base<Botan::secure_allocator> const&)
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::BitRangeOperator(Botan::bitvector_base<Botan::secure_allocator>&)
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::BitRangeOperator(Botan::bitvector_base<std::__1::allocator> const&)
964
965
0
            static constexpr bool is_byte_aligned() { return alignment == BitRangeAlignment::byte_aligned; }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::is_byte_aligned()
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::is_byte_aligned()
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::is_byte_aligned()
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::is_byte_aligned()
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::is_byte_aligned()
966
967
            /**
968
             * @returns the overall number of bits to be iterated with this operator
969
             */
970
0
            size_type size() const { return m_bitlength; }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::size() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::size() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::size() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::size() const
971
972
            /**
973
             * @returns the number of bits not yet read from this operator
974
             */
975
0
            size_type bits_to_read() const { return m_bitlength - m_read_bitpos + m_start_bitoffset; }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::bits_to_read() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::bits_to_read() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::bits_to_read() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::bits_to_read() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::bits_to_read() const
976
977
            /**
978
             * @returns the number of bits still to be written into this operator
979
             */
980
0
            size_type bits_to_write() const { return m_bitlength - m_write_bitpos + m_start_bitoffset; }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::bits_to_write() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::bits_to_write() const
981
982
            /**
983
             * Loads the next block of bits from the underlying bitvector. No
984
             * bounds checks are performed. The caller can define the size of
985
             * the resulting unsigned integer block.
986
             */
987
            template <std::unsigned_integral BlockT>
988
0
            BlockT load_next() const {
989
0
               constexpr size_type block_size = sizeof(BlockT);
990
0
               constexpr size_type block_bits = block_size * 8;
991
0
               const auto bits_remaining = bits_to_read();
992
993
0
               BlockT result_block = 0;
994
0
               if constexpr(is_byte_aligned()) {
995
0
                  result_block = load_le(m_source.as_byte_span().subspan(read_bytepos()).template first<block_size>());
996
0
               } else {
997
0
                  const size_type byte_pos = read_bytepos();
998
0
                  const size_type bits_to_collect = std::min(block_bits, bits_to_read());
999
1000
0
                  const uint8_t first_byte = m_source.as_byte_span()[byte_pos];
1001
1002
                  // Initialize the left-most bits from the first byte.
1003
0
                  result_block = BlockT(first_byte) >> m_unaligned_helper.padding_bits;
1004
1005
                  // If more bits are needed, we pull them from the remaining bytes.
1006
0
                  if(m_unaligned_helper.bits_to_byte_alignment < bits_to_collect) {
1007
0
                     const BlockT block =
1008
0
                        load_le(m_source.as_byte_span().subspan(byte_pos + 1).template first<block_size>());
1009
0
                     result_block |= block << m_unaligned_helper.bits_to_byte_alignment;
1010
0
                  }
1011
0
               }
1012
1013
0
               m_read_bitpos += std::min(block_bits, bits_remaining);
1014
0
               return result_block;
1015
0
            }
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE9load_nextITkNSt3__117unsigned_integralEmEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EE9load_nextITkNSt3__117unsigned_integralEmEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE9load_nextITkNSt3__117unsigned_integralEjEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EE9load_nextITkNSt3__117unsigned_integralEjEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE9load_nextITkNSt3__117unsigned_integralEtEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EE9load_nextITkNSt3__117unsigned_integralEtEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE9load_nextITkNSt3__117unsigned_integralEhEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EE9load_nextITkNSt3__117unsigned_integralEhEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EE9load_nextITkNSt3__117unsigned_integralEhEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKNS0_INSt3__19allocatorEEELNS2_17BitRangeAlignmentE0EE9load_nextITkNS4_17unsigned_integralEhEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EE9load_nextITkNSt3__117unsigned_integralEmEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EE9load_nextITkNSt3__117unsigned_integralEjEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EE9load_nextITkNSt3__117unsigned_integralEtEET_v
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EE9load_nextITkNSt3__117unsigned_integralEhEET_v
1016
1017
            /**
1018
             * Stores the next block of bits into the underlying bitvector.
1019
             * No bounds checks are performed. Storing bit blocks that are not
1020
             * aligned at a byte-boundary in the underlying bitvector is
1021
             * currently not implemented.
1022
             */
1023
            template <std::unsigned_integral BlockT>
1024
               requires(!is_const())
1025
0
            void store_next(BlockT block) {
1026
0
               constexpr size_type block_size = sizeof(BlockT);
1027
0
               constexpr size_type block_bits = block_size * 8;
1028
1029
0
               if constexpr(is_byte_aligned()) {
1030
0
                  auto sink = m_source.as_byte_span().subspan(write_bytepos()).template first<block_size>();
1031
0
                  store_le(sink, block);
1032
0
               } else {
1033
0
                  const size_type byte_pos = write_bytepos();
1034
0
                  const size_type bits_to_store = std::min(block_bits, bits_to_write());
1035
1036
0
                  uint8_t& first_byte = m_source.as_byte_span()[byte_pos];
1037
1038
                  // Set the left-most bits in the first byte, leaving all others unchanged
1039
0
                  first_byte = (first_byte & uint8_t(0xFF >> m_unaligned_helper.bits_to_byte_alignment)) |
1040
0
                               uint8_t(block << m_unaligned_helper.padding_bits);
1041
1042
                  // If more bits are provided, we store them in the remaining bytes.
1043
0
                  if(m_unaligned_helper.bits_to_byte_alignment < bits_to_store) {
1044
0
                     const auto remaining_bytes =
1045
0
                        m_source.as_byte_span().subspan(byte_pos + 1).template first<block_size>();
1046
0
                     const BlockT padding_mask = ~(BlockT(-1) >> m_unaligned_helper.bits_to_byte_alignment);
1047
0
                     const BlockT new_bytes =
1048
0
                        (load_le(remaining_bytes) & padding_mask) | block >> m_unaligned_helper.bits_to_byte_alignment;
1049
0
                     store_le(remaining_bytes, new_bytes);
1050
0
                  }
1051
0
               }
1052
1053
0
               m_write_bitpos += std::min(block_bits, bits_to_write());
1054
0
            }
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE10store_nextITkNSt3__117unsigned_integralEmQntclL_ZNS_14bitvector_base16BitRangeOperator8is_constEvEEEEvT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE10store_nextITkNSt3__117unsigned_integralEjQntclL_ZNS_14bitvector_base16BitRangeOperator8is_constEvEEEEvT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE10store_nextITkNSt3__117unsigned_integralEtQntclL_ZNS_14bitvector_base16BitRangeOperator8is_constEvEEEEvT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE10store_nextITkNSt3__117unsigned_integralEhQntclL_ZNS_14bitvector_base16BitRangeOperator8is_constEvEEEEvT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EE10store_nextITkNSt3__117unsigned_integralEmQntclL_ZNS_14bitvector_base16BitRangeOperator8is_constEvEEEEvT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EE10store_nextITkNSt3__117unsigned_integralEjQntclL_ZNS_14bitvector_base16BitRangeOperator8is_constEvEEEEvT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EE10store_nextITkNSt3__117unsigned_integralEtQntclL_ZNS_14bitvector_base16BitRangeOperator8is_constEvEEEEvT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EE10store_nextITkNSt3__117unsigned_integralEhQntclL_ZNS_14bitvector_base16BitRangeOperator8is_constEvEEEEvT_
1055
1056
            template <std::unsigned_integral BlockT>
1057
               requires(is_byte_aligned() && !is_const())
1058
0
            std::span<BlockT> span(size_type blocks) const {
1059
0
               BOTAN_DEBUG_ASSERT(blocks == 0 || is_memory_aligned_to<BlockT>());
1060
0
               BOTAN_DEBUG_ASSERT(read_bytepos() % sizeof(BlockT) == 0);
1061
               // Intermittently casting to void* to avoid a compiler warning
1062
0
               void* ptr = reinterpret_cast<void*>(m_source.as_byte_span().data() + read_bytepos());
1063
0
               return {reinterpret_cast<BlockT*>(ptr), blocks};
1064
0
            }
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE4spanITkNSt3__117unsigned_integralEmQaaclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEntclL_ZNS9_8is_constEvEEEENS7_4spanIT_Lm18446744073709551615EEEm
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE4spanITkNSt3__117unsigned_integralEjQaaclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEntclL_ZNS9_8is_constEvEEEENS7_4spanIT_Lm18446744073709551615EEEm
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE4spanITkNSt3__117unsigned_integralEtQaaclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEntclL_ZNS9_8is_constEvEEEENS7_4spanIT_Lm18446744073709551615EEEm
1065
1066
            template <std::unsigned_integral BlockT>
1067
               requires(is_byte_aligned() && is_const())
1068
0
            std::span<const BlockT> span(size_type blocks) const {
1069
0
               BOTAN_DEBUG_ASSERT(blocks == 0 || is_memory_aligned_to<BlockT>());
1070
0
               BOTAN_DEBUG_ASSERT(read_bytepos() % sizeof(BlockT) == 0);
1071
               // Intermittently casting to void* to avoid a compiler warning
1072
0
               const void* ptr = reinterpret_cast<const void*>(m_source.as_byte_span().data() + read_bytepos());
1073
0
               return {reinterpret_cast<const BlockT*>(ptr), blocks};
1074
0
            }
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EE4spanITkNSt3__117unsigned_integralEmQaaclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEclL_ZNSA_8is_constEvEEEENS8_4spanIKT_Lm18446744073709551615EEEm
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EE4spanITkNSt3__117unsigned_integralEjQaaclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEclL_ZNSA_8is_constEvEEEENS8_4spanIKT_Lm18446744073709551615EEEm
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EE4spanITkNSt3__117unsigned_integralEtQaaclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEclL_ZNSA_8is_constEvEEEENS8_4spanIKT_Lm18446744073709551615EEEm
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKNS0_INSt3__19allocatorEEELNS2_17BitRangeAlignmentE0EE4spanITkNS4_17unsigned_integralEmQaaclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEclL_ZNSC_8is_constEvEEEENS4_4spanIKT_Lm18446744073709551615EEEm
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKNS0_INSt3__19allocatorEEELNS2_17BitRangeAlignmentE0EE4spanITkNS4_17unsigned_integralEjQaaclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEclL_ZNSC_8is_constEvEEEENS4_4spanIKT_Lm18446744073709551615EEEm
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKNS0_INSt3__19allocatorEEELNS2_17BitRangeAlignmentE0EE4spanITkNS4_17unsigned_integralEtQaaclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEclL_ZNSC_8is_constEvEEEENS4_4spanIKT_Lm18446744073709551615EEEm
1075
1076
            void advance(size_type bytes)
1077
               requires(is_byte_aligned())
1078
0
            {
1079
0
               m_read_bitpos += bytes * 8;
1080
0
               m_write_bitpos += bytes * 8;
1081
0
            }
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EE7advanceEmQclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE7advanceEmQclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKNS0_INSt3__19allocatorEEELNS2_17BitRangeAlignmentE0EE7advanceEmQclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEE
1082
1083
            template <std::unsigned_integral BlockT>
1084
               requires(is_byte_aligned())
1085
0
            size_t is_memory_aligned_to() const {
1086
0
               const void* cptr = m_source.as_byte_span().data() + read_bytepos();
1087
0
               const void* ptr_before = cptr;
1088
1089
               // std::align takes `ptr` as a reference (!), i.e. `void*&` and
1090
               // uses it as an out-param. Though, `cptr` is const because this
1091
               // method is const-qualified, hence the const_cast<>.
1092
0
               void* ptr = const_cast<void*>(cptr);
1093
0
               size_t size = sizeof(BlockT);
1094
0
               return ptr_before != nullptr && std::align(alignof(BlockT), size, ptr, size) == ptr_before;
1095
0
            }
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EE20is_memory_aligned_toITkNSt3__117unsigned_integralEmQclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEEEmv
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EE20is_memory_aligned_toITkNSt3__117unsigned_integralEmQclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEEEmv
Unexecuted instantiation: _ZNK5Botan14bitvector_baseINS_16secure_allocatorEE16BitRangeOperatorIKNS0_INSt3__19allocatorEEELNS2_17BitRangeAlignmentE0EE20is_memory_aligned_toITkNS4_17unsigned_integralEmQclL_ZNS_14bitvector_base16BitRangeOperator15is_byte_alignedEvEEEEmv
1096
1097
         private:
1098
0
            size_type read_bytepos() const { return m_read_bitpos / 8; }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::read_bytepos() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::read_bytepos() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::read_bytepos() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::read_bytepos() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::read_bytepos() const
1099
1100
0
            size_type write_bytepos() const { return m_write_bitpos / 8; }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>::write_bytepos() const
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>::write_bytepos() const
1101
1102
         private:
1103
            BitvectorT& m_source;
1104
            size_type m_start_bitoffset;
1105
            size_type m_bitlength;
1106
1107
            UnalignedDataHelper m_unaligned_helper;
1108
1109
            mutable size_type m_read_bitpos;
1110
            mutable size_type m_write_bitpos;
1111
      };
1112
1113
      /**
1114
       * Helper struct for the low-level handling of blockwise operations
1115
       *
1116
       * This has two main code paths: Optimized for byte-aligned ranges that
1117
       * can simply be taken from memory as-is. And a generic implementation
1118
       * that must assemble blocks from unaligned bits before processing.
1119
       */
1120
      template <typename FnT, typename... ParamTs>
1121
         requires detail::blockwise_processing_callback<FnT, ParamTs...>
1122
      class blockwise_processing_callback_trait {
1123
         public:
1124
            constexpr static bool needs_mask = detail::blockwise_processing_callback_with_mask<FnT, ParamTs...>;
1125
            constexpr static bool is_manipulator = detail::manipulating_blockwise_processing_callback<FnT, ParamTs...>;
1126
            constexpr static bool is_predicate = detail::predicate_blockwise_processing_callback<FnT, ParamTs...>;
1127
            static_assert(!is_manipulator || !is_predicate, "cannot be manipulator and predicate at the same time");
1128
1129
            /**
1130
             * Applies @p fn to the blocks provided in @p blocks by simply reading from
1131
             * memory without re-arranging any bits across byte-boundaries.
1132
             */
1133
            template <std::unsigned_integral... BlockTs>
1134
               requires(all_same_v<std::remove_cv_t<BlockTs>...> && sizeof...(BlockTs) == sizeof...(ParamTs))
1135
0
            constexpr static bool apply_on_full_blocks(FnT fn, std::span<BlockTs>... blocks) {
1136
0
               constexpr size_type bits = sizeof(detail::first_t<BlockTs...>) * 8;
1137
0
               const size_type iterations = detail::first(blocks...).size();
1138
0
               for(size_type i = 0; i < iterations; ++i) {
1139
                  if constexpr(is_predicate) {
1140
                     if(!apply(fn, bits, blocks[i]...)) {
1141
                        return false;
1142
                     }
1143
0
                  } else if constexpr(is_manipulator) {
1144
0
                     detail::first(blocks...)[i] = apply(fn, bits, blocks[i]...);
1145
0
                  } else {
1146
0
                     apply(fn, bits, blocks[i]...);
1147
0
                  }
1148
0
               }
1149
0
               return true;
1150
0
            }
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE20apply_on_full_blocksITpTkNSt3__117unsigned_integralEJKmEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbS5_DpNSC_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE20apply_on_full_blocksITpTkNSt3__117unsigned_integralEJKjEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbS5_DpNSC_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE20apply_on_full_blocksITpTkNSt3__117unsigned_integralEJKtEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbS5_DpNSC_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_eOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_EUlTkNS5_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEE20apply_on_full_blocksITpTkNS5_17unsigned_integralEJmKmEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbSC_DpNS5_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_eOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_EUlTkNS5_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEE20apply_on_full_blocksITpTkNS5_17unsigned_integralEJjKjEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbSC_DpNS5_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_eOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_EUlTkNS5_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEE20apply_on_full_blocksITpTkNS5_17unsigned_integralEJtKtEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbSC_DpNS5_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitINS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUljjE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlttE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSG_IKS2_LSH_0EEEEE20apply_on_full_blocksITpTkNSt3__117unsigned_integralEJmKmEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbSF_DpNSN_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitINS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUljjE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlttE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSG_IKS2_LSH_0EEEEE20apply_on_full_blocksITpTkNSt3__117unsigned_integralEJjKjEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbSF_DpNSN_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitINS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUljjE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlttE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSG_IKS2_LSH_0EEEEE20apply_on_full_blocksITpTkNSt3__117unsigned_integralEJtKtEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbSF_DpNSN_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNSt3__117unsigned_integralES6_S6_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEE20apply_on_full_blocksITpTkNS9_17unsigned_integralEJmKmEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbSA_DpNS9_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNSt3__117unsigned_integralES6_S6_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEE20apply_on_full_blocksITpTkNS9_17unsigned_integralEJjKjEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbSA_DpNS9_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNSt3__117unsigned_integralES6_S6_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEE20apply_on_full_blocksITpTkNS9_17unsigned_integralEJtKtEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbSA_DpNS9_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE20apply_on_full_blocksITpTkNSt3__117unsigned_integralEJKmEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbS5_DpNSC_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE20apply_on_full_blocksITpTkNSt3__117unsigned_integralEJKjEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbS5_DpNSC_4spanIT_Lm18446744073709551615EEE
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE20apply_on_full_blocksITpTkNSt3__117unsigned_integralEJKtEQaa10all_same_vIDpu11__remove_cvITL1__EEeqsZTL1__sZTL0_0_EEbS5_DpNSC_4spanIT_Lm18446744073709551615EEE
1151
1152
            /**
1153
             * Applies @p fn to as many blocks as @p ops provide for the given type.
1154
             */
1155
            template <std::unsigned_integral BlockT, typename... BitRangeOperatorTs>
1156
               requires(sizeof...(BitRangeOperatorTs) == sizeof...(ParamTs))
1157
0
            constexpr static bool apply_on_unaligned_blocks(FnT fn, BitRangeOperatorTs&... ops) {
1158
0
               constexpr size_type block_bits = sizeof(BlockT) * 8;
1159
0
               auto bits = detail::first(ops...).bits_to_read();
1160
0
               if(bits == 0) {
1161
0
                  return true;
1162
0
               }
1163
1164
0
               bits += block_bits;  // avoid unsigned integer underflow in the following loop
1165
0
               while(bits > block_bits * 2 - 8) {
1166
0
                  bits -= block_bits;
1167
                  if constexpr(is_predicate) {
1168
                     if(!apply(fn, bits, ops.template load_next<BlockT>()...)) {
1169
                        return false;
1170
                     }
1171
0
                  } else if constexpr(is_manipulator) {
1172
0
                     detail::first(ops...).store_next(apply(fn, bits, ops.template load_next<BlockT>()...));
1173
0
                  } else {
1174
0
                     apply(fn, bits, ops.template load_next<BlockT>()...);
1175
0
                  }
1176
0
               }
1177
0
               return true;
1178
0
            }
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEE25apply_on_unaligned_blocksITkNS5_17unsigned_integralEmJSD_SF_EQeqsZTL1_0_sZTL0_0_EEbSA_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEE25apply_on_unaligned_blocksITkNS5_17unsigned_integralEjJSD_SF_EQeqsZTL1_0_sZTL0_0_EEbSA_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEE25apply_on_unaligned_blocksITkNS5_17unsigned_integralEtJSD_SF_EQeqsZTL1_0_sZTL0_0_EEbSA_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEE25apply_on_unaligned_blocksITkNS5_17unsigned_integralEhJSD_SF_EQeqsZTL1_0_sZTL0_0_EEbSA_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE25apply_on_unaligned_blocksITkNSt3__117unsigned_integralEhJS9_EQeqsZTL1_0_sZTL0_0_EEbS5_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_eOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_EUlTkNS5_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEE25apply_on_unaligned_blocksITkNS5_17unsigned_integralEhJSF_SH_EQeqsZTL1_0_sZTL0_0_EEbSC_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSA_EEET_mEUlSB_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEE25apply_on_unaligned_blocksITkNSt3__117unsigned_integralEmJSG_EQeqsZTL1_0_sZTL0_0_EEbSC_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSA_EEET_mEUlSB_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEE25apply_on_unaligned_blocksITkNSt3__117unsigned_integralEjJSG_EQeqsZTL1_0_sZTL0_0_EEbSC_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSA_EEET_mEUlSB_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEE25apply_on_unaligned_blocksITkNSt3__117unsigned_integralEtJSG_EQeqsZTL1_0_sZTL0_0_EEbSC_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSA_EEET_mEUlSB_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEE25apply_on_unaligned_blocksITkNSt3__117unsigned_integralEhJSG_EQeqsZTL1_0_sZTL0_0_EEbSC_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS7_EEEvmT_EUlTkNSt3__117unsigned_integralESB_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEE25apply_on_unaligned_blocksITkNSC_17unsigned_integralEmJSG_EQeqsZTL1_0_sZTL0_0_EEbSD_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS7_EEEvmT_EUlTkNSt3__117unsigned_integralESB_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEE25apply_on_unaligned_blocksITkNSC_17unsigned_integralEjJSG_EQeqsZTL1_0_sZTL0_0_EEbSD_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS7_EEEvmT_EUlTkNSt3__117unsigned_integralESB_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEE25apply_on_unaligned_blocksITkNSC_17unsigned_integralEtJSG_EQeqsZTL1_0_sZTL0_0_EEbSD_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS7_EEEvmT_EUlTkNSt3__117unsigned_integralESB_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEE25apply_on_unaligned_blocksITkNSC_17unsigned_integralEhJSG_EQeqsZTL1_0_sZTL0_0_EEbSD_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitINS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUljjE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlttE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSG_IKS2_LSH_0EEEEE25apply_on_unaligned_blocksITkNSt3__117unsigned_integralEhJSI_SK_EQeqsZTL1_0_sZTL0_0_EEbSF_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEE25apply_on_unaligned_blocksITkNS8_17unsigned_integralEmJSG_SI_EQeqsZTL1_0_sZTL0_0_EEbSD_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEE25apply_on_unaligned_blocksITkNS8_17unsigned_integralEjJSG_SI_EQeqsZTL1_0_sZTL0_0_EEbSD_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEE25apply_on_unaligned_blocksITkNS8_17unsigned_integralEtJSG_SI_EQeqsZTL1_0_sZTL0_0_EEbSD_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEE25apply_on_unaligned_blocksITkNS8_17unsigned_integralEhJSG_SI_EQeqsZTL1_0_sZTL0_0_EEbSD_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNSt3__117unsigned_integralES6_S6_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEE25apply_on_unaligned_blocksITkNS9_17unsigned_integralEhJSD_SF_EQeqsZTL1_0_sZTL0_0_EEbSA_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE25apply_on_unaligned_blocksITkNSt3__117unsigned_integralEhJS9_EQeqsZTL1_0_sZTL0_0_EEbS5_DpRT0_
1179
1180
         private:
1181
            template <std::unsigned_integral... BlockTs>
1182
               requires(all_same_v<BlockTs...>)
1183
0
            constexpr static auto apply(FnT fn, size_type bits, BlockTs... blocks) {
1184
               if constexpr(needs_mask) {
1185
                  return fn(blocks..., make_mask<detail::first_t<BlockTs...>>(bits));
1186
0
               } else {
1187
0
                  return fn(blocks...);
1188
0
               }
1189
0
            }
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEE5applyITpTkNS5_17unsigned_integralEJmmEQ10all_same_vIDpTL1__EEEDaSA_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEE5applyITpTkNS5_17unsigned_integralEJjjEQ10all_same_vIDpTL1__EEEDaSA_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEE5applyITpTkNS5_17unsigned_integralEJttEQ10all_same_vIDpTL1__EEEDaSA_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEE5applyITpTkNS5_17unsigned_integralEJhhEQ10all_same_vIDpTL1__EEEDaSA_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE5applyITpTkNSt3__117unsigned_integralEJmEQ10all_same_vIDpTL1__EEEDaS5_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE5applyITpTkNSt3__117unsigned_integralEJjEQ10all_same_vIDpTL1__EEEDaS5_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE5applyITpTkNSt3__117unsigned_integralEJtEQ10all_same_vIDpTL1__EEEDaS5_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE5applyITpTkNSt3__117unsigned_integralEJhEQ10all_same_vIDpTL1__EEEDaS5_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_eOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_EUlTkNS5_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEE5applyITpTkNS5_17unsigned_integralEJmmEQ10all_same_vIDpTL1__EEEDaSC_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_eOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_EUlTkNS5_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEE5applyITpTkNS5_17unsigned_integralEJjjEQ10all_same_vIDpTL1__EEEDaSC_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_eOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_EUlTkNS5_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEE5applyITpTkNS5_17unsigned_integralEJttEQ10all_same_vIDpTL1__EEEDaSC_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_eOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_EUlTkNS5_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEE5applyITpTkNS5_17unsigned_integralEJhhEQ10all_same_vIDpTL1__EEEDaSC_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSA_EEET_mEUlSB_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEE5applyITpTkNSt3__117unsigned_integralEJmEQ10all_same_vIDpTL1__EEEDaSC_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSA_EEET_mEUlSB_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEE5applyITpTkNSt3__117unsigned_integralEJjEQ10all_same_vIDpTL1__EEEDaSC_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSA_EEET_mEUlSB_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEE5applyITpTkNSt3__117unsigned_integralEJtEQ10all_same_vIDpTL1__EEEDaSC_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSA_EEET_mEUlSB_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEE5applyITpTkNSt3__117unsigned_integralEJhEQ10all_same_vIDpTL1__EEEDaSC_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS7_EEEvmT_EUlTkNSt3__117unsigned_integralESB_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEE5applyITpTkNSC_17unsigned_integralEJmEQ10all_same_vIDpTL1__EEEDaSD_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS7_EEEvmT_EUlTkNSt3__117unsigned_integralESB_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEE5applyITpTkNSC_17unsigned_integralEJjEQ10all_same_vIDpTL1__EEEDaSD_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS7_EEEvmT_EUlTkNSt3__117unsigned_integralESB_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEE5applyITpTkNSC_17unsigned_integralEJtEQ10all_same_vIDpTL1__EEEDaSD_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS7_EEEvmT_EUlTkNSt3__117unsigned_integralESB_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEE5applyITpTkNSC_17unsigned_integralEJhEQ10all_same_vIDpTL1__EEEDaSD_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitINS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUljjE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlttE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSG_IKS2_LSH_0EEEEE5applyITpTkNSt3__117unsigned_integralEJmmEQ10all_same_vIDpTL1__EEEDaSF_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitINS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUljjE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlttE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSG_IKS2_LSH_0EEEEE5applyITpTkNSt3__117unsigned_integralEJjjEQ10all_same_vIDpTL1__EEEDaSF_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitINS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUljjE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlttE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSG_IKS2_LSH_0EEEEE5applyITpTkNSt3__117unsigned_integralEJttEQ10all_same_vIDpTL1__EEEDaSF_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitINS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUljjE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlttE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSG_IKS2_LSH_0EEEEE5applyITpTkNSt3__117unsigned_integralEJhhEQ10all_same_vIDpTL1__EEEDaSF_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEE5applyITpTkNS8_17unsigned_integralEJmmEQ10all_same_vIDpTL1__EEEDaSD_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEE5applyITpTkNS8_17unsigned_integralEJjjEQ10all_same_vIDpTL1__EEEDaSD_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEE5applyITpTkNS8_17unsigned_integralEJttEQ10all_same_vIDpTL1__EEEDaSD_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEE5applyITpTkNS8_17unsigned_integralEJhhEQ10all_same_vIDpTL1__EEEDaSD_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNSt3__117unsigned_integralES6_S6_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEE5applyITpTkNS9_17unsigned_integralEJmmEQ10all_same_vIDpTL1__EEEDaSA_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNSt3__117unsigned_integralES6_S6_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEE5applyITpTkNS9_17unsigned_integralEJjjEQ10all_same_vIDpTL1__EEEDaSA_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNSt3__117unsigned_integralES6_S6_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEE5applyITpTkNS9_17unsigned_integralEJttEQ10all_same_vIDpTL1__EEEDaSA_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNSt3__117unsigned_integralES6_S6_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEE5applyITpTkNS9_17unsigned_integralEJhhEQ10all_same_vIDpTL1__EEEDaSA_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE5applyITpTkNSt3__117unsigned_integralEJmEQ10all_same_vIDpTL1__EEEDaS5_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE5applyITpTkNSt3__117unsigned_integralEJjEQ10all_same_vIDpTL1__EEEDaS5_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE5applyITpTkNSt3__117unsigned_integralEJtEQ10all_same_vIDpTL1__EEEDaS5_mDpT_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35blockwise_processing_callback_traitIZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEE5applyITpTkNSt3__117unsigned_integralEJhEQ10all_same_vIDpTL1__EEEDaS5_mDpT_
1190
      };
1191
1192
      /**
1193
       * Helper function of `full_range_operation` and `range_operation` that
1194
       * calls @p fn on a given aligned unsigned integer block as long as the
1195
       * underlying bit range contains enough bits to fill the block fully.
1196
       *
1197
       * This uses bare memory access to gain a speed up for aligned data.
1198
       */
1199
      template <std::unsigned_integral BlockT, typename FnT, typename... BitRangeOperatorTs>
1200
         requires(detail::blockwise_processing_callback<FnT, BitRangeOperatorTs...> &&
1201
                  sizeof...(BitRangeOperatorTs) > 0)
1202
0
      static bool _process_in_fully_aligned_blocks_of(FnT fn, BitRangeOperatorTs&... ops) {
1203
0
         constexpr size_type block_bytes = sizeof(BlockT);
1204
0
         constexpr size_type block_bits = block_bytes * 8;
1205
0
         const size_type blocks = detail::first(ops...).bits_to_read() / block_bits;
1206
1207
0
         using callback_trait = blockwise_processing_callback_trait<FnT, BitRangeOperatorTs...>;
1208
0
         const auto result = callback_trait::apply_on_full_blocks(fn, ops.template span<BlockT>(blocks)...);
1209
0
         (ops.advance(block_bytes * blocks), ...);
1210
0
         return result;
1211
0
      }
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEmZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEjZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEtZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEmZNS2_eOITkNS_12bitvectorishENS0_INS4_9allocatorEEEEERDaRKT_EUlTkNS4_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEjZNS2_eOITkNS_12bitvectorishENS0_INS4_9allocatorEEEEERDaRKT_EUlTkNS4_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEtZNS2_eOITkNS_12bitvectorishENS0_INS4_9allocatorEEEEERDaRKT_EUlTkNS4_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEmNS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUljjE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUlttE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSH_IKS2_LSI_0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEjNS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUljjE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUlttE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSH_IKS2_LSI_0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEtNS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUljjE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUlttE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSH_IKS2_LSI_0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEmZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNS4_17unsigned_integralES7_S7_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEjZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNS4_17unsigned_integralES7_S7_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEtZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNS4_17unsigned_integralES7_S7_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEmZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEjZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE35_process_in_fully_aligned_blocks_ofITkNSt3__117unsigned_integralEtZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEQaasr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EgtsZTL0_1_Li0EEEbT0_DpRT1_
1212
1213
      /**
1214
       * Helper function of `full_range_operation` and `range_operation` that
1215
       * calls @p fn on a given unsigned integer block size as long as the
1216
       * underlying bit range contains enough bits to fill the block.
1217
       */
1218
      template <std::unsigned_integral BlockT, typename FnT, typename... BitRangeOperatorTs>
1219
         requires(detail::blockwise_processing_callback<FnT, BitRangeOperatorTs...>)
1220
0
      static bool _process_in_unaligned_blocks_of(FnT fn, BitRangeOperatorTs&... ops) {
1221
0
         using callback_trait = blockwise_processing_callback_trait<FnT, BitRangeOperatorTs...>;
1222
0
         return callback_trait::template apply_on_unaligned_blocks<BlockT>(fn, ops...);
1223
0
      }
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEmZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNS4_8optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbS9_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEjZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNS4_8optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbS9_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEtZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNS4_8optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbS9_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEhZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNS4_8optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbS9_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEhZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEhZNS2_eOITkNS_12bitvectorishENS0_INS4_9allocatorEEEEERDaRKT_EUlTkNS4_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEmZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSB_EEET_mEUlSC_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEjZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSB_EEET_mEUlSC_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEtZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSB_EEET_mEUlSC_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEhZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSB_EEET_mEUlSC_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEmZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS8_EEEvmT_EUlTkNS4_17unsigned_integralESC_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEjZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS8_EEEvmT_EUlTkNS4_17unsigned_integralESC_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEtZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS8_EEEvmT_EUlTkNS4_17unsigned_integralESC_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEhZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS8_EEEvmT_EUlTkNS4_17unsigned_integralESC_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEhNS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUljjE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUlttE_ZNS6_ITkNS_12bitvectorishES2_EEvS8_SB_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSH_IKS2_LSI_0EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEmZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNS4_8optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbSC_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEjZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNS4_8optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbSC_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEtZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNS4_8optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbSC_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEhZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNS4_8optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbSC_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEhZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNS4_17unsigned_integralES7_S7_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE31_process_in_unaligned_blocks_ofITkNSt3__117unsigned_integralEhZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEQsr6detailE29blockwise_processing_callbackITL0_0_DpTL0_1_EEEbT0_DpRT1_
1224
1225
      /**
1226
       * Apply @p fn to all bits in the ranges defined by @p ops. If more than
1227
       * one range operator is passed to @p ops, @p fn receives corresponding
1228
       * blocks of bits from each operator. Therefore, all @p ops have to define
1229
       * the exact same length of their underlying ranges.
1230
       *
1231
       * @p fn may return a bit block that will be stored into the _first_ bit
1232
       * range passed into @p ops. If @p fn returns a boolean, and its value is
1233
       * `false`, the range operation is cancelled and `false` is returned.
1234
       *
1235
       * The implementation ensures to pull bits in the largest bit blocks
1236
       * possible and reverts to smaller bit blocks only when needed.
1237
       */
1238
      template <typename FnT, typename... BitRangeOperatorTs>
1239
         requires(detail::blockwise_processing_callback<FnT, BitRangeOperatorTs...> &&
1240
                  sizeof...(BitRangeOperatorTs) > 0)
1241
0
      static bool range_operation(FnT fn, BitRangeOperatorTs... ops) {
1242
0
         BOTAN_ASSERT(has_equal_lengths(ops...), "all BitRangeOperators have the same length");
1243
1244
0
         if constexpr((BitRangeOperatorTs::is_byte_aligned() && ...)) {
1245
            // Note: At the moment we can assume that this will always be used
1246
            //       on the _entire_ bitvector. Therefore, we can safely assume
1247
            //       that the bitvectors' underlying buffers are properly aligned.
1248
            //       If this assumption changes, we need to add further handling
1249
            //       to process a byte padding at the beginning of the bitvector
1250
            //       until a memory alignment boundary is reached.
1251
0
            const bool alignment = (ops.template is_memory_aligned_to<uint64_t>() && ...);
1252
0
            BOTAN_ASSERT_NOMSG(alignment);
1253
1254
0
            return _process_in_fully_aligned_blocks_of<uint64_t>(fn, ops...) &&
1255
0
                   _process_in_fully_aligned_blocks_of<uint32_t>(fn, ops...) &&
1256
0
                   _process_in_fully_aligned_blocks_of<uint16_t>(fn, ops...) &&
1257
0
                   _process_in_unaligned_blocks_of<uint8_t>(fn, ops...);
1258
0
         } else {
1259
0
            return _process_in_unaligned_blocks_of<uint64_t>(fn, ops...) &&
1260
0
                   _process_in_unaligned_blocks_of<uint32_t>(fn, ops...) &&
1261
0
                   _process_in_unaligned_blocks_of<uint16_t>(fn, ops...) &&
1262
0
                   _process_in_unaligned_blocks_of<uint8_t>(fn, ops...);
1263
0
         }
1264
0
      }
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE15range_operationIZNKS2_9subvectorITkNS_12bitvectorishES2_EEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_1EEEEQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EgtsZTL0_0_Li0EEEbS8_DpT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE15range_operationIZNKS2_14hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EgtsZTL0_0_Li0EEEbS4_DpT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE15range_operationIZNS2_eOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_EUlTkNS5_17unsigned_integralES9_S9_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSD_IKS7_LSE_0EEEEQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EgtsZTL0_0_Li0EEEbS9_DpT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE15range_operationIZNKS2_9subvectorImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbSA_EEET_mEUlSB_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE1EEEEQaasr6detailE29blockwise_processing_callbackIS7_DpTL0_0_EgtsZTL0_0_Li0EEEbSB_DpT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE15range_operationIZNS2_17subvector_replaceImQaasr3stdE17unsigned_integralINS_6detail19wrapped_type_helperIu14__remove_cvrefITL0__EE4typeEEntsr3stdE7same_asIbS7_EEEvmT_EUlTkNSt3__117unsigned_integralESB_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE1EEEEQaasr6detailE29blockwise_processing_callbackIS7_DpTL0_0_EgtsZTL0_0_Li0EEEbSB_DpT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE15range_operationINS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUljjE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlttE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlhhE_EEEJNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSG_IKS2_LSH_0EEEEQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EgtsZTL0_0_Li0EEEbS8_DpT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE15range_operationIZNKS2_9subvectorITkNS_12bitvectorishENS_6StrongIS2_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEEEUlT_T0_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSE_IKS2_LSF_1EEEEQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EgtsZTL0_0_Li0EEEbSB_DpT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE15range_operationIZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNSt3__117unsigned_integralES6_S6_E_JNS2_16BitRangeOperatorIS2_LNS2_17BitRangeAlignmentE0EEENSB_IKS2_LSC_0EEEEQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EgtsZTL0_0_Li0EEEbS6_DpT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE15range_operationIZNKS2_22has_odd_hamming_weightEvEUlT_E_JNS2_16BitRangeOperatorIKS2_LNS2_17BitRangeAlignmentE0EEEEQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EgtsZTL0_0_Li0EEEbS4_DpT0_
1265
1266
      /**
1267
       * Apply @p fn to all bit blocks in the bitvector(s).
1268
       */
1269
      template <typename FnT, typename... BitvectorTs>
1270
         requires(detail::blockwise_processing_callback<FnT, BitvectorTs...> &&
1271
                  (is_bitvector_v<std::remove_cvref_t<BitvectorTs>> && ... && true))
1272
0
      static bool full_range_operation(FnT&& fn, BitvectorTs&... bitvecs) {
1273
0
         BOTAN_ASSERT(has_equal_lengths(bitvecs...), "all bitvectors have the same length");
1274
0
         return range_operation(std::forward<FnT>(fn), BitRangeOperator<BitvectorTs>(bitvecs)...);
1275
0
      }
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE20full_range_operationIZNKS2_14hamming_weightEvEUlT_E_JKS2_EQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EfRaa14is_bitvector_vIu14__remove_cvrefIS8_EELb1EEEbOS4_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE20full_range_operationIZNS2_eOITkNS_12bitvectorishENS0_INSt3__19allocatorEEEEERDaRKT_EUlTkNS5_17unsigned_integralES9_S9_E_JS2_KS7_EQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EfRaa14is_bitvector_vIu14__remove_cvrefISF_EELb1EEEbOS9_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE20full_range_operationIRNS_10overloadedIJZNS2_18ct_conditional_xorITkNS_12bitvectorishES2_EEvNS_2CT6ChoiceERKT_EUlmmE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUljjE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlttE_ZNS5_ITkNS_12bitvectorishES2_EEvS7_SA_EUlhhE_EEEJS2_KS2_EQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EfRaa14is_bitvector_vIu14__remove_cvrefISJ_EELb1EEEbOS8_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE20full_range_operationIZNS2_aNITkNS_12bitvectorishES2_EERDaRKT_EUlTkNSt3__117unsigned_integralES6_S6_E_JS2_KS2_EQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EfRaa14is_bitvector_vIu14__remove_cvrefISD_EELb1EEEbOS6_DpRT0_
Unexecuted instantiation: _ZN5Botan14bitvector_baseINS_16secure_allocatorEE20full_range_operationIZNKS2_22has_odd_hamming_weightEvEUlT_E_JKS2_EQaasr6detailE29blockwise_processing_callbackITL0__DpTL0_0_EfRaa14is_bitvector_vIu14__remove_cvrefIS8_EELb1EEEbOS4_DpRT0_
1276
1277
      template <typename SomeT, typename... SomeTs>
1278
0
      static bool has_equal_lengths(const SomeT& v, const SomeTs&... vs) {
1279
0
         return ((v.size() == vs.size()) && ... && true);
1280
0
      }
Unexecuted instantiation: bool Botan::bitvector_base<Botan::secure_allocator>::has_equal_lengths<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1> >(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0> const&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1> const&)
Unexecuted instantiation: bool Botan::bitvector_base<Botan::secure_allocator>::has_equal_lengths<Botan::bitvector_base<Botan::secure_allocator>>(Botan::bitvector_base<Botan::secure_allocator> const&)
Unexecuted instantiation: bool Botan::bitvector_base<Botan::secure_allocator>::has_equal_lengths<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0> const&)
Unexecuted instantiation: bool Botan::bitvector_base<Botan::secure_allocator>::has_equal_lengths<Botan::bitvector_base<Botan::secure_allocator>, Botan::bitvector_base<std::__1::allocator> >(Botan::bitvector_base<Botan::secure_allocator> const&, Botan::bitvector_base<std::__1::allocator> const&)
Unexecuted instantiation: bool Botan::bitvector_base<Botan::secure_allocator>::has_equal_lengths<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0> >(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0> const&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<std::__1::allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0> const&)
Unexecuted instantiation: bool Botan::bitvector_base<Botan::secure_allocator>::has_equal_lengths<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1> const&)
Unexecuted instantiation: bool Botan::bitvector_base<Botan::secure_allocator>::has_equal_lengths<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1>>(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)1> const&)
Unexecuted instantiation: bool Botan::bitvector_base<Botan::secure_allocator>::has_equal_lengths<Botan::bitvector_base<Botan::secure_allocator>, Botan::bitvector_base<Botan::secure_allocator> >(Botan::bitvector_base<Botan::secure_allocator> const&, Botan::bitvector_base<Botan::secure_allocator> const&)
Unexecuted instantiation: bool Botan::bitvector_base<Botan::secure_allocator>::has_equal_lengths<Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0>, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0> >(Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator>, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0> const&, Botan::bitvector_base<Botan::secure_allocator>::BitRangeOperator<Botan::bitvector_base<Botan::secure_allocator> const, (Botan::bitvector_base<Botan::secure_allocator>::BitRangeAlignment)0> const&)
1281
1282
      template <std::unsigned_integral T>
1283
      static constexpr T make_mask(size_type bits) {
1284
         const bool max = bits >= sizeof(T) * 8;
1285
         bits &= T(max - 1);
1286
         return (T(!max) << bits) - 1;
1287
      }
1288
1289
0
      auto as_byte_span() { return std::span{m_blocks.data(), m_blocks.size() * sizeof(block_type)}; }
1290
1291
0
      auto as_byte_span() const { return std::span{m_blocks.data(), m_blocks.size() * sizeof(block_type)}; }
Unexecuted instantiation: Botan::bitvector_base<Botan::secure_allocator>::as_byte_span() const
Unexecuted instantiation: Botan::bitvector_base<std::__1::allocator>::as_byte_span() const
1292
1293
   private:
1294
      size_type m_bits;
1295
      std::vector<block_type, allocator_type> m_blocks;
1296
};
1297
1298
using secure_bitvector = bitvector_base<secure_allocator>;
1299
using bitvector = bitvector_base<std::allocator>;
1300
1301
namespace detail {
1302
1303
/**
1304
 * If one of the allocators is a Botan::secure_allocator, this will always
1305
 * prefer it. Otherwise, the allocator of @p lhs will be used as a default.
1306
 */
1307
template <bitvectorish T1, bitvectorish T2>
1308
0
constexpr auto copy_lhs_allocator_aware(const T1& lhs, const T2&) {
1309
0
   constexpr bool needs_secure_allocator =
1310
0
      strong_type_wrapped_type<T1>::uses_secure_allocator || strong_type_wrapped_type<T2>::uses_secure_allocator;
1311
1312
0
   if constexpr(needs_secure_allocator) {
1313
0
      return lhs.template as<secure_bitvector>();
1314
   } else {
1315
      return lhs.template as<bitvector>();
1316
   }
1317
0
}
1318
1319
}  // namespace detail
1320
1321
template <bitvectorish T1, bitvectorish T2>
1322
auto operator|(const T1& lhs, const T2& rhs) {
1323
   auto res = detail::copy_lhs_allocator_aware(lhs, rhs);
1324
   res |= rhs;
1325
   return res;
1326
}
1327
1328
template <bitvectorish T1, bitvectorish T2>
1329
auto operator&(const T1& lhs, const T2& rhs) {
1330
   auto res = detail::copy_lhs_allocator_aware(lhs, rhs);
1331
   res &= rhs;
1332
   return res;
1333
}
1334
1335
template <bitvectorish T1, bitvectorish T2>
1336
0
auto operator^(const T1& lhs, const T2& rhs) {
1337
0
   auto res = detail::copy_lhs_allocator_aware(lhs, rhs);
1338
0
   res ^= rhs;
1339
0
   return res;
1340
0
}
1341
1342
template <bitvectorish T1, bitvectorish T2>
1343
bool operator==(const T1& lhs, const T2& rhs) {
1344
   return lhs.equals_vartime(rhs);
1345
}
1346
1347
template <bitvectorish T1, bitvectorish T2>
1348
bool operator!=(const T1& lhs, const T2& rhs) {
1349
   return lhs.equals_vartime(rhs);
1350
}
1351
1352
namespace detail {
1353
1354
/**
1355
 * A Strong<> adapter for arbitrarily large bitvectors
1356
 */
1357
template <concepts::container T>
1358
   requires is_bitvector_v<T>
1359
class Strong_Adapter<T> : public Container_Strong_Adapter_Base<T> {
1360
   public:
1361
      using size_type = typename T::size_type;
1362
1363
   public:
1364
      using Container_Strong_Adapter_Base<T>::Container_Strong_Adapter_Base;
1365
1366
0
      auto at(size_type i) const { return this->get().at(i); }
1367
1368
0
      auto at(size_type i) { return this->get().at(i); }
1369
1370
      auto set(size_type i) { return this->get().set(i); }
1371
1372
      auto unset(size_type i) { return this->get().unset(i); }
1373
1374
      auto flip(size_type i) { return this->get().flip(i); }
1375
1376
      auto flip() { return this->get().flip(); }
1377
1378
      template <typename OutT>
1379
0
      auto as() const {
1380
0
         return this->get().template as<OutT>();
1381
0
      }
1382
1383
      template <bitvectorish OutT = T>
1384
0
      auto subvector(size_type pos, std::optional<size_type> length = std::nullopt) const {
1385
0
         return this->get().template subvector<OutT>(pos, length);
1386
0
      }
Unexecuted instantiation: _ZNK5Botan6detail14Strong_AdapterINS_14bitvector_baseINS_16secure_allocatorEEEE9subvectorITkNS_12bitvectorishENS_6StrongIS4_NS_13CmceCodeWord_EJEEEEEDamNSt3__18optionalImEE
Unexecuted instantiation: _ZNK5Botan6detail14Strong_AdapterINS_14bitvector_baseINS_16secure_allocatorEEEE9subvectorITkNS_12bitvectorishES4_EEDamNSt3__18optionalImEE
1387
1388
      template <typename OutT>
1389
         requires(std::unsigned_integral<strong_type_wrapped_type<OutT>> &&
1390
                  !std::same_as<bool, strong_type_wrapped_type<OutT>>)
1391
0
      auto subvector(size_type pos) const {
1392
0
         return this->get().template subvector<OutT>(pos);
1393
0
      }
1394
1395
      template <typename InT>
1396
         requires(std::unsigned_integral<strong_type_wrapped_type<InT>> && !std::same_as<bool, InT>)
1397
0
      void subvector_replace(size_type pos, InT value) {
1398
0
         return this->get().subvector_replace(pos, value);
1399
0
      }
1400
1401
      template <bitvectorish OtherT>
1402
0
      auto equals(const OtherT& other) const {
1403
0
         return this->get().equals(other);
1404
0
      }
1405
1406
0
      auto push_back(bool b) { return this->get().push_back(b); }
1407
1408
      auto pop_back() { return this->get().pop_back(); }
1409
1410
      auto front() const { return this->get().front(); }
1411
1412
      auto front() { return this->get().front(); }
1413
1414
      auto back() const { return this->get().back(); }
1415
1416
      auto back() { return this->get().back(); }
1417
1418
      auto any_vartime() const { return this->get().any_vartime(); }
1419
1420
      auto all_vartime() const { return this->get().all_vartime(); }
1421
1422
      auto none_vartime() const { return this->get().none_vartime(); }
1423
1424
      auto has_odd_hamming_weight() const { return this->get().has_odd_hamming_weight(); }
1425
1426
0
      auto hamming_weight() const { return this->get().hamming_weight(); }
1427
1428
      auto from_bytes(std::span<const uint8_t> bytes, std::optional<size_type> bits = std::nullopt) {
1429
         return this->get().from_bytes(bytes, bits);
1430
      }
1431
1432
      template <typename OutT = T>
1433
      auto to_bytes() const {
1434
         return this->get().template to_bytes<OutT>();
1435
      }
1436
1437
0
      auto to_bytes(std::span<uint8_t> out) const { return this->get().to_bytes(out); }
1438
1439
      auto to_string() const { return this->get().to_string(); }
1440
1441
      auto capacity() const { return this->get().capacity(); }
1442
1443
      auto reserve(size_type n) { return this->get().reserve(n); }
1444
1445
0
      constexpr void _const_time_poison() const { this->get()._const_time_poison(); }
1446
1447
0
      constexpr void _const_time_unpoison() const { this->get()._const_time_unpoison(); }
1448
};
1449
1450
}  // namespace detail
1451
1452
}  // namespace Botan
1453
1454
#endif