Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /** file mycpp11std.h */
- #include <limits> // std::numeric_limits
- namespace mycpp11std {
- /** Implementation of enable_if from C++11 `std`, taken from
- http://en.cppreference.com/w/cpp/types/enable_if.
- */
- template<bool B, typename T = void>
- struct enable_if {};
- /** Specialization of enable_if from C++11 `std` for `B = true`.
- Taken from http://en.cppreference.com/w/cpp/types/enable_if.
- */
- template<class T>
- struct enable_if<true, T> { typedef T type; };
- /** Implementation of numeric_limits<T>::lowest from C++11 `std`. Returns the most
- negative value that can be represented by the type T. */
- template <typename T, typename Enable = void>
- struct numeric_limits {
- static T lowest() {
- return -std::numeric_limits<T>::max();
- }
- };
- /** Specialization of numeric_limits<T>::lowest for integers. */
- template <typename T>
- struct numeric_limits<T,
- typename enable_if<std::numeric_limits<T>::is_integer >::type> {
- static T lowest() {
- return std::numeric_limits<T>::min();
- }
- };
- } // end namespace mycpp11std
- /** file range.h */
- #include <limits> // std::numeric_limits
- #include "mycpp11std.h"
- namespace range {
- /** brief Encapsulates a range of acceptable values by setting a lower and upper
- limit.
- The lower limit may be greater than the upper limit. Single-sided limits can also
- be represented by using the `static` functions `no_minimum()` and `no_maximum()`,
- which return the minimum and maximum values, respectively, that can be represented
- by the type `T`. Guardbands are also supported.
- */
- template <typename T> class Range {
- T lgb; /**< brief the lower guardband */
- T ugb; /**< brief the upper guardband */
- /** brief Make sure lower guardband is positive */
- void validate_lgb() { lgb = std::abs(lgb); }
- /** brief Make sure upper guardband is positive */
- void validate_ugb() { ugb = std::abs(ugb); }
- public:
- T lowerlimit; /**< brief the specified lower limit */
- T upperlimit; /**< brief the specified upper limit */
- /** brief Set `lowerlimit` to this value in order to indicate that
- there is no lower limit
- */
- static T no_minimum() {
- /* std::numeric_limits<T>::min() is the smallest value, not necessarily
- the most negative. */
- return mycpp11std::numeric_limits<T>::lowest();
- }
- /** brief Set `upperlimit` to this value in order to indicate that
- there is no upper limit
- */
- static T no_maximum() {
- return std::numeric_limits<T>::max();
- }
- /** brief Construct a `Range` with lower and upper limits, and zero
- guardbands. */
- Range(T lowerlimit, T upperlimit) :
- lowerlimit(lowerlimit), upperlimit(upperlimit), lgb(0), ugb(0) {}
- /** brief Construct a `Range` with lower and upper limits as well as
- guardbands. */
- Range(T lowerlimit, T upperlimit, T lowerguardband, T upperguardband) :
- lowerlimit(lowerlimit), upperlimit(upperlimit),
- lgb(lowerguardband), ugb(upperguardband) {
- validate_lgb();
- validate_ugb();
- }
- /** brief The minimum passing value, defined as the lower limit
- plus the lower guardband. */
- T min() const { return lowerlimit + lgb; }
- /** brief The maximum passing value, defined as the upper limit
- minus the upper guardband. */
- T max() const { return upperlimit - ugb; }
- /** brief Returns the currently set lower guardband value */
- T lowerguardband() const { return lgb; }
- /** brief Returns the currently set upper guardband value */
- T upperguardband() const { return ugb; }
- /** brief Sets the lower guardband.
- param[in] lgb the value to set the lower guardband to. The lower guardband
- will be set to the absolute value of `lgb` if it is not positive.
- */
- void lowerguardband(T lgb) {
- this->lgb = lgb;
- validate_lgb();
- }
- /** brief Sets the upper guardband.
- param[in] ugb the value to set the upper guardband to. The upper guardband
- will be set to the absolute value of `ugb` if it is not positive.
- */
- void upperguardband(T ugb) {
- this->ugb = ugb;
- validate_ugb();
- }
- };
- /** brief Encapsulates a range of acceptable values by setting a lower and upper
- limit, as well as a typical value for a parameter.
- */
- template <typename T> class Parameter : public Range<T> {
- public:
- T typical; /**< brief the typical value of the Parameter */
- /** brief Construct a `Parameter` with lower and upper limits and a typical
- value, but zero guardbands.
- */
- Parameter(T lowerlimit, T typical, T upperlimit) :
- Range(lowerlimit, upperlimit), typical(typical) {}
- /** brief Construct a `Parameter` with lower and upper limits and a typical
- value, as well as guardbands.
- */
- Parameter(T lowerlimit, T typical, T upperlimit,
- T lower_guardband, T upper_guardband) :
- Range(lowerlimit, upperlimit, lower_guardband, upper_guardband),
- typical(typical) {}
- };
- /** brief Determines if `value` is within the (possibly guardbanded) limits
- (inclusive) set by `range`.
- */
- template <typename T> bool pass(T value, const Range<T>& range) {
- return (value >= range.min()) && (value <= range.max());
- }
- } // end namespace range
- #include <iostream>
- #include <fstream>
- #include "range.h"
- using namespace range;
- void check_guardbands(std::ostream& os) {
- Parameter<double> Isc(10, 25, 35);
- os << "Isc guardbands: " << Isc.lowerguardband() << " and " << Isc.upperguardband() << "n";
- os << "Isc min/max: " << Isc.min() << " and " << Isc.max() << "n";
- Isc.lowerguardband(-1); Isc.upperguardband(-1);
- os << "New Isc guardbands: " << Isc.lowerguardband() << " and " << Isc.upperguardband() << "n";
- os << "New Isc min/max: " << Isc.min() << " and " << Isc.max() << "n";
- os << "Isc typical: " << Isc.typical << "n";
- os << "n";
- }
- void check_singlesided(std::ostream& os) {
- Parameter<int> CMRR(80, 95, Parameter<int>::no_maximum());
- Parameter<int> Power(Parameter<int>::no_minimum(), 80, 150);
- Range<unsigned int> Power_hot(Range<unsigned int>::no_minimum(), 135);
- Parameter<double> Isupply(Parameter<double>::no_minimum(), 1.7, 2.8);
- os << "CMRR (int type, no max):n";
- os << "minimum = " << CMRR.min() << ", ";
- os << "typical = " << CMRR.typical << ", ";
- os << "maximum = " << CMRR.max() << "n";
- os << "n";
- os << "Power consumption, ambient (int type, no min):n";
- os << "minimum = " << Power.min() << ", ";
- os << "typical = " << Power.typical << ", ";
- os << "maximum = " << Power.max() << "n";
- os << "n";
- os << "Power consumption, hot (unsigned int type, no min):n";
- os << "minimum = " << Power_hot.min() << ", ";
- os << "maximum = " << Power_hot.max() << "n";
- os << "n";
- os << "Isupply (double type, no minimum):n";
- os << "minimum = " << Isupply.min() << ", ";
- os << "typical = " << Isupply.typical << ", ";
- os << "maximum = " << Isupply.max() << "n";
- os << "n";
- }
- void check_pass(std::ostream& os) {
- const Range<double> Isc_temp(10, 40);
- const Range<int> zero(0, 0);
- Parameter<double> Isc(10, 25, 35);
- Parameter<double> Isupply(Parameter<double>::no_minimum(), 1.7, 2.8);
- Parameter<int> CMRR(80, 95, Parameter<int>::no_maximum());
- os << "Testing pass():n";
- double val = 38;
- os << val << " is between " << Isc_temp.min() << " and " << Isc_temp.max()
- << "?: " << pass<double>(val, Isc_temp) << "n";
- os << val << " is between " << Isc.min() << " and " << Isc.max()
- << "?: " << pass<double>(val, Isc) << "n";
- val = 5;
- os << val << " is between " << Isc.min() << " and " << Isc.max()
- << "?: " << pass<double>(val, Isc) << "n";
- val = 10;
- os << val << " is between " << Isc.min() << " and " << Isc.max()
- << "?: " << pass<double>(val, Isc) << "n";
- val = 2.81;
- os << val << " is between " << Isupply.min() << " and " << Isupply.max()
- << "?: " << pass<double>(val, Isupply) << "n";
- val = 0.1;
- os << val << " is between " << Isupply.min() << " and " << Isupply.max()
- << "?: " << pass<double>(val, Isupply) << "n";
- val = 0;
- os << val << " is between " << Isupply.min() << " and " << Isupply.max()
- << "?: " << pass<double>(val, Isupply) << "n";
- val = -1e3;
- os << val << " is between " << Isupply.min() << " and " << Isupply.max()
- << "?: " << pass<double>(val, Isupply) << "n";
- val = 80;
- os << val << " is between " << CMRR.min() << " and " << CMRR.max()
- << "?: " << pass<int>((int)val, CMRR) << "n";
- val = 0.1;
- os << val << " (double cast to int) is between " << zero.min() << " and " << zero.max()
- << "?: " << pass<int>((int)val, zero) << "n";
- val = 0;
- os << val << " (double cast to int) is between " << zero.min() << " and " << zero.max()
- << "?: " << pass<int>((int)val, zero) << "n";
- int intval = 0;
- os << intval << " (int type) is between " << zero.min() << " and " << zero.max()
- << "?: " << pass<int>(intval, zero) << "n";
- os << "n";
- }
- int main() {
- std::fstream fs("output.txt");
- std::ostream& os = fs; // or std::cout
- os << std::boolalpha;
- check_guardbands(os);
- check_singlesided(os);
- check_pass(os);
- fs.close();
- return 0;
- }
- /** Implementation of numeric_limits<T>::lowest from C++11 `std`. Returns the most
- negative value that can be represented by the type T. */
- template <typename T, typename Enable = void>
- struct numeric_limits {
- static T lowest() {
- return std::numeric_limits<T>::min();
- }
- };
Add Comment
Please, Sign In to add comment