fork download
  1. #ifndef modulus_range_h_
  2. #define modulus_range_h_
  3.  
  4. #include "modulus.h"
  5. /*
  6.  * How do you tell if an hour is between two times?
  7.  * Think about that for a second.
  8.  *
  9.  * Now, how do you tell if an hour is between 11(am) and 2(pm)?
  10.  *
  11.  * Not so easy now, is it?
  12.  *
  13.  * Here's ModulusRange to the rescue!
  14.  *
  15.  * Just give it two Moduluses, a start and an end, and it will tell you
  16.  * if another Modulus is between them
  17.  */
  18. template<typename modulus_base>
  19. class ModulusRange {
  20.  
  21. public:
  22.  
  23. ModulusRange(
  24. modulus_base start=0,
  25. modulus_base end=0 ) :start(start), end(end) {}
  26.  
  27. bool contains(modulus_base elem) const{
  28. /*
  29. There are two cases here:
  30. CASE 1: start < end (mod max_value)
  31. 0 start end max_value
  32. [--------{=============}-----------)
  33. To be in this range, a Modulus needs to be between start and end:
  34.   start <= elem <= end
  35.  
  36. CASE 2: end < start (mod max_value)
  37. 0 end start max_value
  38. [========}-------------{===========)
  39. To be in this range, a Modulus needs to be outside end and start:
  40.  ! (end <= elem <= start)
  41.  
  42. */
  43. if(start < end) {
  44. return start <= elem && elem <= end;
  45. }else{
  46. return start <= elem || elem <= end;
  47. }
  48. }
  49.  
  50. /*
  51.  * Determine if this range overlaps another range
  52.  *
  53.  * That is, if they have any elements in common
  54.  */
  55. bool overlaps(const ModulusRange &other) const{
  56. return this->contains(other.start) ||
  57. other.contains(this->start);
  58. }
  59.  
  60. /**
  61.  * If this range overlaps the other, returns a range representing
  62.  * their overlap.
  63.  *
  64.  * Otherwise, it's going to be jibberish
  65.  */
  66. ModulusRange get_overlap(const ModulusRange &other) const{
  67. if( this->contains(other.start) && this->contains(other.end)){
  68. return other;
  69. }
  70. else if(other.contains(this->start) && other.contains(this->end)){
  71. return *this;
  72. }
  73. else if(this->contains(other.start) ){
  74. return ModulusRange(other.start, this->end);
  75. }
  76. else{
  77. return ModulusRange(this->start, other.end);
  78. }
  79. }
  80.  
  81. /*
  82.  * Returns an element of this range somewhere in the middle
  83.  * of the range
  84.  */
  85. modulus_base get_middle() const{
  86. //this math is wonky because if we average start and end,
  87. //we will end up with an instance outside of this range
  88. //in CASE 2, shown above
  89. return start + (end-start)/2;
  90. }
  91.  
  92. bool operator()(const modulus_base &x) {return contains(x);}
  93.  
  94. public:
  95. /* I am making these class members public. Why? 3 reasons:
  96.  *
  97.  * 1) We aren't going to change them - they're const.
  98.  * Even if we wanted to, we couldn't.
  99.  *
  100.  * 2) They're not really internal to the class
  101.  * They're more like template parameters or hidden arguments
  102.  * to the contains() method. Hiding their access behind
  103.  * unnecessary getter and setters is asinine and adds no
  104.  * value to the class
  105.  *
  106.  * 3) If you want to change a range, you can't
  107.  * Just make another ModulusRange
  108.  * They're easy to make, impossible to modify
  109.  * Just like the integers
  110.  *
  111. */
  112. const modulus_base start;
  113. const modulus_base end;
  114. };
  115.  
  116. #endif
  117.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:4:21: error: modulus.h: No such file or directory
stdout
Standard output is empty