sanisizer
Sanitize sizes to avoid integer overflow
Loading...
Searching...
No Matches
sanisizer Namespace Reference

Sanitize sizes to avoid integer overflow. More...

Classes

struct  Attestation
 Attest to additional compile-time properties of an integer. More...
 
class  Cast
 Cast an integer in a function call. More...
 
class  Exact
 Do not cast an integer in a function call. More...
 
struct  is_Attestation
 
struct  is_Attestation< Attestation< Integer_, max_ > >
 
struct  is_integral_or_Attestation
 

Functions

template<typename Dest_ , typename First_ , typename ... Args_>
constexpr Dest_ sum (First_ first, Args_... more)
 
template<typename Dest_ , typename First_ , typename ... Args_>
constexpr Dest_ sum_unsafe (First_ first, Args_... more)
 
template<typename Dest_ , typename First_ , typename ... Args_>
constexpr Dest_ product (First_ first, Args_... more)
 
template<typename Dest_ , typename First_ , typename ... Args_>
constexpr Dest_ product_unsafe (First_ first, Args_... more)
 
template<typename Value_ >
constexpr auto get_value (Value_ x)
 
template<typename Value_ >
constexpr auto get_max ()
 
template<typename Max_ , Max_ new_max_, typename Value_ >
constexpr auto attest_max (Value_ x)
 
template<typename Max_ , typename Value_ >
constexpr auto attest_max_by_type (Value_ x)
 
template<typename Dest_ , typename Value_ >
constexpr bool check_overflow (Value_ x)
 
template<typename Dest_ , typename Value_ >
constexpr Dest_ cap (Value_ x)
 
template<typename Size_ , typename Value_ >
constexpr auto can_cast (Value_ x)
 
template<typename Dest_ , typename Value_ >
constexpr Dest_ cast (Value_ x)
 
template<typename Left_ , typename Right_ >
constexpr bool is_equal (Left_ left, Right_ right)
 
template<typename Left_ , typename Right_ >
constexpr bool is_less_than (Left_ left, Right_ right)
 
template<typename Left_ , typename Right_ >
constexpr bool is_less_than_or_equal (Left_ left, Right_ right)
 
template<typename Left_ , typename Right_ >
constexpr bool is_greater_than (Left_ left, Right_ right)
 
template<typename Left_ , typename Right_ >
constexpr bool is_greater_than_or_equal (Left_ left, Right_ right)
 
template<typename First_ , typename Second_ >
constexpr auto min (First_ first, Second_ second)
 
template<typename First_ , typename Second_ >
constexpr auto max (First_ first, Second_ second)
 
template<typename Container_ , typename Value_ >
constexpr auto as_size_type (Value_ x)
 
template<class Container_ , typename Value_ , typename ... Args_>
Container_ create (Value_ x, Args_ &&... args)
 
template<class Container_ , typename Value_ , typename ... Args_>
void resize (Container_ &container, Value_ x, Args_ &&... args)
 
template<class Container_ , typename Value_ , typename ... Args_>
void reserve (Container_ &container, Value_ x, Args_ &&... args)
 
template<typename Integer_ , typename Float_ >
Integer_ from_float (Float_ x)
 
template<typename Float_ , typename Integer_ >
Float_ to_float (Integer_ x)
 
template<typename Size_ , typename FirstIndex_ , typename FirstExtent_ , typename SecondIndex_ , typename... Remaining_>
constexpr Size_ nd_offset (FirstIndex_ x1, FirstExtent_ extent1, SecondIndex_ x2, Remaining_... remaining)
 

Detailed Description

Sanitize sizes to avoid integer overflow.

Function Documentation

◆ as_size_type()

template<typename Container_ , typename Value_ >
auto sanisizer::as_size_type ( Value_ x)
constexpr

Cast an integer to the size type of a container. This protects against overflow when using this integer in the container's constructor or resize()/reserve() methods.

Template Parameters
Container_Container class with a size() method and a constructor that accepts the size as the first argument.
Value_Integer type of the input size.
Parameters
xNon-negative value representing the desired container size.
Returns
x as the container's size's type.

◆ attest_max()

template<typename Max_ , Max_ new_max_, typename Value_ >
auto sanisizer::attest_max ( Value_ x)
constexpr
Template Parameters
Max_Integer type of the new compile-time maximum.
new_max_The new compile-time maximum.
Value_Integer or Attestation.
Parameters
xInteger value or an Attestation about an integer.
Returns
x if it is already known to be less than or equal to new_max_, otherwise, an Attestation that attests to this constraint.

