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

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