36 using pure_value_t = MetaStruct::decay_t<U>;
67 template<
typename U,
typename V = T,
typename W = T>
69 V lower_bound = std::numeric_limits<T>::min(),
70 W upper_bound = std::numeric_limits<T>::max(),
71 MetaStruct::enable_if_t<MetaStruct::all_are_integral<T, U, V, W>::value and
72 MetaStruct::all_same_sign<T, U, V, W>::value>* = 0) :
73 value_{static_cast<pure_value_t<T>>(value)},
74 lower_bound_{static_cast<pure_value_t<T>>(lower_bound)},
75 upper_bound_{static_cast<pure_value_t<T>>(upper_bound)}{
103 template<
typename U,
typename V = T,
typename W = T>
105 V lower_bound = std::numeric_limits<T>::min(),
106 W upper_bound = std::numeric_limits<T>::max(),
107 MetaStruct::enable_if_t<MetaStruct::all_are_integral<T, U, V, W>::value and
108 std::is_unsigned<pure_value_t<T>>::value and
109 std::is_signed<pure_value_t<U>>::value and
110 std::is_unsigned<pure_value_t<V>>::value and
111 std::is_unsigned<pure_value_t<W>>::value>* = 0) :
112 value_{static_cast<pure_value_t<T>>(value)},
113 lower_bound_{static_cast<pure_value_t<T>>(lower_bound)},
114 upper_bound_{static_cast<pure_value_t<T>>(upper_bound)}{
118 static_cast<uintmax_t
>(std::numeric_limits<T>::min()));
120 static_cast<uintmax_t
>(std::numeric_limits<T>::max()));
121 sparta_assert(
static_cast<uintmax_t
>(upper_bound) >
static_cast<uintmax_t
>(lower_bound));
143 template<
typename U,
typename V = T,
typename W = T>
145 V lower_bound = std::numeric_limits<T>::min(),
146 W upper_bound = std::numeric_limits<T>::max(),
147 MetaStruct::enable_if_t<MetaStruct::all_are_integral<T, U, V, W>::value and
148 std::is_unsigned<pure_value_t<T>>::value and
149 std::is_unsigned<pure_value_t<U>>::value and
150 (std::is_signed<pure_value_t<V>>::value or
151 std::is_signed<pure_value_t<W>>::value)>* = 0) :
152 value_{static_cast<pure_value_t<T>>(value)},
153 lower_bound_{static_cast<pure_value_t<T>>(lower_bound)},
154 upper_bound_{static_cast<pure_value_t<T>>(upper_bound)}{
157 static_cast<uintmax_t
>(lower_bound) >=
158 static_cast<uintmax_t
>(std::numeric_limits<T>::min()));
160 static_cast<uintmax_t
>(upper_bound) <=
161 static_cast<uintmax_t
>(std::numeric_limits<T>::max()));
162 sparta_assert(
static_cast<uintmax_t
>(upper_bound) >
static_cast<uintmax_t
>(lower_bound));
184 template<
typename U,
typename V = T,
typename W = T>
186 V lower_bound = std::numeric_limits<T>::min(),
187 W upper_bound = std::numeric_limits<T>::max(),
188 MetaStruct::enable_if_t<MetaStruct::all_are_integral<T, U, V, W>::value and
189 std::is_unsigned<pure_value_t<T>>::value and
190 std::is_signed<pure_value_t<U>>::value and
191 (std::is_signed<pure_value_t<V>>::value or
192 std::is_signed<pure_value_t<W>>::value)>* = 0) :
193 value_{static_cast<pure_value_t<T>>(value)},
194 lower_bound_{static_cast<pure_value_t<T>>(lower_bound)},
195 upper_bound_{static_cast<pure_value_t<T>>(upper_bound)}{
199 static_cast<uintmax_t
>(lower_bound) >=
200 static_cast<uintmax_t
>(std::numeric_limits<T>::min()));
202 static_cast<uintmax_t
>(upper_bound) <=
203 static_cast<uintmax_t
>(std::numeric_limits<T>::max()));
204 sparta_assert(
static_cast<uintmax_t
>(upper_bound) >
static_cast<uintmax_t
>(lower_bound));
225 template<
typename U,
typename V = T,
typename W = T>
227 V lower_bound = std::numeric_limits<T>::min(),
228 W upper_bound = std::numeric_limits<T>::max(),
229 MetaStruct::enable_if_t<MetaStruct::all_are_integral<T, U, V, W>::value and
230 std::is_signed<pure_value_t<T>>::value and
231 std::is_unsigned<pure_value_t<U>>::value and
232 std::is_signed<pure_value_t<V>>::value and
233 std::is_signed<pure_value_t<W>>::value>* = 0) :
234 value_{static_cast<pure_value_t<T>>(value)},
235 lower_bound_{static_cast<pure_value_t<T>>(lower_bound)},
236 upper_bound_{static_cast<pure_value_t<T>>(upper_bound)}{
238 sparta_assert(
static_cast<intmax_t
>(lower_bound) >=
static_cast<intmax_t
>(std::numeric_limits<T>::min()));
239 sparta_assert(
static_cast<intmax_t
>(upper_bound) <=
static_cast<intmax_t
>(std::numeric_limits<T>::max()));
240 sparta_assert(
static_cast<intmax_t
>(upper_bound) >
static_cast<intmax_t
>(lower_bound));
241 sparta_assert(
static_cast<uintmax_t
>(value) <=
static_cast<uintmax_t
>(std::numeric_limits<T>::max()));
262 template<
typename U,
typename V = T,
typename W = T>
264 V lower_bound = std::numeric_limits<T>::min(),
265 W upper_bound = std::numeric_limits<T>::max(),
266 MetaStruct::enable_if_t<MetaStruct::all_are_integral<T, U, V, W>::value and
267 std::is_signed<pure_value_t<T>>::value and
268 std::is_signed<pure_value_t<U>>::value and
269 (std::is_unsigned<pure_value_t<V>>::value or
270 std::is_unsigned<pure_value_t<W>>::value)>* = 0) :
271 value_{static_cast<pure_value_t<T>>(value)},
272 lower_bound_{static_cast<pure_value_t<T>>(lower_bound)},
273 upper_bound_{static_cast<pure_value_t<T>>(upper_bound)}{
277 static_cast<intmax_t
>(std::numeric_limits<T>::min()));
281 static_cast<uintmax_t
>(std::numeric_limits<T>::max()));
283 if(upper_bound > 0 and lower_bound > 0){
284 sparta_assert(
static_cast<uintmax_t
>(upper_bound) >
static_cast<uintmax_t
>(lower_bound));
306 template<
typename U,
typename V = T,
typename W = T>
308 V lower_bound = std::numeric_limits<T>::min(),
309 W upper_bound = std::numeric_limits<T>::max(),
310 MetaStruct::enable_if_t<MetaStruct::all_are_integral<T, U, V, W>::value and
311 std::is_signed<pure_value_t<T>>::value and
312 std::is_unsigned<pure_value_t<U>>::value and
313 (std::is_unsigned<pure_value_t<V>>::value or
314 std::is_unsigned<pure_value_t<W>>::value)>* = 0) :
315 value_{static_cast<pure_value_t<T>>(value)},
316 lower_bound_{static_cast<pure_value_t<T>>(lower_bound)},
317 upper_bound_{static_cast<pure_value_t<T>>(upper_bound)}{
321 static_cast<intmax_t
>(std::numeric_limits<T>::min()));
325 static_cast<uintmax_t
>(std::numeric_limits<T>::max()));
327 if(upper_bound > 0 and lower_bound > 0){
328 sparta_assert(
static_cast<uintmax_t
>(upper_bound) >
static_cast<uintmax_t
>(lower_bound));
344 template<
typename U,
typename V = T,
typename W = T>
346 V lower_bound = std::numeric_limits<T>::min(),
347 W upper_bound = std::numeric_limits<T>::max(),
348 MetaStruct::enable_if_t<std::is_integral<pure_value_t<T>>::value and
349 (std::is_floating_point<pure_value_t<U>>::value or
350 std::is_floating_point<pure_value_t<V>>::value or
351 std::is_floating_point<pure_value_t<W>>::value)>* = 0){
356 static_assert(!std::is_floating_point<pure_value_t<U>>::value,
357 "Cannot assign a floating-point limit to integral BoundedValue.");
358 static_assert(!std::is_floating_point<pure_value_t<V>>::value,
359 "Cannot assign a floating-point limit to integral BoundedValue.");
360 static_assert(!std::is_floating_point<pure_value_t<W>>::value,
361 "Cannot assign a floating-point limit to integral BoundedValue.");
370 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value and
371 std::is_signed<pure_value_t<T>>::value ==
372 std::is_signed<pure_value_t<U>>::value>* = 0) :
373 value_{static_cast<pure_value_t<T>>(rhs.
getValue())},
374 lower_bound_{static_cast<pure_value_t<T>>(rhs.
getLowerBound())},
375 upper_bound_{static_cast<pure_value_t<T>>(rhs.
getUpperBound())}{
388 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value and
389 std::is_signed<pure_value_t<T>>::value and
390 std::is_unsigned<pure_value_t<U>>::value>* = 0) :
391 value_{static_cast<pure_value_t<T>>(rhs.
getValue())},
392 lower_bound_{static_cast<pure_value_t<T>>(rhs.
getLowerBound())},
393 upper_bound_{static_cast<pure_value_t<T>>(rhs.
getUpperBound())}{
405 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value and
406 std::is_unsigned<pure_value_t<T>>::value and
407 std::is_signed<pure_value_t<U>>::value>* = 0) :
408 value_{static_cast<pure_value_t<T>>(rhs.
getValue())},
409 lower_bound_{static_cast<pure_value_t<T>>(rhs.
getLowerBound())},
410 upper_bound_{static_cast<pure_value_t<T>>(rhs.
getUpperBound())}{
415 static_cast<T
>(rhs.
getLowerBound()) >= std::numeric_limits<T>::min());
417 static_cast<T
>(rhs.
getUpperBound()) <= std::numeric_limits<T>::max());
426 MetaStruct::enable_if_t<std::is_floating_point<pure_value_t<U>>::value and
427 std::is_integral<pure_value_t<T>>::value>* = 0){
429 static_assert(std::is_floating_point<pure_value_t<T>>::value,
430 "Cannot assign a floating-point BoundedValue to integral BoundedValue.");
438 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value and
439 std::is_signed<pure_value_t<T>>::value ==
440 std::is_signed<pure_value_t<U>>::value,
447 value_ =
static_cast<pure_value_t<T>
>(rhs.
getValue());
448 lower_bound_ =
static_cast<pure_value_t<T>
>(rhs.
getLowerBound());
449 upper_bound_ =
static_cast<pure_value_t<T>
>(rhs.
getUpperBound());
458 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value and
459 std::is_signed<pure_value_t<T>>::value and
460 std::is_unsigned<pure_value_t<U>>::value,
466 value_ =
static_cast<pure_value_t<T>
>(rhs.
getValue());
467 lower_bound_ =
static_cast<pure_value_t<T>
>(rhs.
getLowerBound());
468 upper_bound_ =
static_cast<pure_value_t<T>
>(rhs.
getUpperBound());
477 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value and
478 std::is_signed<pure_value_t<U>>::value and
479 std::is_unsigned<pure_value_t<T>>::value,
485 static_cast<T
>(rhs.
getLowerBound()) >= std::numeric_limits<T>::min());
487 static_cast<T
>(rhs.
getUpperBound()) <= std::numeric_limits<T>::max());
489 value_ =
static_cast<pure_value_t<T>
>(rhs.
getValue());
490 lower_bound_ =
static_cast<pure_value_t<T>
>(rhs.
getLowerBound());
491 upper_bound_ =
static_cast<pure_value_t<T>
>(rhs.
getUpperBound());
500 MetaStruct::enable_if_t<std::is_floating_point<pure_value_t<U>>::value and
501 std::is_integral<pure_value_t<T>>::value,
505 static_assert(std::is_floating_point<pure_value_t<T>>::value,
506 "Cannot assign a floating-point BoundedValue to integral BoundedValue.");
514 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value,
518 value_ =
static_cast<pure_value_t<T>
>(value);
527 MetaStruct::enable_if_t<std::is_floating_point<pure_value_t<U>>::value and
528 std::is_integral<pure_value_t<T>>::value,
532 static_assert(std::is_floating_point<pure_value_t<T>>::value,
533 "Cannot assign a floating-point number to integral BoundedValue.");
541 checkRange_(value_ + 1);
560 checkRange_(value_ - 1);
578 template<
typename U = T>
579 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value,
BoundedValue<T>&>
582 const auto remaining = upper_bound_ - value_;
583 sparta_assert(
static_cast<uintmax_t
>(remaining) >=
static_cast<uintmax_t
>(value),
584 "Adding the right hand side value would violate the upper-bound of this BV.");
588 const auto remaining = value_ - lower_bound_;
589 sparta_assert(
static_cast<uintmax_t
>(-value) <=
static_cast<uintmax_t
>(remaining),
590 "Adding the right hand side value would violate the lower-bound of this BV.");
599 template<
typename U = T>
600 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value,
BoundedValue<T>&>
603 const auto remaining = value_ - lower_bound_;
604 sparta_assert(
static_cast<uintmax_t
>(remaining) >=
static_cast<uintmax_t
>(value),
605 "Deducting the right hand side value would violate the lower-bound of this BV.");
609 const auto remaining = upper_bound_ - value_;
610 sparta_assert(
static_cast<uintmax_t
>(-value) <=
static_cast<uintmax_t
>(remaining),
611 "Deducting the right hand side value would violate the upper-bound of this BV.");
668 operator const value_type& ()
const{
676 operator value_type& (){
689 void checkRange_(
const U & value)
const{
690 checkLowerBound_<U>(value);
691 checkUpperBound_<U>(value);
700 MetaStruct::enable_if_t<std::is_signed<pure_value_t<U>>::value ==
701 std::is_signed<pure_value_t<T>>::value,
void>
702 checkLowerBound_(
const U& value)
const{
712 MetaStruct::enable_if_t<std::is_unsigned<pure_value_t<U>>::value and
713 std::is_signed<pure_value_t<T>>::value,
void>
714 checkLowerBound_(
const U& value)
const{
715 if(lower_bound_ >= 0){
716 sparta_assert(value >=
static_cast<uintmax_t
>(lower_bound_));
726 MetaStruct::enable_if_t<std::is_signed<pure_value_t<U>>::value and
727 std::is_unsigned<pure_value_t<T>>::value,
void>
728 checkLowerBound_(
const U& value)
const{
729 sparta_assert((value >= 0) && (
static_cast<uintmax_t
>(value) >= lower_bound_));
738 MetaStruct::enable_if_t<std::is_signed<pure_value_t<U>>::value ==
739 std::is_signed<pure_value_t<T>>::value,
void>
740 checkUpperBound_(
const U& value)
const{
750 MetaStruct::enable_if_t<std::is_unsigned<pure_value_t<U>>::value and
751 std::is_signed<T>::value,
void>
752 checkUpperBound_(
const U& value)
const{
753 sparta_assert((upper_bound_ >= 0) && (value <=
static_cast<uintmax_t
>(upper_bound_)));
762 MetaStruct::enable_if_t<std::is_signed<pure_value_t<U>>::value and
763 std::is_unsigned<pure_value_t<T>>::value,
void>
764 checkUpperBound_(
const U& value)
const{
765 sparta_assert((value >= 0) && (
static_cast<uintmax_t
>(value) <= upper_bound_));
776inline std::ostream & operator << (std::ostream & os,
Set of macros for Sparta assertions. Caught by the framework.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
This class allows a developer to bound a value within an upper and lower value.
BoundedValue< T > operator++(int)
Overload post-increment operator.
MetaStruct::enable_if_t< std::is_integral< pure_value_t< U > >::value, BoundedValue< T > & > operator+=(U value)
Overload shorthand += operator.
const value_type getUpperBound() const
Return the upper bound value, const version.
BoundedValue(U value, V lower_bound=std::numeric_limits< T >::min(), W upper_bound=std::numeric_limits< T >::max(), MetaStruct::enable_if_t< MetaStruct::all_are_integral< T, U, V, W >::value and MetaStruct::all_same_sign< T, U, V, W >::value > *=0)
Parameterized Constructor from related integral arguments. The 4 variables are BV type,...
BoundedValue(U value, V lower_bound=std::numeric_limits< T >::min(), W upper_bound=std::numeric_limits< T >::max(), MetaStruct::enable_if_t< MetaStruct::all_are_integral< T, U, V, W >::value and std::is_signed< pure_value_t< T > >::value and std::is_signed< pure_value_t< U > >::value and(std::is_unsigned< pure_value_t< V > >::value or std::is_unsigned< pure_value_t< W > >::value)> *=0)
Parameterized Constructor from related integral arguments.
MetaStruct::enable_if_t< std::is_integral< pure_value_t< U > >::value and std::is_signed< pure_value_t< T > >::value==std::is_signed< pure_value_t< U > >::value, BoundedValue< pure_value_t< T > > & > operator=(const BoundedValue< U > &rhs)
Copy Assignment Operator from related integral BV of same sign.
BoundedValue(U value, V lower_bound=std::numeric_limits< T >::min(), W upper_bound=std::numeric_limits< T >::max(), MetaStruct::enable_if_t< MetaStruct::all_are_integral< T, U, V, W >::value and std::is_unsigned< pure_value_t< T > >::value and std::is_signed< pure_value_t< U > >::value and(std::is_signed< pure_value_t< V > >::value or std::is_signed< pure_value_t< W > >::value)> *=0)
Parameterized Constructor from related integral arguments.
BoundedValue(U value, V lower_bound=std::numeric_limits< T >::min(), W upper_bound=std::numeric_limits< T >::max(), MetaStruct::enable_if_t< MetaStruct::all_are_integral< T, U, V, W >::value and std::is_signed< pure_value_t< T > >::value and std::is_unsigned< pure_value_t< U > >::value and(std::is_unsigned< pure_value_t< V > >::value or std::is_unsigned< pure_value_t< W > >::value)> *=0)
Parameterized Constructor from related integral arguments.
BoundedValue< T > & operator++()
Overload pre-increment operator.
BoundedValue< T > operator--(int)
Overload post-decrement operator.
const value_type getLowerBound() const
Return the lower bound value, const version.
value_type getUpperBound()
Return the upper bound value, non-const version.
BoundedValue(U value, V lower_bound=std::numeric_limits< T >::min(), W upper_bound=std::numeric_limits< T >::max(), MetaStruct::enable_if_t< MetaStruct::all_are_integral< T, U, V, W >::value and std::is_unsigned< pure_value_t< T > >::value and std::is_unsigned< pure_value_t< U > >::value and(std::is_signed< pure_value_t< V > >::value or std::is_signed< pure_value_t< W > >::value)> *=0)
Parameterized Constructor from related integral arguments.
BoundedValue< T > & operator--()
Overload pre-decrement operator.
value_type getLowerBound()
Return the lower bound value, non-const version.
BoundedValue(const BoundedValue< U > &rhs, MetaStruct::enable_if_t< std::is_floating_point< pure_value_t< U > >::value and std::is_integral< pure_value_t< T > >::value > *=0)
Copy Constructor from floating-point BV to integral BV.
value_type getValue()
Get the value - non-const version.
BoundedValue(U value, V lower_bound=std::numeric_limits< T >::min(), W upper_bound=std::numeric_limits< T >::max(), MetaStruct::enable_if_t< MetaStruct::all_are_integral< T, U, V, W >::value and std::is_unsigned< pure_value_t< T > >::value and std::is_signed< pure_value_t< U > >::value and std::is_unsigned< pure_value_t< V > >::value and std::is_unsigned< pure_value_t< W > >::value > *=0)
Parameterized Constructor from related integral arguments. The 4 variables are BV type,...
BoundedValue(U value, V lower_bound=std::numeric_limits< T >::min(), W upper_bound=std::numeric_limits< T >::max(), MetaStruct::enable_if_t< MetaStruct::all_are_integral< T, U, V, W >::value and std::is_signed< pure_value_t< T > >::value and std::is_unsigned< pure_value_t< U > >::value and std::is_signed< pure_value_t< V > >::value and std::is_signed< pure_value_t< W > >::value > *=0)
Parameterized Constructor from related integral arguments.
BoundedValue(const BoundedValue< U > &rhs, MetaStruct::enable_if_t< std::is_integral< pure_value_t< U > >::value and std::is_signed< pure_value_t< T > >::value and std::is_unsigned< pure_value_t< U > >::value > *=0)
Copy Constructor from related unsigned integral BV to signed BV.
MetaStruct::enable_if_t< std::is_integral< pure_value_t< U > >::value, BoundedValue< T > & > operator-=(U value)
Overload shorthand -= operator.
BoundedValue(U value, V lower_bound=std::numeric_limits< T >::min(), W upper_bound=std::numeric_limits< T >::max(), MetaStruct::enable_if_t< std::is_integral< pure_value_t< T > >::value and(std::is_floating_point< pure_value_t< U > >::value or std::is_floating_point< pure_value_t< V > >::value or std::is_floating_point< pure_value_t< W > >::value)> *=0)
Parameterized Constructor from related integral arguments.
const value_type getValue() const
Get the value - const version.
BoundedValue(const BoundedValue< U > &rhs, MetaStruct::enable_if_t< std::is_integral< pure_value_t< U > >::value and std::is_unsigned< pure_value_t< T > >::value and std::is_signed< pure_value_t< U > >::value > *=0)
Copy Constructor from related signed integral BV to unsigned BV.
BoundedValue(const BoundedValue< U > &rhs, MetaStruct::enable_if_t< std::is_integral< pure_value_t< U > >::value and std::is_signed< pure_value_t< T > >::value==std::is_signed< pure_value_t< U > >::value > *=0)
Copy Constructor from related integral BV of same sign.
Macros for handling exponential backoff.