25 #include "common/file.h" 26 #include "common/memstream.h" 27 #include "common/safe-bool.h" 28 #include "common/scummsys.h" 29 #include "common/type_traits.h" 33 #define COMMON_SPAN_TYPEDEFS \ 34 typedef typename super_type::value_type value_type; \ 35 typedef typename super_type::difference_type difference_type; \ 36 typedef typename super_type::index_type index_type; \ 37 typedef typename super_type::size_type size_type; \ 38 typedef typename super_type::const_iterator const_iterator; \ 39 typedef typename super_type::iterator iterator; \ 40 typedef typename super_type::pointer pointer; \ 41 typedef typename super_type::const_pointer const_pointer; \ 42 typedef typename super_type::reference reference; \ 43 typedef typename super_type::const_reference const_reference 46 kSpanMaxSize = 0xFFFFFFFF,
47 kSpanKeepOffset = 0xFFFFFFFF
51 #pragma mark SpanValidationMode 53 enum SpanValidationMode {
59 namespace SpanInternal {
61 #pragma mark SpanIterator 65 template <
typename Span,
bool IsConst>
67 typedef typename Span::value_type span_value_type;
71 typedef typename Span::difference_type difference_type;
72 typedef typename remove_const<span_value_type>::type value_type;
78 inline SpanIterator(span_type *
const span,
const difference_type index) :
81 if (span !=
nullptr) {
82 span->validate(index, 0, kValidateSeek);
88 _index(other._index) {}
92 _index = other._index;
97 #pragma mark SpanIterator - Dereferencing operations 100 inline reference operator*()
const {
102 return (*_span)[_index];
105 inline pointer operator->()
const {
109 inline reference operator[](
const difference_type index)
const {
111 return *(*
this + index);
115 #pragma mark SpanIterator - Arithmetic operations 118 inline SpanIterator &operator+=(
const difference_type delta) {
119 assert(_span !=
nullptr);
120 _span->validate(_index, delta, kValidateSeek);
125 inline SpanIterator &operator-=(
const difference_type delta) {
126 return operator+=(-delta);
130 return operator+=(1);
140 return operator+=(-1);
149 inline SpanIterator operator+(
const difference_type delta)
const {
154 inline SpanIterator operator-(
const difference_type delta)
const {
155 return operator+(-delta);
158 inline difference_type operator-(
const SpanIterator &other)
const {
159 assert(_span == other._span);
160 return _index - other._index;
164 #pragma mark SpanIterator - Comparison operations 167 inline bool operator==(
const SpanIterator& other)
const {
168 return _span == other._span && _index == other._index;
171 inline bool operator!=(
const SpanIterator& other)
const {
172 return !operator==(other);
175 inline bool operator<(
const SpanIterator& other)
const {
176 assert(_span == other._span);
177 return _index < other._index;
180 inline bool operator<=(
const SpanIterator& other)
const {
181 return !other.operator<(*this);
184 inline bool operator>(
const SpanIterator& other)
const {
185 return other.operator<(*this);
188 inline bool operator>=(
const SpanIterator& other)
const {
189 return !operator<(other);
193 #pragma mark SpanIterator - Data access convenience functions 196 inline int8 getInt8()
const {
197 return _span->getInt8At(_index);
200 inline uint8 getUint8()
const {
201 return _span->getUint8At(_index);
204 inline int16 getInt16BE()
const {
205 return _span->getInt16BEAt(_index);
208 inline int16 getInt16LE()
const {
209 return _span->getInt16LEAt(_index);
212 inline uint16 getUint16BE()
const {
213 return _span->getUint16BEAt(_index);
216 inline uint16 getUint16LE()
const {
217 return _span->getUint16LEAt(_index);
220 inline uint32 getUint24LE()
const {
221 return _span->getUint24LEAt(_index);
224 inline uint32 getUint32()
const {
225 return _span->getUint32At(_index);
228 inline int32 getInt32BE()
const {
229 return _span->getInt32BEAt(_index);
232 inline int32 getInt32LE()
const {
233 return _span->getInt32LEAt(_index);
236 inline uint32 getUint32BE()
const {
237 return _span->getUint32BEAt(_index);
240 inline uint32 getUint32LE()
const {
241 return _span->getUint32LEAt(_index);
246 difference_type _index;
251 #pragma mark SpanBase 253 template <
typename ValueType,
template <
typename>
class Derived>
255 typedef Derived<ValueType> derived_type;
256 typedef typename add_const<derived_type>::type const_derived_type;
257 typedef typename remove_const<derived_type>::type mutable_derived_type;
260 template <
typename T,
template <
typename>
class U>
friend class SpanBase;
261 template <
typename T,
typename U>
friend struct SafeBool;
262 #ifdef CXXTEST_RUNNING 263 friend class ::SpanTestSuite;
267 typedef ValueType value_type;
268 typedef int32 difference_type;
269 typedef uint32 index_type;
270 typedef uint32 size_type;
273 typedef value_type *pointer;
274 typedef const value_type *const_pointer;
275 typedef value_type &reference;
276 typedef const value_type &const_reference;
278 inline size_type byteSize()
const {
return impl().size() *
sizeof(value_type); }
280 #if !defined(_MSC_VER) 288 inline const_derived_type &impl()
const {
return static_cast<const_derived_type &
>(*this); }
289 inline mutable_derived_type &impl() {
return static_cast<mutable_derived_type &
>(*this); }
292 #pragma mark SpanBase - Interface 294 #if !defined(_MSC_VER) 299 inline size_type size()
const;
301 inline const_iterator cbegin()
const;
302 inline const_iterator cend()
const;
303 inline const_iterator begin()
const;
304 inline const_iterator end()
const;
305 inline iterator begin();
306 inline iterator end();
308 inline pointer data()
const;
311 #pragma mark SpanBase - Data access functions 314 inline const_reference operator[](
const index_type index)
const {
315 impl().validate(index,
sizeof(value_type));
316 return impl().data()[index];
319 inline reference operator[](
const index_type index) {
320 impl().validate(index,
sizeof(value_type));
321 return impl().data()[index];
324 inline int8 getInt8At(
const index_type index)
const {
325 STATIC_ASSERT(
sizeof(value_type) ==
sizeof(uint8), int8_can_only_be_read_from_byte_or_char_spans);
326 return (int8)getUint8At(index);
329 inline uint8 getUint8At(
const index_type index)
const {
330 STATIC_ASSERT(
sizeof(value_type) ==
sizeof(uint8), uint8_can_only_be_read_from_byte_or_char_spans);
331 impl().validate(index,
sizeof(uint8));
332 return (uint8)impl().data()[index];
335 inline int16 getInt16BEAt(
const index_type index)
const {
336 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint16), int16_can_only_be_read_from_int16_or_smaller_spans);
337 return (int16)impl().getUint16BEAt(index);
340 inline int16 getInt16LEAt(
const index_type index)
const {
341 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint16), int16_can_only_be_read_from_int16_or_smaller_spans);
342 return (int16)impl().getUint16LEAt(index);
345 inline uint16 getUint16BEAt(
const index_type index)
const {
346 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint16), uint16_can_only_be_read_from_int16_or_smaller_spans);
347 impl().validate(index,
sizeof(uint16));
348 return READ_BE_UINT16(impl().data() + index);
351 inline uint16 getUint16LEAt(
const index_type index)
const {
352 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint16), uint16_can_only_be_read_from_int16_or_smaller_spans);
353 impl().validate(index,
sizeof(uint16));
354 return READ_LE_UINT16(impl().data() + index);
357 inline uint32 getUint24LEAt(
const index_type index)
const {
358 STATIC_ASSERT(
sizeof(value_type) <= 3, uint24_can_only_be_read_from_int24_or_smaller_spans);
359 impl().validate(index, 3);
360 return READ_LE_UINT24(impl().data() + index);
363 inline uint32 getUint32At(
const index_type index)
const {
364 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint32), uint32_can_only_be_read_from_int32_or_smaller_spans);
365 impl().validate(index,
sizeof(uint32));
366 return READ_UINT32(impl().data() + index);
369 inline int32 getInt32BEAt(
const index_type index)
const {
370 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint32), int32_can_only_be_read_from_int32_or_smaller_spans);
371 return (int32)impl().getUint32BEAt(index);
374 inline int32 getInt32LEAt(
const index_type index)
const {
375 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint32), int32_can_only_be_read_from_int32_or_smaller_spans);
376 return (int32)impl().getUint32LEAt(index);
379 inline uint32 getUint32BEAt(
const index_type index)
const {
380 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint32), uint32_can_only_be_read_from_int32_or_smaller_spans);
381 impl().validate(index,
sizeof(uint32));
382 return READ_BE_UINT32(impl().data() + index);
385 inline uint32 getUint32LEAt(
const index_type index)
const {
386 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint32), uint32_can_only_be_read_from_int32_or_smaller_spans);
387 impl().validate(index,
sizeof(uint32));
388 return READ_LE_UINT32(impl().data() + index);
391 inline String getStringAt(
const index_type index, size_type numEntries = kSpanMaxSize)
const {
392 STATIC_ASSERT(
sizeof(value_type) ==
sizeof(
char), strings_can_only_be_read_from_byte_or_char_spans);
393 const char *
string = (
const char *)impl().data() + index;
395 if (numEntries == kSpanMaxSize) {
396 numEntries =
strnlen(
string, impl().size() - index);
399 impl().validate(index, numEntries);
400 return String(
string, numEntries);
409 inline const_pointer
getUnsafeDataAt(
const index_type index, size_type numEntries = kSpanMaxSize)
const {
410 if (numEntries == kSpanMaxSize) {
411 numEntries = impl().size() - index;
414 impl().validate(index, numEntries *
sizeof(value_type));
415 return impl().data() + index;
418 inline pointer getUnsafeDataAt(
const index_type index, size_type numEntries = kSpanMaxSize) {
419 if (numEntries == kSpanMaxSize) {
420 numEntries = impl().size() - index;
423 impl().validate(index, numEntries *
sizeof(value_type));
424 return impl().data() + index;
427 inline MemoryReadStream toStream(
const index_type index = 0, size_type numEntries = kSpanMaxSize)
const {
428 if (numEntries == kSpanMaxSize) {
429 numEntries = impl().size() - index;
432 impl().validate(index, numEntries *
sizeof(value_type));
433 return MemoryReadStream(impl().data() + index, numEntries *
sizeof(value_type), DisposeAfterUse::NO);
437 #pragma mark SpanBase - Operators 440 template <
typename Other>
441 inline bool operator==(
const Other &other)
const {
442 return impl().data() == other.impl().data() && impl().size() == other.impl().size();
445 template <
typename Other>
446 inline bool operator!=(
const Other &other)
const {
447 return !operator==(other);
450 template <
typename Other>
451 inline difference_type operator-(
const Other &other)
const {
452 return impl().data() - other.impl().data();
455 template <
typename Other>
456 inline bool operator<(
const Other &other)
const {
457 return impl().data() < other.impl().data();
460 template <
typename Other>
461 inline bool operator<=(
const Other &other)
const {
462 return !other.operator<(*this);
465 template <
typename Other>
466 inline bool operator>(
const Other &other)
const {
467 return other.operator<(*this);
470 template <
typename Other>
471 inline bool operator>=(
const Other &other)
const {
472 return !operator<(other);
475 #if !defined(_MSC_VER) 478 inline bool operator_bool()
const {
return impl().data() !=
nullptr; }
481 #pragma mark SpanBase - Copying 489 memcpy(target, impl().data(), impl().byteSize());
496 template <
typename Other>
498 assert((impl().byteSize() %
sizeof(
typename Other::value_type)) == 0);
499 target.impl().validate(0, impl().byteSize(), kValidateWrite);
500 memcpy(target.impl().data(), impl().data(), impl().byteSize());
504 #pragma mark SpanBase - Validation 506 #if !defined(_MSC_VER) 517 const size_t maxByteOffset = index * (signed)
sizeof(value_type) + deltaInBytes;
518 return index > impl().size() || deltaInBytes > (difference_type)impl().byteSize() || maxByteOffset > impl().byteSize();
521 inline void validate(
const index_type index,
const difference_type deltaInBytes,
const SpanValidationMode mode = kValidateRead)
const {
523 if (impl().checkInvalidBounds(index, deltaInBytes)) {
524 error(
"%s", impl().getValidationMessage(index, deltaInBytes, mode).c_str());
531 #pragma mark SpanImpl 533 template <
typename ValueType,
template <
typename>
class Derived>
539 template <
typename T,
template <
typename>
class U>
friend class SpanImpl;
540 #ifdef CXXTEST_RUNNING 541 friend class ::SpanTestSuite;
545 COMMON_SPAN_TYPEDEFS;
547 inline SpanImpl() : super_type(), _data(
nullptr), _size(0) {}
549 inline SpanImpl(
const pointer data_,
const size_type size_) :
554 template <
typename Other>
555 inline SpanImpl(
const Other &other) :
558 _size(other.size()) {}
560 inline void clear() {
565 inline size_type size()
const {
return _size; }
566 inline pointer data()
const {
return _data; }
577 String getValidationMessage(
const index_type index,
const difference_type deltaInBytes,
const SpanValidationMode mode)
const {
578 const char *modeName =
"unknown";
581 modeName =
"reading";
584 modeName =
"writing";
587 modeName =
"seeking";
595 this->impl().name().c_str(),
597 deltaInBytes / (
int)
sizeof(value_type),
602 #pragma mark SpanImpl - Subspan 605 template <
typename NewValueType>
606 inline const Derived<NewValueType> subspan(
const index_type index, size_type numEntries = kSpanMaxSize)
const {
607 Derived<NewValueType> span;
608 populateSubspan(span, index, numEntries);
612 template <
typename NewValueType>
613 inline Derived<NewValueType> subspan(
const index_type index, size_type numEntries = kSpanMaxSize) {
614 Derived<NewValueType> span;
615 populateSubspan(span, index, numEntries);
619 inline const_derived_type subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize)
const {
620 return subspan<value_type>(index, numEntries);
623 inline mutable_derived_type subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize) {
624 return subspan<value_type>(index, numEntries);
627 #if !defined(_MSC_VER) 630 template <
typename NewValueType>
631 void populateSubspan(Derived<NewValueType> &span,
const index_type index, size_type numEntries)
const {
632 if (numEntries == kSpanMaxSize) {
633 numEntries = CLIP<size_type>(size() - index, 0, size());
636 assert(numEntries *
sizeof(value_type) %
sizeof(NewValueType) == 0);
637 this->validate(index, numEntries *
sizeof(value_type), kValidateSeek);
639 span._data = (NewValueType *)const_cast<mutable_value_type *>(_data + index);
640 span._size = numEntries *
sizeof(value_type) /
sizeof(NewValueType);
644 #pragma mark SpanImpl - Allocation 647 typedef typename remove_const<value_type>::type mutable_value_type;
648 typedef Derived<mutable_value_type> mutable_value_derived_type;
651 mutable_value_derived_type &allocate(
const size_type numEntries) {
652 assert(_data ==
nullptr);
653 assert(numEntries != kSpanMaxSize);
654 _data =
new mutable_value_type[numEntries];
656 return reinterpret_cast<mutable_value_derived_type &
>(
const_cast<Derived<value_type> &
>(this->impl()));
659 template <
typename Other>
660 mutable_value_derived_type &allocateFromSpan(
const Other &other) {
661 assert(_data ==
nullptr);
662 assert(
sizeof(value_type) ==
sizeof(
typename Other::value_type));
663 _data =
new mutable_value_type[other.size()];
664 _size = other.size();
665 copy(other.begin(), other.end(),
const_cast<mutable_value_type *
>(_data));
666 return reinterpret_cast<mutable_value_derived_type &
>(
const_cast<Derived<value_type> &
>(this->impl()));
669 mutable_value_derived_type &allocateFromStream(
SeekableReadStream &stream, size_type numEntries = kSpanMaxSize) {
670 if (numEntries == kSpanMaxSize) {
671 numEntries = (stream.
size() - stream.
pos()) /
sizeof(value_type);
674 const uint32 bytesRequested = numEntries *
sizeof(value_type);
675 assert(stream.
pos() + bytesRequested <= (uint)stream.
size());
676 allocate(numEntries);
677 const uint32 bytesRead = stream.
read((
void *)const_cast<mutable_value_type *>(_data), bytesRequested);
678 assert(bytesRead == bytesRequested);
680 return reinterpret_cast<mutable_value_derived_type &
>(
const_cast<Derived<value_type> &
>(this->impl()));
690 template <
typename ValueType>
695 template <
typename T>
friend class Span;
698 COMMON_SPAN_TYPEDEFS;
700 inline Span() : super_type() {}
702 inline Span(
const pointer data_,
const size_type size_) : super_type(data_, size_) {}
706 template <
typename Other>
707 inline Span(
const Other &other) : super_type(other) {}
711 #pragma mark NamedSpanImpl 713 template <
typename ValueType,
template <
typename>
class Derived>
719 template <
typename T,
template <
typename>
class U>
friend class NamedSpanImpl;
720 #ifdef CXXTEST_RUNNING 721 friend class ::SpanTestSuite;
725 COMMON_SPAN_TYPEDEFS;
730 const size_type size_,
732 const size_type sourceByteOffset_ = 0) :
733 super_type(data_, size_),
735 _sourceByteOffset(sourceByteOffset_) {}
737 template <
typename Other>
741 _sourceByteOffset(other.sourceByteOffset()) {}
743 inline void clear() {
746 _sourceByteOffset = 0;
749 const String &name()
const {
return _name; }
750 String &name() {
return _name; }
752 const size_type &sourceByteOffset()
const {
return _sourceByteOffset; }
753 size_type &sourceByteOffset() {
return _sourceByteOffset; }
757 size_type _sourceByteOffset = 0;
760 #pragma mark NamedSpanImpl - Subspan 763 template <
typename NewValueType>
764 inline const Derived<NewValueType> subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize,
const String &name_ =
String(),
const size_type sourceByteOffset_ = kSpanKeepOffset)
const {
765 Derived<NewValueType> span;
766 populateSubspan(span, index, numEntries, name_, sourceByteOffset_);
770 template <
typename NewValueType>
771 inline Derived<NewValueType> subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize,
const String &name_ =
String(),
const size_type sourceByteOffset_ = kSpanKeepOffset) {
772 Derived<NewValueType> span;
773 populateSubspan(span, index, numEntries, name_, sourceByteOffset_);
777 inline const_derived_type subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize,
const String &name_ =
String(),
const size_type sourceByteOffset_ = kSpanKeepOffset)
const {
778 return subspan<value_type>(index, numEntries, name_, sourceByteOffset_);
781 inline mutable_derived_type subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize,
const String &name_ =
String(),
const size_type sourceByteOffset_ = kSpanKeepOffset) {
782 return subspan<value_type>(index, numEntries, name_, sourceByteOffset_);
785 #if !defined(_MSC_VER) 788 template <
typename NewValueType>
789 void populateSubspan(Derived<NewValueType> &span,
const index_type index, size_type numEntries,
const String &name_,
const size_type sourceByteOffset_ = kSpanKeepOffset)
const {
790 super_type::template populateSubspan<NewValueType>(span, index, numEntries);
798 if (sourceByteOffset_ == kSpanKeepOffset) {
799 span._sourceByteOffset = _sourceByteOffset + index *
sizeof(value_type);
801 span._sourceByteOffset = sourceByteOffset_;
806 #pragma mark NamedSpanImpl - Validation 809 String getValidationMessage(
const index_type index,
const difference_type deltaInBytes,
const SpanValidationMode mode)
const {
810 const index_type indexInBytes = index *
sizeof(value_type);
811 const size_type maxSizeInBytes = this->impl().byteSize();
813 return super_type::getValidationMessage(index, deltaInBytes, mode) +
815 this->impl().sourceByteOffset() + indexInBytes,
817 this->impl().sourceByteOffset() + maxSizeInBytes);
821 #pragma mark NamedSpanImpl - Allocation 824 typedef typename remove_const<value_type>::type mutable_value_type;
825 typedef Derived<mutable_value_type> mutable_value_derived_type;
828 mutable_value_derived_type &allocate(
const size_type numEntries,
const String &name_ =
String()) {
829 super_type::allocate(numEntries);
831 _sourceByteOffset = 0;
832 return reinterpret_cast<mutable_value_derived_type &
>(
const_cast<Derived<value_type> &
>(this->impl()));
835 template <
typename OtherValueType>
837 super_type::allocateFromSpan(other);
838 _name = other.name();
839 _sourceByteOffset = other.sourceByteOffset();
840 return reinterpret_cast<mutable_value_derived_type &
>(
const_cast<Derived<value_type> &
>(this->impl()));
843 template <
typename OtherValueType,
template <
typename>
class OtherDerived>
845 super_type::allocateFromSpan(other);
846 return reinterpret_cast<mutable_value_derived_type &
>(
const_cast<Derived<value_type> &
>(this->impl()));
850 super_type::allocateFromStream(stream, numEntries);
852 _sourceByteOffset = 0;
853 return reinterpret_cast<mutable_value_derived_type &
>(
const_cast<Derived<value_type> &
>(this->impl()));
856 mutable_value_derived_type &allocateFromStream(
File &file,
const size_type numEntries = kSpanMaxSize) {
857 return allocateFromStream(file, numEntries, file.
getName());
862 #pragma mark NamedSpan 864 template <
typename ValueType>
868 template <
typename T>
friend class NamedSpan;
871 COMMON_SPAN_TYPEDEFS;
876 const size_type size_,
878 const size_type sourceByteOffset_ = 0) :
879 super_type(data_, size_, name_, sourceByteOffset_) {}
881 template <
typename Other>
882 inline NamedSpan(
const Other &other) : super_type(other) {}
886 #pragma mark SpanOwner 892 template <
typename OwnedSpan>
894 typedef typename OwnedSpan::value_type value_type;
895 typedef typename OwnedSpan::size_type size_type;
896 typedef typename OwnedSpan::index_type index_type;
897 typedef typename OwnedSpan::pointer pointer;
898 typedef typename OwnedSpan::reference reference;
899 typedef typename OwnedSpan::const_reference const_reference;
901 template <
typename T,
typename U>
friend struct SafeBool;
906 inline SpanOwner(
const OwnedSpan &span) : _span(span) {}
920 _span.allocateFromSpan(other._span);
924 if (
this == &other) {
928 delete[]
const_cast<typename remove_const<value_type>::type *
>(_span.data());
935 _span.allocateFromSpan(other._span);
942 delete[]
const_cast<typename remove_const<value_type>::type *
>(_span.data());
949 if (
this == &other) {
953 delete[]
const_cast<typename remove_const<value_type>::type *
>(_span.data());
963 pointer data = _span.data();
972 delete[]
const_cast<typename remove_const<value_type>::type *
>(_span.data());
976 #if !defined(_MSC_VER) 979 inline bool operator_bool()
const {
return _span; }
985 #pragma mark SpanOwner - Data access 988 inline const OwnedSpan &operator*()
const {
return _span; }
989 inline OwnedSpan &operator*() {
return _span; }
991 inline const OwnedSpan *operator->()
const {
return &_span; }
992 inline OwnedSpan *operator->() {
return &_span; }
994 inline const_reference operator[](
const index_type index)
const {
return _span[index]; }
995 inline reference operator[](
const index_type index) {
return _span[index]; }
bool checkInvalidBounds(const index_type index, const difference_type deltaInBytes) const
Definition: span.h:512
virtual int64 size() const =0
virtual int64 pos() const =0
void unsafeCopyDataTo(void *target) const
Definition: span.h:488
void clear()
Definition: span.h:971
static String format(MSVC_PRINTF const char *fmt,...) GCC_PRINTF(1
void copyDataTo(Other &target) const
Definition: span.h:497
pointer release()
Definition: span.h:962
Out copy(In first, In last, Out dst)
Definition: algorithm.h:52
const char * getName() const
Definition: file.h:126
Definition: type_traits.h:44
Definition: algorithm.h:29
Definition: type_traits.h:66
SpanOwner & moveFrom(SpanOwner &other)
Definition: span.h:948
Definition: memstream.h:43
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
SpanOwner(const SpanOwner &other)
Definition: span.h:911
Definition: safe-bool.h:56
size_t strnlen(const char *src, size_t maxSize)
const_pointer getUnsafeDataAt(const index_type index, size_type numEntries=kSpanMaxSize) const
Definition: span.h:409
virtual uint32 read(void *dataPtr, uint32 dataSize)=0