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.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #pragma once
  2. #include <optional>
  3. #include <functional>
  4. #include <memory>
  5. #include <chrono>
  6. #include <type_traits>
  7. namespace Swan {
  8. // Inherit from this class to make a class non-copyable
  9. class NonCopyable {
  10. protected:
  11. NonCopyable() = default;
  12. NonCopyable(NonCopyable &&) = default;
  13. NonCopyable(const NonCopyable &) = delete;
  14. NonCopyable &operator=(const NonCopyable &) = delete;
  15. };
  16. template<typename T, typename Del = void (*)(T *)>
  17. using RaiiPtr = std::unique_ptr<T, Del>;
  18. template<typename T, typename Del>
  19. RaiiPtr<T, Del> makeRaiiPtr(T *val, Del d) {
  20. return std::unique_ptr<T, Del>(val, d);
  21. }
  22. template<typename Func>
  23. class Deferred: NonCopyable {
  24. public:
  25. Deferred(Func func): func_(func) {}
  26. Deferred(Deferred &&def) noexcept: func_(def.func_) { def.active_ = false; }
  27. ~Deferred() { if (active_) func_(); }
  28. Deferred &operator=(Deferred &&def) noexcept {
  29. func_ = def.func_;
  30. def.active_ = false;
  31. return *this;
  32. }
  33. private:
  34. Func func_;
  35. bool active_ = true;
  36. };
  37. template<typename Func>
  38. Deferred<Func> makeDeferred(Func func) {
  39. return Deferred(func);
  40. }
  41. // Ret can't be a reference, because C++ doesn't support optional<T&>.
  42. template<typename Ret, typename Func = std::function<std::optional<Ret>()>>
  43. class Iter {
  44. public:
  45. class It {
  46. public:
  47. It(std::optional<Ret> next, Func &func): next_(std::move(next)), func_(func) {}
  48. bool operator==(const It &other) {
  49. return next_ == std::nullopt && other.next_ == std::nullopt;
  50. }
  51. bool operator!=(const It &other) {
  52. return !(*this == other);
  53. }
  54. void operator++() {
  55. next_ = std::move(func_());
  56. }
  57. Ret operator*() {
  58. return std::move(*next_);
  59. }
  60. private:
  61. std::optional<Ret> next_;
  62. Func &func_;
  63. };
  64. Iter(Func func): func_(func) {}
  65. operator Iter<Ret, std::function<std::optional<Ret>()>>() {
  66. return Iter<Ret, std::function<std::optional<Ret>()>>(func_);
  67. }
  68. It begin() {
  69. return It(func_(), func_);
  70. }
  71. It end() {
  72. return It(std::nullopt, func_);
  73. }
  74. private:
  75. Func func_;
  76. };
  77. template<typename InputIterator, typename Func>
  78. auto map(InputIterator first, InputIterator last, Func func) {
  79. using RetT = decltype(func(*first));
  80. auto l = [=]() mutable -> std::optional<RetT> {
  81. if (first == last)
  82. return std::nullopt;
  83. RetT r = func(*first);
  84. ++first;
  85. return r;
  86. };
  87. return Iter<RetT, decltype(l)>(l);
  88. }
  89. template<typename InputIterator, typename Func>
  90. auto filter(InputIterator first, InputIterator last, Func pred) {
  91. using RetT = std::remove_reference_t<decltype(*first)>;
  92. auto l = [=]() mutable -> std::optional<RetT> {
  93. if (first == last)
  94. return std::nullopt;
  95. while (!pred(*first)) {
  96. ++first;
  97. if (first == last)
  98. return std::nullopt;
  99. }
  100. RetT r = *first;
  101. ++first;
  102. return r;
  103. };
  104. return Iter<RetT, decltype(l)>(l);
  105. }
  106. template<typename InputIterator, typename Func>
  107. auto mapFilter(InputIterator first, InputIterator last, Func func) {
  108. using RetT = std::remove_reference_t<decltype(*func(*first))>;
  109. auto l = [=]() mutable -> std::optional<RetT> {
  110. if (first == last)
  111. return std::nullopt;
  112. std::optional<RetT> r;
  113. while ((r = func(*first)) == std::nullopt) {
  114. ++first;
  115. if (first == last)
  116. return std::nullopt;
  117. }
  118. ++first;
  119. return r;
  120. };
  121. return Iter<RetT, decltype(l)>(l);
  122. }
  123. }