simple_span.h#

namespace onnx_light

Alias that makes onnx-light headers compatible with code that references ONNX_LIGHT_NAMESPACE (the macro used in the standard onnx package).

Set to ONNX_LIGHT_NAMESPACE so both names resolve to the same namespace.

Symbol-visibility attribute for the public onnx-light C++ API.

Maps the upstream compatibility macro to onnx-light’s explicit proto ABI annotation. This keeps declarations from vendored ONNX headers visible when lib_onnx_proto uses hidden visibility by default.

Namespace alias so that ONNX C++ code (and consumers such as onnxruntime) that refers to the literal onnx namespace — rather than the ONNX_NAMESPACE macro — resolves to the onnx-light namespace. The standard onnx package lives in namespace onnx; onnx-light uses onnx_light (via ONNX_LIGHT_NAMESPACE), so this alias keeps onnx-light a true drop-in. It is only introduced when the onnx-light namespace differs from onnx.

namespace utils
class ByteSpan : public onnx_light::utils::Span#
#include <simple_span.h>

A byte buffer that can either own its data or borrow a non-owning view into an external buffer. Inherits the non-owning-view interface from Span and overrides all read accessors so they always return correct data in both modes.

The borrowed mode is used for zero-copy parsing: when ParseOptions::no_copy is true and the stream supports it, tensor raw data is not copied — instead assign_borrowed() sets the base-class ptr_/size_ to point directly into the source bytes buffer. The caller MUST keep that buffer alive for as long as the ByteSpan is in borrowed mode.

The aligned-owned mode is used when ParseOptions::alignment > 0: the buffer is over-allocated by (alignment - 1) bytes and ptr_/size_ are set to the aligned region within owned_. In this mode mutable data() returns the aligned pointer and size() returns the logical (not allocated) size.

An explicit borrowed_ flag is used to unambiguously track the storage mode, including degenerate edge cases such as a zero-length borrowed span.

In plain owned mode the class behaves like a growable byte buffer; all read accessors delegate to owned_.data() / owned_.size() so there is no risk of stale cached pointers when owned_ reallocates.

Public Functions

ByteSpan() = default#

Constructs an empty buffer (owned mode, no allocation).

inline ByteSpan(const std::vector<uint8_t> &v)#

Constructs an owned buffer by copying from a std::vector<uint8_t>.

inline ByteSpan(const ByteSpan &other)#

Copy constructor: handles aligned-owned mode by recomputing the internal pointer.

inline ByteSpan &operator=(const ByteSpan &other)#

Copy assignment: handles aligned-owned mode by recomputing the internal pointer.

inline ByteSpan(ByteSpan &&other) noexcept#

Move constructor: for aligned-owned mode the pointer remains valid after the move.

inline ByteSpan &operator=(ByteSpan &&other) noexcept#

Move assignment: for aligned-owned mode the pointer remains valid after the move.

inline ByteSpan &operator=(const std::vector<uint8_t> &v)#

Assigns owned data by copying from a std::vector<uint8_t>; clears all special modes.

inline bool is_borrowed() const#

Returns true when the data is borrowed (non-owning).

inline const std::shared_ptr<void> &owner() const#

Returns the token retaining borrowed storage, or an empty token when caller-owned.

inline operator std::string() const#

Implicit conversion to a standard string so the type is a drop-in for protobuf bytes fields (which are std::string) in consuming code.

inline bool is_aligned_owned() const#

Returns true when the data is in aligned-owned mode.

inline size_t size() const#

Returns the number of bytes in either storage mode.

inline bool empty() const#

Returns true when no data is stored (zero bytes in either mode).

inline const uint8_t *data() const#

Returns a const pointer to the byte data in either storage mode.

inline const uint8_t &operator[](size_t i) const#

Returns a const reference to the byte at index i (no bounds check).

inline const char *c_str() const#

Returns a const char pointer to the data (std::string compatibility).

inline bool operator==(const ByteSpan &other) const#

Returns true when both ByteSpans have the same size and byte content.

inline bool operator!=(const ByteSpan &other) const#

Returns true when the ByteSpans differ in size or content.

inline bool operator==(const std::string &other) const#

Compare with std::string (byte-level comparison).

inline bool operator!=(const std::string &other) const#
inline uint8_t *data()#

Returns a mutable pointer to the owned data. Calling this in borrowed mode raises an error at runtime.

inline char *data_as_char()#

Returns a mutable char pointer to the data (std::string compatibility).

inline uint8_t &operator[](size_t i)#

Returns a mutable reference to the byte at index i; valid only in owned mode. No bounds check is performed; behaviour is undefined for i >= size().

inline void resize(size_t n)#

Resizes the owned buffer to n bytes and switches to plain owned mode.

inline void set_empty()#

Represents an explicitly present empty byte sequence.

inline void assign(const char *data, size_t len)#
inline void assign(const void *data, size_t len)#
inline void resize_aligned(size_t n, size_t align)#

Resizes the owned buffer ensuring data() is aligned to align bytes. Over-allocates by (align - 1) bytes so std::align can find a suitable start. If align <= 1 or n == 0, falls back to plain resize(n). The caller may read/write the data via data() as usual; size() returns n.

inline void assign_borrowed(const uint8_t *ptr, size_t sz, std::shared_ptr<void> owner = {})#

Sets borrowed mode: stores ptr/size in the base-class Span fields without any copy. The pointed-to buffer MUST outlive this ByteSpan.

template<typename Deleter>
inline void assign_with_deleter(const uint8_t *ptr, size_t sz, Deleter &&deleter)#

Sets borrowed mode with a custom deleter. Stores ptr/size without any copy and arranges for deleter() to be called when all copies of this ByteSpan are destroyed (or the span is overwritten/cleared). The deleter receives no arguments and returns void.

