Botan 3.11.0
Crypto and TLS for C&
range_concepts.h
Go to the documentation of this file.
1/**
2 * (C) 2023 Jack Lloyd
3 * 2023 René Meusel - Rohde & Schwarz Cybersecurity
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8#ifndef BOTAN_RANGE_CONCEPTS_H_
9#define BOTAN_RANGE_CONCEPTS_H_
10
11#include <botan/types.h>
12#include <concepts>
13#include <ranges>
14#include <span>
15#include <utility>
16
17BOTAN_FUTURE_INTERNAL_HEADER(range_concepts.h)
18
19namespace Botan::ranges {
20
21/**
22 * Models a std::ranges::contiguous_range that (optionally) restricts its
23 * value_type to ValueT. In other words: a stretch of contiguous memory of
24 * a certain type (optional ValueT).
25 */
26template <typename T, typename ValueT = std::ranges::range_value_t<T>>
27concept contiguous_range = std::ranges::contiguous_range<T> && std::same_as<ValueT, std::ranges::range_value_t<T>>;
28
29/**
30 * Models a std::ranges::contiguous_range that satisfies
31 * std::ranges::output_range with an arbitrary value_type. In other words: a
32 * stretch of contiguous memory of a certain type (optional ValueT) that can be
33 * written to.
34 */
35template <typename T, typename ValueT = std::ranges::range_value_t<T>>
36concept contiguous_output_range = contiguous_range<T, ValueT> && std::ranges::output_range<T, ValueT>;
37
38/**
39 * Models a range that can be turned into a std::span<>. Typically, this is some
40 * form of ranges::contiguous_range.
41 */
42template <typename T>
43concept spanable_range = std::constructible_from<std::span<const std::ranges::range_value_t<T>>, T>;
44
45/**
46 * Models a range that can be turned into a std::span<> with a static extent.
47 * Typically, this is a std::array or a std::span derived from an array.
48 */
49// clang-format off
50template <typename T>
52 decltype(std::span{std::declval<T&>()})::extent != std::dynamic_extent;
53
54// clang-format on
55
56/**
57 * Find the length in bytes of a given contiguous range @p r.
58 */
59inline constexpr size_t size_bytes(const spanable_range auto& r) {
60 return std::span{r}.size_bytes();
61}
62
63/**
64* Throws an exception indicating that the attempted read or write was invalid
65*/
66[[noreturn]] void BOTAN_UNSTABLE_API memory_region_size_violation();
67
68/**
69 * Check that a given range @p r has a certain statically-known byte length. If
70 * the range's extent is known at compile time, this is a static check,
71 * otherwise a runtime argument check will be added.
72 *
73 * @throws Invalid_Argument if range @p r has a dynamic extent and does not
74 * feature the expected byte length.
75 */
76template <size_t expected, spanable_range R>
77inline constexpr void assert_exact_byte_length(const R& r) {
78 const std::span s{r};
79 if constexpr(statically_spanable_range<R>) {
80 static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
81 } else {
82 if(s.size_bytes() != expected) {
84 }
85 }
86}
87
88/**
89 * Check that a list of ranges (in @p r0 and @p rs) all have the same byte
90 * lengths. If the first range's extent is known at compile time, this will be a
91 * static check for all other ranges whose extents are known at compile time,
92 * otherwise a runtime argument check will be added.
93 *
94 * @throws Invalid_Argument if any range has a dynamic extent and not all
95 * ranges feature the same byte length.
96 */
97template <spanable_range R0, spanable_range... Rs>
98inline constexpr void assert_equal_byte_lengths(const R0& r0, const Rs&... rs)
99 requires(sizeof...(Rs) > 0)
100{
101 const std::span s0{r0};
102
103 if constexpr(statically_spanable_range<R0>) {
104 constexpr size_t expected_size = s0.size_bytes();
106 } else {
107 const size_t expected_size = s0.size_bytes();
108 const bool correct_size =
109 ((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...);
110
111 if(!correct_size) {
113 }
114 }
115}
116
117} // namespace Botan::ranges
118
119#endif
#define BOTAN_FUTURE_INTERNAL_HEADER(hdr)
Definition api.h:98
#define BOTAN_UNSTABLE_API
Definition api.h:34
constexpr size_t size_bytes(const spanable_range auto &r)
void BOTAN_UNSTABLE_API memory_region_size_violation()
Definition assert.cpp:32
constexpr void assert_equal_byte_lengths(const R0 &r0, const Rs &... rs)
constexpr void assert_exact_byte_length(const R &r)