/src/botan/build/include/public/botan/concepts.h
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * Useful concepts that are available throughout the library |
3 | | * (C) 2023 Jack Lloyd |
4 | | * 2023 René Meusel - Rohde & Schwarz Cybersecurity |
5 | | * |
6 | | * Botan is released under the Simplified BSD License (see license.txt) |
7 | | */ |
8 | | |
9 | | #ifndef BOTAN_CONCEPTS_H_ |
10 | | #define BOTAN_CONCEPTS_H_ |
11 | | |
12 | | #include <botan/assert.h> |
13 | | |
14 | | #include <compare> |
15 | | #include <concepts> |
16 | | #include <cstdint> |
17 | | #include <ostream> |
18 | | #include <ranges> |
19 | | #include <span> |
20 | | #include <type_traits> |
21 | | |
22 | | namespace Botan { |
23 | | |
24 | | template <typename T, typename Tag, typename... Capabilities> |
25 | | class Strong; |
26 | | |
27 | | template <typename... Ts> |
28 | | struct is_strong_type : std::false_type {}; |
29 | | |
30 | | template <typename... Ts> |
31 | | struct is_strong_type<Strong<Ts...>> : std::true_type {}; |
32 | | |
33 | | template <typename... Ts> |
34 | | constexpr bool is_strong_type_v = is_strong_type<std::remove_const_t<Ts>...>::value; |
35 | | |
36 | | template <typename T0 = void, typename... Ts> |
37 | | struct all_same { |
38 | | static constexpr bool value = (std::is_same_v<T0, Ts> && ... && true); |
39 | | }; |
40 | | |
41 | | template <typename... Ts> |
42 | | static constexpr bool all_same_v = all_same<Ts...>::value; |
43 | | |
44 | | namespace detail { |
45 | | |
46 | | /** |
47 | | * Helper type to indicate that a certain type should be automatically |
48 | | * detected based on the context. |
49 | | */ |
50 | | struct AutoDetect { |
51 | | constexpr AutoDetect() = delete; |
52 | | }; |
53 | | |
54 | | } // namespace detail |
55 | | |
56 | | namespace ranges { |
57 | | |
58 | | /** |
59 | | * Models a std::ranges::contiguous_range that (optionally) restricts its |
60 | | * value_type to ValueT. In other words: a stretch of contiguous memory of |
61 | | * a certain type (optional ValueT). |
62 | | */ |
63 | | template <typename T, typename ValueT = std::ranges::range_value_t<T>> |
64 | | concept contiguous_range = std::ranges::contiguous_range<T> && std::same_as<ValueT, std::ranges::range_value_t<T>>; |
65 | | |
66 | | /** |
67 | | * Models a std::ranges::contiguous_range that satisfies |
68 | | * std::ranges::output_range with an arbitrary value_type. In other words: a |
69 | | * stretch of contiguous memory of a certain type (optional ValueT) that can be |
70 | | * written to. |
71 | | */ |
72 | | template <typename T, typename ValueT = std::ranges::range_value_t<T>> |
73 | | concept contiguous_output_range = contiguous_range<T, ValueT> && std::ranges::output_range<T, ValueT>; |
74 | | |
75 | | /** |
76 | | * Models a range that can be turned into a std::span<>. Typically, this is some |
77 | | * form of ranges::contiguous_range. |
78 | | */ |
79 | | template <typename T> |
80 | | concept spanable_range = std::constructible_from<std::span<const std::ranges::range_value_t<T>>, T>; |
81 | | |
82 | | /** |
83 | | * Models a range that can be turned into a std::span<> with a static extent. |
84 | | * Typically, this is a std::array or a std::span derived from an array. |
85 | | */ |
86 | | // clang-format off |
87 | | template <typename T> |
88 | | concept statically_spanable_range = spanable_range<T> && |
89 | | decltype(std::span{std::declval<T&>()})::extent != std::dynamic_extent; |
90 | | |
91 | | // clang-format on |
92 | | |
93 | | /** |
94 | | * Find the length in bytes of a given contiguous range @p r. |
95 | | */ |
96 | 11.5M | inline constexpr size_t size_bytes(spanable_range auto&& r) { |
97 | 11.5M | return std::span{r}.size_bytes(); |
98 | 11.5M | } unsigned long Botan::ranges::size_bytes<std::__1::array<unsigned long, 4ul>&>(std::__1::array<unsigned long, 4ul>&) Line | Count | Source | 96 | 131k | inline constexpr size_t size_bytes(spanable_range auto&& r) { | 97 | 131k | return std::span{r}.size_bytes(); | 98 | 131k | } |
unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned char, 32ul>&>(std::__1::span<unsigned char, 32ul>&) Line | Count | Source | 96 | 65.9k | inline constexpr size_t size_bytes(spanable_range auto&& r) { | 97 | 65.9k | return std::span{r}.size_bytes(); | 98 | 65.9k | } |
Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned long, 18446744073709551615ul>&>(std::__1::span<unsigned long, 18446744073709551615ul>&) unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned char, 18446744073709551615ul>&>(std::__1::span<unsigned char, 18446744073709551615ul>&) Line | Count | Source | 96 | 41.7k | inline constexpr size_t size_bytes(spanable_range auto&& r) { | 97 | 41.7k | return std::span{r}.size_bytes(); | 98 | 41.7k | } |
unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned long, 1ul>&>(std::__1::span<unsigned long, 1ul>&) Line | Count | Source | 96 | 5.22M | inline constexpr size_t size_bytes(spanable_range auto&& r) { | 97 | 5.22M | return std::span{r}.size_bytes(); | 98 | 5.22M | } |
unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned char, 8ul>&>(std::__1::span<unsigned char, 8ul>&) Line | Count | Source | 96 | 413k | inline constexpr size_t size_bytes(spanable_range auto&& r) { | 97 | 413k | return std::span{r}.size_bytes(); | 98 | 413k | } |
unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned int, 18446744073709551615ul>&>(std::__1::span<unsigned int, 18446744073709551615ul>&) Line | Count | Source | 96 | 78.3k | inline constexpr size_t size_bytes(spanable_range auto&& r) { | 97 | 78.3k | return std::span{r}.size_bytes(); | 98 | 78.3k | } |
unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned int, 1ul>&>(std::__1::span<unsigned int, 1ul>&) Line | Count | Source | 96 | 5.22M | inline constexpr size_t size_bytes(spanable_range auto&& r) { | 97 | 5.22M | return std::span{r}.size_bytes(); | 98 | 5.22M | } |
unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned char, 4ul>&>(std::__1::span<unsigned char, 4ul>&) Line | Count | Source | 96 | 381k | inline constexpr size_t size_bytes(spanable_range auto&& r) { | 97 | 381k | return std::span{r}.size_bytes(); | 98 | 381k | } |
Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned char, 2ul>&>(std::__1::span<unsigned char, 2ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned short, 1ul>&>(std::__1::span<unsigned short, 1ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned long, 4ul>&>(std::__1::span<unsigned long, 4ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned long, 6ul>&>(std::__1::span<unsigned long, 6ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned char, 48ul>&>(std::__1::span<unsigned char, 48ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::array<unsigned long, 6ul>&>(std::__1::array<unsigned long, 6ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned long, 8ul>&>(std::__1::span<unsigned long, 8ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned char, 64ul>&>(std::__1::span<unsigned char, 64ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::array<unsigned long, 8ul>&>(std::__1::array<unsigned long, 8ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned char, 72ul>&>(std::__1::span<unsigned char, 72ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::array<unsigned long, 9ul>&>(std::__1::array<unsigned long, 9ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned long, 9ul>&>(std::__1::span<unsigned long, 9ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned char, 66ul>&>(std::__1::span<unsigned char, 66ul>&) Unexecuted instantiation: unsigned long Botan::ranges::size_bytes<std::__1::span<unsigned char, 98ul>&>(std::__1::span<unsigned char, 98ul>&) |
99 | | |
100 | | /** |
101 | | * Check that a given range @p r has a certain statically-known byte length. If |
102 | | * the range's extent is known at compile time, this is a static check, |
103 | | * otherwise a runtime argument check will be added. |
104 | | * |
105 | | * @throws Invalid_Argument if range @p r has a dynamic extent and does not |
106 | | * feature the expected byte length. |
107 | | */ |
108 | | template <size_t expected, spanable_range R> |
109 | 23.2M | inline constexpr void assert_exact_byte_length(R&& r) { |
110 | 23.2M | const std::span s{r}; |
111 | 23.2M | if constexpr(statically_spanable_range<R>) { |
112 | 23.2M | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); |
113 | 23.2M | } else { |
114 | 23.2M | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); |
115 | 23.2M | } |
116 | 23.2M | } void Botan::ranges::assert_exact_byte_length<32ul, std::__1::span<unsigned char, 32ul>&>(std::__1::span<unsigned char, 32ul>&) Line | Count | Source | 109 | 478 | inline constexpr void assert_exact_byte_length(R&& r) { | 110 | 478 | const std::span s{r}; | 111 | 478 | if constexpr(statically_spanable_range<R>) { | 112 | 478 | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 113 | 478 | } else { | 114 | 478 | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 115 | 478 | } | 116 | 478 | } |
void Botan::ranges::assert_exact_byte_length<32ul, std::__1::span<unsigned char const, 32ul>&>(std::__1::span<unsigned char const, 32ul>&) Line | Count | Source | 109 | 131k | inline constexpr void assert_exact_byte_length(R&& r) { | 110 | 131k | const std::span s{r}; | 111 | 131k | if constexpr(statically_spanable_range<R>) { | 112 | 131k | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 113 | 131k | } else { | 114 | 131k | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 115 | 131k | } | 116 | 131k | } |
void Botan::ranges::assert_exact_byte_length<32ul, std::__1::array<unsigned long, 4ul>&>(std::__1::array<unsigned long, 4ul>&) Line | Count | Source | 109 | 65.9k | inline constexpr void assert_exact_byte_length(R&& r) { | 110 | 65.9k | const std::span s{r}; | 111 | 65.9k | if constexpr(statically_spanable_range<R>) { | 112 | 65.9k | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 113 | 65.9k | } else { | 114 | 65.9k | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 115 | 65.9k | } | 116 | 65.9k | } |
void Botan::ranges::assert_exact_byte_length<8ul, std::__1::span<unsigned char const, 8ul>&>(std::__1::span<unsigned char const, 8ul>&) Line | Count | Source | 109 | 10.4M | inline constexpr void assert_exact_byte_length(R&& r) { | 110 | 10.4M | const std::span s{r}; | 111 | 10.4M | if constexpr(statically_spanable_range<R>) { | 112 | 10.4M | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 113 | 10.4M | } else { | 114 | 10.4M | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 115 | 10.4M | } | 116 | 10.4M | } |
void Botan::ranges::assert_exact_byte_length<8ul, std::__1::span<unsigned char, 8ul>&>(std::__1::span<unsigned char, 8ul>&) Line | Count | Source | 109 | 663k | inline constexpr void assert_exact_byte_length(R&& r) { | 110 | 663k | const std::span s{r}; | 111 | 663k | if constexpr(statically_spanable_range<R>) { | 112 | 663k | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 113 | 663k | } else { | 114 | 663k | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 115 | 663k | } | 116 | 663k | } |
void Botan::ranges::assert_exact_byte_length<8ul, std::__1::span<unsigned long const, 1ul>&>(std::__1::span<unsigned long const, 1ul>&) Line | Count | Source | 109 | 413k | inline constexpr void assert_exact_byte_length(R&& r) { | 110 | 413k | const std::span s{r}; | 111 | 413k | if constexpr(statically_spanable_range<R>) { | 112 | 413k | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 113 | 413k | } else { | 114 | 413k | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 115 | 413k | } | 116 | 413k | } |
void Botan::ranges::assert_exact_byte_length<4ul, std::__1::span<unsigned char const, 4ul>&>(std::__1::span<unsigned char const, 4ul>&) Line | Count | Source | 109 | 10.4M | inline constexpr void assert_exact_byte_length(R&& r) { | 110 | 10.4M | const std::span s{r}; | 111 | 10.4M | if constexpr(statically_spanable_range<R>) { | 112 | 10.4M | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 113 | 10.4M | } else { | 114 | 10.4M | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 115 | 10.4M | } | 116 | 10.4M | } |
void Botan::ranges::assert_exact_byte_length<4ul, std::__1::span<unsigned char, 4ul>&>(std::__1::span<unsigned char, 4ul>&) Line | Count | Source | 109 | 664k | inline constexpr void assert_exact_byte_length(R&& r) { | 110 | 664k | const std::span s{r}; | 111 | 664k | if constexpr(statically_spanable_range<R>) { | 112 | 664k | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 113 | 664k | } else { | 114 | 664k | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 115 | 664k | } | 116 | 664k | } |
void Botan::ranges::assert_exact_byte_length<4ul, std::__1::span<unsigned int const, 1ul>&>(std::__1::span<unsigned int const, 1ul>&) Line | Count | Source | 109 | 381k | inline constexpr void assert_exact_byte_length(R&& r) { | 110 | 381k | const std::span s{r}; | 111 | 381k | if constexpr(statically_spanable_range<R>) { | 112 | 381k | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 113 | 381k | } else { | 114 | 381k | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 115 | 381k | } | 116 | 381k | } |
Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<2ul, std::__1::span<unsigned char, 2ul>&>(std::__1::span<unsigned char, 2ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<2ul, std::__1::span<unsigned short const, 1ul>&>(std::__1::span<unsigned short const, 1ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<16ul, std::__1::span<unsigned char, 16ul>&>(std::__1::span<unsigned char, 16ul>&) void Botan::ranges::assert_exact_byte_length<8ul, std::__1::array<unsigned char, 8ul>&>(std::__1::array<unsigned char, 8ul>&) Line | Count | Source | 109 | 14.0k | inline constexpr void assert_exact_byte_length(R&& r) { | 110 | 14.0k | const std::span s{r}; | 111 | 14.0k | if constexpr(statically_spanable_range<R>) { | 112 | 14.0k | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 113 | 14.0k | } else { | 114 | 14.0k | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 115 | 14.0k | } | 116 | 14.0k | } |
Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<2ul, std::__1::span<unsigned char const, 2ul>&>(std::__1::span<unsigned char const, 2ul>&) void Botan::ranges::assert_exact_byte_length<16ul, std::__1::array<unsigned char, 16ul>&>(std::__1::array<unsigned char, 16ul>&) Line | Count | Source | 109 | 713 | inline constexpr void assert_exact_byte_length(R&& r) { | 110 | 713 | const std::span s{r}; | 111 | 713 | if constexpr(statically_spanable_range<R>) { | 112 | 713 | static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 113 | 713 | } else { | 114 | 713 | BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths"); | 115 | 713 | } | 116 | 713 | } |
Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<16ul, std::__1::span<unsigned char const, 16ul>&>(std::__1::span<unsigned char const, 16ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<64ul, std::__1::span<unsigned char const, 64ul>&>(std::__1::span<unsigned char const, 64ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<64ul, std::__1::span<unsigned char, 64ul>&>(std::__1::span<unsigned char, 64ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<32ul, std::__1::array<unsigned long, 4ul> const&>(std::__1::array<unsigned long, 4ul> const&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<8ul, std::__1::array<unsigned long, 1ul>&>(std::__1::array<unsigned long, 1ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<32ul, std::__1::span<unsigned long, 4ul>&>(std::__1::span<unsigned long, 4ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<48ul, std::__1::array<unsigned long, 6ul> const&>(std::__1::array<unsigned long, 6ul> const&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<48ul, std::__1::array<unsigned long, 6ul>&>(std::__1::array<unsigned long, 6ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<48ul, std::__1::span<unsigned char const, 48ul>&>(std::__1::span<unsigned char const, 48ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<48ul, std::__1::span<unsigned long, 6ul>&>(std::__1::span<unsigned long, 6ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<64ul, std::__1::array<unsigned long, 8ul> const&>(std::__1::array<unsigned long, 8ul> const&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<64ul, std::__1::array<unsigned long, 8ul>&>(std::__1::array<unsigned long, 8ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<64ul, std::__1::span<unsigned long, 8ul>&>(std::__1::span<unsigned long, 8ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<72ul, std::__1::span<unsigned char const, 72ul>&>(std::__1::span<unsigned char const, 72ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<72ul, std::__1::span<unsigned long const, 9ul>&>(std::__1::span<unsigned long const, 9ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<72ul, std::__1::array<unsigned long, 9ul> const&>(std::__1::array<unsigned long, 9ul> const&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<72ul, std::__1::array<unsigned long, 9ul>&>(std::__1::array<unsigned long, 9ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<66ul, std::__1::span<unsigned char const, 66ul>&>(std::__1::span<unsigned char const, 66ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<98ul, std::__1::span<unsigned char const, 98ul>&>(std::__1::span<unsigned char const, 98ul>&) Unexecuted instantiation: void Botan::ranges::assert_exact_byte_length<72ul, std::__1::span<unsigned long, 9ul>&>(std::__1::span<unsigned long, 9ul>&) |
117 | | |
118 | | /** |
119 | | * Check that a list of ranges (in @p r0 and @p rs) all have the same byte |
120 | | * lengths. If the first range's extent is known at compile time, this will be a |
121 | | * static check for all other ranges whose extents are known at compile time, |
122 | | * otherwise a runtime argument check will be added. |
123 | | * |
124 | | * @throws Invalid_Argument if any range has a dynamic extent and not all |
125 | | * ranges feature the same byte length. |
126 | | */ |
127 | | template <spanable_range R0, spanable_range... Rs> |
128 | | inline constexpr void assert_equal_byte_lengths(R0&& r0, Rs&&... rs) |
129 | | requires(sizeof...(Rs) > 0) |
130 | 11.7M | { |
131 | 11.7M | const std::span s0{r0}; |
132 | | |
133 | 11.7M | if constexpr(statically_spanable_range<R0>) { |
134 | 277k | constexpr size_t expected_size = s0.size_bytes(); |
135 | 277k | (assert_exact_byte_length<expected_size>(rs), ...); |
136 | 277k | } else { |
137 | 277k | const size_t expected_size = s0.size_bytes(); |
138 | 277k | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), |
139 | 277k | "memory regions don't have equal lengths"); |
140 | 277k | } |
141 | 11.7M | } void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::span<unsigned char const, 18446744073709551615ul>&>(std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::span<unsigned char const, 18446744073709551615ul>&) Line | Count | Source | 130 | 16.1k | { | 131 | 16.1k | const std::span s0{r0}; | 132 | | | 133 | 16.1k | if constexpr(statically_spanable_range<R0>) { | 134 | 16.1k | constexpr size_t expected_size = s0.size_bytes(); | 135 | 16.1k | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 16.1k | } else { | 137 | 16.1k | const size_t expected_size = s0.size_bytes(); | 138 | 16.1k | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 16.1k | "memory regions don't have equal lengths"); | 140 | 16.1k | } | 141 | 16.1k | } |
Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::array<unsigned long, 4ul>&, std::__1::span<unsigned char, 32ul>&>(std::__1::array<unsigned long, 4ul>&, std::__1::span<unsigned char, 32ul>&) void Botan::ranges::assert_equal_byte_lengths<std::__1::array<unsigned long, 4ul>&, std::__1::span<unsigned char const, 32ul>&>(std::__1::array<unsigned long, 4ul>&, std::__1::span<unsigned char const, 32ul>&) Line | Count | Source | 130 | 131k | { | 131 | 131k | const std::span s0{r0}; | 132 | | | 133 | 131k | if constexpr(statically_spanable_range<R0>) { | 134 | 131k | constexpr size_t expected_size = s0.size_bytes(); | 135 | 131k | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 131k | } else { | 137 | 131k | const size_t expected_size = s0.size_bytes(); | 138 | 131k | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 131k | "memory regions don't have equal lengths"); | 140 | 131k | } | 141 | 131k | } |
void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 32ul>&, std::__1::array<unsigned long, 4ul>&>(std::__1::span<unsigned char, 32ul>&, std::__1::array<unsigned long, 4ul>&) Line | Count | Source | 130 | 65.9k | { | 131 | 65.9k | const std::span s0{r0}; | 132 | | | 133 | 65.9k | if constexpr(statically_spanable_range<R0>) { | 134 | 65.9k | constexpr size_t expected_size = s0.size_bytes(); | 135 | 65.9k | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 65.9k | } else { | 137 | 65.9k | const size_t expected_size = s0.size_bytes(); | 138 | 65.9k | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 65.9k | "memory regions don't have equal lengths"); | 140 | 65.9k | } | 141 | 65.9k | } |
void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::span<unsigned char const, 18446744073709551615ul>&, std::__1::span<unsigned char const, 18446744073709551615ul>&>(std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::span<unsigned char const, 18446744073709551615ul>&, std::__1::span<unsigned char const, 18446744073709551615ul>&) Line | Count | Source | 130 | 11.9k | { | 131 | 11.9k | const std::span s0{r0}; | 132 | | | 133 | 11.9k | if constexpr(statically_spanable_range<R0>) { | 134 | 11.9k | constexpr size_t expected_size = s0.size_bytes(); | 135 | 11.9k | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 11.9k | } else { | 137 | 11.9k | const size_t expected_size = s0.size_bytes(); | 138 | 11.9k | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 11.9k | "memory regions don't have equal lengths"); | 140 | 11.9k | } | 141 | 11.9k | } |
Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned long, 18446744073709551615ul>&, std::__1::span<unsigned char const, 18446744073709551615ul>&>(std::__1::span<unsigned long, 18446744073709551615ul>&, std::__1::span<unsigned char const, 18446744073709551615ul>&) void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::span<unsigned long const, 18446744073709551615ul>&>(std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::span<unsigned long const, 18446744073709551615ul>&) Line | Count | Source | 130 | 32.8k | { | 131 | 32.8k | const std::span s0{r0}; | 132 | | | 133 | 32.8k | if constexpr(statically_spanable_range<R0>) { | 134 | 32.8k | constexpr size_t expected_size = s0.size_bytes(); | 135 | 32.8k | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 32.8k | } else { | 137 | 32.8k | const size_t expected_size = s0.size_bytes(); | 138 | 32.8k | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 32.8k | "memory regions don't have equal lengths"); | 140 | 32.8k | } | 141 | 32.8k | } |
void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned long, 1ul>&, std::__1::span<unsigned char const, 8ul>&>(std::__1::span<unsigned long, 1ul>&, std::__1::span<unsigned char const, 8ul>&) Line | Count | Source | 130 | 5.21M | { | 131 | 5.21M | const std::span s0{r0}; | 132 | | | 133 | 5.21M | if constexpr(statically_spanable_range<R0>) { | 134 | 5.21M | constexpr size_t expected_size = s0.size_bytes(); | 135 | 5.21M | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 5.21M | } else { | 137 | 5.21M | const size_t expected_size = s0.size_bytes(); | 138 | 5.21M | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 5.21M | "memory regions don't have equal lengths"); | 140 | 5.21M | } | 141 | 5.21M | } |
void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 8ul>&, std::__1::span<unsigned long const, 1ul>&>(std::__1::span<unsigned char, 8ul>&, std::__1::span<unsigned long const, 1ul>&) Line | Count | Source | 130 | 413k | { | 131 | 413k | const std::span s0{r0}; | 132 | | | 133 | 413k | if constexpr(statically_spanable_range<R0>) { | 134 | 413k | constexpr size_t expected_size = s0.size_bytes(); | 135 | 413k | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 413k | } else { | 137 | 413k | const size_t expected_size = s0.size_bytes(); | 138 | 413k | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 413k | "memory regions don't have equal lengths"); | 140 | 413k | } | 141 | 413k | } |
void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned int, 18446744073709551615ul>&, std::__1::span<unsigned char const, 18446744073709551615ul>&>(std::__1::span<unsigned int, 18446744073709551615ul>&, std::__1::span<unsigned char const, 18446744073709551615ul>&) Line | Count | Source | 130 | 156k | { | 131 | 156k | const std::span s0{r0}; | 132 | | | 133 | 156k | if constexpr(statically_spanable_range<R0>) { | 134 | 156k | constexpr size_t expected_size = s0.size_bytes(); | 135 | 156k | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 156k | } else { | 137 | 156k | const size_t expected_size = s0.size_bytes(); | 138 | 156k | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 156k | "memory regions don't have equal lengths"); | 140 | 156k | } | 141 | 156k | } |
void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::span<unsigned int const, 18446744073709551615ul>&>(std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::span<unsigned int const, 18446744073709551615ul>&) Line | Count | Source | 130 | 59.8k | { | 131 | 59.8k | const std::span s0{r0}; | 132 | | | 133 | 59.8k | if constexpr(statically_spanable_range<R0>) { | 134 | 59.8k | constexpr size_t expected_size = s0.size_bytes(); | 135 | 59.8k | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 59.8k | } else { | 137 | 59.8k | const size_t expected_size = s0.size_bytes(); | 138 | 59.8k | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 59.8k | "memory regions don't have equal lengths"); | 140 | 59.8k | } | 141 | 59.8k | } |
void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned int, 1ul>&, std::__1::span<unsigned char const, 4ul>&>(std::__1::span<unsigned int, 1ul>&, std::__1::span<unsigned char const, 4ul>&) Line | Count | Source | 130 | 5.22M | { | 131 | 5.22M | const std::span s0{r0}; | 132 | | | 133 | 5.22M | if constexpr(statically_spanable_range<R0>) { | 134 | 5.22M | constexpr size_t expected_size = s0.size_bytes(); | 135 | 5.22M | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 5.22M | } else { | 137 | 5.22M | const size_t expected_size = s0.size_bytes(); | 138 | 5.22M | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 5.22M | "memory regions don't have equal lengths"); | 140 | 5.22M | } | 141 | 5.22M | } |
void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 4ul>&, std::__1::span<unsigned int const, 1ul>&>(std::__1::span<unsigned char, 4ul>&, std::__1::span<unsigned int const, 1ul>&) Line | Count | Source | 130 | 381k | { | 131 | 381k | const std::span s0{r0}; | 132 | | | 133 | 381k | if constexpr(statically_spanable_range<R0>) { | 134 | 381k | constexpr size_t expected_size = s0.size_bytes(); | 135 | 381k | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 381k | } else { | 137 | 381k | const size_t expected_size = s0.size_bytes(); | 138 | 381k | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 381k | "memory regions don't have equal lengths"); | 140 | 381k | } | 141 | 381k | } |
Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 2ul>&, std::__1::span<unsigned short const, 1ul>&>(std::__1::span<unsigned char, 2ul>&, std::__1::span<unsigned short const, 1ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::span<unsigned char, 18446744073709551615ul>&>(std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::span<unsigned char, 18446744073709551615ul>&) void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned long, 1ul>&, std::__1::span<unsigned char, 8ul>&>(std::__1::span<unsigned long, 1ul>&, std::__1::span<unsigned char, 8ul>&) Line | Count | Source | 130 | 14.0k | { | 131 | 14.0k | const std::span s0{r0}; | 132 | | | 133 | 14.0k | if constexpr(statically_spanable_range<R0>) { | 134 | 14.0k | constexpr size_t expected_size = s0.size_bytes(); | 135 | 14.0k | (assert_exact_byte_length<expected_size>(rs), ...); | 136 | 14.0k | } else { | 137 | 14.0k | const size_t expected_size = s0.size_bytes(); | 138 | 14.0k | BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...), | 139 | 14.0k | "memory regions don't have equal lengths"); | 140 | 14.0k | } | 141 | 14.0k | } |
Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&>(std::__1::span<unsigned char, 18446744073709551615ul>&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned short, 1ul>&, std::__1::span<unsigned char const, 2ul>&>(std::__1::span<unsigned short, 1ul>&, std::__1::span<unsigned char const, 2ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned long, 4ul>&, std::__1::array<unsigned long, 4ul> const&>(std::__1::span<unsigned long, 4ul>&, std::__1::array<unsigned long, 4ul> const&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, unsigned long (&) [8]>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, unsigned long (&) [8]) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 32ul>&, std::__1::span<unsigned char const, 32ul>&>(std::__1::span<unsigned char, 32ul>&, std::__1::span<unsigned char const, 32ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned long, 1ul>&, std::__1::array<unsigned long, 1ul>&>(std::__1::span<unsigned long, 1ul>&, std::__1::array<unsigned long, 1ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::array<unsigned long, 4ul>&, std::__1::span<unsigned long, 4ul>&>(std::__1::array<unsigned long, 4ul>&, std::__1::span<unsigned long, 4ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned long, 6ul>&, std::__1::array<unsigned long, 6ul> const&>(std::__1::span<unsigned long, 6ul>&, std::__1::array<unsigned long, 6ul> const&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, unsigned long (&) [12]>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, unsigned long (&) [12]) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 48ul>&, std::__1::array<unsigned long, 6ul>&>(std::__1::span<unsigned char, 48ul>&, std::__1::array<unsigned long, 6ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 48ul>&, std::__1::span<unsigned char const, 48ul>&>(std::__1::span<unsigned char, 48ul>&, std::__1::span<unsigned char const, 48ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::array<unsigned long, 6ul>&, std::__1::span<unsigned long, 6ul>&>(std::__1::array<unsigned long, 6ul>&, std::__1::span<unsigned long, 6ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned long, 8ul>&, std::__1::array<unsigned long, 8ul> const&>(std::__1::span<unsigned long, 8ul>&, std::__1::array<unsigned long, 8ul> const&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, unsigned long (&) [16]>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, unsigned long (&) [16]) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 64ul>&, std::__1::array<unsigned long, 8ul>&>(std::__1::span<unsigned char, 64ul>&, std::__1::array<unsigned long, 8ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 64ul>&, std::__1::span<unsigned char const, 64ul>&>(std::__1::span<unsigned char, 64ul>&, std::__1::span<unsigned char const, 64ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::array<unsigned long, 8ul>&, std::__1::span<unsigned long, 8ul>&>(std::__1::array<unsigned long, 8ul>&, std::__1::span<unsigned long, 8ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 72ul>&, std::__1::span<unsigned char const, 72ul>&>(std::__1::span<unsigned char, 72ul>&, std::__1::span<unsigned char const, 72ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::array<unsigned long, 9ul>&, std::__1::span<unsigned long const, 9ul>&>(std::__1::array<unsigned long, 9ul>&, std::__1::span<unsigned long const, 9ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned long, 9ul>&, std::__1::array<unsigned long, 9ul> const&>(std::__1::span<unsigned long, 9ul>&, std::__1::array<unsigned long, 9ul> const&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, unsigned long (&) [18]>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, unsigned long (&) [18]) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::array<unsigned char, 72ul>&, std::__1::array<unsigned long, 9ul>&>(std::__1::array<unsigned char, 72ul>&, std::__1::array<unsigned long, 9ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 66ul>&, std::__1::span<unsigned char const, 66ul>&>(std::__1::span<unsigned char, 66ul>&, std::__1::span<unsigned char const, 66ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::span<unsigned char, 98ul>&, std::__1::span<unsigned char const, 98ul>&>(std::__1::span<unsigned char, 98ul>&, std::__1::span<unsigned char const, 98ul>&) Unexecuted instantiation: void Botan::ranges::assert_equal_byte_lengths<std::__1::array<unsigned long, 9ul>&, std::__1::span<unsigned long, 9ul>&>(std::__1::array<unsigned long, 9ul>&, std::__1::span<unsigned long, 9ul>&) |
142 | | |
143 | | } // namespace ranges |
144 | | |
145 | | namespace concepts { |
146 | | |
147 | | // TODO: C++20 provides concepts like std::ranges::range or ::sized_range |
148 | | // but at the time of this writing clang had not caught up on all |
149 | | // platforms. E.g. clang 14 on Xcode does not support ranges properly. |
150 | | |
151 | | template <typename IterT, typename ContainerT> |
152 | | concept container_iterator = |
153 | | std::same_as<IterT, typename ContainerT::iterator> || std::same_as<IterT, typename ContainerT::const_iterator>; |
154 | | |
155 | | template <typename PtrT, typename ContainerT> |
156 | | concept container_pointer = |
157 | | std::same_as<PtrT, typename ContainerT::pointer> || std::same_as<PtrT, typename ContainerT::const_pointer>; |
158 | | |
159 | | template <typename T> |
160 | | concept container = requires(T a) { |
161 | | { a.begin() } -> container_iterator<T>; |
162 | | { a.end() } -> container_iterator<T>; |
163 | | { a.cbegin() } -> container_iterator<T>; |
164 | | { a.cend() } -> container_iterator<T>; |
165 | | { a.size() } -> std::same_as<typename T::size_type>; |
166 | | typename T::value_type; |
167 | | }; |
168 | | |
169 | | template <typename T> |
170 | | concept contiguous_container = container<T> && requires(T a) { |
171 | | { a.data() } -> container_pointer<T>; |
172 | | }; |
173 | | |
174 | | template <typename T> |
175 | | concept has_empty = requires(T a) { |
176 | | { a.empty() } -> std::same_as<bool>; |
177 | | }; |
178 | | |
179 | | template <typename T> |
180 | | concept resizable_container = container<T> && requires(T& c, typename T::size_type s) { |
181 | | T(s); |
182 | | c.resize(s); |
183 | | }; |
184 | | |
185 | | template <typename T> |
186 | | concept reservable_container = container<T> && requires(T& c, typename T::size_type s) { c.reserve(s); }; |
187 | | |
188 | | template <typename T> |
189 | | concept resizable_byte_buffer = |
190 | | contiguous_container<T> && resizable_container<T> && std::same_as<typename T::value_type, uint8_t>; |
191 | | |
192 | | template <typename T> |
193 | | concept streamable = requires(std::ostream& os, T a) { os << a; }; |
194 | | |
195 | | template <class T> |
196 | | concept strong_type = is_strong_type_v<T>; |
197 | | |
198 | | template <class T> |
199 | | concept contiguous_strong_type = strong_type<T> && contiguous_container<T>; |
200 | | |
201 | | template <class T> |
202 | | concept integral_strong_type = strong_type<T> && std::integral<typename T::wrapped_type>; |
203 | | |
204 | | template <class T> |
205 | | concept unsigned_integral_strong_type = strong_type<T> && std::unsigned_integral<typename T::wrapped_type>; |
206 | | |
207 | | template <typename T, typename Capability> |
208 | | concept strong_type_with_capability = T::template has_capability<Capability>(); |
209 | | |
210 | | } // namespace concepts |
211 | | |
212 | | } // namespace Botan |
213 | | |
214 | | #endif |