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

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