Coverage Report

Created: 2024-06-28 06:08

/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