sanisizer
Sanitize sizes to avoid integer overflow
Loading...
Searching...
No Matches
attest.hpp
Go to the documentation of this file.
1#ifndef SANISIZER_ATTEST_HPP
2#define SANISIZER_ATTEST_HPP
3
4#include <limits>
5#include <type_traits>
6#include <cassert>
7#include <stdexcept>
8
9#include "utils.hpp"
10
16namespace sanisizer {
17
29template<typename Integer_, Integer_ max_>
31 static_assert(std::is_integral<Integer_>::value);
32 static_assert(max_ >= 0);
33
38 constexpr Attestation(Integer_ x) : value(x) {
39 assert(x <= max_);
40 }
41
45 typedef Integer_ Integer;
46
51 static constexpr Integer_ max = max_;
52
56 Integer_ value;
57};
58
64template<typename Value_>
69 static constexpr bool value = false;
70};
71
78template<typename Integer_, Integer_ max_>
79struct is_Attestation<Attestation<Integer_, max_> > {
83 static constexpr bool value = true;
84};
85
91template<typename Value_>
96 static constexpr bool value = std::is_integral<Value_>::value || is_Attestation<Value_>::value;
97};
98
104template<typename Value_>
105constexpr auto get_value(Value_ x) {
106 if constexpr(std::is_integral<Value_>::value) {
107 return x;
108 } else {
109 static_assert(is_Attestation<Value_>::value);
110 return x.value;
111 }
112}
113
118template<typename Value_>
119constexpr auto get_max() {
120 if constexpr(std::is_integral<Value_>::value) {
121 return std::numeric_limits<Value_>::max();
122 } else {
123 static_assert(is_Attestation<Value_>::value);
124 return Value_::max;
125 }
126}
127
136template<typename Max_, Max_ new_max_, typename Value_>
137constexpr auto attest_max(Value_ x) {
138 constexpr auto unsigned_new_limit = static_cast<typename std::make_unsigned<Max_>::type>(new_max_);
139 if constexpr(std::is_integral<Value_>::value) {
140 constexpr auto max_value = static_cast<typename std::make_unsigned<Value_>::type>(std::numeric_limits<Value_>::max());
141 if constexpr(max_value <= unsigned_new_limit) {
142 return x;
143 } else {
144 return Attestation<Value_, static_cast<Value_>(new_max_)>(x);
145 }
146 } else {
147 static_assert(is_Attestation<Value_>::value);
148 typedef typename Value_::Integer WrappedInteger;
149 constexpr auto max_value = static_cast<typename std::make_unsigned<WrappedInteger>::type>(Value_::max);
150 if constexpr(max_value <= unsigned_new_limit) {
151 return x;
152 } else {
154 }
155 }
156}
157
165template<typename Max_, typename Value_>
166constexpr auto attest_max_by_type(Value_ x) {
167 return attest_max<Max_, std::numeric_limits<Max_>::max()>(x);
168}
169
177template<typename Dest_, typename Value_>
178constexpr bool check_overflow(Value_ x) {
179 static_assert(std::is_integral<Dest_>::value);
180 constexpr auto umaxed = as_unsigned(std::numeric_limits<Dest_>::max());
182 if constexpr(umaxed < as_unsigned(get_max<Value_>())) {
183 if (umaxed < as_unsigned(get_value(x))) {
184 throw std::overflow_error("overflow detected when casting size-like values in sanisizer");
185 }
186 }
187 return false;
188}
189
193template<typename Value_>
194Value_ attest_gez(Value_ x) { return x; }
199}
200
201#endif
Sanitize sizes to avoid integer overflow.
Definition arithmetic.hpp:16
constexpr auto get_value(Value_ x)
Definition attest.hpp:105
constexpr bool check_overflow(Value_ x)
Definition attest.hpp:178
constexpr auto get_max()
Definition attest.hpp:119
constexpr auto attest_max(Value_ x)
Definition attest.hpp:137
constexpr auto attest_max_by_type(Value_ x)
Definition attest.hpp:166
Attest to additional compile-time properties of an integer.
Definition attest.hpp:30
static constexpr Integer_ max
Definition attest.hpp:51
Integer_ Integer
Definition attest.hpp:45
constexpr Attestation(Integer_ x)
Definition attest.hpp:38
Integer_ value
Definition attest.hpp:56
Definition attest.hpp:65
static constexpr bool value
Definition attest.hpp:69
static constexpr bool value
Definition attest.hpp:96