◆ attest_max_by_type()

template<typename Max_ , typename Value_ >
auto sanisizer::attest_max_by_type ( Value_ x)
constexpr
Template Parameters
Max_Integer type of the new compile-time maximum.
Value_Integer or Attestation.
Parameters
xInteger value or an Attestation about an integer.
Returns
x if it is already known to be less than or equal to the maximum value of Max_; otherwise, an Attestation that attests to this constraint.

◆ can_cast()

template<typename Size_ , typename Value_ >
auto sanisizer::can_cast ( Value_ x)
constexpr

Check that a non-negative integer can be cast to a destination type, typically the size type of a C-style array or STL container. This is useful for chaining together checks without actually doing the cast itself.

Template Parameters
Dest_Integer type of the destination.
Value_Integer type of the input value. This may also be an Attestation.
Parameters
xNon-negative value to be casted.
Returns
x as its input type (or the corresponding integer type, if it was an Attestation). An error is thrown if overflow would occur.

◆ cap()

template<typename Dest_ , typename Value_ >
Dest_ sanisizer::cap ( Value_ x)
constexpr

Cap a non-negative integer at the largest value of a destination type. This is primarily intended for setting appropriate default values of function arguments and class variables.

Template Parameters
Dest_Integer type of the destination.
Value_Integer type of the input value. This may also be an Attestation.
Parameters
xNon-negative value to be capped.
Returns
x if it can be represented in Dest_, otherwise the maximum value of Dest_.

◆ cast()

template<typename Dest_ , typename Value_ >
Dest_ sanisizer::cast ( Value_ x)
constexpr

Cast a non-negative integer to a destination type, typically the size type of a C-style array or STL container. This avoids accidental overflow from an implicit cast when x is used in new or the container's constructor.

Template Parameters
Dest_Integer type of the destination.
Value_Integer type of the input value. This may also be an Attestation.
Parameters
xNon-negative value to be casted.
Returns
x as a Dest_. An error is thrown if overflow would occur.

◆ check_overflow()

template<typename Dest_ , typename Value_ >
bool sanisizer::check_overflow ( Value_ x)
constexpr
Template Parameters
Dest_Integer type of the destination.
Value_Integer or Attestation.
Parameters
xInteger value or an Attestation about an integer.
Returns
An overflow error is thrown if x's value would overflow when stored in Dest_. Otherwise, false is returned.

◆ create()

template<class Container_ , typename Value_ , typename ... Args_>
Container_ sanisizer::create ( Value_ x,
Args_ &&... args )

Create a new container of a specified size. This protects against overflow when casting the integer size to the container's size type, see as_size_type() for details.

Template Parameters
Container_Container class with a size() method and a constructor that accepts the size as the first argument.
Value_Integer type of the input size.
Args_Further arguments to pass to the container's constructor.
Parameters
xNon-negative value representing the desired container size.
argsAdditional arguments to pass to the Container_ constructor after the size.
Returns
An instance of the container, constructed to be of size x.

◆ from_float()

template<typename Integer_ , typename Float_ >
Integer_ sanisizer::from_float ( Float_ x)

Safely convert a non-negative floating-point number to an integer with truncation. This is occasionally necessary when the size of a container or number of loop iterations is determined by floating-point calculations.

Template Parameters
Integer_Integer type.
Float_Floating-point type.
Parameters
xFloating-point number, usually holding some kind of size.
Returns
The value of x as an integer, after truncation. An exception is raised if x is negative, non-finite or overflow would occur.

◆ get_max()

template<typename Value_ >
auto sanisizer::get_max ( )
constexpr
Template Parameters
Value_Integer or Attestation.
Returns
The maximum value of all instances of Value_.

◆ get_value()

template<typename Value_ >
auto sanisizer::get_value ( Value_ x)
constexpr
Template Parameters
Value_Integer or Attestation.
Parameters
xInteger value or an Attestation about an integer.
Returns
x if it is already an integer, otherwise Attestation::value.

◆ is_equal()

template<typename Left_ , typename Right_ >
bool sanisizer::is_equal ( Left_ left,
Right_ right )
constexpr
Template Parameters
Left_Integer type on the left hand side of the comparison. This may also be an Attestation.
Right_Integer type on the right hand side of the comparison. This may also be an Attestation.
Parameters
leftNon-negative value on the left hand side of the comparison.
rightNon-negative value on the right hand side of the comparison.
Returns
Whether left is equal to right.

◆ is_greater_than()

