Open DanRStevens opened 5 years ago
Saw this article about if constexpr(expression)
in C++17:
https://www.codingame.com/playgrounds/2205/7-features-of-c17-that-will-simplify-your-code/constexpr-if
This could be used to ensure a zero-cost runtime check when SizeType
parameters are set such that overflow is impossible, or such that negative values are impossible.
This could be used to wrap the existing runtime checks, such that they are only present in the compiled code if some SizeType
range check determines a runtime check is necessary.
if constexpr(compileTimeSizeTypeRangeCheck) {
if (existingRuntimeOverflowCheck) {
throw std::runtime_error("Overflow ...");
}
}
Here's some additional update info detailing if constexpr(...)
:
https://en.cppreference.com/w/cpp/language/if
We can improve the static checks for the StreamReader and StreamWriter template methods. In particular, the length prefixed data types can use some bounds checking on the length. The checks depend on Read/Write, as well as the relative data sizes between the chosen type and
std::size_t
.For reading: With signed length values, negative values should result in an exception. For positive values (either signed or unsigned types), exceeding the bounds of a
std::size_t
should result in an exception.For writing: No bounds checking is needed for negative values, as an object can never have negative size. If the size of the object (bounded by the range of
std::size_t
) exceeds the range of the chosen length type, an exception should be raised.Depending on the type parameter, either case may be impossible. It is desirable to not incur any runtime cost for these checks when the condition is impossible. For instance, a
uint32_t
can never be negative, and can never overflow the bounds of astd::size_t
.It may be possible to implement this with template specialization using some combination of the following methods:
From
<type_traits>
:std::integral_constant
std::is_signed
std::is_unsigned
From
<numeric_limits>
:std::numeric_limits::is_integer
std::numeric_limits::is_signed