A 2D tile-based sandbox game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

util.h 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #pragma once
  2. #include <optional>
  3. #include <functional>
  4. #include <memory>
  5. #include <chrono>
  6. #include <type_traits>
  7. #include <stddef.h>
  8. namespace Swan {
  9. // Inherit from this class to make a class non-copyable
  10. class NonCopyable {
  11. public:
  12. NonCopyable(const NonCopyable &) = delete;
  13. NonCopyable &operator=(const NonCopyable &) = delete;
  14. NonCopyable(NonCopyable &&) noexcept = default;
  15. protected:
  16. NonCopyable() = default;
  17. ~NonCopyable() = default;
  18. };
  19. // Take a deleter function, turn it into a class with an operator() for unique_ptr
  20. template<typename T, void (*Func)(T *)>
  21. class CPtrDeleter {
  22. public:
  23. void operator()(T *ptr) { Func(ptr); }
  24. };
  25. // This is just a bit nicer to use than using unique_ptr directly
  26. template<typename T, void (*Func)(T *)>
  27. using CPtr = std::unique_ptr<T, CPtrDeleter<T, Func>>;
  28. // Take a function, run it when the object goes out of scope
  29. template<void (*Func)()>
  30. class Deferred: NonCopyable {
  31. public:
  32. Deferred() = default;
  33. ~Deferred() { Func(); }
  34. };
  35. // Calling begin/end is stupid...
  36. template<typename T>
  37. auto callBegin(T &v) {
  38. using namespace std;
  39. return begin(v);
  40. }
  41. template<typename T>
  42. auto callEnd(T &v) {
  43. using namespace std;
  44. return end(v);
  45. }
  46. // Ret can't be a reference, because C++ doesn't support optional<T&>.
  47. template<typename Ret, typename Func = std::function<std::optional<Ret>()>>
  48. class Iter {
  49. public:
  50. class It {
  51. public:
  52. It(std::optional<Ret> next, Func &func): next_(std::move(next)), func_(func) {}
  53. bool operator==(const It &other) const {
  54. return next_ == std::nullopt && other.next_ == std::nullopt;
  55. }
  56. bool operator!=(const It &other) const {
  57. return !(*this == other);
  58. }
  59. void operator++() {
  60. auto val(func_());
  61. if (val)
  62. next_.emplace(std::move(*val));
  63. else
  64. next_.reset();
  65. }
  66. Ret operator*() {
  67. return std::move(*next_);
  68. }
  69. private:
  70. std::optional<Ret> next_;
  71. Func &func_;
  72. };
  73. Iter(Func func): func_(func) {}
  74. operator Iter<Ret, std::function<std::optional<Ret>()>>() {
  75. return Iter<Ret, std::function<std::optional<Ret>()>>(func_);
  76. }
  77. It begin() {
  78. return It(func_(), func_);
  79. }
  80. It end() {
  81. return It(std::nullopt, func_);
  82. }
  83. private:
  84. Func func_;
  85. };
  86. template<typename InputIterator, typename Func>
  87. auto map(InputIterator first, InputIterator last, Func func) {
  88. using RetT = decltype(func(*first));
  89. auto l = [=]() mutable -> std::optional<RetT> {
  90. if (first == last)
  91. return std::nullopt;
  92. RetT r = func(*first);
  93. ++first;
  94. return r;
  95. };
  96. return Iter<RetT, decltype(l)>(l);
  97. }
  98. template<typename Range, typename Func>
  99. auto map(Range &rng, Func func) {
  100. return map(callBegin(rng), callEnd(rng), func);
  101. }
  102. template<typename InputIterator, typename Func>
  103. auto filter(InputIterator first, InputIterator last, Func pred) {
  104. using RetT = std::remove_reference_t<decltype(*first)>;
  105. auto l = [=]() mutable -> std::optional<RetT> {
  106. if (first == last)
  107. return std::nullopt;
  108. while (!pred(*first)) {
  109. ++first;
  110. if (first == last)
  111. return std::nullopt;
  112. }
  113. RetT r = *first;
  114. ++first;
  115. return r;
  116. };
  117. return Iter<RetT, decltype(l)>(l);
  118. }
  119. template<typename Range, typename Func>
  120. auto filter(Range &rng, Func func) {
  121. return filter(callBegin(rng), callEnd(rng), func);
  122. }
  123. template<typename InputIterator, typename Func>
  124. auto mapFilter(InputIterator first, InputIterator last, Func func) {
  125. using RetT = std::remove_reference_t<decltype(*func(*first))>;
  126. auto l = [=]() mutable -> std::optional<RetT> {
  127. if (first == last)
  128. return std::nullopt;
  129. std::optional<RetT> r;
  130. while ((r = func(*first)) == std::nullopt) {
  131. ++first;
  132. if (first == last)
  133. return std::nullopt;
  134. }
  135. ++first;
  136. return r;
  137. };
  138. return Iter<RetT, decltype(l)>(l);
  139. }
  140. template<typename Range, typename Func>
  141. auto mapFilter(Range &rng, Func func) {
  142. return mapFilter(callBegin(rng), callEnd(rng), func);
  143. }
  144. }