template<typename Left_ , typename Right_ >
bool sanisizer::is_greater_than ( Left_ left,
Right_ right )
constexpr
Template Parameters
Left_Integer type on the left hand side of the comparison. This may also be an Attestation.
Right_Integer type on the right hand side of the comparison. This may also be an Attestation.
Parameters
leftNon-negative value on the left hand side of the comparison.
rightNon-negative value on the right hand side of the comparison.
Returns
Whether left is greater than right.

◆ is_greater_than_or_equal()

template<typename Left_ , typename Right_ >
bool sanisizer::is_greater_than_or_equal ( Left_ left,
Right_ right )
constexpr
Template Parameters
Left_Integer type on the left hand side of the comparison. This may also be an Attestation.
Right_Integer type on the right hand side of the comparison. This may also be an Attestation.
Parameters
leftNon-negative value on the left hand side of the comparison.
rightNon-negative value on the right hand side of the comparison.
Returns
Whether left is greater than or equal to right.

◆ is_less_than()

template<typename Left_ , typename Right_ >
bool sanisizer::is_less_than ( Left_ left,
Right_ right )
constexpr
Template Parameters
Left_Integer type on the left hand side of the comparison. This may also be an Attestation.
Right_Integer type on the right hand side of the comparison. This may also be an Attestation.
Parameters
leftNon-negative value on the left hand side of the comparison.
rightNon-negative value on the right hand side of the comparison.
Returns
Whether left is less than right.

◆ is_less_than_or_equal()

template<typename Left_ , typename Right_ >
bool sanisizer::is_less_than_or_equal ( Left_ left,
Right_ right )
constexpr
Template Parameters
Left_Integer type on the left hand side of the comparison. This may also be an Attestation.
Right_Integer type on the right hand side of the comparison. This may also be an Attestation.
Parameters
leftNon-negative value on the left hand side of the comparison.
rightNon-negative value on the right hand side of the comparison.
Returns
Whether left is less than or equal to right.

◆ max()

template<typename First_ , typename Second_ >
auto sanisizer::max ( First_ first,
Second_ second )
constexpr
Template Parameters
First_First integer type. This may also be an Attestation.
Second_Second integer type. This may also be an Attestation.
Parameters
firstFirst non-negative value.
secondSecond non-negative value.
Returns
The larger of first and second, in the larger integer type of First_ and Second_.

◆ min()

template<typename First_ , typename Second_ >
auto sanisizer::min ( First_ first,
Second_ second )
constexpr
Template Parameters
First_First integer type. This may also be an Attestation.
Second_Second integer type. This may also be an Attestation.
Parameters
firstFirst non-negative value.
secondSecond non-negative value.
Returns
The smaller of first and second, in the smaller integer type of First_ and Second_.

◆ nd_offset()

template<typename Size_ , typename FirstIndex_ , typename FirstExtent_ , typename SecondIndex_ , typename... Remaining_>
Size_ sanisizer::nd_offset ( FirstIndex_ x1,
FirstExtent_ extent1,
SecondIndex_ x2,
Remaining_... remaining )
constexpr

Compute offsets for accessing elements in a flattened N-dimensional array (for N > 1). The first dimension is assumed to be the fastest-changing, followed by the second dimension, and so on.

Template Parameters
Size_Integer type to represent the size of the flattened array.
FirstIndex_Integer type to represent the index on the first dimension. It is assumed that this can be safely cast to Size_, as overflow checks should have been performed during array allocation, e.g., via product().
FirstExtent_Integer type to represent the extent of the first dimension. It is assumed that this can be safely cast to Size_, as overflow checks should have been performed during array allocation, e.g., via product().
SecondIndex_Integer type to represent the index on the second dimension. It is assumed that this can be safely cast to Size_, as overflow checks should have been performed during array allocation, e.g., via product().
Remaining_Additional arguments for further dimensions. It is assumed that all types can be safely cast to Size_, as overflow checks should have been performed during array allocation, e.g., product().
Parameters
x1Position on the first dimension.
extent1Extent of the first dimension.
x2Position on the second dimension.
remainingAdditional arguments for further dimensions. These should be (extentP, xQ) pairs where extentP is the extent of the P-th dimension and xQ is the position on the Q = P + 1-th dimension. For example, for a 3-dimensional array, we would expect an extent2 and x3 argument.
Returns
Offset into the array for element (x1, x2, ...).

◆ product()

template<typename Dest_ , typename First_ , typename ... Args_>
Dest_ sanisizer::product ( First_ first,
Args_... more )
constexpr

