span

template<typename T, typename Dimensions, typename Strides>
class span

A multidimensional span. Matrix and vector arguments to wrenfold functions are internally converted to spans. Any user-provided vector or buffer can be passed to a wrenfold C++ function, provided it implements the convert_to_span trait.

Warning

Typically you do not want construct this type directly. Instead, specialize convert_to_span for whatever matrix/vector class you wish to support.

Template Parameters:
  • T – Numeric type of the underlying buffer (eg. float, double).

  • Dimensionsvalue_pack describing the dimensions of the data.

  • Stridesvalue_pack describing the strides of the data.

Public Functions

template<typename U, typename = detail::enable_if_adding_const_t<T, U>>
inline constexpr span(const span<U, Dimensions, Strides> &s) noexcept

Permit implicit promotion from span<T, ...> to span<const T, ....>.

Template Parameters:

U – Non-const version of type T.

Parameters:

s – Source span to copy parameters from.

inline std::size_t rows() const noexcept

Number of rows (the dimension at index 0).

inline std::size_t cols() const noexcept

Number of columns (the dimension at index 1). Valid for spans with two or more dimensions.

inline const Dimensions &dimensions() const noexcept

Access value_pack of dimensions.

inline const Strides &strides() const noexcept

Access value_pack of strides.

template<std::size_t A>
inline auto dimension() const noexcept

Retrieve the size/shape of the span on a particular dimension.

Template Parameters:

A – Axis to retrieve.

template<std::size_t A>
inline auto stride() const noexcept

Retrieve the stride of the spanned data on a particular dimension.

Template Parameters:

A – Axis to retrieve.

template<typename ...Indices>
inline reference operator()(Indices... indices) const noexcept

Matrix-access operator.

Warning

No bounds checking is applied.

Template Parameters:

Indices – These must be integral values that are convertible to std::ptrdiff_t.

Parameters:

indices – Indices into the underlying data. For a 2D span, this will be a (row, column) pair.

Returns:

A reference to an element in the span.

inline reference operator[](const std::ptrdiff_t index) const noexcept

Array access operator. Valid only for 1D spans.

Warning

No bounds checking is applied.

Parameters:

index – Element to access.

Returns:

A reference to an element in the span.

inline pointer data() const noexcept

Pointer to the start of the underlying data.

inline constexpr operator bool() const noexcept

Implicit conversion to bool. Evaluates to true if the underlying data pointer is non-null.

inline span<const std::remove_const_t<T>, Dimensions, Strides> as_const() const noexcept

Create a span with the same underlying dimensions and strides as this, but with a const data type.

Returns:

A new span of the form span<const T, ...>.

template<typename O, typename D>
inline auto block(O offsets, D dims) const noexcept

Create a new span referencing a sub-block of this.

Warning

No checks are employed to enforce that the new span does not exceed the bounds of the original.

Template Parameters:
Parameters:
  • offsets – Where the block starts.

  • dims – The size of the block on each exis.

Returns:

A new span with the same strides as the original, but with a new starting address and dimensions of type D.

Public Static Attributes

static std::size_t num_dimensions = Dimensions::length

Number of dimensions in the span.

template<typename Dimensions, typename T, typename = void>
struct convert_to_span

Trait that implements conversion of user-provided type T to wf::span. The trait must implement a single method, convert(...), which accepts an instance of type T and returns a span.

An example implementation for a simple 2D matrix type with compile-time dimensions might look something like:

template <typename Dimensions, int Rows, int Cols>
struct convert_to_span<Dimensions, MyMatrixType<Rows, Cols>> {
  // We employ a forwarding reference to accept both const and non-const.
  // If the type of `U` is const, we want to return a `span<const V, ...>`.
  template <typename U>
  constexpr auto convert(U&& matrix) const noexcept {
    // We'll assume the dimensions are always known at compile time. In practice, you may wish
    // to make this a runtime assertion if the matrix type is dynamic.
    static_assert(constant_value_pack_axis_v<0, Dimensions> == Rows);
    static_assert(constant_value_pack_axis_v<1, Dimensions> == Cols);
    // This example assumes row-major storage, so the stride between rows is `Cols`.
    // The stride between columns is 1 (each row is densely packed).
    constexpr auto strides = make_constant_value_pack<Cols, 1>();
    return make_span(matrix.data(), make_constant_value_pack<Rows, Cols>(), strides);
  }
};

Scroll down this file for an example implementation that converts Eigen::MatrixBase-derived classes to spans.

Warning

The user-provided specialization is ultimately responsible for checking that a specific instance of T satisfies the values in Dimensions.

Template Parameters:
  • Dimensionswf::value_pack describing the expected dimensions of the resulting span. As of the time of this writing, these values are always compile-time constants.

  • T – User-provided type being converted.

template<typename T, typename Dimensions, typename Strides>
auto wf::make_span(T *data, Dimensions dims, Strides strides) noexcept

