utils.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #ifndef UTILS_HPP
  2. #define UTILS_HPP
  3. #include <cstddef>
  4. #include <limits>
  5. #include <type_traits>
  6. #include <iterator>
  7. #include "simple/support/algorithm.hpp"
  8. #include "simple.hpp"
  9. // this was really hard :/
  10. template <typename Range>
  11. class loop
  12. {
  13. public:
  14. using iterator = decltype(std::begin(std::declval<Range>()));
  15. using difference_type = typename std::iterator_traits<iterator>::difference_type;
  16. using value_type = typename std::iterator_traits<iterator>::value_type;
  17. using pointer = typename std::iterator_traits<iterator>::pointer;
  18. using reference = typename std::iterator_traits<iterator>::reference;
  19. using iterator_category = typename std::iterator_traits<iterator>::iterator_category;
  20. constexpr loop(Range range, iterator current) :
  21. range(range), current(current), count_(0)
  22. { }
  23. constexpr loop(Range range) :
  24. range(range), current(std::begin(range)), count_(0)
  25. { }
  26. constexpr auto operator*() const
  27. { return *current; }
  28. constexpr auto operator->() const
  29. { return current.operator->(); }
  30. constexpr auto operator*()
  31. { return *current; }
  32. constexpr auto operator->()
  33. { return current.operator->(); }
  34. constexpr loop& operator++()
  35. {
  36. ++current;
  37. if(current == std::end(range))
  38. {
  39. current = std::begin(range);
  40. ++count_;
  41. }
  42. return *this;
  43. }
  44. constexpr loop operator++(int)
  45. {
  46. loop ret = loop(range, current);
  47. operator++();
  48. return ret;
  49. }
  50. constexpr loop& operator--()
  51. {
  52. if(current == std::begin(range))
  53. {
  54. current = std::end(range);
  55. ++count_;
  56. }
  57. --current;
  58. return *this;
  59. }
  60. constexpr loop operator--(int)
  61. {
  62. loop ret = loop(range, current);
  63. operator--();
  64. return ret;
  65. }
  66. constexpr loop& operator+=(difference_type d)
  67. {
  68. const iterator begin = std::begin(range);
  69. const iterator end = std::end(range);
  70. const difference_type size = std::distance(begin, end);
  71. const difference_type current_index = std::distance(begin, current);
  72. auto new_index = current_index + d;
  73. count_ += new_index/size;
  74. current = begin + simple::support::wrap(new_index % size, size);
  75. return *this;
  76. }
  77. constexpr loop& operator-=(difference_type d)
  78. {
  79. return *this += -d;
  80. }
  81. constexpr friend loop operator+(const loop& one, difference_type d)
  82. {
  83. return loop(one) += d;
  84. }
  85. constexpr friend loop operator+(difference_type d, const loop& one)
  86. {
  87. return loop(one) += d;
  88. }
  89. constexpr friend loop operator-(const loop& one, difference_type d)
  90. {
  91. return loop(one) -= d;
  92. }
  93. constexpr friend loop operator-(difference_type d, const loop& one)
  94. {
  95. return loop(one) -= d;
  96. }
  97. constexpr friend bool operator==(const loop& one, const loop& other)
  98. {
  99. return one.range == other.range && one.current == other.current;
  100. }
  101. constexpr friend bool operator!=(const loop& one, const loop& other)
  102. {
  103. return !(one == other);
  104. }
  105. constexpr operator iterator()
  106. {
  107. return current;
  108. }
  109. constexpr void reset()
  110. {
  111. current = std::begin(range);
  112. count_ = 0;
  113. }
  114. int count() { return count_; }
  115. private:
  116. Range range;
  117. iterator current;
  118. int count_;
  119. };
  120. class random_access_istream_iterator // more or less
  121. {
  122. // TODO:
  123. };
  124. template <typename Range>
  125. constexpr auto center(const Range& area)
  126. {
  127. return (area.upper() - area.lower())/2;
  128. }
  129. template <typename Object, typename Area>
  130. constexpr auto center(const Object& object, const Area& area)
  131. {
  132. return center(area) - center(object);
  133. }
  134. void outline(const graphical::surface&, graphical::color, range2D);
  135. void lowlight(const graphical::surface&, graphical::color, range2D, int2 dim = int2(2,1));
  136. void outline_lowlight(const graphical::surface&, graphical::color, range2D, int2 dim = int2(2,2));
  137. template <typename ExtractedDuration, typename Duration>
  138. ExtractedDuration extract_duration(Duration& duration)
  139. {
  140. auto extracted = std::chrono::duration_cast<ExtractedDuration>(duration);
  141. duration -= extracted;
  142. return extracted;
  143. }
  144. template <typename... SplitDuration, typename Duration>
  145. std::tuple<SplitDuration...> split_duration(Duration duration)
  146. {
  147. return { extract_duration<SplitDuration>(duration)... };
  148. };
  149. #endif /* end of include guard */