51template <
typename T,
typename ValueT = std::ranges::range_value_t<T>>
52concept contiguous_range = std::ranges::contiguous_range<T> && std::same_as<ValueT, std::ranges::range_value_t<T>>;
60template <
typename T,
typename ValueT = std::ranges::range_value_t<T>>
68concept spanable_range = std::constructible_from<std::span<const std::ranges::range_value_t<T>>,
T>;
77 decltype(std::span{std::declval<T&>()})::extent != std::dynamic_extent;
85 return std::span{r}.size_bytes();
96template <
size_t expected, spanable_range R>
100 static_assert(s.size_bytes() == expected,
"memory region does not have expected byte lengths");
102 BOTAN_ASSERT(s.size_bytes() == expected,
"memory region does not have expected byte lengths");
115template <spanable_range R0, spanable_range... Rs>
117 requires(
sizeof...(Rs) > 0)
119 const std::span s0{r0};
122 constexpr size_t expected_size = s0.size_bytes();
123 (assert_exact_byte_length<expected_size>(rs), ...);
125 const size_t expected_size = s0.size_bytes();
126 BOTAN_ARG_CHECK(((std::span<
const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...),
127 "memory regions don't have equal lengths");