22#if defined(ONIXS_CMEMDH_CXX20)
37#if defined(ONIXS_CMEMDH_CXX20)
48namespace ByteSpanDetails {
51constexpr Value* toAddress(Value* value)
noexcept
56template <
class Iterator>
57auto toAddress(
const Iterator& value)
noexcept(
noexcept(value.operator->()))
58 ->
decltype(value.operator->())
60 return value.operator->();
75 using element_type =
const std::uint8_t;
78 using value_type =
typename std::remove_cv<element_type>::type;
81 using size_type = std::size_t;
84 using difference_type = std::ptrdiff_t;
87 using pointer = element_type*;
90 using const_pointer =
const element_type*;
93 using reference = element_type&;
96 using const_reference =
const element_type&;
99 using iterator = pointer;
102 using reverse_iterator = std::reverse_iterator<iterator>;
107 extent =
static_cast<size_type
>(-1)
111 constexpr ByteSpan() noexcept
125 typename std::enable_if<
126 std::is_pointer<Data>::value && std::is_convertible<Data, pointer>::value,
130 constexpr ByteSpan(Data data, size_type size) noexcept
131 : data_(
static_cast<pointer
>(data))
146 typename std::enable_if<
147 std::is_pointer<First>::value && std::is_convertible<First, pointer>::value &&
148 std::is_pointer<End>::value && std::is_convertible<End, pointer>::value,
152 constexpr ByteSpan(First first, End last) noexcept
153 : data_(
static_cast<pointer
>(first))
154 , size_(first ==
nullptr
156 :
static_cast<size_type
>(
static_cast<pointer
>(last) -
static_cast<pointer
>(first)))
169 typename std::enable_if<
170 !std::is_pointer<Iterator>::value &&
172 decltype(ByteSpanDetails::toAddress(std::declval<const Iterator&>())),
178 ByteSpan(Iterator first, size_type size)
noexcept(
noexcept(ByteSpanDetails::toAddress(first)))
179 : data_(size == 0 ? nullptr : static_cast<pointer>(ByteSpanDetails::toAddress(first)))
195 typename std::enable_if<
196 !std::is_pointer<Iterator>::value &&
198 decltype(ByteSpanDetails::toAddress(std::declval<const Iterator&>())),
202 decltype(std::declval<End>() - std::declval<Iterator>()),
209 noexcept(
noexcept(ByteSpanDetails::toAddress(first)) &&
noexcept(last - first))
211 , size_(static_cast<size_type>(last - first))
215 data_ =
static_cast<pointer
>(ByteSpanDetails::toAddress(first));
223 template <
size_type Count>
224 constexpr ByteSpan(
const value_type (&array)[Count]) noexcept
234 template <
size_type Count>
235 ByteSpan(
const std::array<value_type, Count>& array) noexcept
236 : data_(array.data())
249 typename std::enable_if<
250 !std::is_same<typename std::decay<Range>::type,
ByteSpan>::value &&
252 decltype(std::declval<Range>().data()),
256 decltype(std::declval<Range>().size()),
264 noexcept(std::forward<Range>(range).data()) &&
265 noexcept(std::forward<Range>(range).size()))
266 : data_(static_cast<pointer>(std::forward<Range>(range).data()))
267 , size_(static_cast<size_type>(std::forward<Range>(range).size()))
273 constexpr iterator begin() const noexcept
280 constexpr iterator end() const noexcept
282 return pointerAt(size_);
287 reverse_iterator rbegin() const noexcept
289 return reverse_iterator(end());
294 reverse_iterator rend() const noexcept
296 return reverse_iterator(begin());
303 constexpr reference operator[](size_type index)
const noexcept
311 reference front() const noexcept
320 reference back() const noexcept
323 return data_[size_ - 1];
329 constexpr pointer data() const noexcept
336 constexpr size_type size() const noexcept
343 constexpr size_type size_bytes() const noexcept
345 return size_ *
sizeof(element_type);
350 constexpr bool empty() const noexcept
359 template <
size_type Count>
362 assert(Count <= size_);
370 ByteSpan first(size_type count)
const noexcept
372 assert(count <= size_);
380 template <
size_type Count>
383 assert(Count <= size_);
384 return ByteSpan(pointerAt(size_ - Count), Count);
391 ByteSpan last(size_type count)
const noexcept
393 assert(count <= size_);
394 return ByteSpan(pointerAt(size_ - count), count);
402 template <
size_type Offset,
size_type Count = extent>
405 assert(Offset <= size_);
406 const size_type count = Count == extent ? size_ - Offset : Count;
407 assert(count <= size_ - Offset);
408 return ByteSpan(pointerAt(Offset), count);
416 ByteSpan subspan(size_type offset, size_type count = extent)
const noexcept
418 assert(offset <= size_);
419 const size_type actualCount = count == extent ? size_ - offset : count;
420 assert(actualCount <= size_ - offset);
421 return ByteSpan(pointerAt(offset), actualCount);
425 constexpr pointer pointerAt(size_type offset)
const noexcept
427 return data_ ==
nullptr ? nullptr : data_ + offset;
471 toStr(str, spans, spansCount);
#define ONIXS_CME_MDH_TESTING_NAMESPACE_END
#define ONIXS_CME_MDH_TESTING_NAMESPACE_BEGIN
#define ONIXS_CMEMDH_EXPORTED
void toStr(std::string &str, const MessageHolder< MessageType, MaxMessageSize > &holder)
Appends the holder's capacity, prefix, and message to a string.
std::span< const std::uint8_t > ByteSpan
Provides a non-owning read-only view over contiguous byte storage.