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>>;
35template <
typename T,
typename ValueT = std::ranges::range_value_t<T>>
43concept spanable_range = std::constructible_from<std::span<const std::ranges::range_value_t<T>>, T>;
52 decltype(std::span{std::declval<T&>()})::extent != std::dynamic_extent;
60 return std::span{r}.size_bytes();
76template <
size_t expected, spanable_range R>
80 static_assert(s.size_bytes() == expected,
"memory region does not have expected byte lengths");
82 if(s.size_bytes() != expected) {
97template <spanable_range R0, spanable_range... Rs>
99 requires(
sizeof...(Rs) > 0)
101 const std::span s0{r0};
104 constexpr size_t expected_size = s0.size_bytes();
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) && ...);