sanisizer
Sanitize sizes to avoid integer overflow
Loading...
Searching...
No Matches
Bounded.hpp
Go to the documentation of this file.
1#ifndef SANISIZER_BOUNDED_HPP
2#define SANISIZER_BOUNDED_HPP
3
4#include <type_traits>
5#include <cassert>
6#include <stdexcept>
7
8#include "utils.hpp"
9
15namespace sanisizer {
16
28template<typename Integer_, Integer_ max_>
29struct Bounded {
30 static_assert(std::is_integral<Integer_>::value);
31 static_assert(max_ >= 0);
32
37 constexpr Bounded(Integer_ x) : value(x) {
38 assert(x <= max_);
39 }
40
44 typedef Integer_ Integer;
45
50 static constexpr Integer_ max = max_;
51
55 Integer_ value;
56};
57
63template<typename Value_>
64struct is_Bounded {
68 static constexpr bool value = false;
69};
70
77template<typename Integer_, Integer_ max_>
78struct is_Bounded<Bounded<Integer_, max_> > {
82 static constexpr bool value = true;
83};
84
88// Avoid issues with constness.
89template<typename Integer_, Integer_ max_>
90struct is_Bounded<const Bounded<Integer_, max_> > {
91 static constexpr bool value = true;
92};
93
94// Declarations below.
95template<typename Value_>
96constexpr auto get_value(const Value_);
97
98template<typename Value_>
99constexpr auto get_max();
100
101template<typename Left_, typename Right_>
102constexpr bool is_greater_than(Left_, Right_);
103
104// Internal function.
105template<bool safe_, typename Max_, Max_ new_max_, typename Value_>
106constexpr auto set_bound_internal(Value_ x) {
107 if constexpr(is_greater_than(get_max<Value_>(), new_max_)) {
108 const auto val = get_value(x);
109 if constexpr(safe_) {
110 if (is_greater_than(val, new_max_)) {
111 throw std::domain_error("input value exceeds the declared upper bound");
112 }
113 }
114 return Bounded<I<decltype(val)>, new_max_>(val);
115 } else {
116 return x;
117 }
118}
136template<typename Max_, Max_ new_max_, typename Value_>
137constexpr auto set_bound(Value_ x) {
138 return set_bound_internal<true, Max_, new_max_>(x);
139}
140
153template<typename MaxType_, typename Value_>
154constexpr auto set_bound_by_type(Value_ x) {
156}
157
169template<typename Max_, Max_ new_max_, typename Value_>
170constexpr auto set_bound_unsafe(Value_ x) {
171 return set_bound_internal<false, Max_, new_max_>(x);
172}
173
184template<typename MaxType_, typename Value_>
185constexpr auto set_bound_by_type_unsafe(Value_ x) {
187}
188
192// Back-compatibility.
193template<typename Integer_, Integer_ max_>
194using Attestation = Bounded<Integer_, max_>;
195
196template<typename ... Args_>
197using is_Attestation = is_Bounded<Args_...>;
198
199template<typename Max_, Max_ new_max_, typename Value_>
200constexpr auto attest_max(Value_ x) { return set_bound<Max_, new_max_, Value_>(x); }
201
202template<typename MaxType_, typename Value_>
203constexpr auto attest_max_by_type(Value_ x) { return set_bound_by_type<MaxType_, Value_>(x); }
204
205template<typename Value_>
206Value_ attest_gez(Value_ x) { return x; }
211}
212
213#endif
Sanitize sizes to avoid integer overflow.
Definition Bounded.hpp:15
constexpr bool is_greater_than(Left_ left, Right_ right)
Definition comparisons.hpp:91
constexpr auto get_value(const Value_ x)
Definition generics.hpp:23
constexpr auto set_bound_unsafe(Value_ x)
Definition Bounded.hpp:170
constexpr auto get_max()
Definition generics.hpp:39
constexpr auto set_bound_by_type(Value_ x)
Definition Bounded.hpp:154
constexpr auto set_bound_by_type_unsafe(Value_ x)
Definition Bounded.hpp:185
constexpr auto set_bound(Value_ x)
Definition Bounded.hpp:137
Bound the maximum possible value of an integer.
Definition Bounded.hpp:29
static constexpr Integer_ max
Definition Bounded.hpp:50
constexpr Bounded(Integer_ x)
Definition Bounded.hpp:37
Integer_ Integer
Definition Bounded.hpp:44
Integer_ value
Definition Bounded.hpp:55
Definition Bounded.hpp:64
static constexpr bool value
Definition Bounded.hpp:68