63template <
typename T,
typename ValueT = std::ranges::range_value_t<T>>
64concept contiguous_range = std::ranges::contiguous_range<T> && std::same_as<ValueT, std::ranges::range_value_t<T>>;
72template <
typename T,
typename ValueT = std::ranges::range_value_t<T>>
80concept spanable_range = std::constructible_from<std::span<const std::ranges::range_value_t<T>>,
T>;
89 decltype(std::span{std::declval<T&>()})::extent != std::dynamic_extent;
97 return std::span{r}.size_bytes();
108template <
size_t expected, spanable_range R>
110 const std::span s{r};
112 static_assert(s.size_bytes() == expected,
"memory region does not have expected byte lengths");
114 BOTAN_ASSERT(s.size_bytes() == expected,
"memory region does not have expected byte lengths");
127template <spanable_range R0, spanable_range... Rs>
129 requires(
sizeof...(Rs) > 0)
131 const std::span s0{r0};
134 constexpr size_t expected_size = s0.size_bytes();
137 const size_t expected_size = s0.size_bytes();
138 BOTAN_ARG_CHECK(((std::span<
const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...),
139 "memory regions don't have equal lengths");
151template <
typename IterT,
typename ContainerT>
153 std::same_as<IterT, typename ContainerT::iterator> || std::same_as<IterT, typename ContainerT::const_iterator>;
155template <
typename PtrT,
typename ContainerT>
157 std::same_as<PtrT, typename ContainerT::pointer> || std::same_as<PtrT, typename ContainerT::const_pointer>;
165 { a.size() } -> std::same_as<typename T::size_type>;
166 typename T::value_type;
176 { a.empty() } -> std::same_as<bool>;
207template <
typename T,
typename Capability>