RESTinio
Loading...
Searching...
No Matches
overflow_controlled_integer_accumulator.hpp
Go to the documentation of this file.
1/*
2 * RESTinio
3 */
4
12#pragma once
13
15
16#include <type_traits>
17#include <limits>
18
19namespace restinio
20{
21
22namespace impl
23{
24
25//
26// check_positive_extremum
27//
29
30//
31// check_negative_extremum
32//
34
35namespace overflow_controlled_integer_accumulator_details
36{
37
38template< typename T, typename Storage_Type >
40typename std::enable_if< std::is_signed<T>::value, bool >::type
42{
43 return v > maximum;
44}
45
46// If T is unsigned type then this comparison has no sense.
47template< typename T, typename Storage_Type >
49typename std::enable_if< !std::is_signed<T>::value, bool >::type
54
55//
56// extremum_value
57//
58template< typename T, typename Ext >
60
61template< typename T >
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
70template< typename T >
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//
131template<
132 typename T,
133 int Multiplier,
136{
139 T,
141
143 using storage_type = typename extremum_value::storage_type;
144
148 bool m_overflow_detected{ false };
149
150public :
152
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
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
172 }
173
175 bool
180
182 T
184 {
185 return static_cast<T>(m_current);
186 }
187};
188
189} /* namespace restinio */
190
191} /* namespace restinio */
192
Helper class for accumulating integer value during parsing it from string (with check for overflow).
void next_digit(T digit) noexcept
Try to add another digit to the accumulator.
typename extremum_value::storage_type storage_type
Type to be used for holding intermediate value.
bool overflow_detected() const noexcept
Is overflow detected during previous call to next_digit?
Detection of compiler version and absence of various features.
#define RESTINIO_NODISCARD
RESTINIO_NODISCARD std::enable_if< std::is_signed< T >::value, bool >::type is_greater_than_maximum(Storage_Type v, Storage_Type maximum)
run_on_this_thread_settings_t< Traits > on_this_thread()
A special marker for the case when http_server must be run on the context of the current thread.
#define const
Definition zconf.h:230