More flexible than assign_borrowed(ptr, sz, owner) because any callable — lambda, function pointer, or functor — can be supplied directly instead of wrapping it in a shared_ptr first.

template<typename Deleter>
inline void attach_deleter(Deleter &&deleter)#

Attaches a custom deleter to the data without changing the stored bytes or the storage mode (owned, aligned-owned or borrowed). deleter() is called exactly once when the last copy of this ByteSpan that shares the owner token is destroyed (or the span is overwritten/cleared). The deleter receives no arguments and returns void.

Unlike assign_with_deleter, this method keeps the current pointer/size in place, so it can register cleanup for data that has already been parsed (for example a tensor’s raw_data relocated by a parse callback). Any previously stored owner token is replaced.

inline void clear()#

Clears all data and resets to the empty owned state.

inline void push_back(uint8_t v)#

Appends a single byte; switches to owned mode (copying any borrowed/aligned data first).

inline const std::string &value() const#

BREAKING CHANGE: value() is no longer supported and always raises.

It used to return a const std::string& by lazily materializing an internal cache. That is fundamentally incompatible with the ByteSpan storage model: a ByteSpan may hold data in borrowed (zero-copy) or aligned-owned mode, where the bytes are NOT stored as a std::string. Returning them as a std::string therefore required a hidden full copy on every call (defeating the zero-copy and alignment guarantees), and the returned reference could dangle as soon as the underlying buffer was mutated or reassigned.

Access the bytes through the ByteSpan API instead: data()/size(), operator[], the explicit operator std::string() conversion (when a real copy is wanted), or the field’s ref_<name>() accessor.

inline std::string *mutable_value()#

BREAKING CHANGE: mutable_value() is no longer supported and always raises.

It used to return a std::string* into an internal cache that had to be written back with sync_from_cache() after mutation — an error-prone step that was easy to forget — and it could not preserve the buffer’s alignment or its borrowed semantics. Because a ByteSpan does not own its bytes as a std::string in borrowed/aligned-owned mode, there is no std::string to hand out safely.

Mutate the bytes through the ByteSpan API instead: data()/data_as_char() and operator[] for in-place edits, or assign()/resize()/resize_aligned() to replace the contents.

Private Members

OwnedByteBuffer owned_#
bool borrowed_ = false#
bool aligned_owned_ = false#
size_t align_ = 0#

Stored alignment for aligned-owned mode; used to re-align on copy.

std::shared_ptr<void> owner_#

Keeps borrowed backing storage alive when the model owns the shared buffer.

Friends

inline friend bool operator==(const std::string &lhs, const ByteSpan &rhs)#

Allow std::string == ByteSpan.

inline friend bool operator!=(const std::string &lhs, const ByteSpan &rhs)#
class OwnedByteBuffer#
#include <simple_span.h>

Owns a contiguous byte buffer without value-initializing newly allocated bytes. It preserves the existing prefix on resize and grows geometrically for append-heavy use.

Public Functions

OwnedByteBuffer() = default#

Initializes an empty buffer.

inline OwnedByteBuffer(const OwnedByteBuffer &other)#

Creates a deep copy of the stored bytes.

inline OwnedByteBuffer &operator=(const OwnedByteBuffer &other)#

Replaces the buffer with a deep copy of the stored bytes.

inline OwnedByteBuffer(OwnedByteBuffer &&other) noexcept#

Transfers ownership of the stored bytes and empties the source buffer.

inline OwnedByteBuffer &operator=(OwnedByteBuffer &&other) noexcept#

Transfers ownership of the stored bytes and empties the source buffer.

inline OwnedByteBuffer(const std::vector<uint8_t> &v)#

Creates a buffer by copying bytes from a vector.

inline OwnedByteBuffer &operator=(const std::vector<uint8_t> &v)#

Replaces the buffer content by copying bytes from a vector.

inline size_t size() const#

Returns the number of stored bytes.

inline uint8_t *data()#

Returns a mutable pointer to the stored bytes.

inline const uint8_t *data() const#

Returns a const pointer to the stored bytes.

inline void clear()#

Clears the logical content while preserving capacity.

inline void reset()#

Releases all storage.

inline void resize(size_t n)#

Resizes the buffer without value-initializing newly exposed bytes.

inline void assign(const uint8_t *src, size_t n)#

Replaces the content by copying raw bytes.

inline void assign(const uint8_t *begin, const uint8_t *end)#

Replaces the content by copying a byte range.

inline void push_back(uint8_t v)#

Appends one byte, growing geometrically when needed.

Private Functions

inline void reserve(size_t n)#

Ensures the buffer can store at least n bytes.

Private Members

std::unique_ptr<uint8_t[]> storage_#
size_t size_ = 0#
size_t capacity_ = 0#
class Span#
#include <simple_span.h>

Non-owning, read-only view of a contiguous byte sequence. It references existing memory and never allocates or frees storage. Analogous to RefString but for raw bytes.

Subclassed by onnx_light::utils::ByteSpan

Public Functions

inline Span() = default#

Initializes an empty span.

inline Span(const uint8_t *ptr, size_t size)#

Initializes a span from a pointer and a size.

inline size_t size() const#

Returns the number of bytes in the span.

inline const uint8_t *data() const#

Returns a const pointer to the byte data.

inline bool empty() const#

Returns true when the span covers zero bytes.

inline const uint8_t &operator[](size_t i) const#

Returns a const reference to the byte at index i (no bounds check).

inline bool operator==(const Span &other) const#

Returns true when both spans have the same size and byte content.

inline bool operator!=(const Span &other) const#

Returns true when the spans differ in size or content.

Protected Attributes

const uint8_t *ptr_ = nullptr#
size_t size_ = 0#