sanisizer
Sanitize sizes to avoid integer overflow
Loading...
Searching...
No Matches
nd_offset.hpp
Go to the documentation of this file.
1#ifndef SANISIZER_ND_OFFSET_HPP
2#define SANISIZER_ND_OFFSET_HPP
3
4#include <type_traits>
5
11namespace sanisizer {
12
16template<typename Size_>
17constexpr Size_ nd_offset_internal(Size_ extent, Size_ pos) {
18 static_assert(std::is_integral<Size_>::value);
19 return extent * pos;
20}
21
22template<typename Size_, typename... MoreArgs_>
23constexpr Size_ nd_offset_internal(Size_ extent, Size_ pos, MoreArgs_... more_args) {
24 static_assert(std::is_integral<Size_>::value);
25 return (pos + nd_offset_internal<Size_>(more_args...)) * extent;
26}
54template<typename Size_, typename FirstIndex_, typename FirstExtent_, typename SecondIndex_, typename... Remaining_>
55constexpr Size_ nd_offset(FirstIndex_ x1, FirstExtent_ extent1, SecondIndex_ x2, Remaining_... remaining) {
56 static_assert(std::is_integral<Size_>::value);
57 static_assert(std::is_integral<FirstIndex_>::value);
58 static_assert(std::is_integral<FirstExtent_>::value);
59 static_assert(std::is_integral<SecondIndex_>::value);
60
61 // Note that we don't use Size_ in the function signature, even though everything is cast to Size_.
62 // This avoids inadvertent deduction of Size_ from the input types.
63 // The user is always forced to explicitly specify Size_ to avoid any risk of accidental overflow.
64 return static_cast<Size_>(x1) + nd_offset_internal<Size_>(extent1, x2, remaining...);
65}
66
67}
68
69#endif
70
Sanitize sizes to avoid integer overflow.
Definition arithmetic.hpp:16
constexpr Size_ nd_offset(FirstIndex_ x1, FirstExtent_ extent1, SecondIndex_ x2, Remaining_... remaining)
Definition nd_offset.hpp:55