The range library proposal for the std library included size
which calculated the distance between begin(r)
and end(r)
. This value usually ends up in a ptrdiff_t
. I often need to put the size of a range into much smaller size types when using C APIs and C structs. Just adding a static_cast
is no sufficient as I not only want to cast the type, but ensure that the value fits.
I added size_cast
. It requires an explicit ReturnType template parameter. Then it can verify that the value will fit and only then do a static_cast
to coerce the value into the ResultType.
The next post will demonstrate some usage.
Implementation
maintained here
template< class ResultType, class InputType > ResultType size_cast(InputType size) { const static size_t bitsOfPositiveRepresentationInResultType = (sizeof(ResultType) * 8) - static_cast<ResultType>( std::is_signed<ResultType>::value); const static size_t bitsOfPositiveRepresentationInInputType = (sizeof(InputType) * 8) - static_cast<InputType>( std::is_signed<InputType>::value); typedef std::conditional < bitsOfPositiveRepresentationInResultType < bitsOfPositiveRepresentationInInputType, InputType, ResultType >::type check_type; check_type size_check = static_cast<check_type>(size); FAIL_FAST_IF( (false, (std::is_signed<InputType>::value && size < 0)) || (size_check >> ( bitsOfPositiveRepresentationInResultType - 1)) != 0, ERROR_INVALID_PARAMETER ); return static_cast<ResultType>(size); }
No comments:
Post a Comment