c_span

c_span is a type that is generated by defining the macro ZTD_IDK_C_SPAN_TYPE to a specific type name and including the header #include <ztd/idk/c_span.g.h>. Occasionally, some types include spaces or similar, and therefore need some additional tweaking in order to handle it all properly. This comes up to forming 3 different macros which can help control configuration:

  • ZTD_IDK_C_SPAN_TYPE, the type;

  • ZTD_IDK_C_SPAN_TYPE_IS_CONST, an optional definition that, if defined, must be either 1 or 0. If 1, it indicates that the stored pointer should be to a const T type;

  • ZTD_IDK_C_SPAN_TYPE_NAME, an optional name of the type if it should not be derived directly from the type itself (defaults to ZTD_ID_C_SPAN_TYPE);

  • ZTD_IDK_C_SPAN_SIZE_TYPE, an optional type name used to control the type for the storage of the size (defaults to size_t).

  • ZTD_IDK_C_SPAN_SIZE_TYPE_NAME, an optional suffix for the c_spanβ€˜s name to override the default which is generated from the type (defaults to ZTD_ID_C_SPAN_SIZE_TYPE); and,

  • ZTD_IDK_C_SPAN_NAME, an optional override for the entire name of the structure and its functions (ignores all previous name-based derivations).

  • ZTD_IDK_C_SPAN_SIZE_FIRST, an optional definition that, if defined, must be either 1 or 0. If 1, it indicates that the size member should go first.

The final name is composed of either just the type name suffixed on c_span; the type name and the size type name (if defined) suffixed onto c_span; or, the the full name provided in the override.

Important

Any macros that are consumed by this header are undefined by the end of the header, including the ones listed above.

The <ztd/idk/c_span.h> header includes some common definitions of a c_span to be used, most notably c_span_uchar. The documentation below is for c_span_uchar, but works for all entities.

Note

ztd_generic_type is a name used as a placeholder. When it appears as a name (or within a name) or a type, it can be substituted out for another type name!

Structure + Functions

void copy_c_span(c_span *__destination, c_span __source)

Copies on c_span into the memory of another.

Remark

Preconditions:

  • __destination != NULL

Parameters
  • __destination – [in] Pointer to the destination.

  • __source – [in] The source span to copy.

c_span make_c_span(ztd_generic_type *__first, ztd_generic_type *__last)

Create a c_span from two pointers which denote a region of memory.

Remark

Preconditions:

  • __first < __last (__first is reachable from __last).

  • __first and __last are part of the same storage and form a valid range.

Parameters
  • __first – [in] The start of the region of memory, inclusive.

  • __last – [in] The end of the region of memory, non-inclusive.

c_span make_sized_c_span(ztd_generic_type *__first, size_t __size)

Create a c_span from two pointers which denote a region of memory.

Remark

Preconditions:

  • __first and __first + __size are part of the same storage and form a valid range.

Parameters
  • __first – [in] The start of the region of memory, inclusive.

  • __size – [in] The number of elements of the region of memory.

ztd_generic_type *c_span_data(c_span __span)

Retrieves a pointer to the start of this span of memory.

Parameters

__span – [in] The β€œself” object.

size_t c_span_size(c_span __span)

Retrieves the size of this span of memory, in number of elements.

Parameters

__span – [in] The β€œself” object.

bool c_span_empty(c_span __span)

Returns whether or not this span is empty.

Parameters

__span – [in] The β€œself” object.

ztd_generic_type c_span_front(c_span __span)

Retrieves the first element of this span of elements.

Remark

Preconditions:

  • __span.size > 0.

Parameters

__span – [in] The β€œself” object.

ztd_generic_type c_span_back(c_span __span)

Retrieves the last element of this span of elements.

Remark

Preconditions:

  • __span.size > 0.

ztd_generic_type c_span_at(c_span __span, size_t __index)

Retrieves the the element at the provided index.

Remark

Preconditions:

  • __span.size > __index.

Parameters
  • __span – [in] The β€œself” object.

  • __index – [in] The offset into the span of elements to access.

void c_span_set(c_span __span, size_t __index, ztd_generic_type __value)

Retrieves the the element at the provided index.

Remark

Preconditions:

  • __span.size > __index.

Parameters
  • __span – [in] The β€œself” object.

  • __index – [in] The offset into the span of elements to access.

  • __value – [in] The value to insert.

ztd_generic_type *c_span_ptr_at(c_span __span, size_t __index)

Retrieves the the element at the provided index.

Remark

Preconditions:

  • __span.size > __index.

Parameters
  • __span – [in] The β€œself” object.

  • __index – [in] The offset into the span of elements to access.

ztd_generic_type *c_span_maybe_ptr_at(c_span __span, size_t __index)

