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 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #pragma once
  2. #include <optional>
  3. #include <functional>
  4. #include <memory>
  5. #include <chrono>
  6. #include <type_traits>
  7. #include <string>
  8. #include <stddef.h>
  9. namespace Swan {
  10. // Inherit from this class to make a class non-copyable
  11. class NonCopyable {
  12. public:
  13. NonCopyable(const NonCopyable &) = delete;
  14. NonCopyable(NonCopyable &&) noexcept = default;
  15. NonCopyable &operator=(const NonCopyable &) = delete;
  16. NonCopyable &operator=(NonCopyable &&) = default;
  17. protected:
  18. NonCopyable() = default;
  19. ~NonCopyable() = default;
  20. };
  21. // Take a deleter function, turn it into a class with an operator() for unique_ptr
  22. template<typename T, void (*Func)(T *)>
  23. class CPtrDeleter {
  24. public:
  25. void operator()(T *ptr) { Func(ptr); }
  26. };
  27. // This is just a bit nicer to use than using unique_ptr directly
  28. template<typename T, void (*Func)(T *)>
  29. using CPtr = std::unique_ptr<T, CPtrDeleter<T, Func>>;
  30. // Take a function, run it when the object goes out of scope
  31. template<void (*Func)()>
  32. class Deferred: NonCopyable {
  33. public:
  34. Deferred() = default;
  35. ~Deferred() { Func(); }
  36. };
  37. inline struct ResultOk {} Ok;
  38. inline struct ResultErr {} Err;
  39. // Result type for potential errors
  40. template<typename T, typename Err = std::string>
  41. class Result {
  42. public:
  43. Result(ResultOk, T &&val): isOk_(true), v_(ResultOk{}, std::move(val)) {}
  44. Result(ResultErr, Err &&err): isOk_(false), v_(ResultErr{}, std::move(err)) {}
  45. Result(const Result &other): isOk_(other.isOk_) {
  46. if (isOk_) {
  47. new (&v_.val) T(other.v_.val);
  48. } else {
  49. new (&v_.err) T(other.v_.err);
  50. }
  51. }
  52. Result(Result &&other): isOk_(other.isOk_) {
  53. if (other.isOk_) {
  54. new (&v_.val) T(std::move(other.v_.val));
  55. } else {
  56. new (&v_.err) Err(std::move(other.v_.err));
  57. }
  58. }
  59. ~Result() {
  60. destroy();
  61. }
  62. Result<T, Err> &operator=(const Result<T, Err> &other) {
  63. destroy();
  64. isOk_ = other.isOk_;
  65. if (isOk_) {
  66. new (&v_.val) T(other.v_.val);
  67. } else {
  68. new (&v_.err) Err(other.v_.err);
  69. }
  70. return *this;
  71. }
  72. Result<T, Err> &operator=(Result<T, Err> &&other) {
  73. destroy();
  74. isOk_ = other.isOk_;
  75. if (other.isOk_) {
  76. new (&v_.val) T(std::move(other.v_.val));
  77. } else {
  78. new (&v_.err) Err(std::move(other.v_.err));
  79. }
  80. return *this;
  81. }
  82. explicit operator bool() { return isOk_; }
  83. bool isOk() { return isOk_; }
  84. Err &err() { return v_.err; }
  85. T &value() { return v_.val; }
  86. T *operator->() {
  87. return &v_.val;
  88. }
  89. T &operator*() {
  90. return v_.val;
  91. }
  92. private:
  93. void destroy() {
  94. if (isOk_) {
  95. v_.val.~T();
  96. } else {
  97. v_.err.~Err();
  98. }
  99. }
  100. bool isOk_;
  101. union U {
  102. U() {}
  103. U(ResultOk, T &&val): val(std::move(val)) {}
  104. U(ResultOk, const T &val): val(val) {}
  105. U(ResultErr, Err &&err): err(std::move(err)) {}
  106. U(ResultErr, const Err &err): err(err) {}
  107. ~U() {}
  108. T val;
  109. Err err;
  110. } v_;
  111. };
  112. // Calling begin/end is stupid...
  113. template<typename T>
  114. auto callBegin(T &v) {
  115. using namespace std;
  116. return begin(v);
  117. }
  118. template<typename T>
  119. auto callEnd(T &v) {
  120. using namespace std;
  121. return end(v);
  122. }
  123. // Ret can't be a reference, because C++ doesn't support optional<T&>.
  124. template<typename Ret, typename Func = std::function<std::optional<Ret>()>>
  125. class Iter {
  126. public:
  127. class It {
  128. public:
  129. It(std::optional<Ret> next, Func &func): next_(std::move(next)), func_(func) {}
  130. bool operator==(const It &other) const {
  131. return next_ == std::nullopt && other.next_ == std::nullopt;
  132. }
  133. bool operator!=(const It &other) const {
  134. return !(*this == other);
  135. }
  136. void operator++() {
  137. auto val(func_());
  138. if (val)
  139. next_.emplace(std::move(*val));
  140. else
  141. next_.reset();
  142. }
  143. Ret operator*() {
  144. return std::move(*next_);
  145. }
  146. private:
  147. std::optional<Ret> next_;
  148. Func &func_;
  149. };
  150. Iter(Func func): func_(func) {}
  151. operator Iter<Ret, std::function<std::optional<Ret>()>>() {
  152. return Iter<Ret, std::function<std::optional<Ret>()>>(func_);
  153. }
  154. It begin() {
  155. return It(func_(), func_);
  156. }
  157. It end() {
  158. return It(std::nullopt, func_);
  159. }
  160. private:
  161. Func func_;
  162. };
  163. template<typename InputIterator, typename Func>
  164. auto map(InputIterator first, InputIterator last, Func func) {
  165. using RetT = decltype(func(*first));
  166. auto l = [=]() mutable -> std::optional<RetT> {
  167. if (first == last)
  168. return std::nullopt;
  169. RetT r = func(*first);
  170. ++first;
  171. return r;
  172. };
  173. return Iter<RetT, decltype(l)>(l);
  174. }
  175. template<typename Range, typename Func>
  176. auto map(Range &rng, Func func) {
  177. return map(callBegin(rng), callEnd(rng), func);
  178. }
  179. template<typename InputIterator, typename Func>
  180. auto filter(InputIterator first, InputIterator last, Func pred) {
  181. using RetT = std::remove_reference_t<decltype(*first)>;
  182. auto l = [=]() mutable -> std::optional<RetT> {
  183. if (first == last)
  184. return std::nullopt;
  185. while (!pred(*first)) {
  186. ++first;
  187. if (first == last)
  188. return std::nullopt;
  189. }
  190. RetT r = *first;
  191. ++first;
  192. return r;
  193. };
  194. return Iter<RetT, decltype(l)>(l);
  195. }
  196. template<typename Range, typename Func>
  197. auto filter(Range &rng, Func func) {
  198. return filter(callBegin(rng), callEnd(rng), func);
  199. }
  200. template<typename InputIterator, typename Func>
  201. auto mapFilter(InputIterator first, InputIterator last, Func func) {
  202. using RetT = std::remove_reference_t<decltype(*func(*first))>;
  203. auto l = [=]() mutable -> std::optional<RetT> {
  204. if (first == last)
  205. return std::nullopt;
  206. std::optional<RetT> r;
  207. while ((r = func(*first)) == std::nullopt) {
  208. ++first;
  209. if (first == last)
  210. return std::nullopt;
  211. }
  212. ++first;
  213. return r;
  214. };
  215. return Iter<RetT, decltype(l)>(l);
  216. }
  217. template<typename Range, typename Func>
  218. auto mapFilter(Range &rng, Func func) {
  219. return mapFilter(callBegin(rng), callEnd(rng), func);
  220. }
  221. }