/* * Copyright (c) 2017-2023 zhllxt * * author : zhllxt * email : 37792738@qq.com * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * * refrenced from https://github.com/loveyacper/ananas */ #ifndef __ASIO2_DEFER_HPP__ #define __ASIO2_DEFER_HPP__ #if defined(_MSC_VER) && (_MSC_VER >= 1200) #pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include namespace asio2 { class defer { protected: template struct is_callable : std::false_type {}; template struct is_callable&>() ((std::declval())...)), char>, Args...> : std::true_type {}; public: defer() noexcept = default; // movable defer(defer&&) noexcept = default; defer& operator=(defer&&) noexcept = default; // non copyable defer(const defer&) = delete; void operator=(const defer&) = delete; template ::value, int> = 0> defer(Fun&& fun, Args&&... args) { this->fn_ = std::bind(std::forward(fun), std::forward(args)...); } template ::value && is_callable::value, int> = 0> defer(Constructor&& ctor, Destructor&& dtor) { (ctor)(); this->fn_ = std::forward(dtor); } ~defer() noexcept { if (this->fn_) this->fn_(); } protected: std::function fn_; }; #ifndef ASIO2_CONCAT #define ASIO2_CONCAT(a, b) a##b #endif #define ASIO2_MAKE_DEFER(line) ::asio2::defer ASIO2_CONCAT(_asio2_defer_, line) = [&]() #define ASIO2_DEFER ASIO2_MAKE_DEFER(__LINE__) } #endif // !__ASIO2_DEFER_HPP__