on_block_exit.h 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. #pragma once
  2. #include <concepts>
  3. #include <functional>
  4. #include <utility>
  5. namespace jvalidate::detail {
  6. /**
  7. * @brief An object representing a cleanup function, to be called as if it was
  8. * a destructor for the current function scope. Similar to e.g. D-lang's
  9. * scope(exit) or @see https://en.cppreference.com/w/cpp/experimental/scope_exit
  10. *
  11. * Is movable - allowing us to return this scope object from its constructing
  12. * context into the actual owning context that wants to control that scope.
  13. */
  14. class OnBlockExit {
  15. private:
  16. std::function<void()> callback_;
  17. public:
  18. OnBlockExit() = default;
  19. template <typename F>
  20. requires std::constructible_from<std::function<void()>, F>
  21. explicit(false) OnBlockExit(F && callback) : callback_(std::forward<F>(callback)) {}
  22. OnBlockExit(OnBlockExit const &) = delete;
  23. OnBlockExit & operator=(OnBlockExit const &) = delete;
  24. // Must be explicity implemented because function's move ctor is non-destructive
  25. OnBlockExit(OnBlockExit && other) noexcept { std::swap(other.callback_, callback_); }
  26. // Must be explicity implemented because function's move-assign is non-destructive
  27. OnBlockExit & operator=(OnBlockExit && other) noexcept {
  28. std::swap(other.callback_, callback_);
  29. return *this;
  30. }
  31. ~OnBlockExit() {
  32. if (callback_) {
  33. callback_();
  34. }
  35. }
  36. };
  37. }