Construct a span from a pointer, dimensions, and strides.

Example usage:

// Make a span over a fixed-size array. The data is assumed to have a shape of 4x6, in
// column-major order.
std::array<double, 24> buffer{};
const auto span = make_span(buffer.data(), make_constant_value_pack<4, 6>(),
                            make_constant_value_pack<1, 6>());

Template Parameters:
  • T – Type of the underlying data (eg. float, double).

  • Dimensions – A wf::value_pack.

  • Strides – A wf::value_pack, the length of which should match Dimensions.

Parameters:
  • data – Pointer to the start of the spanned data.

  • dims – The shape of the data.

  • strides – The stride of the spanned data.

Returns:

A new span.

template<typename Dimensions>
auto wf::make_always_null_span() noexcept

Create a null span with the specified dimensions. Null spans can be passed to optional output arguments in generated functions.

Template Parameters:

Dimensions – A wf::value_pack of compile-time integrals.

Returns:

A span with a null data pointer.

template<typename T, typename = detail::enable_if_array_like_t<T>>
auto wf::make_array_span(T &&array) noexcept

Create a 1D span from an array-like object. An array-like object meets the following criteria:

  • Exposes a data() function that returns a pointer.

  • Exposes a size() function that returns an integral value.

For example, std::vector satifies these criteria.

Todo:

In some cases (std::array for example) the span could have compile-time length. This has yet to be implemented.

Template Parameters:

T – A type satisfying enable_if_array_like_t

Parameters:

array – It is assumed the data in array is layed out densely (ie. stride of 1).

Returns:

A new span.

template<typename T, std::size_t N>
auto wf::make_array_span(T (&array)[N]) noexcept

Create a 1D span from a C-style array.

Template Parameters:
  • T – Type of the elements in the array.

  • N – Size of the array. Must be at least one.

Parameters:

array – It is assumed the data in array is layed out densely (ie. stride of 1).

Returns:

A new span.

template<typename Dimensions, typename T>
auto wf::make_input_span(const T &input)

Create an input span. This method will instantiate convert_to_span<Dimensions, T> and invoke the member function convert(input).

Template Parameters:

Dimensionswf::value_pack of compile-time values indicating the expected dimensions of the resultant span.

Parameters:

input – Object whose data will be accessed through the underlying span. Input spans must point to valid data - behavior is undefined if this object is null/invalid.

Returns:

A new immutable span.

template<typename Dimensions, typename T>
auto wf::make_output_span(T &output)

Create a span for an output argument. This method will instantiate convert_to_span<Dimensions, T> and invoke the member function convert(input).

Template Parameters:

Dimensionswf::value_pack of compile-time values indicating the expected dimensions of the resultant span.

Parameters:

output – Object whose data will be accessed through the underlying span. Output spans must point to valid data - behavior is undefined if this object is null/invalid.

Returns:

A new mutable span.

template<typename Dimensions, typename T>
auto wf::make_optional_output_span(T &output)

Create a span for an optional output argument. This method will instantiate convert_to_span<Dimensions, T> and invoke the member function convert(input). Unlike input and output spans, optional output spans may be null.

Template Parameters:

Dimensionswf::value_pack of compile-time values indicating the expected dimensions of the resultant span.

Parameters:

output – Object whose data will be accessed through the underlying span.

Returns:

A new mutable span.

template<std::size_t D>
class constant

A length or stride value that is known at compile-time.

Template Parameters:

D – Dimension/stride.

Public Static Functions

static inline std::size_t value() noexcept

Retrieve the value.

class dynamic

Store a length or stride value that is determined at runtime.

Public Functions

inline std::size_t value() const noexcept

Retrieve the value.

template<typename ...Values>
class value_pack : public std::conditional_t<detail::conjunction_v<detail::is_constant<Values>...>, detail::value_pack_const<Values...>, detail::value_pack_dynamic<Values...>>

Store a sequence of values, each of which represents the size or stride along a partiular axis of a span.

Template Parameters:

Values – Variadic list of wf::constant or wf::dynamic values.

Public Functions

template<std::size_t A>
inline auto get() const noexcept

Access value for a particular dimension.

Template Parameters:

A – Index of the element to retrieve.

Public Static Attributes

static bool known_at_compile_time = detail::conjunction_v<detail::is_constant<Values>...>

True if all values are compile-time constants.

static std::size_t length = sizeof...(Values)

Number of values in this pack.

template<typename ...Values>
auto wf::make_value_pack(Values... values) noexcept

Construct a value_pack from variadic arguments.

Example usage:

// Create dimensions for a 2x8x3 sized buffer.
const auto dims = make_value_pack(constant<2>{}, 8, dynamic(3));

Parameters:

values – These may be wf::constant compile-time values, wf::dynamic runtime values, or integrals that will automatically be promoted to wf::dynamic.

Returns:

Instance of value_pack with the specified values.