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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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) {
  46. isOk_ = other.isOk_;
  47. if (other.isOk_) {
  48. new (&v_.val) T(other.v_.val);
  49. } else {
  50. new (&v_.err) T(other.v_.err);
  51. }
  52. }
  53. Result(Result &&other) {
  54. isOk_ = other.isOk_;
  55. if (other.isOk_) {
  56. new (&v_.val) T(std::move(other.v_.val));
  57. } else {
  58. new (&v_.err) T(std::move(other.v_.err));
  59. }
  60. }
  61. ~Result() {
  62. destroy();
  63. }
  64. Result<T, Err> &operator=(const Result<T, Err> &other) {
  65. destroy();
  66. isOk_ = other.isOk_;
  67. if (other.isOk_) {
  68. new (&v_.val) T(other.v_.val);
  69. } else {
  70. new (&v_.err) Err(other.v_.err);
  71. }
  72. return *this;
  73. }
  74. Result<T, Err> &operator=(Result<T, Err> &&other) {
  75. destroy();
  76. isOk_ = other.isOk_;
  77. if (other.isOk_) {
  78. new (&v_.val) T(std::move(other.v_.val));
  79. } else {
  80. new (&v_.err) Err(std::move(other.v_.err));
  81. }
  82. return *this;
  83. }
  84. operator bool() { return isOk_; }
  85. bool isOk() { return isOk_; }
  86. Err &err() { return v_.err; }
  87. T &value() { return v_.val; }
  88. T *operator->() {
  89. return &v_.val;
  90. }
  91. T &operator*() {
  92. return v_.val;
  93. }
  94. private:
  95. void destroy() {
  96. if (isOk_) {
  97. v_.val.~T();
  98. } else {
  99. v_.err.~Err();
  100. }
  101. }
  102. bool isOk_;
  103. union U {
  104. U() {}
  105. U(ResultOk, T &&val): val(std::move(val)) {}
  106. U(ResultOk, const T &val): val(val) {}
  107. U(ResultErr, Err &&err): err(std::move(err)) {}
  108. U(ResultErr, const Err &err): err(err) {}
  109. ~U() {}
  110. T val;
  111. Err err;
  112. } v_;
  113. };
  114. // Calling begin/end is stupid...
  115. template<typename T>
  116. auto callBegin(T &v) {
  117. using namespace std;
  118. return begin(v);
  119. }
  120. template<typename T>
  121. auto callEnd(T &v) {
  122. using namespace std;
  123. return end(v);
  124. }
  125. // Ret can't be a reference, because C++ doesn't support optional<T&>.
  126. template<typename Ret, typename Func = std::function<std::optional<Ret>()>>
  127. class Iter {
  128. public:
  129. class It {
  130. public:
  131. It(std::optional<Ret> next, Func &func): next_(std::move(next)), func_(func) {}
  132. bool operator==(const It &other) const {
  133. return next_ == std::nullopt && other.next_ == std::nullopt;
  134. }
  135. bool operator!=(const It &other) const {
  136. return !(*this == other);
  137. }
  138. void operator++() {
  139. auto val(func_());
  140. if (val)
  141. next_.emplace(std::move(*val));
  142. else
  143. next_.reset();
  144. }
  145. Ret operator*() {
  146. return std::move(*next_);
  147. }
  148. private:
  149. std::optional<Ret> next_;
  150. Func &func_;
  151. };
  152. Iter(Func func): func_(func) {}
  153. operator Iter<Ret, std::function<std::optional<Ret>()>>() {
  154. return Iter<Ret, std::function<std::optional<Ret>()>>(func_);
  155. }
  156. It begin() {
  157. return It(func_(), func_);
  158. }
  159. It end() {
  160. return It(std::nullopt, func_);
  161. }
  162. private:
  163. Func func_;
  164. };
  165. template<typename InputIterator, typename Func>
  166. auto map(InputIterator first, InputIterator last, Func func) {
  167. using RetT = decltype(func(*first));
  168. auto l = [=]() mutable -> std::optional<RetT> {
  169. if (first == last)
  170. return std::nullopt;
  171. RetT r = func(*first);
  172. ++first;
  173. return r;
  174. };
  175. return Iter<RetT, decltype(l)>(l);
  176. }
  177. template<typename Range, typename Func>
  178. auto map(Range &rng, Func func) {
  179. return map(callBegin(rng), callEnd(rng), func);
  180. }
  181. template<typename InputIterator, typename Func>
  182. auto filter(InputIterator first, InputIterator last, Func pred) {
  183. using RetT = std::remove_reference_t<decltype(*first)>;
  184. auto l = [=]() mutable -> std::optional<RetT> {
  185. if (first == last)
  186. return std::nullopt;
  187. while (!pred(*first)) {
  188. ++first;
  189. if (first == last)
  190. return std::nullopt;
  191. }
  192. RetT r = *first;
  193. ++first;
  194. return r;
  195. };
  196. return Iter<RetT, decltype(l)>(l);
  197. }
  198. template<typename Range, typename Func>
  199. auto filter(Range &rng, Func func) {
  200. return filter(callBegin(rng), callEnd(rng), func);
  201. }
  202. template<typename InputIterator, typename Func>
  203. auto mapFilter(InputIterator first, InputIterator last, Func func) {
  204. using RetT = std::remove_reference_t<decltype(*func(*first))>;
  205. auto l = [=]() mutable -> std::optional<RetT> {
  206. if (first == last)
  207. return std::nullopt;
  208. std::optional<RetT> r;
  209. while ((r = func(*first)) == std::nullopt) {
  210. ++first;
  211. if (first == last)
  212. return std::nullopt;
  213. }
  214. ++first;
  215. return r;
  216. };
  217. return Iter<RetT, decltype(l)>(l);
  218. }
  219. template<typename Range, typename Func>
  220. auto mapFilter(Range &rng, Func func) {
  221. return mapFilter(callBegin(rng), callEnd(rng), func);
  222. }
  223. }