cuda::narrow
ο
struct narrowing_error;
template <typename To, typename From>
[[nodiscard]] constexpr
To narrow(From from);
template <typename To, typename From>
[[nodiscard]] constexpr
To narrow_cast(From&& __from) noexcept;
Both functions use a static_cast
to cast the value from
to type To
.
From
needs to be convertible to To
, and implement operator!=
.
cuda::narrow
additionally checks whether the value has changed,
and if so, throws cuda::narrowing_error
in host code and traps in device code.
In this case, To
additionally needs to be convertible to From
.
cuda::narrow_cast
does not perform such a check (itβs a plain cast) and is just intended to show
that narrowing and a potential change of the value is intended.
The functions are modelled after gsl::narrow
and gsl::narrow_cast
.
See also the C++ Core Guidelines
ES.46 and
ES.49.
Exampleο
#include <cuda/numeric>
__global__ void kernel(size_t n) {
unsigned int r1 = cuda::narrow<unsigned int>(n); // traps
unsigned int r2 = cuda::narrow_cast<unsigned int>(n); // truncation of value is intended
}
void host() {
unsigned char r1 = cuda::narrow<unsigned char>( 200); // ok
unsigned char r2 = cuda::narrow<unsigned char>( 300); // throws narrowing_error
unsigned int r3 = cuda::narrow<unsigned int >(-100); // throws narrowing_error
unsigned char r4 = cuda::narrow_cast<unsigned char>(300); // truncation of value is intended
kernel<<<1, 1>>>(2LL << 35); // size larger than unsigned int
}