Guest User

Untitled

a guest
Dec 13th, 2017
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.38 KB | None | 0 0
  1. /** file mycpp11std.h */
  2.  
  3. #include <limits> // std::numeric_limits
  4.  
  5. namespace mycpp11std {
  6.  
  7. /** Implementation of enable_if from C++11 `std`, taken from
  8. http://en.cppreference.com/w/cpp/types/enable_if.
  9. */
  10. template<bool B, typename T = void>
  11. struct enable_if {};
  12.  
  13. /** Specialization of enable_if from C++11 `std` for `B = true`.
  14. Taken from http://en.cppreference.com/w/cpp/types/enable_if.
  15. */
  16. template<class T>
  17. struct enable_if<true, T> { typedef T type; };
  18.  
  19. /** Implementation of numeric_limits<T>::lowest from C++11 `std`. Returns the most
  20. negative value that can be represented by the type T. */
  21. template <typename T, typename Enable = void>
  22. struct numeric_limits {
  23. static T lowest() {
  24. return -std::numeric_limits<T>::max();
  25. }
  26. };
  27.  
  28. /** Specialization of numeric_limits<T>::lowest for integers. */
  29. template <typename T>
  30. struct numeric_limits<T,
  31. typename enable_if<std::numeric_limits<T>::is_integer >::type> {
  32. static T lowest() {
  33. return std::numeric_limits<T>::min();
  34. }
  35. };
  36.  
  37. } // end namespace mycpp11std
  38.  
  39. /** file range.h */
  40.  
  41. #include <limits> // std::numeric_limits
  42.  
  43. #include "mycpp11std.h"
  44.  
  45. namespace range {
  46.  
  47. /** brief Encapsulates a range of acceptable values by setting a lower and upper
  48. limit.
  49.  
  50. The lower limit may be greater than the upper limit. Single-sided limits can also
  51. be represented by using the `static` functions `no_minimum()` and `no_maximum()`,
  52. which return the minimum and maximum values, respectively, that can be represented
  53. by the type `T`. Guardbands are also supported.
  54. */
  55. template <typename T> class Range {
  56. T lgb; /**< brief the lower guardband */
  57. T ugb; /**< brief the upper guardband */
  58.  
  59. /** brief Make sure lower guardband is positive */
  60. void validate_lgb() { lgb = std::abs(lgb); }
  61.  
  62. /** brief Make sure upper guardband is positive */
  63. void validate_ugb() { ugb = std::abs(ugb); }
  64.  
  65. public:
  66. T lowerlimit; /**< brief the specified lower limit */
  67. T upperlimit; /**< brief the specified upper limit */
  68.  
  69. /** brief Set `lowerlimit` to this value in order to indicate that
  70. there is no lower limit
  71. */
  72. static T no_minimum() {
  73. /* std::numeric_limits<T>::min() is the smallest value, not necessarily
  74. the most negative. */
  75. return mycpp11std::numeric_limits<T>::lowest();
  76. }
  77.  
  78. /** brief Set `upperlimit` to this value in order to indicate that
  79. there is no upper limit
  80. */
  81. static T no_maximum() {
  82. return std::numeric_limits<T>::max();
  83. }
  84.  
  85. /** brief Construct a `Range` with lower and upper limits, and zero
  86. guardbands. */
  87. Range(T lowerlimit, T upperlimit) :
  88. lowerlimit(lowerlimit), upperlimit(upperlimit), lgb(0), ugb(0) {}
  89.  
  90. /** brief Construct a `Range` with lower and upper limits as well as
  91. guardbands. */
  92. Range(T lowerlimit, T upperlimit, T lowerguardband, T upperguardband) :
  93. lowerlimit(lowerlimit), upperlimit(upperlimit),
  94. lgb(lowerguardband), ugb(upperguardband) {
  95. validate_lgb();
  96. validate_ugb();
  97. }
  98.  
  99. /** brief The minimum passing value, defined as the lower limit
  100. plus the lower guardband. */
  101. T min() const { return lowerlimit + lgb; }
  102.  
  103. /** brief The maximum passing value, defined as the upper limit
  104. minus the upper guardband. */
  105. T max() const { return upperlimit - ugb; }
  106.  
  107. /** brief Returns the currently set lower guardband value */
  108. T lowerguardband() const { return lgb; }
  109.  
  110. /** brief Returns the currently set upper guardband value */
  111. T upperguardband() const { return ugb; }
  112.  
  113. /** brief Sets the lower guardband.
  114. param[in] lgb the value to set the lower guardband to. The lower guardband
  115. will be set to the absolute value of `lgb` if it is not positive.
  116. */
  117. void lowerguardband(T lgb) {
  118. this->lgb = lgb;
  119. validate_lgb();
  120. }
  121.  
  122. /** brief Sets the upper guardband.
  123. param[in] ugb the value to set the upper guardband to. The upper guardband
  124. will be set to the absolute value of `ugb` if it is not positive.
  125. */
  126. void upperguardband(T ugb) {
  127. this->ugb = ugb;
  128. validate_ugb();
  129. }
  130. };
  131.  
  132. /** brief Encapsulates a range of acceptable values by setting a lower and upper
  133. limit, as well as a typical value for a parameter.
  134. */
  135. template <typename T> class Parameter : public Range<T> {
  136. public:
  137. T typical; /**< brief the typical value of the Parameter */
  138.  
  139. /** brief Construct a `Parameter` with lower and upper limits and a typical
  140. value, but zero guardbands.
  141. */
  142. Parameter(T lowerlimit, T typical, T upperlimit) :
  143. Range(lowerlimit, upperlimit), typical(typical) {}
  144.  
  145. /** brief Construct a `Parameter` with lower and upper limits and a typical
  146. value, as well as guardbands.
  147. */
  148. Parameter(T lowerlimit, T typical, T upperlimit,
  149. T lower_guardband, T upper_guardband) :
  150. Range(lowerlimit, upperlimit, lower_guardband, upper_guardband),
  151. typical(typical) {}
  152. };
  153.  
  154. /** brief Determines if `value` is within the (possibly guardbanded) limits
  155. (inclusive) set by `range`.
  156. */
  157. template <typename T> bool pass(T value, const Range<T>& range) {
  158. return (value >= range.min()) && (value <= range.max());
  159. }
  160.  
  161. } // end namespace range
  162.  
  163. #include <iostream>
  164. #include <fstream>
  165.  
  166. #include "range.h"
  167.  
  168. using namespace range;
  169.  
  170. void check_guardbands(std::ostream& os) {
  171. Parameter<double> Isc(10, 25, 35);
  172.  
  173. os << "Isc guardbands: " << Isc.lowerguardband() << " and " << Isc.upperguardband() << "n";
  174. os << "Isc min/max: " << Isc.min() << " and " << Isc.max() << "n";
  175. Isc.lowerguardband(-1); Isc.upperguardband(-1);
  176. os << "New Isc guardbands: " << Isc.lowerguardband() << " and " << Isc.upperguardband() << "n";
  177. os << "New Isc min/max: " << Isc.min() << " and " << Isc.max() << "n";
  178. os << "Isc typical: " << Isc.typical << "n";
  179.  
  180. os << "n";
  181. }
  182.  
  183. void check_singlesided(std::ostream& os) {
  184. Parameter<int> CMRR(80, 95, Parameter<int>::no_maximum());
  185. Parameter<int> Power(Parameter<int>::no_minimum(), 80, 150);
  186. Range<unsigned int> Power_hot(Range<unsigned int>::no_minimum(), 135);
  187. Parameter<double> Isupply(Parameter<double>::no_minimum(), 1.7, 2.8);
  188.  
  189. os << "CMRR (int type, no max):n";
  190. os << "minimum = " << CMRR.min() << ", ";
  191. os << "typical = " << CMRR.typical << ", ";
  192. os << "maximum = " << CMRR.max() << "n";
  193. os << "n";
  194.  
  195. os << "Power consumption, ambient (int type, no min):n";
  196. os << "minimum = " << Power.min() << ", ";
  197. os << "typical = " << Power.typical << ", ";
  198. os << "maximum = " << Power.max() << "n";
  199. os << "n";
  200.  
  201. os << "Power consumption, hot (unsigned int type, no min):n";
  202. os << "minimum = " << Power_hot.min() << ", ";
  203. os << "maximum = " << Power_hot.max() << "n";
  204. os << "n";
  205.  
  206. os << "Isupply (double type, no minimum):n";
  207. os << "minimum = " << Isupply.min() << ", ";
  208. os << "typical = " << Isupply.typical << ", ";
  209. os << "maximum = " << Isupply.max() << "n";
  210. os << "n";
  211. }
  212.  
  213. void check_pass(std::ostream& os) {
  214. const Range<double> Isc_temp(10, 40);
  215. const Range<int> zero(0, 0);
  216. Parameter<double> Isc(10, 25, 35);
  217. Parameter<double> Isupply(Parameter<double>::no_minimum(), 1.7, 2.8);
  218. Parameter<int> CMRR(80, 95, Parameter<int>::no_maximum());
  219.  
  220. os << "Testing pass():n";
  221.  
  222. double val = 38;
  223.  
  224. os << val << " is between " << Isc_temp.min() << " and " << Isc_temp.max()
  225. << "?: " << pass<double>(val, Isc_temp) << "n";
  226. os << val << " is between " << Isc.min() << " and " << Isc.max()
  227. << "?: " << pass<double>(val, Isc) << "n";
  228.  
  229. val = 5;
  230. os << val << " is between " << Isc.min() << " and " << Isc.max()
  231. << "?: " << pass<double>(val, Isc) << "n";
  232.  
  233. val = 10;
  234. os << val << " is between " << Isc.min() << " and " << Isc.max()
  235. << "?: " << pass<double>(val, Isc) << "n";
  236.  
  237. val = 2.81;
  238. os << val << " is between " << Isupply.min() << " and " << Isupply.max()
  239. << "?: " << pass<double>(val, Isupply) << "n";
  240. val = 0.1;
  241. os << val << " is between " << Isupply.min() << " and " << Isupply.max()
  242. << "?: " << pass<double>(val, Isupply) << "n";
  243. val = 0;
  244. os << val << " is between " << Isupply.min() << " and " << Isupply.max()
  245. << "?: " << pass<double>(val, Isupply) << "n";
  246. val = -1e3;
  247. os << val << " is between " << Isupply.min() << " and " << Isupply.max()
  248. << "?: " << pass<double>(val, Isupply) << "n";
  249.  
  250. val = 80;
  251. os << val << " is between " << CMRR.min() << " and " << CMRR.max()
  252. << "?: " << pass<int>((int)val, CMRR) << "n";
  253.  
  254. val = 0.1;
  255. os << val << " (double cast to int) is between " << zero.min() << " and " << zero.max()
  256. << "?: " << pass<int>((int)val, zero) << "n";
  257.  
  258. val = 0;
  259. os << val << " (double cast to int) is between " << zero.min() << " and " << zero.max()
  260. << "?: " << pass<int>((int)val, zero) << "n";
  261.  
  262. int intval = 0;
  263. os << intval << " (int type) is between " << zero.min() << " and " << zero.max()
  264. << "?: " << pass<int>(intval, zero) << "n";
  265.  
  266. os << "n";
  267. }
  268.  
  269. int main() {
  270. std::fstream fs("output.txt");
  271. std::ostream& os = fs; // or std::cout
  272. os << std::boolalpha;
  273.  
  274. check_guardbands(os);
  275. check_singlesided(os);
  276. check_pass(os);
  277.  
  278. fs.close();
  279. return 0;
  280. }
  281.  
  282. /** Implementation of numeric_limits<T>::lowest from C++11 `std`. Returns the most
  283. negative value that can be represented by the type T. */
  284. template <typename T, typename Enable = void>
  285. struct numeric_limits {
  286. static T lowest() {
  287. return std::numeric_limits<T>::min();
  288. }
  289. };
Add Comment
Please, Sign In to add comment