![]() |
|
|||
File indexing completed on 2025-04-19 08:44:21
0001 /* 0002 * Distributed under the Boost Software License, Version 1.0. 0003 * (See accompanying file LICENSE_1_0.txt or copy at 0004 * https://www.boost.org/LICENSE_1_0.txt) 0005 * 0006 * Copyright (c) 2022 Andrey Semashev 0007 */ 0008 /*! 0009 * \file scope/scope_fail.hpp 0010 * 0011 * This header contains definition of \c scope_fail template. 0012 */ 0013 0014 #ifndef BOOST_SCOPE_SCOPE_FAIL_HPP_INCLUDED_ 0015 #define BOOST_SCOPE_SCOPE_FAIL_HPP_INCLUDED_ 0016 0017 #include <type_traits> 0018 #include <boost/scope/detail/config.hpp> 0019 #include <boost/scope/exception_checker.hpp> 0020 #include <boost/scope/scope_exit.hpp> 0021 #include <boost/scope/detail/is_not_like.hpp> 0022 #include <boost/scope/detail/type_traits/conjunction.hpp> 0023 #include <boost/scope/detail/type_traits/is_invocable.hpp> 0024 #include <boost/scope/detail/header.hpp> 0025 0026 #ifdef BOOST_HAS_PRAGMA_ONCE 0027 #pragma once 0028 #endif 0029 0030 namespace boost { 0031 namespace scope { 0032 0033 template< typename Func, typename Cond > 0034 class scope_fail; 0035 0036 namespace detail { 0037 0038 // Workaround for clang < 5.0 which can't pass scope_fail as a template template parameter from within scope_fail definition 0039 template< typename T > 0040 using is_not_like_scope_fail = detail::is_not_like< T, scope_fail >; 0041 0042 } // namespace detail 0043 0044 /*! 0045 * \brief Scope exit guard that invokes a function upon leaving the scope, if 0046 * a failure condition is satisfied. 0047 * 0048 * The scope guard wraps two function objects: the scope guard action and 0049 * a failure condition for invoking the action. Both function objects must 0050 * be callable with no arguments and can be one of: 0051 * 0052 * \li A user-defined class with a public `operator()`. 0053 * \li An lvalue reference to such class. 0054 * \li An lvalue reference or pointer to function taking no arguments. 0055 * 0056 * The condition function object `operator()` must return a value 0057 * contextually convertible to \c true, if the failure is detected and the 0058 * action function object is allowed to be executed, and \c false otherwise. 0059 * Additionally, the failure condition function object `operator()` must not 0060 * throw, as otherwise the action function object may not be called. If not 0061 * specified, the default failure condition checks whether the scope is left 0062 * due to an exception - the action function object will not be called if 0063 * the scope is left normally. 0064 * 0065 * \sa scope_exit 0066 * \sa scope_success 0067 * 0068 * \tparam Func Scope guard action function object type. 0069 * \tparam Cond Scope guard failure condition function object type. 0070 */ 0071 template< typename Func, typename Cond = exception_checker > 0072 class scope_fail : 0073 public scope_exit< Func, Cond > 0074 { 0075 //! \cond 0076 private: 0077 using base_type = scope_exit< Func, Cond >; 0078 0079 //! \endcond 0080 public: 0081 /*! 0082 * \brief Constructs a scope guard with a given callable function object. 0083 * 0084 * **Requires:** \c Func is constructible from \a func. \c Cond is nothrow default-constructible. 0085 * 0086 * **Effects:** Constructs the scope guard as if by calling 0087 * `scope_fail(std::forward< F >(func), Cond(), active)`. 0088 * 0089 * **Throws:** Nothing, unless construction of the function objects throw. 0090 * 0091 * \param func The callable action function object to invoke on destruction. 0092 * \param active Indicates whether the scope guard should be active upon construction. 0093 * 0094 * \post `this->active() == active` 0095 */ 0096 template< 0097 typename F 0098 //! \cond 0099 , typename = typename std::enable_if< detail::conjunction< 0100 std::is_constructible< base_type, F, bool >, 0101 detail::is_not_like_scope_fail< F > 0102 >::value >::type 0103 //! \endcond 0104 > 0105 explicit scope_fail(F&& func, bool active = true) 0106 noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_constructible< base_type, F, bool >::value)) : 0107 base_type(static_cast< F&& >(func), active) 0108 { 0109 } 0110 0111 /*! 0112 * \brief Constructs a scope guard with a given callable action and failure condition function objects. 0113 * 0114 * **Requires:** \c Func is constructible from \a func. \c Cond is constructible from \a cond. 0115 * 0116 * **Effects:** If \c Func is nothrow constructible from `F&&` then constructs \c Func from 0117 * `std::forward< F >(func)`, otherwise constructs from `func`. If \c Cond is 0118 * nothrow constructible from `C&&` then constructs \c Cond from 0119 * `std::forward< C >(cond)`, otherwise constructs from `cond`. 0120 * 0121 * If \c Func or \c Cond construction throws and \a active is \c true, invokes 0122 * \a cond and, if it returns \c true, \a func before returning with the exception. 0123 * 0124 * **Throws:** Nothing, unless construction of the function objects throw. 0125 * 0126 * \param func The callable action function object to invoke on destruction. 0127 * \param cond The callable failure condition function object. 0128 * \param active Indicates whether the scope guard should be active upon construction. 0129 * 0130 * \post `this->active() == active` 0131 */ 0132 template< 0133 typename F, 0134 typename C 0135 //! \cond 0136 , typename = typename std::enable_if< std::is_constructible< base_type, F, C, bool >::value >::type 0137 //! \endcond 0138 > 0139 explicit scope_fail(F&& func, C&& cond, bool active = true) 0140 noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_constructible< base_type, F, C, bool >::value)) : 0141 base_type(static_cast< F&& >(func), static_cast< C&& >(cond), active) 0142 { 0143 } 0144 0145 /*! 0146 * \brief Move-constructs a scope guard. 0147 * 0148 * **Requires:** \c Func and \c Cond are nothrow move-constructible or copy-constructible. 0149 * 0150 * **Effects:** If \c Func is nothrow move-constructible then move-constructs \c Func from 0151 * a member of \a that, otherwise copy-constructs \c Func. If \c Cond is nothrow 0152 * move-constructible then move-constructs \c Cond from a member of \a that, 0153 * otherwise copy-constructs \c Cond. 0154 * 0155 * If \c Func or \c Cond construction throws and `that.active() == true`, invokes 0156 * \c Cond object stored in \a that and, if it returns \c true, \a Func object 0157 * (either the newly constructed one, if its construction succeeded, or the original 0158 * one stored in \a that) before returning with the exception. 0159 * 0160 * If the construction succeeds, marks \a that as inactive. 0161 * 0162 * **Throws:** Nothing, unless move-construction of the function objects throw. 0163 * 0164 * \param that Move source. 0165 * 0166 * \post `that.active() == false` 0167 */ 0168 //! \cond 0169 template< 0170 bool Requires = std::is_move_constructible< base_type >::value, 0171 typename = typename std::enable_if< Requires >::type 0172 > 0173 //! \endcond 0174 scope_fail(scope_fail&& that) 0175 noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_move_constructible< base_type >::value)) : 0176 base_type(static_cast< base_type&& >(that)) 0177 { 0178 } 0179 0180 scope_fail& operator= (scope_fail&&) = delete; 0181 0182 scope_fail(scope_fail const&) = delete; 0183 scope_fail& operator= (scope_fail const&) = delete; 0184 }; 0185 0186 #if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES) 0187 template< typename Func > 0188 explicit scope_fail(Func) -> scope_fail< Func >; 0189 0190 template< typename Func > 0191 explicit scope_fail(Func, bool) -> scope_fail< Func >; 0192 0193 template< 0194 typename Func, 0195 typename Cond, 0196 typename = typename std::enable_if< detail::is_invocable< Cond const& >::value >::type 0197 > 0198 explicit scope_fail(Func, Cond) -> scope_fail< Func, Cond >; 0199 0200 template< 0201 typename Func, 0202 typename Cond, 0203 typename = typename std::enable_if< detail::is_invocable< Cond const& >::value >::type 0204 > 0205 explicit scope_fail(Func, Cond, bool) -> scope_fail< Func, Cond >; 0206 #endif // !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES) 0207 0208 /*! 0209 * \brief Creates a scope fail guard with a given action function object. 0210 * 0211 * **Effects:** Constructs a scope guard as if by calling 0212 * `scope_fail< std::decay_t< F > >(std::forward< F >(func), active)`. 0213 * 0214 * \param func The callable function object to invoke on destruction. 0215 * \param active Indicates whether the scope guard should be active upon construction. 0216 */ 0217 template< typename F > 0218 inline scope_fail< typename std::decay< F >::type > make_scope_fail(F&& func, bool active = true) 0219 noexcept(std::is_nothrow_constructible< 0220 scope_fail< typename std::decay< F >::type >, 0221 F, 0222 bool 0223 >::value) 0224 { 0225 return scope_fail< typename std::decay< F >::type >(static_cast< F&& >(func), active); 0226 } 0227 0228 /*! 0229 * \brief Creates a scope fail with given callable function objects. 0230 * 0231 * **Effects:** Constructs a scope guard as if by calling 0232 * `scope_fail< std::decay_t< F >, std::decay_t< C > >( 0233 * std::forward< F >(func), std::forward< C >(cond), active)`. 0234 * 0235 * \param func The callable action function object to invoke on destruction. 0236 * \param cond The callable failure condition function object. 0237 * \param active Indicates whether the scope guard should be active upon construction. 0238 */ 0239 template< typename F, typename C > 0240 inline 0241 #if !defined(BOOST_SCOPE_DOXYGEN) 0242 typename std::enable_if< 0243 detail::is_invocable< C const& >::value, 0244 scope_fail< typename std::decay< F >::type, typename std::decay< C >::type > 0245 >::type 0246 #else 0247 scope_fail< typename std::decay< F >::type, typename std::decay< C >::type > 0248 #endif 0249 make_scope_fail(F&& func, C&& cond, bool active = true) 0250 noexcept(std::is_nothrow_constructible< 0251 scope_fail< typename std::decay< F >::type, typename std::decay< C >::type >, 0252 F, 0253 C, 0254 bool 0255 >::value) 0256 { 0257 return scope_fail< typename std::decay< F >::type, typename std::decay< C >::type >(static_cast< F&& >(func), static_cast< C&& >(cond), active); 0258 } 0259 0260 } // namespace scope 0261 } // namespace boost 0262 0263 #include <boost/scope/detail/footer.hpp> 0264 0265 #endif // BOOST_SCOPE_SCOPE_FAIL_HPP_INCLUDED_
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |