The accessor policy in std::mdspan
is an optional template parameter that allows you to customize how elements are accessed and potentially modified when using the []
operator or the accessor
member function of mdspan
.
The primary purposes of the accessor policy are:
The accessor policy enables you to define custom behavior for accessing elements in the mdspan
. This can be useful in various scenarios, such as:
mdspan
, preventing out-of-bounds access.When working with external libraries or APIs that expect a specific accessor behavior, you can use an appropriate accessor policy to adapt the mdspan
 to match those expectations.
For example, if an external library expects accessor objects with certain member functions or operators, you can define an accessor policy that provides those required interfaces.
In some cases, the accessor policy can be used to optimize element access performance. By defining a custom accessor policy, you can avoid unnecessary function calls or indirections and provide a more efficient way to access elements.
However, it's important to note that the performance impact of accessor policies depends on the specific use case and compiler optimizations. In many cases, the default accessor policy provided by std::mdspan
 is already optimized for common scenarios.
Here's an example that demonstrates a custom accessor policy that applies a scaling factor to the elements:
#include <iostream>
#include <mdspan>
// Custom accessor policy that scales
// elements by a factor of 10
struct ScalingAccessor {
template <typename T>
struct accessor {
T* data;
accessor(T* ptr) : data(ptr) {}
T read(std::size_t offset) const {
return data[offset] * 10;
}
void write(std::size_t offset, T value) {
data[offset] = value / 10;
}
};
};
int main() {
std::array<int, 6> arr{1, 2, 3, 4, 5, 6};
std::mdspan<int, std::extents<
std::size_t, 2, 3>, std::layout_right,
ScalingAccessor>
scalingSpan{arr.data()};
std::cout << "Original elements:\n";
for (std::size_t i = 0;
i < scalingSpan.extent(0); ++i) {
for (std::size_t j = 0;
j < scalingSpan.extent(1); ++j) {
std::cout << scalingSpan[i, j] << " ";
}
std::cout << "\n";
}
// Modify elements through the accessor policy
scalingSpan[0, 0] = 10;
scalingSpan[1, 1] = 50;
std::cout << "\nModified elements:\n";
for (std::size_t i = 0;
i < scalingSpan.extent(0); ++i) {
for (std::size_t j = 0;
j < scalingSpan.extent(1); ++j) {
std::cout
<< arr[i * scalingSpan.extent(1) + j]
<< " ";
}
std::cout << "\n";
}
}
Original elements:
10 20 30
40 50 60
Modified elements:
1 2 3
4 5 6
In this example, we define a custom accessor policy called ScalingAccessor
that scales the elements by a factor of 10 when reading and divides them by 10 when writing.
We create an mdspan
object scalingSpan
with the ScalingAccessor
policy. When accessing elements through scalingSpan
, the scaling behavior is applied transparently.
Note that the accessor policy only affects the access through the mdspan
object. When we modify elements through scalingSpan
, the underlying array arr
is updated with the original unscaled values.
Accessor policies provide a powerful way to customize element access behavior in mdspan
, enabling various use cases and optimizations.
Answers to questions are automatically generated and may not have been reviewed.
std::mdspan
A guide to std::mdspan
, allowing us to interact with arrays as if they have multiple dimensions