Multiply two or more non-negative values, checking for overflow in the destination type. This is typically used to compute the size of a flattened N-dimensional array as the product of its dimension extents.

For consistency, this function will also check that each input value can be cast to Dest_. This ensures that per-dimension indices/extents can be safely represented as Dest_ in later steps (e.g., nd_offset()). These checks are necessary as the product may fit in Dest_ but not the input values if one of the inputs is zero.

Template Parameters
Dest_Integer type of the destination.
First_Integer type of the first value. This may also be an Attestation.
Args_Integer types of additional values. Any number of these may also be Attestations.
Parameters
firstNon-negative value to multiply.
moreAdditional non-negative values to multiply.
Returns
Product of all arguments as a Dest_. An error is raised if an overflow would occur.

◆ product_unsafe()

template<typename Dest_ , typename First_ , typename ... Args_>
Dest_ sanisizer::product_unsafe ( First_ first,
Args_... more )
constexpr

Unsafe version of product() that casts its arguments to Dest_ but does not check for overflow. This is more efficent if it is known that the product will not overflow, e.g., from previous calls to product() with larger values.

Template Parameters
Dest_Integer type of the destination.
Args_Integer types of additional values.
Parameters
firstValue to multiply.
moreAdditional values to multiply.
Returns
Product of all arguments as a Dest_.

◆ reserve()

template<class Container_ , typename Value_ , typename ... Args_>
void sanisizer::reserve ( Container_ & container,
Value_ x,
Args_ &&... args )

Reserve a container to the desired size. This protects against overflow when casting the integer size to the container's size type, see as_size_type() for details.

Template Parameters
Container_Container class with a size() method and a reserve() method that accepts the size as the first argument.
Value_Integer type of the input size.
Args_Further arguments to pass to the container's reserve() method.
Parameters
containerAn existing instance of the container. On return, its allocation is set to x.
xNon-negative value representing the desired container size.
argsAdditional arguments to pass to reserve() after the size.

◆ resize()

template<class Container_ , typename Value_ , typename ... Args_>
void sanisizer::resize ( Container_ & container,
Value_ x,
Args_ &&... args )

Resize a container to the desired size. This protects against overflow when casting the integer size to the container's size type, see as_size_type() for details.

Template Parameters
Container_Container class with a size() method and a resize() method that accepts the size as the first argument.
Value_Integer type of the input size.
Args_Further arguments to pass to the container's resize() method.
Parameters
containerAn existing instance of the container. This is resized to size x.
xNon-negative value representing the desired container size.
argsAdditional arguments to pass to resize() after the size.

◆ sum()

template<typename Dest_ , typename First_ , typename ... Args_>
Dest_ sanisizer::sum ( First_ first,
Args_... more )
constexpr

Add two or more non-negative values, checking for overflow in the destination type. This is typically used to compute the size of an array that is a concatenation of smaller arrays.

Template Parameters
Dest_Integer type of the destination.
First_Integer type of the first value. This may also be an Attestation.
Args_Integer types of additional values. Any number of these may also be Attestations.
Parameters
firstFirst non-negative value to add.
moreAdditional non-negative values to add.
Returns
Sum of all arguments as a Dest_. An error is raised if an overflow would occur.

◆ sum_unsafe()

template<typename Dest_ , typename First_ , typename ... Args_>
Dest_ sanisizer::sum_unsafe ( First_ first,
Args_... more )
constexpr

Unsafe version of sum() that casts its arguments to Dest_ before summation but does not check for overflow. This is more efficent if it is already known that the sum will not overflow, e.g., from previous calls to sum() with larger values.

Template Parameters
Dest_Integer type of the destination.
First_Integer type of the first value.
Args_Integer types of additional values.
Parameters
firstNon-negative value to add.
moreAdditional non-negative values to add.
Returns
Sum of all arguments as a Dest_.

◆ to_float()

template<typename Float_ , typename Integer_ >
Float_ sanisizer::to_float ( Integer_ x)

Safely convert a non-negative integer into a floating-point number without loss of precision. This is occasionally necessary when the surrounding environment does not have a dedicated integer type (e.g., Javascript).

Note that the "safety" of this function is based on preserving precision rather than avoiding undefined behavior. If the implementation's floats are compliant with the IEEE-754 specifiation, very large integers will already be safely converted to positive infinity via regular casts.

Template Parameters
Integer_Integer type. This can also be an Attestation.
Float_Floating-point type.
Parameters
xNon-negative integer, usually holding some kind of size.
Returns
The value of x as a floating-point number. An exception is raised if overflow would occur.