RESTinio
Toggle main menu visibility
Loading...
Searching...
No Matches
restinio
impl
overflow_controlled_integer_accumulator.hpp
Go to the documentation of this file.
1
/*
2
* RESTinio
3
*/
4
5
/*!
6
* @file
7
* @brief Helper for parsing integer values.
8
*
9
* @since v.0.6.2
10
*/
11
12
#
pragma
once
13
14
#
include
<
restinio
/
compiler_features
.
hpp
>
15
16
#
include
<
type_traits
>
17
#
include
<
limits
>
18
19
namespace
restinio
20
{
21
22
namespace
impl
23
{
24
25
//
26
// check_positive_extremum
27
//
28
struct
check_positive_extremum
{};
29
30
//
31
// check_negative_extremum
32
//
33
struct
check_negative_extremum
{};
34
35
namespace
overflow_controlled_integer_accumulator_details
36
{
37
38
template
<
typename
T,
typename
Storage_Type >
39
[[nodiscard]]
40
typename
std::enable_if< std::is_signed<T>::value,
bool
>::
type
41
is_greater_than_maximum
( Storage_Type v, Storage_Type maximum )
42
{
43
return
v > maximum;
44
}
45
46
// If T is unsigned type then this comparison has no sense.
47
template
<
typename
T,
typename
Storage_Type >
48
[[nodiscard]]
49
typename
std::enable_if< !std::is_signed<T>::value,
bool
>::
type
50
is_greater_than_maximum
( Storage_Type, Storage_Type )
51
{
52
return
false
;
53
}
54
55
//
56
// extremum_value
57
//
58
template
<
typename
T,
typename
Ext >
59
struct
extremum_value
;
60
61
template
<
typename
T >
62
struct
extremum_value
< T,
check_positive_extremum
>
63
{
64
using
storage_type
= std::make_unsigned_t<T>;
65
66
static
constexpr
storage_type
value
=
static_cast
<
storage_type
>(
67
std::numeric_limits<T>::max() );
68
};
69
70
template
<
typename
T >
71
struct
extremum_value
< T,
check_negative_extremum
>
72
{
73
static_assert
( std::is_signed<T>::value,
74
"extremum_value<T, check_negative_extremum> is defined only "
75
"for signed numeric types"
);
76
77
using
storage_type
= std::make_unsigned_t<T>;
78
79
static
constexpr
storage_type
value
=
static_cast
<
storage_type
>(
80
std::numeric_limits<T>::min() );
81
82
static_assert
(
83
value
== (
static_cast
<
storage_type
>(std::numeric_limits<T>::max()) + 1u),
84
"The integer representation is expected to be two's complement"
);
85
};
86
87
}
/* namespace overflow_controlled_integer_accumulator_details */
88
89
//
90
// overflow_controlled_integer_accumulator_t
91
//
92
/*!
93
* @brief Helper class for accumulating integer value during parsing
94
* it from string (with check for overflow).
95
*
96
* Usage example:
97
* @code
98
int parse_int(string_view_t str) {
99
overflow_controlled_integer_accumulator_t<int> acc;
100
for(const auto ch : str) {
101
if(!is_digit(ch))
102
throw not_a_digit(ch);
103
acc.next_digit(ch);
104
if(acc.overflow_detected())
105
throw too_big_value();
106
}
107
return acc.value();
108
}
109
* @endcode
110
*
111
* @note
112
* Since v.0.6.6 it can be used for parcing not only decinal numbers,
113
* but also numbers with base of @a Multiplier.
114
*
115
* @note
116
* Since v.0.6.6 it can be used for parsing digits of negative decimal
117
* numbers. In that case it should be used like that:
118
* @code
119
* char ch = next_char();
120
* if('-' == ch) {
121
* // Digits of negative number should be extracted.
122
* overflow_controlled_integer_accumulator_t<
123
* int,
124
* check_negative_extremum > acc;
125
* ...
126
* }
127
* @endcode
128
*
129
* @since v.0.6.2
130
*/
131
template
<
132
typename
T,
133
int
Multiplier,
134
typename
Extremum_Type =
check_positive_extremum
>
135
class
overflow_controlled_integer_accumulator_t
136
{
137
using
extremum_value
=
138
overflow_controlled_integer_accumulator_details
::
extremum_value
<
139
T,
140
Extremum_Type >;
141
142
//! Type to be used for holding intermediate value.
143
using
storage_type
=
typename
extremum_value
::
storage_type
;
144
145
//! The current value of the accumulator.
146
storage_type
m_current
{};
147
//! Overflow detection flag.
148
bool
m_overflow_detected
{
false
};
149
150
public
:
151
//! Try to add another digit to the accumulator.
152
/*!
153
* Value of the accumulator will be changed only if there is no overflow.
154
*/
155
void
156
next_digit
( T digit )
noexcept
157
{
158
using
namespace
overflow_controlled_integer_accumulator_details
;
159
160
constexpr
storage_type
multiplier{
161
static_cast
<
storage_type
>(Multiplier)
162
};
163
164
const
storage_type
updated_value =
m_current
* multiplier +
165
static_cast
<
storage_type
>(digit);
166
167
if
( updated_value <
m_current
||
168
is_greater_than_maximum<T>( updated_value,
extremum_value
::value ) )
169
m_overflow_detected
=
true
;
170
else
171
m_current
= updated_value;
172
}
173
174
//! Is overflow detected during previous call to next_digit?
175
bool
176
overflow_detected
()
const
noexcept
177
{
178
return
m_overflow_detected
;
179
}
180
181
//! Get the current accumulator value.
182
T
183
value
()
const
noexcept
184
{
185
return
static_cast
<T>(
m_current
);
186
}
187
};
188
189
}
/* namespace restinio */
190
191
}
/* namespace restinio */
restinio::impl::overflow_controlled_integer_accumulator_t
Helper class for accumulating integer value during parsing it from string (with check for overflow).
Definition
overflow_controlled_integer_accumulator.hpp:136
restinio::impl::overflow_controlled_integer_accumulator_t::extremum_value
overflow_controlled_integer_accumulator_details::extremum_value< T, Extremum_Type > extremum_value
Definition
overflow_controlled_integer_accumulator.hpp:137
restinio::impl::overflow_controlled_integer_accumulator_t::m_current
storage_type m_current
The current value of the accumulator.
Definition
overflow_controlled_integer_accumulator.hpp:146
restinio::impl::overflow_controlled_integer_accumulator_t::next_digit
void next_digit(T digit) noexcept
Try to add another digit to the accumulator.
Definition
overflow_controlled_integer_accumulator.hpp:156
restinio::impl::overflow_controlled_integer_accumulator_t::storage_type
typename extremum_value::storage_type storage_type
Type to be used for holding intermediate value.
Definition
overflow_controlled_integer_accumulator.hpp:143
restinio::impl::overflow_controlled_integer_accumulator_t::value
T value() const noexcept
Get the current accumulator value.
Definition
overflow_controlled_integer_accumulator.hpp:183
restinio::impl::overflow_controlled_integer_accumulator_t::overflow_detected
bool overflow_detected() const noexcept
Is overflow detected during previous call to next_digit?
Definition
overflow_controlled_integer_accumulator.hpp:176
restinio::impl::overflow_controlled_integer_accumulator_t::m_overflow_detected
bool m_overflow_detected
Overflow detection flag.
Definition
overflow_controlled_integer_accumulator.hpp:148
restinio::impl::overflow_controlled_integer_accumulator_details
Definition
overflow_controlled_integer_accumulator.hpp:36
restinio::impl::overflow_controlled_integer_accumulator_details::is_greater_than_maximum
std::enable_if<!std::is_signed< T >::value, bool >::type is_greater_than_maximum(Storage_Type, Storage_Type)
Definition
overflow_controlled_integer_accumulator.hpp:50
restinio::impl::overflow_controlled_integer_accumulator_details::is_greater_than_maximum
std::enable_if< std::is_signed< T >::value, bool >::type is_greater_than_maximum(Storage_Type v, Storage_Type maximum)
Definition
overflow_controlled_integer_accumulator.hpp:41
restinio::impl
Definition
sendfile_operation_default.ipp:15
restinio
Definition
sendfile_operation_default.ipp:12
restinio::impl::check_negative_extremum
Definition
overflow_controlled_integer_accumulator.hpp:33
restinio::impl::check_positive_extremum
Definition
overflow_controlled_integer_accumulator.hpp:28
restinio::impl::overflow_controlled_integer_accumulator_details::extremum_value
Definition
overflow_controlled_integer_accumulator.hpp:59
restinio::impl::overflow_controlled_integer_accumulator_details::extremum_value< T, check_positive_extremum >
Definition
overflow_controlled_integer_accumulator.hpp:63
restinio::impl::overflow_controlled_integer_accumulator_details::extremum_value< T, check_positive_extremum >::storage_type
std::make_unsigned_t< T > storage_type
Definition
overflow_controlled_integer_accumulator.hpp:64
restinio::impl::overflow_controlled_integer_accumulator_details::extremum_value< T, check_positive_extremum >::value
static constexpr storage_type value
Definition
overflow_controlled_integer_accumulator.hpp:66
restinio::impl::overflow_controlled_integer_accumulator_details::extremum_value< T, check_negative_extremum >
Definition
overflow_controlled_integer_accumulator.hpp:72
restinio::impl::overflow_controlled_integer_accumulator_details::extremum_value< T, check_negative_extremum >::value
static constexpr storage_type value
Definition
overflow_controlled_integer_accumulator.hpp:79
restinio::impl::overflow_controlled_integer_accumulator_details::extremum_value< T, check_negative_extremum >::storage_type
std::make_unsigned_t< T > storage_type
Definition
overflow_controlled_integer_accumulator.hpp:77
Generated by
1.17.0