#ifndef ABSL_CLEANUP_CLEANUP_H_
#define ABSL_CLEANUP_CLEANUP_H_
#include <utility>
#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/cleanup/internal/cleanup.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
template <typename Arg, typename Callback = void()>
class ABSL_MUST_USE_RESULT Cleanup final {
static_assert(cleanup_internal::WasDeduced<Arg>(),
"Explicit template parameters are not supported.");
static_assert(cleanup_internal::ReturnsVoid<Callback>(),
"Callbacks that return values are not supported.");
public:
Cleanup(Callback callback) : storage_(std::move(callback)) {}
Cleanup(Cleanup&& other) = default;
void Cancel() && {
ABSL_HARDENING_ASSERT(storage_.IsCallbackEngaged());
storage_.DestroyCallback();
}
void Invoke() && {
ABSL_HARDENING_ASSERT(storage_.IsCallbackEngaged());
storage_.InvokeCallback();
storage_.DestroyCallback();
}
~Cleanup() {
if (storage_.IsCallbackEngaged()) {
storage_.InvokeCallback();
storage_.DestroyCallback();
}
}
private:
cleanup_internal::Storage<Callback> storage_;
};
#if defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION)
template <typename Callback>
Cleanup(Callback callback) -> Cleanup<cleanup_internal::Tag, Callback>;
#endif
template <typename... Args, typename Callback>
absl::Cleanup<cleanup_internal::Tag, Callback> MakeCleanup(Callback callback) {
static_assert(cleanup_internal::WasDeduced<cleanup_internal::Tag, Args...>(),
"Explicit template parameters are not supported.");
static_assert(cleanup_internal::ReturnsVoid<Callback>(),
"Callbacks that return values are not supported.");
return {std::move(callback)};
}
ABSL_NAMESPACE_END
}
#endif