#pragma once

template <typename F> class defer_handle {
public:
  defer_handle(defer_handle &&) = delete;
  defer_handle(const defer_handle &) = delete;
  defer_handle &operator=(const defer_handle &) = delete;
  defer_handle &operator=(defer_handle &&) = delete;

  template <typename FF> defer_handle(FF &&f) : clean(std::forward<FF>(f)) {}
  ~defer_handle() { clean(); }

private:
  F clean;
};

template <typename F> defer_handle<F> defer(F &&f) {
  return {std::forward<F>(f)};
}

#ifdef __COUNTER__
#define DEFER(lambda__) const auto &defer_object_##__COUNTER__ = defer([&]() lambda__);
#else
#define DEFER(lambda__) const auto &defer_object_##__LINE__ = defer([&]() lambda__);
#endif