@@ -208,7 +208,7 @@ ByteBuffer<Codec>::ByteBuffer(
208208// Initializes `num_elements_` and `offsets_` from the span.
209209// Called in a lazy manner when the buffer is accessed with GetElement or GetNumElements, avoiding unnecessary initialization.
210210template <class Codec >
211- void ByteBuffer<Codec>::InitializeFromSpan() const {
211+ inline void ByteBuffer<Codec>::InitializeFromSpan() const {
212212 if (elements_span_.size () < prefix_size_) {
213213 throw InvalidInputException (" Malformed buffer: prefix_size exceeds span size" );
214214 }
@@ -265,7 +265,7 @@ void ByteBuffer<Codec>::InitializeFromSpan() const {
265265}
266266
267267template <class Codec >
268- void ByteBuffer<Codec>::EnsureInitializedFromSpan() const {
268+ inline void ByteBuffer<Codec>::EnsureInitializedFromSpan() const {
269269 // If the span is already initialized, skip it.
270270 if (is_initialized_from_span_) {
271271 return ;
@@ -280,7 +280,7 @@ void ByteBuffer<Codec>::EnsureInitializedFromSpan() const {
280280// For read-only buffers, gets the number of elements in the buffer and sets num_elements_ if not already set.
281281// A lighter version to only get num_elements_ and avoid calling InitializeFromSpan that also builds offsets_.
282282template <class Codec >
283- size_t ByteBuffer<Codec>::GetNumElements() const {
283+ inline size_t ByteBuffer<Codec>::GetNumElements() const {
284284 if (num_elements_ != kUnsetSize ) {
285285 return num_elements_;
286286 }
@@ -291,7 +291,7 @@ size_t ByteBuffer<Codec>::GetNumElements() const {
291291}
292292
293293template <class Codec >
294- size_t ByteBuffer<Codec>::EstimateOffsetsReserveCountFromSample(tcb::span<const uint8_t > bytes) {
294+ inline size_t ByteBuffer<Codec>::EstimateOffsetsReserveCountFromSample(tcb::span<const uint8_t > bytes) {
295295 if (bytes.empty ())
296296 return 0 ;
297297
@@ -338,7 +338,7 @@ size_t ByteBuffer<Codec>::EstimateOffsetsReserveCountFromSample(tcb::span<const
338338// -----------------------------------------------------------------------------
339339
340340template <class Codec >
341- size_t ByteBuffer<Codec>::CalculateOffsetOfElement(size_t position) const {
341+ inline size_t ByteBuffer<Codec>::CalculateOffsetOfElement(size_t position) const {
342342 EnsureInitializedFromSpan ();
343343 if (position >= num_elements_) {
344344 throw InvalidInputException (" Element position out of range during CalculateOffsetOfElement" );
@@ -350,19 +350,23 @@ size_t ByteBuffer<Codec>::CalculateOffsetOfElement(size_t position) const {
350350}
351351
352352template <class Codec >
353- tcb::span<const uint8_t > ByteBuffer<Codec>::GetRawElement(size_t position) const {
353+ inline tcb::span<const uint8_t > ByteBuffer<Codec>::GetRawElement(size_t position) const {
354354 EnsureInitializedFromSpan ();
355- if (position >= num_elements_) {
356- throw InvalidInputException (" Element position out of range during GetRawElement" );
357- }
358- const size_t offset = CalculateOffsetOfElement (position);
359355
360356 // For fixed-size elements are stored contiguously.
361357 if constexpr (is_fixed_sized) {
358+ if (position >= num_elements_) {
359+ throw InvalidInputException (" Element position out of range during GetRawElement" );
360+ }
361+ const size_t offset = prefix_size_ + (position * element_size_);
362362 return elements_span_.subspan (offset, element_size_);
363363 }
364364
365365 // For variable-size elements, we need to read the size first [u32 size][element].
366+ if (position >= num_elements_) {
367+ throw InvalidInputException (" Element position out of range during GetRawElement" );
368+ }
369+ const size_t offset = offsets_[position];
366370 if (offset == kUnsetSize ) {
367371 throw InvalidInputException (" Element position has not been written yet" );
368372 }
@@ -371,7 +375,7 @@ tcb::span<const uint8_t> ByteBuffer<Codec>::GetRawElement(size_t position) const
371375}
372376
373377template <class Codec >
374- typename ByteBuffer<Codec>::value_type ByteBuffer<Codec>::GetElement(size_t position) const {
378+ inline typename ByteBuffer<Codec>::value_type ByteBuffer<Codec>::GetElement(size_t position) const {
375379 return codec_.Decode (GetRawElement (position));
376380}
377381
@@ -384,7 +388,7 @@ typename ByteBuffer<Codec>::value_type ByteBuffer<Codec>::GetElement(size_t posi
384388// -----------------------------------------------------------------------------
385389
386390template <class Codec >
387- ByteBuffer<Codec>::ConstIterator::ConstIterator(const ByteBuffer<Codec>* buffer, size_t cursor_offset)
391+ inline ByteBuffer<Codec>::ConstIterator::ConstIterator(const ByteBuffer<Codec>* buffer, size_t cursor_offset)
388392 : buffer_(buffer),
389393 cursor_offset_ (cursor_offset),
390394 elements_span_size_(buffer != nullptr ? buffer->elements_span_.size() : 0u),
@@ -416,7 +420,7 @@ inline size_t ByteBuffer<Codec>::ConstIterator::ReadAndValidateVariableElementSi
416420}
417421
418422template <class Codec >
419- tcb::span<const uint8_t > ByteBuffer<Codec>::ConstIterator::RawSpanAtCursor() const {
423+ inline tcb::span<const uint8_t > ByteBuffer<Codec>::ConstIterator::RawSpanAtCursor() const {
420424 if (buffer_ == nullptr || cursor_offset_ >= elements_span_size_) {
421425 throw InvalidInputException (" Cannot dereference ByteBuffer iterator at end position" );
422426 }
@@ -429,14 +433,14 @@ tcb::span<const uint8_t> ByteBuffer<Codec>::ConstIterator::RawSpanAtCursor() con
429433}
430434
431435template <class Codec >
432- typename ByteBuffer<Codec>::ConstIterator::value_type ByteBuffer<Codec>::ConstIterator::operator *() const {
436+ inline typename ByteBuffer<Codec>::ConstIterator::value_type ByteBuffer<Codec>::ConstIterator::operator *() const {
433437 // Decode converts raw bytes into the codec's value_type (e.g. int32_t, float, string_view).
434438 // This keeps the iterator's return type consistent with GetElement across all codecs.
435439 return buffer_->codec_ .Decode (RawSpanAtCursor ());
436440}
437441
438442template <class Codec >
439- typename ByteBuffer<Codec>::ConstIterator& ByteBuffer<Codec>::ConstIterator::operator ++() {
443+ inline typename ByteBuffer<Codec>::ConstIterator& ByteBuffer<Codec>::ConstIterator::operator ++() {
440444 if (buffer_ == nullptr || cursor_offset_ >= elements_span_size_) {
441445 return *this ;
442446 }
@@ -451,23 +455,23 @@ typename ByteBuffer<Codec>::ConstIterator& ByteBuffer<Codec>::ConstIterator::ope
451455}
452456
453457template <class Codec >
454- bool ByteBuffer<Codec>::ConstIterator::operator ==(const ConstIterator& other) const {
458+ inline bool ByteBuffer<Codec>::ConstIterator::operator ==(const ConstIterator& other) const {
455459 return buffer_ == other.buffer_ && cursor_offset_ == other.cursor_offset_ ;
456460}
457461
458462template <class Codec >
459- bool ByteBuffer<Codec>::ConstIterator::operator !=(const ConstIterator& other) const {
463+ inline bool ByteBuffer<Codec>::ConstIterator::operator !=(const ConstIterator& other) const {
460464 return !(*this == other);
461465}
462466
463467template <class Codec >
464- tcb::span<const uint8_t > ByteBuffer<Codec>::ConstRawIterator::operator *() const {
468+ inline tcb::span<const uint8_t > ByteBuffer<Codec>::ConstRawIterator::operator *() const {
465469 // Returns the raw bytes for the current element, consistent with GetRawElement.
466470 return this ->RawSpanAtCursor ();
467471}
468472
469473template <class Codec >
470- void ByteBuffer<Codec>::ValidateIteratorReadPreconditions() const {
474+ inline void ByteBuffer<Codec>::ValidateIteratorReadPreconditions() const {
471475 if (is_write_buffer_initialized_) {
472476 throw InvalidInputException (" Iterator is only available for read buffers" );
473477 }
@@ -486,19 +490,19 @@ void ByteBuffer<Codec>::ValidateIteratorReadPreconditions() const {
486490}
487491
488492template <class Codec >
489- typename ByteBuffer<Codec>::ConstIterator ByteBuffer<Codec>::begin() const {
493+ inline typename ByteBuffer<Codec>::ConstIterator ByteBuffer<Codec>::begin() const {
490494 ValidateIteratorReadPreconditions ();
491495 return ConstIterator (this , prefix_size_);
492496}
493497
494498template <class Codec >
495- typename ByteBuffer<Codec>::ConstIterator ByteBuffer<Codec>::end() const {
499+ inline typename ByteBuffer<Codec>::ConstIterator ByteBuffer<Codec>::end() const {
496500 ValidateIteratorReadPreconditions ();
497501 return ConstIterator (this , elements_span_.size ());
498502}
499503
500504template <class Codec >
501- typename ByteBuffer<Codec>::RawElementsView ByteBuffer<Codec>::raw_elements() const {
505+ inline typename ByteBuffer<Codec>::RawElementsView ByteBuffer<Codec>::raw_elements() const {
502506 ValidateIteratorReadPreconditions ();
503507 return RawElementsView{this };
504508}
@@ -540,7 +544,7 @@ ByteBuffer<Codec>::ByteBuffer(
540544
541545// Initializes `write_buffer_`, `offsets_` and `elements_span_`
542546template <class Codec >
543- void ByteBuffer<Codec>::InitializeForWriteBuffer(size_t variable_size_reserved_bytes_hint) {
547+ inline void ByteBuffer<Codec>::InitializeForWriteBuffer(size_t variable_size_reserved_bytes_hint) {
544548 // Fixed-size elements
545549 if constexpr (is_fixed_sized) {
546550 if (element_size_ <= 0 ) {
@@ -592,7 +596,7 @@ void ByteBuffer<Codec>::InitializeForWriteBuffer(size_t variable_size_reserved_b
592596
593597
594598template <class Codec >
595- tcb::span<uint8_t > ByteBuffer<Codec>::GetWritableSpanForElement(size_t position, size_t payload_size) {
599+ inline tcb::span<uint8_t > ByteBuffer<Codec>::GetWritableSpanForElement(size_t position, size_t payload_size) {
596600 if (!is_write_buffer_initialized_) {
597601 throw InvalidInputException (" Cannot GetWriteSpanForElement: write buffer is not initialized." );
598602 }
@@ -651,7 +655,7 @@ tcb::span<uint8_t> ByteBuffer<Codec>::GetWritableSpanForElement(size_t position,
651655}
652656
653657template <class Codec >
654- void ByteBuffer<Codec>::SetElement(size_t position, const value_type& element) {
658+ inline void ByteBuffer<Codec>::SetElement(size_t position, const value_type& element) {
655659 if constexpr (is_fixed_sized) {
656660 auto write_span = GetWritableSpanForElement (position, element_size_);
657661 codec_.Encode (element, write_span);
@@ -662,13 +666,13 @@ void ByteBuffer<Codec>::SetElement(size_t position, const value_type& element) {
662666}
663667
664668template <class Codec >
665- void ByteBuffer<Codec>::SetRawElement(size_t position, tcb::span<const uint8_t > raw) {
669+ inline void ByteBuffer<Codec>::SetRawElement(size_t position, tcb::span<const uint8_t > raw) {
666670 auto write_span = GetWritableSpanForElement (position, raw.size ());
667671 std::memcpy (write_span.data (), raw.data (), raw.size ());
668672}
669673
670674template <class Codec >
671- std::vector<uint8_t > ByteBuffer<Codec>::FinalizeAndTakeBuffer() {
675+ inline std::vector<uint8_t > ByteBuffer<Codec>::FinalizeAndTakeBuffer() {
672676 if (is_write_buffer_finalized_) {
673677 throw InvalidInputException (" FinalizeAndTakeBuffer: write buffer has already been finalized" );
674678 }
@@ -739,7 +743,7 @@ std::vector<uint8_t> ByteBuffer<Codec>::FinalizeAndTakeBuffer() {
739743}
740744
741745template <class Codec >
742- void ByteBuffer<Codec>::RebindSpanToWriteBuffer() {
746+ inline void ByteBuffer<Codec>::RebindSpanToWriteBuffer() {
743747 elements_span_ = tcb::span<const uint8_t >(write_buffer_.data (), write_buffer_.size ());
744748}
745749
0 commit comments