The Sparta Modeling Framework
Loading...
Searching...
No Matches
BoundedValue.hpp
Go to the documentation of this file.
1// <BoundedValue.hpp> -*- C++ -*-
2
3
13#pragma once
14
15#include <iostream>
16#include <limits>
17#include <algorithm>
18#include <type_traits>
19
22
23namespace sparta{
24namespace utils{
25
31template<typename T>
33public:
34 using value_type = T;
35 template<typename U>
36 using pure_value_t = MetaStruct::decay_t<U>;
37
67 template<typename U, typename V = T, typename W = T>
68 explicit BoundedValue(U value,
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)}{
76 // Sanity checks.
77 sparta_assert(upper_bound > lower_bound);
78 // TODO how can you be a value lower than the min() value for a type?
79 //sparta_assert(lower_bound >= std::numeric_limits<T>::min());
80 sparta_assert(upper_bound <= std::numeric_limits<T>::max());
81
82 // Range check.
83 checkRange_(value);
84 }
85
103 template<typename U, typename V = T, typename W = T>
104 explicit BoundedValue(U value,
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)}{
115 // Sanity checks.
116 sparta_assert(value >= 0);
117 sparta_assert(static_cast<uintmax_t>(lower_bound) >=
118 static_cast<uintmax_t>(std::numeric_limits<T>::min()));
119 sparta_assert(static_cast<uintmax_t>(upper_bound) <=
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));
122
123 // Range check.
124 checkRange_(value);
125 }
126
143 template<typename U, typename V = T, typename W = T>
144 explicit BoundedValue(U value,
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)}{
155 // Sanity checks.
156 sparta_assert(lower_bound >= 0 and
157 static_cast<uintmax_t>(lower_bound) >=
158 static_cast<uintmax_t>(std::numeric_limits<T>::min()));
159 sparta_assert(upper_bound >= 0 and
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));
163
164 // Range check.
165 checkRange_(value);
166 }
167
184 template<typename U, typename V = T, typename W = T>
185 explicit BoundedValue(U value,
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)}{
196 // Sanity checks.
197 sparta_assert(value >= 0);
198 sparta_assert(lower_bound >= 0 and
199 static_cast<uintmax_t>(lower_bound) >=
200 static_cast<uintmax_t>(std::numeric_limits<T>::min()));
201 sparta_assert(upper_bound >= 0 and
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));
205
206 // Range check.
207 checkRange_(value);
208 }
209
225 template<typename U, typename V = T, typename W = T>
226 explicit BoundedValue(U value,
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)}{
237 // Sanity checks.
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()));
242
243 // Range check.
244 checkRange_(value);
245 }
246
262 template<typename U, typename V = T, typename W = T>
263 explicit BoundedValue(U value,
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)}{
274 // Sanity checks.
275 if(lower_bound < 0){
276 sparta_assert(static_cast<intmax_t>(lower_bound) >=
277 static_cast<intmax_t>(std::numeric_limits<T>::min()));
278 }
279 if(upper_bound > 0){
280 sparta_assert(static_cast<uintmax_t>(upper_bound) <=
281 static_cast<uintmax_t>(std::numeric_limits<T>::max()));
282 }
283 if(upper_bound > 0 and lower_bound > 0){
284 sparta_assert(static_cast<uintmax_t>(upper_bound) > static_cast<uintmax_t>(lower_bound));
285 }
286
287 // Range check.
288 checkRange_(value);
289 }
290
306 template<typename U, typename V = T, typename W = T>
307 explicit BoundedValue(U value,
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)}{
318 // Sanity checks.
319 if(lower_bound < 0){
320 sparta_assert(static_cast<intmax_t>(lower_bound) >=
321 static_cast<intmax_t>(std::numeric_limits<T>::min()));
322 }
323 if(upper_bound > 0){
324 sparta_assert(static_cast<uintmax_t>(upper_bound) <=
325 static_cast<uintmax_t>(std::numeric_limits<T>::max()));
326 }
327 if(upper_bound > 0 and lower_bound > 0){
328 sparta_assert(static_cast<uintmax_t>(upper_bound) > static_cast<uintmax_t>(lower_bound));
329 }
330
331 // Range check.
332 checkRange_(value);
333 }
334
344 template<typename U, typename V = T, typename W = T>
345 explicit BoundedValue(U value,
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){
352 (void) value;
353 (void) lower_bound;
354 (void) upper_bound;
355
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.");
362 }
363
368 template<typename U>
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())}{
376
377 // Sanity checks.
378 sparta_assert(rhs.getLowerBound() >= std::numeric_limits<T>::min());
379 sparta_assert(rhs.getUpperBound() <= std::numeric_limits<T>::max());
380 }
381
386 template<typename U>
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())}{
394
395 // Sanity check.
396 sparta_assert(rhs.getUpperBound() <= static_cast<U>(std::numeric_limits<T>::max()));
397 }
398
403 template<typename U>
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())}{
411
412 // Sanity checks.
413 sparta_assert(rhs.getValue() >= 0);
414 sparta_assert(rhs.getLowerBound() >= 0 and
415 static_cast<T>(rhs.getLowerBound()) >= std::numeric_limits<T>::min());
416 sparta_assert(rhs.getUpperBound() >= 0 and
417 static_cast<T>(rhs.getUpperBound()) <= std::numeric_limits<T>::max());
418 }
419
424 template<typename U>
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){
428 (void)rhs;
429 static_assert(std::is_floating_point<pure_value_t<T>>::value,
430 "Cannot assign a floating-point BoundedValue to integral BoundedValue.");
431 }
432
437 template<typename U>
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,
443 // Sanity checks.
444 sparta_assert(rhs.getLowerBound() >= std::numeric_limits<T>::min());
445 sparta_assert(rhs.getUpperBound() <= std::numeric_limits<T>::max());
446
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());
450 return *this;
451 }
452
457 template<typename U>
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,
463 // Sanity checks.
464 sparta_assert(rhs.getUpperBound() <= static_cast<U>(std::numeric_limits<T>::max()));
465
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());
469 return *this;
470 }
471
476 template<typename U>
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,
482 // Sanity checks.
483 sparta_assert(rhs.getValue() >= 0);
484 sparta_assert(rhs.getLowerBound() >= 0 and
485 static_cast<T>(rhs.getLowerBound()) >= std::numeric_limits<T>::min());
486 sparta_assert(rhs.getUpperBound() >= 0 and
487 static_cast<T>(rhs.getUpperBound()) <= std::numeric_limits<T>::max());
488
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());
492 return *this;
493 }
494
499 template<typename U>
500 MetaStruct::enable_if_t<std::is_floating_point<pure_value_t<U>>::value and
501 std::is_integral<pure_value_t<T>>::value,
502 void>
504 (void)rhs;
505 static_assert(std::is_floating_point<pure_value_t<T>>::value,
506 "Cannot assign a floating-point BoundedValue to integral BoundedValue.");
507 }
508
513 template<typename U>
514 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value,
516 operator = (U value){
517 checkRange_(value);
518 value_ = static_cast<pure_value_t<T>>(value);
519 return *this;
520 }
521
526 template<typename U>
527 MetaStruct::enable_if_t<std::is_floating_point<pure_value_t<U>>::value and
528 std::is_integral<pure_value_t<T>>::value,
529 void>
530 operator = (U value){
531 (void)value;
532 static_assert(std::is_floating_point<pure_value_t<T>>::value,
533 "Cannot assign a floating-point number to integral BoundedValue.");
534 }
535
540 sparta_assert(value_ < upper_bound_);
541 checkRange_(value_ + 1);
542 ++value_;
543 return *this;
544 }
545
550 BoundedValue<T> copy(*this);
551 ++(*this);
552 return copy;
553 }
554
559 sparta_assert(value_ > lower_bound_);
560 checkRange_(value_ - 1);
561 --value_;
562 return *this;
563 }
564
569 BoundedValue<T> copy(*this);
570 --(*this);
571 return copy;
572 }
573
578 template<typename U = T>
579 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value, BoundedValue<T>&>
580 operator+=(U value){
581 if(value >= 0){
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.");
585 value_ += value;
586 return *this;
587 }
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.");
591 value_ += value;
592 return *this;
593 }
594
599 template<typename U = T>
600 MetaStruct::enable_if_t<std::is_integral<pure_value_t<U>>::value, BoundedValue<T>&>
601 operator-=(U value){
602 if(value >= 0){
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.");
606 value_ -= value;
607 return *this;
608 }
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.");
612 value_ -= value;
613 return *this;
614 }
615
620 const value_type getValue() const{
621 return value_;
622 }
623
628 value_type getValue(){
629 return value_;
630 }
631
636 const value_type getLowerBound() const{
637 return lower_bound_;
638 }
639
644 value_type getLowerBound(){
645 return lower_bound_;
646 }
647
652 const value_type getUpperBound() const{
653 return upper_bound_;
654 }
655
660 value_type getUpperBound(){
661 return upper_bound_;
662 }
663
668 operator const value_type& () const{
669 return value_;
670 }
671
676 operator value_type& (){
677 return value_;
678 }
679private:
680 T value_;
681 T lower_bound_;
682 T upper_bound_;
683
688 template<typename U>
689 void checkRange_(const U & value) const{
690 checkLowerBound_<U>(value);
691 checkUpperBound_<U>(value);
692 }
693
699 template<typename U>
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{
703 sparta_assert(value >= lower_bound_);
704 }
705
711 template<typename U>
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_));
717 }
718 }
719
725 template<typename U>
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_));
730 }
731
737 template<typename U>
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{
741 sparta_assert(value <= upper_bound_);
742 }
743
749 template<typename U>
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_)));
754 }
755
761 template<typename U>
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_));
766 }
767};
768
775template<typename T>
776inline std::ostream & operator << (std::ostream & os,
777 const sparta::utils::BoundedValue<T> & data){
778 os << data.getValue();
779 return os;
780}
781}
782}
Contains a collection implementation of various compile-time metaprogramming and Type-Detection APIs ...
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.