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

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #pragma once
  2. #include <optional>
  3. #include <functional>
  4. #include <memory>
  5. namespace Swan {
  6. template<typename Func>
  7. class Deferred {
  8. public:
  9. Deferred(Func func): func_(func) {}
  10. Deferred(const Deferred &def) = delete;
  11. Deferred(Deferred &&def) noexcept: func_(def.func_) { def.active_ = false; }
  12. ~Deferred() { if (active_) func_(); }
  13. private:
  14. Func func_;
  15. bool active_ = true;
  16. };
  17. template<typename T, typename Del>
  18. std::unique_ptr<T, Del> makeRaiiPtr(T *val, Del d) {
  19. return std::unique_ptr<T, Del>(val, d);
  20. }
  21. template<typename Func>
  22. Deferred<Func> makeDeferred(Func func) {
  23. return Deferred(func);
  24. }
  25. // Ret can't be a reference, because C++ doesn't support optional<T&>.
  26. template<typename Ret, typename Func = std::function<std::optional<Ret>()>>
  27. class Iter {
  28. public:
  29. class It {
  30. public:
  31. It(std::optional<Ret> next, Func &func): next_(std::move(next)), func_(func) {}
  32. bool operator==(It &other) {
  33. return next_ == std::nullopt && other.next_ == std::nullopt;
  34. }
  35. bool operator!=(It &other) {
  36. return !(*this == other);
  37. }
  38. void operator++() {
  39. next_ = std::move(func_());
  40. }
  41. Ret operator*() {
  42. return std::move(*next_);
  43. }
  44. private:
  45. std::optional<Ret> next_;
  46. Func &func_;
  47. };
  48. Iter(Func func): func_(func) {}
  49. operator Iter<Ret, std::function<std::optional<Ret>()>>() {
  50. return Iter<Ret, std::function<std::optional<Ret>()>>(func_);
  51. }
  52. It begin() {
  53. return It(func_(), func_);
  54. }
  55. It end() {
  56. return It(std::nullopt, func_);
  57. }
  58. private:
  59. Func func_;
  60. };
  61. template<typename InputIterator, typename Func>
  62. auto map(InputIterator first, InputIterator last, Func func) {
  63. using RetT = decltype(func(*first));
  64. auto l = [=]() mutable -> std::optional<RetT> {
  65. if (first == last)
  66. return std::nullopt;
  67. RetT r = func(*first);
  68. first++;
  69. return r;
  70. };
  71. return Iter<RetT, decltype(l)>(l);
  72. }
  73. }