#ifndef __VEREIGN_CORE_SCOPE_GUARD_HH
#define __VEREIGN_CORE_SCOPE_GUARD_HH

#include <type_traits>
#include <utility>

namespace vereign {
namespace core {

template<typename Func>
class ScopeGuard {
public:
  static_assert(
    std::is_nothrow_constructible<Func, Func&&>::value,
    "func must be nothrow_constructible"
  );

  ScopeGuard(Func&& func) : func_{std::move(func)} {}

  ~ScopeGuard() noexcept {
    func_();
  }

private:
  Func func_;
};

template<typename Func>
auto MakeScopeGuard(Func&& func) -> ScopeGuard<Func> {
  return ScopeGuard<Func>{std::move(func)};
}

}
}

#endif