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
}