Add an ignored dimension to a structure.
#include <noarr/structures_extended.hpp>
template<char Dim, typename T>
struct noarr::bcast_t;
template<char... Dims>
constexpr proto noarr::bcast();
template<char... Dims>
constexpr proto noarr::bcast(auto... lengths);
// = noarr::bcast<Dims...>() ^ noarr::set_length<Dims...>(lengths)
(proto
is an unspecified proto-structure)
The bcast_t
structure adds to structure T
dimension Dim
, which is not involved in any size or offset calculations.
Effectively, this makes the structure appear as if it were repeated once for each index in the new dimension.
Each one element of the original structure will be broadcast to multiple elements of the new structure
(the coordinates of these new elements will only differ in the newly added dimension Dim
).
Note that the memory layout is not modified and (in case of bags) no data are copied -- only the view is changed.
The bcast
function can accept a list of dimensions: it will compose multiple bcast_t
s if necessary.
Neither bcast_t
itself nor the first overload of bcast
set the length of the new dimension - it must be set externally.
The second overload of bcast
provides a shortcut for this by setting the length in the structure immediately using noarr::set_length
.
See the first section of Dimension Kinds for the allowed types of lengths
.
This structure can be used to have a traverser visit each element repeatedly:
auto structure = noarr::scalar<float>() ^ noarr::vector<'i'>(42);
noarr::traverser(structure ^ noarr::bcast<'r'>(5)).for_each([&](auto state) {
int round = noarr::get_index<'r'>(state);
// fine, structure will ignore 'r' (same with e.g. bag[] or get_at)
std::size_t off = structure | noarr::offset(state);
});
Broadcast can also be used to make a structure appear as having more dimensions without really changing the dimensionality of the data.
Specifically, if the length is set to one (noarr::bcast<'...'>(1)
), it will still appear as having the same elements.