Retrieves the the element at the provided index.

Remark

This function checks size so there are no preconditions.

Parameters
  • __span – [in] The β€œself” object.

  • __index – [in] The offset into the span of elements to access.

size_t c_span_byte_size(c_span __span)

Retrieves the size of this span of memory, in number of unsigned chars.

Parameters

__span – [in] The β€œself” object.

c_span c_span_begin(c_span __span)

An iterator to the beginning of the span of elements.

Parameters

__span – [in] The β€œself” object.

ztd_generic_type *c_span_end(c_span __span)

An iterator to the end of the span of elements.

Parameters

__span – [in] The β€œself” object.

c_span c_span_subspan(c_span __span, size_t __offset_index, size_t __size)

Creates a smaller span from this span, using the given offset into the span and the desired size.

Remark

Preconditions:

  • __span.size >= (__offset_index + __size).

Parameters
  • __span – [in] The β€œself” object.

  • __offset_index – [in] The offset into the span.

  • __size – [in] The size of the resulting span.

c_span c_span_subspan_at(c_span __span, size_t __offset_index)

Creates a smaller span from this span, from the given offset. The resulting size is the offset minus the __span’s current size.

Remark

Preconditions:

  • __span.size >= __offset_index.

Parameters
  • __span – [in] The β€œself” object.

  • __offset_index – [in] The offset into the span.

c_span c_span_subspan_prefix(c_span __span, size_t __size)

Creates a smaller span from this span, from the given size. The resulting offset is from 0 and has the given size.

Remark

Preconditions:

  • __span.size >= __size.

Parameters
  • __span – [in] The β€œself” object.

  • __size – [in] The size of the span, from the beginning.

c_span c_span_subspan_suffix(c_span __span, size_t __size)

Creates a smaller span from this span, from the given size.

Remark

The resulting offset is from the current span’s size minus the desired size, and has the given __size.

Preconditions:

  • __span.size >= __size.

Parameters
  • __span – [in] The β€œself” object.

  • __size – [in] The size of the span, from the beginning.

struct c_span
#include <c_span.h>

A structured pointer which keeps its size type, which represents a non-owning view into a buffer.

This type can be initialized with designated initializers.

Remark

This type is meant to be β€œimmutable”, which is why the members are marked const. This can present some issues when dealing with, for example, trying to fill out members manually in structures that are heap-allocated. Instead, copy it using memcpy, like memcpy(my_span_ptr, &some_span, sizeof(some_span)); rather than my_span_ptr->data = some_ptr; my_span_ptr->size = some_size;.

Defines

ZTD_IDK_C_SPAN_TYPE

The type used to create a new c_span type.

Remark

This definition is required. If a type is not provided and the generation header is included, then an error will be produced.

ZTD_IDK_C_SPAN_TYPE_NAME

The name to use when generating the function and structure names.

Remark

This definition is optional. The default is whatever ZTD_IDK_C_SPAN_TYPE is. However, that may be bad since sometimes type names can have spaces in them (such as unsigned char). Therefore, one can se names to make it all better, like uchar to represent unsigned char.

ZTD_IDK_C_SPAN_SIZE_TYPE

The size type used to create a new c_span type.

Remark

This definition is optional. The default is size_t. In certain cases, a more compact size type may be beneficial than the original size_type. Some may also want to provide a signed type rather than an unsigned type. Note that contract checks will still check for things such as > 0 or < size, even if what is provided is a signed size type (span will not allow negative indexing, where viable).

ZTD_IDK_C_SPAN_SIZE_TYPE_NAME

The name to use when generating the function and structure names.

Remark

This definition is optional. Normally, it would be defaulted to whatever ZTD_IDK_C_SPAN_SIZE_TYPE is. However, that may be bad since sometimes type names can have spaces in them (such as long long). Therefore, one can se names to make it all better, like uchar to represent unsigned char.

ZTD_IDK_C_SPAN_NAME

The whole name of the generated type.

Remark

This definition is optional. When not provided, a sequence of checks are gone through to define a hopefully unique name for the newly generated c_span. The first generated attempt is just using c_span{type name}{size type}, where the size type is only used if ZTD_IDK_C_SPAN_SIZE_TYPE is also defined by you. Otherwise, it defaults to just c_span{type name} (without the brackets and with the names substituted in).

ZTD_IDK_C_SPAN_SIZE_FIRST

Whether or not the size type comes before the pointer.

Remark

This definition is optional. When not provided, the default layout is { pointer_type , size_type }. If this is defined and its value is 1, the layout is { size_type, pointer_type }. This can aid when generating certain types that are meant to be compatible with other kinds of buffers, e.g. with POSIX’s iovec.