diff --git a/src/libraries/util/util/counted.h b/src/libraries/util/util/counted.h index ff1c3a0..ed59225 100644 --- a/src/libraries/util/util/counted.h +++ b/src/libraries/util/util/counted.h @@ -36,17 +36,61 @@ struct counted /// Return an iterator to the end of the array inline const_iterator end() const { return offset_pointer(pointer, sizeof(T)*count); } + /// Return a counted advanced by N items + inline counted operator+(size_t i) { + counted other = *this; + other += i; + return other; + } + + /// Return a const counted advanced by N items + inline const counted operator+(size_t i) const { + counted other = *this; + other += i; + return other; + } + /// Advance the pointer by N items - inline counted & operator+=(unsigned i) { + inline counted & operator+=(size_t i) { if (i > count) i = count; pointer += i; count -= i; return *this; } +}; - /// Get a constant buffer from a const pointer - static const counted from_const(const T *p, size_t count) { - return { const_cast(p), count }; +/// Specialize for `const void` which cannot be indexed or iterated +template <> +struct counted +{ + const void *pointer; + size_t count; + + template + static inline counted from(T *p, size_t c) { + return {reinterpret_cast(p), c}; + } + + /// Return a counted advanced by N items + inline counted operator+(size_t i) { + counted other = *this; + other += i; + return other; + } + + /// Return a const counted advanced by N items + inline const counted operator+(size_t i) const { + counted other = *this; + other += i; + return other; + } + + /// Advance the pointer by N bytes + inline counted & operator+=(unsigned i) { + if (i > count) i = count; + pointer = offset_pointer(pointer, i); + count -= i; + return *this; } }; @@ -57,6 +101,27 @@ struct counted void *pointer; size_t count; + template + static inline counted from(T *p, size_t c) { + return {reinterpret_cast(p), c}; + } + + operator counted() const { return {pointer, count}; } + + /// Return a counted advanced by N items + inline counted operator+(size_t i) { + counted other = *this; + other += i; + return other; + } + + /// Return a const counted advanced by N items + inline const counted operator+(size_t i) const { + counted other = *this; + other += i; + return other; + } + /// Advance the pointer by N bytes inline counted & operator+=(unsigned i) { if (i > count) i = count; @@ -64,23 +129,22 @@ struct counted count -= i; return *this; } - - /// Get a constant buffer from a const pointer - static const counted from_const(const void *p, size_t count) { - return { const_cast(p), count }; - } }; using buffer = counted; +using const_buffer = counted; template -const T * read(buffer &b) { - if (b.count < sizeof(T)) - return nullptr; +T * read(buffer &b) { + T *p = reinterpret_cast(b.pointer); + b += sizeof(T); + return p; +} +template +const T * read(const_buffer &b) { const T *p = reinterpret_cast(b.pointer); - b.pointer = offset_pointer(b.pointer, sizeof(T)); - b.count -= sizeof(T); + b += sizeof(T); return p; }