// MIT License // // Copyright (c) 2017-2021 offa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #pragma once #include #include namespace sr::detail { // From P0550 template using remove_cvref = std::remove_cv>; template using remove_cvref_t = typename remove_cvref::type; template struct is_noexcept_dtor : public std::true_type { }; template inline constexpr bool is_noexcept_dtor_v = is_noexcept_dtor::value; template constexpr decltype(auto) forward_if_nothrow_move_constructible(T&& arg) { if constexpr( std::is_nothrow_move_constructible_v == true ) { return std::forward(arg); } return arg; } template class scope_guard_base : private Strategy { public: template, int> = 0, std::enable_if_t<(!std::is_lvalue_reference_v) && std::is_nothrow_constructible_v, int> = 0 > explicit scope_guard_base(EFP&& exitFunction) noexcept(std::is_nothrow_constructible_v || std::is_nothrow_constructible_v) : exitfunction(std::forward(exitFunction)), execute_on_destruction(true) { } template, int> = 0, std::enable_if_t, int> = 0 > explicit scope_guard_base(EFP&& exitFunction) try : exitfunction(exitFunction), execute_on_destruction(true) { } catch( ... ) { exitFunction(); throw; } template || std::is_copy_constructible_v), int> = 0 > scope_guard_base(scope_guard_base&& other) noexcept(std::is_nothrow_move_constructible_v || std::is_nothrow_copy_constructible_v) : Strategy(other), exitfunction(forward_if_nothrow_move_constructible(other.exitfunction)), execute_on_destruction(other.execute_on_destruction) { other.release(); } scope_guard_base(const scope_guard_base&) = delete; ~scope_guard_base() noexcept(is_noexcept_dtor_v) { if( (execute_on_destruction == true) && (this->should_execute() == true) ) { exitfunction(); } } void release() noexcept { execute_on_destruction = false; } scope_guard_base& operator=(const scope_guard_base&) = delete; scope_guard_base& operator=(scope_guard_base&&) = delete; private: EF exitfunction; bool execute_on_destruction; }; }