123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- #ifndef UTILS_HPP
- #define UTILS_HPP
- #include <cstddef>
- #include <limits>
- #include <type_traits>
- #include <iterator>
- #include "simple/support/algorithm.hpp"
- #include "simple.hpp"
- // this was really hard :/
- template <typename Range>
- class loop
- {
- public:
- using iterator = decltype(std::begin(std::declval<Range>()));
- using difference_type = typename std::iterator_traits<iterator>::difference_type;
- using value_type = typename std::iterator_traits<iterator>::value_type;
- using pointer = typename std::iterator_traits<iterator>::pointer;
- using reference = typename std::iterator_traits<iterator>::reference;
- using iterator_category = typename std::iterator_traits<iterator>::iterator_category;
- constexpr loop(Range range, iterator current) :
- range(range), current(current), count_(0)
- { }
- constexpr loop(Range range) :
- range(range), current(std::begin(range)), count_(0)
- { }
- constexpr auto operator*() const
- { return *current; }
- constexpr auto operator->() const
- { return current.operator->(); }
- constexpr auto operator*()
- { return *current; }
- constexpr auto operator->()
- { return current.operator->(); }
- constexpr loop& operator++()
- {
- ++current;
- if(current == std::end(range))
- {
- current = std::begin(range);
- ++count_;
- }
- return *this;
- }
- constexpr loop operator++(int)
- {
- loop ret = loop(range, current);
- operator++();
- return ret;
- }
- constexpr loop& operator--()
- {
- if(current == std::begin(range))
- {
- current = std::end(range);
- ++count_;
- }
- --current;
- return *this;
- }
- constexpr loop operator--(int)
- {
- loop ret = loop(range, current);
- operator--();
- return ret;
- }
- constexpr loop& operator+=(difference_type d)
- {
- const iterator begin = std::begin(range);
- const iterator end = std::end(range);
- const difference_type size = std::distance(begin, end);
- const difference_type current_index = std::distance(begin, current);
- auto new_index = current_index + d;
- count_ += new_index/size;
- current = begin + simple::support::wrap(new_index % size, size);
- return *this;
- }
- constexpr loop& operator-=(difference_type d)
- {
- return *this += -d;
- }
- constexpr friend loop operator+(const loop& one, difference_type d)
- {
- return loop(one) += d;
- }
- constexpr friend loop operator+(difference_type d, const loop& one)
- {
- return loop(one) += d;
- }
- constexpr friend loop operator-(const loop& one, difference_type d)
- {
- return loop(one) -= d;
- }
- constexpr friend loop operator-(difference_type d, const loop& one)
- {
- return loop(one) -= d;
- }
- constexpr friend bool operator==(const loop& one, const loop& other)
- {
- return one.range == other.range && one.current == other.current;
- }
- constexpr friend bool operator!=(const loop& one, const loop& other)
- {
- return !(one == other);
- }
- constexpr operator iterator()
- {
- return current;
- }
- constexpr void reset()
- {
- current = std::begin(range);
- count_ = 0;
- }
- int count() { return count_; }
- private:
- Range range;
- iterator current;
- int count_;
- };
- class random_access_istream_iterator // more or less
- {
- // TODO:
- };
- template <typename Range>
- constexpr auto center(const Range& area)
- {
- return (area.upper() - area.lower())/2;
- }
- template <typename Object, typename Area>
- constexpr auto center(const Object& object, const Area& area)
- {
- return center(area) - center(object);
- }
- void outline(const graphical::surface&, graphical::color, range2D);
- void lowlight(const graphical::surface&, graphical::color, range2D, int2 dim = int2(2,1));
- void outline_lowlight(const graphical::surface&, graphical::color, range2D, int2 dim = int2(2,2));
- template <typename ExtractedDuration, typename Duration>
- ExtractedDuration extract_duration(Duration& duration)
- {
- auto extracted = std::chrono::duration_cast<ExtractedDuration>(duration);
- duration -= extracted;
- return extracted;
- }
- template <typename... SplitDuration, typename Duration>
- std::tuple<SplitDuration...> split_duration(Duration duration)
- {
- return { extract_duration<SplitDuration>(duration)... };
- };
- #endif /* end of include guard */
|