|
19779 | 19779 | template<class ElementType>
|
19780 | 19780 | class default_accessor;
|
19781 | 19781 |
|
| 19782 | + // \ref{mdspan.accessor.aligned}, class template \tcode{aligned_accessor} |
| 19783 | + template<class ElementType, size_t ByteAlignment> |
| 19784 | + class aligned_accessor; |
| 19785 | + |
19782 | 19786 | // \ref{mdspan.mdspan}, class template \tcode{mdspan}
|
19783 | 19787 | template<class ElementType, class Extents, class LayoutPolicy = layout_right,
|
19784 | 19788 | class AccessorPolicy = default_accessor<ElementType>>
|
@@ -23151,6 +23155,195 @@
|
23151 | 23155 | Equivalent to: \tcode{return p + i;}
|
23152 | 23156 | \end{itemdescr}
|
23153 | 23157 |
|
| 23158 | +\rSec4[mdspan.accessor.aligned]{Class template \tcode{aligned_accessor}} |
| 23159 | + |
| 23160 | +\rSec5[mdspan.accessor.aligned.overview]{Overview} |
| 23161 | + |
| 23162 | +\begin{codeblock} |
| 23163 | +namespace std { |
| 23164 | + template<class ElementType, size_t ByteAlignment> |
| 23165 | + struct @\libglobal{aligned_accessor}@ { |
| 23166 | + using offset_policy = default_accessor<ElementType>; |
| 23167 | + using element_type = ElementType; |
| 23168 | + using reference = ElementType&; |
| 23169 | + using data_handle_type = ElementType*; |
| 23170 | + |
| 23171 | + static constexpr size_t byte_alignment = ByteAlignment; |
| 23172 | + |
| 23173 | + constexpr aligned_accessor() noexcept = default; |
| 23174 | + template<class OtherElementType, size_t OtherByteAlignment> |
| 23175 | + constexpr aligned_accessor( |
| 23176 | + aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept; |
| 23177 | + template<class OtherElementType> |
| 23178 | + constexpr explicit aligned_accessor(default_accessor<OtherElementType>) noexcept; |
| 23179 | + |
| 23180 | + template<class OtherElementType> |
| 23181 | + constexpr operator default_accessor<OtherElementType>() const noexcept; |
| 23182 | + |
| 23183 | + constexpr reference access(data_handle_type p, size_t i) const noexcept; |
| 23184 | + |
| 23185 | + constexpr typename offset_policy::data_handle_type offset( |
| 23186 | + data_handle_type p, size_t i) const noexcept; |
| 23187 | + }; |
| 23188 | +} |
| 23189 | +\end{codeblock} |
| 23190 | + |
| 23191 | +\pnum |
| 23192 | +\mandates |
| 23193 | +\begin{itemize} |
| 23194 | +\item \tcode{byte_alignment} is a power of two, and |
| 23195 | +\item \tcode{byte_alignment >= alignof(ElementType)} is \tcode{true}. |
| 23196 | +\end{itemize} |
| 23197 | + |
| 23198 | +\pnum |
| 23199 | +\tcode{aligned_accessor} meets the accessor policy requirements. |
| 23200 | + |
| 23201 | +\pnum |
| 23202 | +\tcode{ElementType} is required to be a complete object type |
| 23203 | +that is neither an abstract class type nor an array type. |
| 23204 | + |
| 23205 | +\pnum |
| 23206 | +Each specialization of \tcode{aligned_accessor} is |
| 23207 | +a trivially copyable type that models \libconcept{semiregular}. |
| 23208 | + |
| 23209 | +\pnum |
| 23210 | +\range{0}{$n$} is an accessible range |
| 23211 | +for an object \tcode{p} of type \tcode{data_handle_type} and |
| 23212 | +an object of type \tcode{aligned_accessor} if and only if |
| 23213 | +\begin{itemize} |
| 23214 | +\item |
| 23215 | +\range{p}{p + $n$} is a valid range, and, |
| 23216 | +\item |
| 23217 | +if $n$ is greater than zero, |
| 23218 | +then \tcode{is_sufficiently_aligned<byte_alignment>(p)} is \tcode{true}. |
| 23219 | +\end{itemize} |
| 23220 | + |
| 23221 | +\pnum |
| 23222 | +\begin{example} |
| 23223 | +The following function \tcode{compute} |
| 23224 | +uses \tcode{is_sufficiently_aligned} to check |
| 23225 | +whether a given \tcode{mdspan} with \tcode{default_accessor} has |
| 23226 | +a data handle with sufficient alignment |
| 23227 | +to be used with \tcode{aligned_accessor<float, 4 * sizeof(float)>}. |
| 23228 | +If so, the function dispatches to |
| 23229 | +a function \tcode{compute_using_fourfold_overalignment} |
| 23230 | +that requires fourfold over-alignment of arrays, |
| 23231 | +but can therefore use hardware-specific instructions, |
| 23232 | +such as four-wide SIMD (Single Instruction Multiple Data) instructions. |
| 23233 | +Otherwise, \tcode{compute} dispatches to a |
| 23234 | +possibly less optimized function \tcode{compute_without_requiring_overalignment} |
| 23235 | +that has no over-alignment requirement. |
| 23236 | +\begin{codeblock} |
| 23237 | +void compute_using_fourfold_overalignment( |
| 23238 | + std::mdspan<float, std::dims<1>, std::layout_right, |
| 23239 | + std::aligned_accessor<float, 4 * alignof(float)>> x); |
| 23240 | + |
| 23241 | +void compute_without_requiring_overalignment( |
| 23242 | + std::mdspan<float, std::dims<1>, std::layout_right> x); |
| 23243 | + |
| 23244 | +void compute(std::mdspan<float, std::dims<1>> x) { |
| 23245 | + constexpr auto byte_alignment = 4 * sizeof(float); |
| 23246 | + auto accessor = std::aligned_accessor<float, byte_alignment>{}; |
| 23247 | + auto x_handle = x.data_handle(); |
| 23248 | + |
| 23249 | + if (std::is_sufficiently_aligned<byte_alignment>(x_handle)) { |
| 23250 | + compute_using_fourfold_overalignment(std::mdspan{x_handle, x.mapping(), accessor}); |
| 23251 | + } else { |
| 23252 | + compute_without_requiring_overalignment(x); |
| 23253 | + } |
| 23254 | +} |
| 23255 | +\end{codeblock} |
| 23256 | +\end{example} |
| 23257 | + |
| 23258 | +\rSec5[mdspan.accessor.aligned.members]{Members} |
| 23259 | + |
| 23260 | +\indexlibraryctor{aligned_accessor}% |
| 23261 | +\begin{itemdecl} |
| 23262 | +template<class OtherElementType, size_t OtherByteAlignment> |
| 23263 | + constexpr aligned_accessor(aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept; |
| 23264 | +\end{itemdecl} |
| 23265 | + |
| 23266 | +\begin{itemdescr} |
| 23267 | +\pnum |
| 23268 | +\constraints |
| 23269 | +\begin{itemize} |
| 23270 | +\item |
| 23271 | +\tcode{is_convertible_v<OtherElementType(*)[], element_type(*)[]>} |
| 23272 | +is \tcode{true}. |
| 23273 | +\item |
| 23274 | +\tcode{OtherByteAlignment >= byte_alignment} is \tcode{true}. |
| 23275 | +\end{itemize} |
| 23276 | + |
| 23277 | +\pnum |
| 23278 | +\effects |
| 23279 | +None. |
| 23280 | +\end{itemdescr} |
| 23281 | + |
| 23282 | +\indexlibraryctor{aligned_accessor}% |
| 23283 | +\begin{itemdecl} |
| 23284 | +template<class OtherElementType> |
| 23285 | + constexpr explicit aligned_accessor(default_accessor<OtherElementType>) noexcept; |
| 23286 | +\end{itemdecl} |
| 23287 | + |
| 23288 | +\begin{itemdescr} |
| 23289 | +\pnum |
| 23290 | +\constraints |
| 23291 | +\tcode{is_convertible_v<OtherElementType(*)[], element_type(*)[]>} |
| 23292 | +is \tcode{true}. |
| 23293 | + |
| 23294 | +\pnum |
| 23295 | +\effects |
| 23296 | +None. |
| 23297 | +\end{itemdescr} |
| 23298 | + |
| 23299 | +\indexlibrarymember{access}{aligned_accessor}% |
| 23300 | +\begin{itemdecl} |
| 23301 | +constexpr reference access(data_handle_type p, size_t i) const noexcept; |
| 23302 | +\end{itemdecl} |
| 23303 | + |
| 23304 | +\begin{itemdescr} |
| 23305 | +\pnum |
| 23306 | +\expects |
| 23307 | +\range{0}{i + 1} is an accessible range for \tcode{p} and \tcode{*this}. |
| 23308 | + |
| 23309 | +\pnum |
| 23310 | +\effects |
| 23311 | +Equivalent to: \tcode{return assume_aligned<byte_alignment>(p)[i];} |
| 23312 | +\end{itemdescr} |
| 23313 | + |
| 23314 | +\indexlibrarymember{operator default_accessor}{aligned_accessor}% |
| 23315 | +\begin{itemdecl} |
| 23316 | +template<class OtherElementType> |
| 23317 | + constexpr operator default_accessor<OtherElementType>() const noexcept; |
| 23318 | +\end{itemdecl} |
| 23319 | + |
| 23320 | +\begin{itemdescr} |
| 23321 | +\pnum |
| 23322 | +\constraints |
| 23323 | +\tcode{is_convertible_v<element_type(*)[], OtherElementType(*)[]>} |
| 23324 | +is \tcode{true}. |
| 23325 | + |
| 23326 | +\pnum |
| 23327 | +\effects |
| 23328 | +Equivalent to: \tcode{return \{\};} |
| 23329 | +\end{itemdescr} |
| 23330 | + |
| 23331 | +\indexlibrarymember{offset}{aligned_accessor}% |
| 23332 | +\begin{itemdecl} |
| 23333 | +constexpr typename offset_policy::data_handle_type |
| 23334 | + offset(data_handle_type p, size_t i) const noexcept; |
| 23335 | +\end{itemdecl} |
| 23336 | + |
| 23337 | +\begin{itemdescr} |
| 23338 | +\pnum |
| 23339 | +\expects |
| 23340 | +\range{0}{i + 1} is an accessible range for \tcode{p} and \tcode{*this}. |
| 23341 | + |
| 23342 | +\pnum |
| 23343 | +\effects |
| 23344 | +Equivalent to: \tcode{return assume_aligned<byte_alignment>(p) + i;} |
| 23345 | +\end{itemdescr} |
| 23346 | + |
23154 | 23347 | \rSec3[mdspan.mdspan]{Class template \tcode{mdspan}}
|
23155 | 23348 |
|
23156 | 23349 | \rSec4[mdspan.mdspan.overview]{Overview}
|
|
0 commit comments