Blame boost/scope_exit.hpp

Packit 58578d
Packit 58578d
// Copyright (C) 2006-2009, 2012 Alexander Nasonov
Packit 58578d
// Copyright (C) 2012 Lorenzo Caminiti
Packit 58578d
// Distributed under the Boost Software License, Version 1.0
Packit 58578d
// (see accompanying file LICENSE_1_0.txt or a copy at
Packit 58578d
// http://www.boost.org/LICENSE_1_0.txt)
Packit 58578d
// Home at http://www.boost.org/libs/scope_exit
Packit 58578d
Packit 58578d
#ifndef FILE_boost_scope_exit_hpp_INCLUDED
Packit 58578d
#define FILE_boost_scope_exit_hpp_INCLUDED
Packit 58578d
Packit 58578d
#ifndef DOXYGEN
Packit 58578d
Packit 58578d
#include <boost/detail/workaround.hpp>
Packit 58578d
#include <boost/mpl/assert.hpp>
Packit 58578d
#include <boost/mpl/int.hpp>
Packit 58578d
#include <boost/utility/enable_if.hpp>
Packit 58578d
#include <boost/function.hpp>
Packit 58578d
#include <boost/typeof/typeof.hpp>
Packit 58578d
#include <boost/config.hpp>
Packit 58578d
#include <boost/preprocessor/cat.hpp>
Packit 58578d
#include <boost/preprocessor/control/iif.hpp>
Packit 58578d
#include <boost/preprocessor/control/expr_iif.hpp>
Packit 58578d
#include <boost/preprocessor/comparison/equal.hpp>
Packit 58578d
#include <boost/preprocessor/logical/bitor.hpp>
Packit 58578d
#include <boost/preprocessor/logical/bitand.hpp>
Packit 58578d
#include <boost/preprocessor/facilities/empty.hpp>
Packit 58578d
#include <boost/preprocessor/facilities/is_empty.hpp>
Packit 58578d
#include <boost/preprocessor/facilities/identity.hpp>
Packit 58578d
#include <boost/preprocessor/punctuation/comma_if.hpp>
Packit 58578d
#include <boost/preprocessor/punctuation/paren_if.hpp>
Packit 58578d
#include <boost/preprocessor/seq/cat.hpp>
Packit 58578d
#include <boost/preprocessor/seq/size.hpp>
Packit 58578d
#include <boost/preprocessor/seq/to_tuple.hpp>
Packit 58578d
#include <boost/preprocessor/tuple/elem.hpp>
Packit 58578d
#include <boost/preprocessor/tuple/eat.hpp>
Packit 58578d
#include <boost/preprocessor/tuple/to_list.hpp>
Packit 58578d
#include <boost/preprocessor/list/append.hpp>
Packit 58578d
#include <boost/preprocessor/list/fold_left.hpp>
Packit 58578d
#include <boost/preprocessor/list/enum.hpp>
Packit 58578d
#include <boost/preprocessor/list/adt.hpp>
Packit 58578d
#include <boost/preprocessor/list/for_each_i.hpp>
Packit 58578d
#include <boost/preprocessor/detail/is_unary.hpp>
Packit 58578d
Packit 58578d
// PRIVATE/PROTECTED //
Packit 58578d
Packit 58578d
// NOTE: AUX prefix and aux namespace mark "private" symbols that shall be used
Packit 58578d
// only within this library; DETAIL prefix and detail namespace mark "protected"
Packit 58578d
// symbols that can be used by other Boost libraries but not outside Boost.
Packit 58578d
Packit 58578d
// WARNING: BOOST_SCOPE_EXIT_AUX_GCC also used by some regression test.
Packit 58578d
#if defined(__GNUC__) && !defined(BOOST_INTEL)
Packit 58578d
#   define BOOST_SCOPE_EXIT_AUX_GCC (__GNUC__ * 100 + __GNUC_MINOR__)
Packit 58578d
#else
Packit 58578d
#   define BOOST_SCOPE_EXIT_AUX_GCC 0
Packit 58578d
#endif
Packit 58578d
Packit 58578d
#if BOOST_WORKAROUND(BOOST_SCOPE_EXIT_AUX_GCC, BOOST_TESTED_AT(413))
Packit 58578d
#   define BOOST_SCOPE_EXIT_AUX_TPL_GCC_WORKAROUND_01 1
Packit 58578d
#else
Packit 58578d
#   define BOOST_SCOPE_EXIT_AUX_TPL_GCC_WORKAROUND_01 0
Packit 58578d
#endif
Packit 58578d
Packit 58578d
#if BOOST_MSVC
Packit 58578d
#   define BOOST_SCOPE_EXIT_AUX_TYPEOF_THIS_MSVC_WORKAROUND_01 1
Packit 58578d
#else
Packit 58578d
#   define BOOST_SCOPE_EXIT_AUX_TYPEOF_THIS_MSVC_WORKAROUND_01 0
Packit 58578d
#endif
Packit 58578d
Packit 58578d
// MSVC has problems expanding __LINE__ so use (the non standard) __COUNTER__.
Packit 58578d
#ifdef BOOST_MSVC
Packit 58578d
#   define BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER __COUNTER__
Packit 58578d
#else
Packit 58578d
#   define BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER __LINE__
Packit 58578d
#endif
Packit 58578d
Packit 58578d
// Preprocessor "keyword" detection.
Packit 58578d
Packit 58578d
// These are not a local macros, do not #undefine them (these are used by the
Packit 58578d
// ..._BACK macros below).
Packit 58578d
#define this_BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_THISUNDERSCORE_IS (1) /* unary */
Packit 58578d
#define void_BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_VOID_IS (1) /* unary */
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_BACK_(token, checking_postfix) \
Packit 58578d
    BOOST_PP_IS_UNARY(BOOST_PP_CAT(token, checking_postfix))
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_THISUNDERSCORE_BACK(token) \
Packit 58578d
    BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_BACK_(token, \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_THISUNDERSCORE_IS)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_VOID_BACK(token) \
Packit 58578d
    BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_BACK_(token, \
Packit 58578d
            _BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_VOID_IS)
Packit 58578d
Packit 58578d
// Preprocessor "void-list".
Packit 58578d
Packit 58578d
// NOTE: Empty list must always be represented as void (which is also a way to
Packit 58578d
// specify no function parameter) and it can never be empty because (1)
Packit 58578d
// IS_EMPTY(&var) fails (because of the leading non alphanumeric symbol) and
Packit 58578d
// (2) some compilers (MSVC) fail to correctly pass empty macro parameters
Packit 58578d
// even if they support variadic macros. Therefore, always using void to
Packit 58578d
// represent is more portable.
Packit 58578d
Packit 58578d
// Argument: (token1)...
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_FROM_SEQ_(unused, seq) \
Packit 58578d
    BOOST_PP_TUPLE_TO_LIST(BOOST_PP_SEQ_SIZE(seq), BOOST_PP_SEQ_TO_TUPLE(seq))
Packit 58578d
Packit 58578d
// Token: void | token1
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_HANDLE_VOID_( \
Packit 58578d
        is_void_macro, token) \
Packit 58578d
    BOOST_PP_IIF(is_void_macro(token), \
Packit 58578d
        BOOST_PP_NIL \
Packit 58578d
    , \
Packit 58578d
        (token, BOOST_PP_NIL) \
Packit 58578d
    )
Packit 58578d
Packit 58578d
// Token: (a)(b)... | empty | void | token
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_HANDLE_SEQ_( \
Packit 58578d
        is_void_macro, token) \
Packit 58578d
    BOOST_PP_IIF(BOOST_PP_IS_UNARY(token), /* unary paren (a)... */ \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_FROM_SEQ_ \
Packit 58578d
    , \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_HANDLE_VOID_ \
Packit 58578d
    )(is_void_macro, token)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_NEVER_(tokens) \
Packit 58578d
    0 /* void check always returns false */
Packit 58578d
Packit 58578d
#ifdef BOOST_NO_CXX11_VARIADIC_MACROS
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_(is_void_macro, seq) \
Packit 58578d
    BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_HANDLE_SEQ_(is_void_macro, seq)
Packit 58578d
Packit 58578d
// Expand `void | (a)(b)...` to pp-list `NIL | (a, (b, NIL))`.
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(sign) \
Packit 58578d
    BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_( \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_VOID_BACK, sign)
Packit 58578d
Packit 58578d
// Expand `(a)(b)...` to pp-list `(a, (b, NIL))`.
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_NON_VOID_LIST(seq) \
Packit 58578d
    BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_( \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_NEVER_, seq)
Packit 58578d
Packit 58578d
#else // VARIADICS
Packit 58578d
Packit 58578d
// FUTURE: Replace this with BOOST_PP_VARIADIC_SIZE when and if
Packit 58578d
// BOOST_PP_VARIAIDCS detection will match !BOOST_NO_CXX11_VARIADIC_MACROS (for
Packit 58578d
// now Boost.Preprocessor and Boost.Config disagree on detecting compiler
Packit 58578d
// variadic support while this VARIADIC_SIZE works on compilers not detected by
Packit 58578d
// PP).
Packit 58578d
#if BOOST_MSVC
Packit 58578d
#   define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_VARIADIC_SIZE_(...) \
Packit 58578d
        BOOST_PP_CAT(BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_VARIADIC_SIZE_I_(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,),)
Packit 58578d
#else // MSVC
Packit 58578d
#   define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_VARIADIC_SIZE_(...) \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_VARIADIC_SIZE_I_(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,)
Packit 58578d
#endif // MSVC
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_VARIADIC_SIZE_I_(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63, size, ...) size
Packit 58578d
Packit 58578d
// Argument: token1, ...
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_FROM_VARIADIC_(unused, ...) \
Packit 58578d
    BOOST_PP_TUPLE_TO_LIST( \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_VARIADIC_SIZE_( \
Packit 58578d
                    __VA_ARGS__), (__VA_ARGS__))
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_(is_void_macro, ...) \
Packit 58578d
    BOOST_PP_IIF(BOOST_PP_EQUAL( \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_VARIADIC_SIZE_( \
Packit 58578d
                    __VA_ARGS__), 1), \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_HANDLE_SEQ_ \
Packit 58578d
    , \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_FROM_VARIADIC_ \
Packit 58578d
    )(is_void_macro, __VA_ARGS__)
Packit 58578d
Packit 58578d
// Expand `void | (a)(b)... | a, b, ...` to pp-list `NIL | (a, (b, NIL))`.
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(...) \
Packit 58578d
    BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_( \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_VOID_BACK, __VA_ARGS__)
Packit 58578d
Packit 58578d
// Expand `(a)(b)... | a, b, ...` to pp-list `(a, (b, NIL))`.
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PP_NON_VOID_LIST(...) \
Packit 58578d
    BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_( \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_NEVER_, __VA_ARGS__)
Packit 58578d
Packit 58578d
#endif // VARIADICS
Packit 58578d
Packit 58578d
// Steven Watanabe's trick with a modification suggested by Kim Barrett
Packit 58578d
namespace boost { namespace scope_exit { namespace detail {
Packit 58578d
Packit 58578d
// Type of a local BOOST_SCOPE_EXIT_AUX_ARGS variable.
Packit 58578d
// First use in a local scope will declare the BOOST_SCOPE_EXIT_AUX_ARGS
Packit 58578d
// variable, subsequent uses will be resolved as two comparisons
Packit 58578d
// (cmp1 with 0 and cmp2 with BOOST_SCOPE_EXIT_AUX_ARGS).
Packit 58578d
template<int Dummy = 0>
Packit 58578d
struct declared
Packit 58578d
{
Packit 58578d
    void* value;
Packit 58578d
    static int const cmp2 = 0;
Packit 58578d
    friend void operator>(int, declared const&) {}
Packit 58578d
};
Packit 58578d
Packit 58578d
struct undeclared { declared<> dummy[2]; };
Packit 58578d
Packit 58578d
template<int> struct resolve;
Packit 58578d
Packit 58578d
template<>
Packit 58578d
struct resolve<sizeof(declared<>)>
Packit 58578d
{
Packit 58578d
    static const int cmp1 = 0;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<>
Packit 58578d
struct resolve<sizeof(undeclared)>
Packit 58578d
{
Packit 58578d
    template<int>
Packit 58578d
    struct cmp1
Packit 58578d
    {
Packit 58578d
        static int const cmp2 = 0;
Packit 58578d
    };
Packit 58578d
};
Packit 58578d
Packit 58578d
typedef void (*ref_tag)(int&);
Packit 58578d
typedef void (*val_tag)(int );
Packit 58578d
Packit 58578d
template<class T, class Tag> struct member;
Packit 58578d
Packit 58578d
template<class T>
Packit 58578d
struct member<T,ref_tag>
Packit 58578d
{
Packit 58578d
    T& value;
Packit 58578d
#if !BOOST_SCOPE_EXIT_AUX_TPL_GCC_WORKAROUND_01
Packit 58578d
    member(T& ref) : value(ref) {}
Packit 58578d
#endif
Packit 58578d
};
Packit 58578d
Packit 58578d
template<class T>
Packit 58578d
struct member<T,val_tag>
Packit 58578d
{
Packit 58578d
    T value;
Packit 58578d
#if !BOOST_SCOPE_EXIT_AUX_TPL_GCC_WORKAROUND_01
Packit 58578d
    member(T& val) : value(val) {}
Packit 58578d
#endif
Packit 58578d
};
Packit 58578d
Packit 58578d
template<class T> inline T& deref(T* p, ref_tag) { return *p; }
Packit 58578d
template<class T> inline T& deref(T& r, val_tag) { return  r; }
Packit 58578d
Packit 58578d
template<class T>
Packit 58578d
struct wrapper
Packit 58578d
{
Packit 58578d
    typedef T type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<class T> wrapper<T> wrap(T&);
Packit 58578d
Packit 58578d
} } } // namespace
Packit 58578d
Packit 58578d
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
Packit 58578d
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::scope_exit::detail::wrapper, 1)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_ARGS boost_scope_exit_aux_args
Packit 58578d
extern boost::scope_exit::detail::undeclared BOOST_SCOPE_EXIT_AUX_ARGS;
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_GUARD(id)   \
Packit 58578d
    BOOST_PP_CAT(boost_se_guard_, id)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_GUARD_T(id) \
Packit 58578d
    BOOST_PP_CAT(boost_se_guard_t_, id)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PARAMS(id)  \
Packit 58578d
    BOOST_PP_CAT(boost_se_params_, id)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_THIS_T(id)  \
Packit 58578d
    BOOST_PP_CAT(boost_se_this_t_,  id)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_THIS_CAPTURE_T(id) \
Packit 58578d
    BOOST_PP_CAT(boost_se_this_capture_t_,  id)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id) \
Packit 58578d
    BOOST_PP_CAT(boost_se_params_t_, id)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_TAG(id, i) \
Packit 58578d
    BOOST_PP_SEQ_CAT( (boost_se_tag_)(i)(_)(id) )
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_PARAM_THIS(id) \
Packit 58578d
    BOOST_PP_SEQ_CAT( (boost_se_param_this_)(id) )
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_PARAM(id, i, var) \
Packit 58578d
    BOOST_PP_SEQ_CAT( (boost_se_param_)(i)(_)(id) )
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_PARAM_T(id, i, var) \
Packit 58578d
    BOOST_PP_SEQ_CAT( (boost_se_param_t_)(i)(_)(id) )
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(id, i, var) \
Packit 58578d
    BOOST_PP_SEQ_CAT( (boost_se_capture_t_)(i)(_)(id) )
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_WRAPPED(id, i) \
Packit 58578d
    BOOST_PP_SEQ_CAT( (boost_se_wrapped_t_)(i)(_)(id) )
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_DEREF(id, i, var) \
Packit 58578d
    ::boost::scope_exit::detail::deref(var, \
Packit 58578d
            static_cast<BOOST_SCOPE_EXIT_DETAIL_TAG(id, i)>(0))
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_MEMBER(r, id, i, var) \
Packit 58578d
    ::boost::scope_exit::detail::member< \
Packit 58578d
        BOOST_SCOPE_EXIT_DETAIL_PARAM_T(id, i, var), \
Packit 58578d
        BOOST_SCOPE_EXIT_DETAIL_TAG(id, i) \
Packit 58578d
    > BOOST_SCOPE_EXIT_DETAIL_PARAM(id, i, var);
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_ARG_DECL(r, id_ty, i, var) \
Packit 58578d
    BOOST_PP_COMMA_IF(i) \
Packit 58578d
    BOOST_PP_TUPLE_ELEM(2, 1, id_ty) \
Packit 58578d
    BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty)):: \
Packit 58578d
            BOOST_SCOPE_EXIT_DETAIL_PARAM_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
Packit 58578d
                    i, var) \
Packit 58578d
    var
Packit 58578d
 
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_ARG(r, id, i, var) \
Packit 58578d
    BOOST_PP_COMMA_IF(i) \
Packit 58578d
    boost_se_params_->BOOST_SCOPE_EXIT_DETAIL_PARAM(id, i, var).value
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_TAG_DECL(r, id, i, var) \
Packit 58578d
    typedef void (*BOOST_SCOPE_EXIT_DETAIL_TAG(id, i))(int var);
Packit 58578d
Packit 58578d
// Adam Butcher's workaround to deduce `this` type on MSVC revision < 10.
Packit 58578d
// Boost.Typeof for VC71's typeid-based workaround does not work to determine
Packit 58578d
// `this` type due to error C2355 being incorrectly reported. The typical
Packit 58578d
// avoidance strategy implemented below is to make an indirect compile-time
Packit 58578d
// constant by assigning an enum and use that as type-index-- this only works
Packit 58578d
// with the sizeof() approach and not with the typeid() approach. Lorenzo
Packit 58578d
// Caminiti extended this approach to work in type-of emulation mode. This code
Packit 58578d
// is very similar (and somewhat of a duplication) of the code in
Packit 58578d
// boost/typeof/msvc/typeof_impl.hpp). However, this code cannot be integrated
Packit 58578d
// into Boost.Typeof because its final API has to be a `typedef ...` and it
Packit 58578d
// cannot be a `typeof(...)`.
Packit 58578d
#if BOOST_SCOPE_EXIT_AUX_TYPEOF_THIS_MSVC_WORKAROUND_01
Packit 58578d
Packit 58578d
#include <boost/config.hpp>
Packit 58578d
#include <boost/detail/workaround.hpp>
Packit 58578d
#include <boost/mpl/int.hpp>
Packit 58578d
#include <boost/type_traits/is_function.hpp>
Packit 58578d
#include <boost/utility/enable_if.hpp>
Packit 58578d
Packit 58578d
#if defined(BOOST_MSVC)
Packit 58578d
#   include <typeinfo>
Packit 58578d
#endif
Packit 58578d
Packit 58578d
namespace boost { namespace scope_exit { namespace aux {
Packit 58578d
        namespace msvc_typeof_this {
Packit 58578d
Packit 58578d
// compile-time constant code
Packit 58578d
#if defined(BOOST_MSVC) && defined(_MSC_EXTENSIONS)
Packit 58578d
Packit 58578d
template<int N> struct the_counter;
Packit 58578d
Packit 58578d
template<typename T,int N = 5 /* for similarity */>
Packit 58578d
struct encode_counter {
Packit 58578d
    __if_exists(the_counter<N + 256>) {
Packit 58578d
        BOOST_STATIC_CONSTANT(unsigned,
Packit 58578d
            count=(encode_counter<T,N + 257>::count));
Packit 58578d
    }
Packit 58578d
    __if_not_exists(the_counter<N + 256>) {
Packit 58578d
        __if_exists(the_counter<N + 64>) {
Packit 58578d
            BOOST_STATIC_CONSTANT(unsigned,
Packit 58578d
                    count=(encode_counter<T,N + 65>::count));
Packit 58578d
        }
Packit 58578d
        __if_not_exists(the_counter<N + 64>) {
Packit 58578d
            __if_exists(the_counter<N + 16>) {
Packit 58578d
                BOOST_STATIC_CONSTANT(unsigned,
Packit 58578d
                        count=(encode_counter<T,N + 17>::count));
Packit 58578d
            }
Packit 58578d
            __if_not_exists(the_counter<N + 16>) {
Packit 58578d
                __if_exists(the_counter<N + 4>) {
Packit 58578d
                    BOOST_STATIC_CONSTANT(unsigned,
Packit 58578d
                            count=(encode_counter<T,N + 5>::count));
Packit 58578d
                }
Packit 58578d
                __if_not_exists(the_counter<N + 4>) {
Packit 58578d
                    __if_exists(the_counter<N>) {
Packit 58578d
                        BOOST_STATIC_CONSTANT(unsigned,
Packit 58578d
                                count=(encode_counter<T,N + 1>::count));
Packit 58578d
                    }
Packit 58578d
                    __if_not_exists(the_counter<N>) {
Packit 58578d
                        BOOST_STATIC_CONSTANT(unsigned,count=N);
Packit 58578d
                        typedef the_counter<N> type;
Packit 58578d
                    }
Packit 58578d
                }
Packit 58578d
            }
Packit 58578d
        }
Packit 58578d
    }
Packit 58578d
};
Packit 58578d
Packit 58578d
#else // compile-time constant code
Packit 58578d
    
Packit 58578d
template<int N> struct encode_counter : encode_counter<N - 1> {};
Packit 58578d
Packit 58578d
template<> struct encode_counter<0> {};
Packit 58578d
Packit 58578d
#endif // compile-time constant code
Packit 58578d
Packit 58578d
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) // type-of code
Packit 58578d
Packit 58578d
struct msvc_extract_type_default_param {};
Packit 58578d
Packit 58578d
template<typename ID, typename T = msvc_extract_type_default_param>
Packit 58578d
struct msvc_extract_type;
Packit 58578d
Packit 58578d
template<typename ID>
Packit 58578d
struct msvc_extract_type<ID, msvc_extract_type_default_param> {
Packit 58578d
    template<bool>
Packit 58578d
    struct id2type_impl;
Packit 58578d
Packit 58578d
    typedef id2type_impl<true> id2type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<typename ID, typename T>
Packit 58578d
struct msvc_extract_type
Packit 58578d
        : msvc_extract_type<ID, msvc_extract_type_default_param> {
Packit 58578d
    template<>
Packit 58578d
    struct id2type_impl<true> { // VC8.0 specific bug-feature.
Packit 58578d
        typedef T type;
Packit 58578d
    };
Packit 58578d
Packit 58578d
    template<bool>
Packit 58578d
    struct id2type_impl;
Packit 58578d
Packit 58578d
    typedef id2type_impl<true> id2type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<typename T, typename ID>
Packit 58578d
struct msvc_register_type : msvc_extract_type<ID, T> {};
Packit 58578d
Packit 58578d
#else // type-of code
Packit 58578d
Packit 58578d
template<typename ID>
Packit 58578d
struct msvc_extract_type {
Packit 58578d
    struct id2type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<typename T, typename ID>
Packit 58578d
struct msvc_register_type : msvc_extract_type<ID> {
Packit 58578d
    typedef msvc_extract_type<ID> base_type;
Packit 58578d
    struct base_type::id2type { // This uses nice VC6.5 and VC7.1 bug-features.
Packit 58578d
        typedef T type;
Packit 58578d
    };
Packit 58578d
};
Packit 58578d
Packit 58578d
#endif // typeof code
Packit 58578d
Packit 58578d
template<int Id>
Packit 58578d
struct msvc_typeid_wrapper {
Packit 58578d
    typedef typename msvc_extract_type<boost::mpl::int_<Id>
Packit 58578d
            >::id2type id2type;
Packit 58578d
    typedef typename id2type::type type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<>
Packit 58578d
struct msvc_typeid_wrapper<4> {
Packit 58578d
    typedef msvc_typeid_wrapper<4> type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<typename T>
Packit 58578d
struct encode_type {
Packit 58578d
    BOOST_STATIC_CONSTANT(unsigned, value = encode_counter<T>::count);
Packit 58578d
    typedef typename msvc_register_type
Packit 58578d
            boost::mpl::int_<value> >::id2type type;
Packit 58578d
    BOOST_STATIC_CONSTANT(unsigned, next = value + 1);
Packit 58578d
};
Packit 58578d
Packit 58578d
template<class T>
Packit 58578d
struct sizer {
Packit 58578d
    typedef char(*type)[encode_type<T>::value];
Packit 58578d
};
Packit 58578d
Packit 58578d
template<typename T>
Packit 58578d
typename boost::disable_if<
Packit 58578d
      typename boost::is_function<T>::type
Packit 58578d
    , typename sizer<T>::type
Packit 58578d
>::type encode_start(T const&);
Packit 58578d
Packit 58578d
template<typename T>
Packit 58578d
typename boost::enable_if<
Packit 58578d
      typename boost::is_function<T>::type
Packit 58578d
    , typename sizer<T>::type
Packit 58578d
>::type encode_start(T&);
Packit 58578d
Packit 58578d
template<typename Organizer, typename T>
Packit 58578d
msvc_register_type<T, Organizer> typeof_register_type(const T&,
Packit 58578d
        Organizer* = 0);
Packit 58578d
Packit 58578d
} } } } // namespace
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_TYPEDEF_TYPEOF_THIS_INDEX_(id) \
Packit 58578d
    BOOST_PP_CAT(boost_se_thistype_index_, id)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_TYPEDEF_TYPEOF_THIS(id, ty, new_type) \
Packit 58578d
    /* unfortunately, we need to go via this enum which causes this to be */ \
Packit 58578d
    /* a typedef construct and not a typeof (so this code cannot be */ \
Packit 58578d
    /* integrated into Boost.Typeof) */ \
Packit 58578d
    enum { \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_TYPEDEF_TYPEOF_THIS_INDEX_(id) = sizeof( \
Packit 58578d
            *::boost::scope_exit::aux::msvc_typeof_this::encode_start(this)) \
Packit 58578d
    }; \
Packit 58578d
    typedef \
Packit 58578d
        ty ::boost::scope_exit::aux::msvc_typeof_this::msvc_typeid_wrapper< \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_TYPEDEF_TYPEOF_THIS_INDEX_(id) \
Packit 58578d
        >::type \
Packit 58578d
        new_type \
Packit 58578d
    ;
Packit 58578d
Packit 58578d
#else // TYPEOF_THIS_MSVC_WORKAROUND
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_TYPEDEF_TYPEOF_THIS(id, ty, new_type) \
Packit 58578d
    typedef /* trailing `EMPTY()` handles empty `ty` */ \
Packit 58578d
        BOOST_PP_IIF(BOOST_PP_IS_EMPTY(ty BOOST_PP_EMPTY()), \
Packit 58578d
            BOOST_TYPEOF \
Packit 58578d
        , \
Packit 58578d
            BOOST_TYPEOF_TPL \
Packit 58578d
        )(this) \
Packit 58578d
        new_type \
Packit 58578d
    ;
Packit 58578d
Packit 58578d
#endif // TYPEOF_THIS_MSVC_WORKAROUND
Packit 58578d
Packit 58578d
#if BOOST_SCOPE_EXIT_AUX_TPL_GCC_WORKAROUND_01
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PARAMS_T_CTOR(id, ty, captures, has_this) \
Packit 58578d
    /* expand to nothing */
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_PARAM_INIT(r, id, i, var) \
Packit 58578d
    BOOST_PP_COMMA_IF(i) { BOOST_SCOPE_EXIT_AUX_DEREF(id, i, var) }
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PARAMS_INIT(id, captures, has_this) \
Packit 58578d
    BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(has_this, \
Packit 58578d
            BOOST_PP_LIST_IS_CONS(captures)), \
Packit 58578d
        = { \
Packit 58578d
    ) \
Packit 58578d
    BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_DETAIL_PARAM_INIT, id, captures) \
Packit 58578d
    BOOST_PP_COMMA_IF(BOOST_PP_BITAND(BOOST_PP_LIST_IS_CONS(captures), \
Packit 58578d
            has_this)) \
Packit 58578d
    BOOST_PP_EXPR_IIF(has_this, this) /* no extra {...} needed here */ \
Packit 58578d
    BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(has_this, \
Packit 58578d
            BOOST_PP_LIST_IS_CONS(captures)), \
Packit 58578d
        } /* trailing `;` will be added by the caller */ \
Packit 58578d
    )
Packit 58578d
Packit 58578d
#else // TPL_GCC_WORKAROUND
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_CTOR_ARG(r, id, i, var) \
Packit 58578d
    BOOST_PP_COMMA_IF(i) \
Packit 58578d
    BOOST_SCOPE_EXIT_DETAIL_PARAM_T(id, i, var) & BOOST_PP_CAT(a, i)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_MEMBER_INIT(r, id, i, var) \
Packit 58578d
    BOOST_PP_COMMA_IF(i) \
Packit 58578d
    BOOST_SCOPE_EXIT_DETAIL_PARAM(id, i, var) ( BOOST_PP_CAT(a, i) )
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_CTOR_ARG_THIS_NAME(id) \
Packit 58578d
    BOOST_PP_CAT(boost_se_this_arg_, id)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_CTOR_ARG_THIS(id, ty, comma01) \
Packit 58578d
    BOOST_PP_COMMA_IF(comma01) \
Packit 58578d
    ty BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id)::BOOST_SCOPE_EXIT_AUX_THIS_T(id) \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_CTOR_ARG_THIS_NAME(id) /* ptr so no & */
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_MEMBER_THIS_INIT(id, comma01) \
Packit 58578d
    BOOST_PP_COMMA_IF(comma01) \
Packit 58578d
    BOOST_SCOPE_EXIT_DETAIL_PARAM_THIS(id)( \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_CTOR_ARG_THIS_NAME(id))
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PARAMS_T_CTOR(id, ty, captures, has_this) \
Packit 58578d
    BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id)( \
Packit 58578d
        BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_CTOR_ARG, id, captures) \
Packit 58578d
        BOOST_PP_IIF(has_this, \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_CTOR_ARG_THIS \
Packit 58578d
        , \
Packit 58578d
            BOOST_PP_TUPLE_EAT(3) \
Packit 58578d
        )(id, ty, BOOST_PP_LIST_IS_CONS(captures)) \
Packit 58578d
    ) \
Packit 58578d
        BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(BOOST_PP_LIST_IS_CONS(captures), \
Packit 58578d
                has_this), \
Packit 58578d
            : \
Packit 58578d
        ) \
Packit 58578d
        BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_MEMBER_INIT, id, \
Packit 58578d
                captures) \
Packit 58578d
        BOOST_PP_IIF(has_this, \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_MEMBER_THIS_INIT \
Packit 58578d
        , \
Packit 58578d
            BOOST_PP_TUPLE_EAT(2) \
Packit 58578d
        )(id, BOOST_PP_LIST_IS_CONS(captures)) \
Packit 58578d
    {}
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_PARAM_INIT(r, id, i, var) \
Packit 58578d
    BOOST_PP_COMMA_IF(i) BOOST_SCOPE_EXIT_AUX_DEREF(id,i,var)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_PARAMS_INIT(id, captures, has_this) \
Packit 58578d
    BOOST_PP_LPAREN_IF(BOOST_PP_BITOR(has_this, \
Packit 58578d
            BOOST_PP_LIST_IS_CONS(captures))) \
Packit 58578d
    BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_DETAIL_PARAM_INIT, id, captures) \
Packit 58578d
    BOOST_PP_COMMA_IF(BOOST_PP_BITAND(BOOST_PP_LIST_IS_CONS(captures), \
Packit 58578d
            has_this)) \
Packit 58578d
    BOOST_PP_EXPR_IIF(has_this, this) \
Packit 58578d
    BOOST_PP_RPAREN_IF(BOOST_PP_BITOR(has_this, \
Packit 58578d
            BOOST_PP_LIST_IS_CONS(captures)))
Packit 58578d
Packit 58578d
#endif // TPL_GCC_WORKAROUND
Packit 58578d
Packit 58578d
#if defined(BOOST_TYPEOF_EMULATION)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_CAPTURE_DECL(r, id_ty, i, var) \
Packit 58578d
    struct BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), i) \
Packit 58578d
        /* no need to use TYPEOF_TPL here because it's within inheritance */ \
Packit 58578d
        : BOOST_TYPEOF(::boost::scope_exit::detail::wrap( \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_DEREF(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
Packit 58578d
                        i, var))) \
Packit 58578d
    {}; \
Packit 58578d
    typedef BOOST_PP_TUPLE_ELEM(2, 1, id_ty) \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), i)::type\
Packit 58578d
        BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
Packit 58578d
                i, var) \
Packit 58578d
    ;
Packit 58578d
Packit 58578d
#elif defined(BOOST_INTEL)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_CAPTURE_DECL(r, id_ty, i, var) \
Packit 58578d
    typedef \
Packit 58578d
        /* no TYPEOF_TPL here because uses TYPEOF_KEYWORD directly */ \
Packit 58578d
        BOOST_TYPEOF_KEYWORD(BOOST_SCOPE_EXIT_AUX_DEREF( \
Packit 58578d
                BOOST_PP_TUPLE_ELEM(2, 0, id_ty), i, var)) \
Packit 58578d
        BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
Packit 58578d
                i, var) \
Packit 58578d
    ;
Packit 58578d
Packit 58578d
#else
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_CAPTURE_DECL(r, id_ty, i, var) \
Packit 58578d
    typedef \
Packit 58578d
        /* no need to use TYPEOF_TPL here because it's a typedef */ \
Packit 58578d
        BOOST_TYPEOF(::boost::scope_exit::detail::wrap( \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_DEREF(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
Packit 58578d
                        i, var))) \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), i) \
Packit 58578d
    ; \
Packit 58578d
    typedef BOOST_PP_TUPLE_ELEM(2, 1, id_ty) \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), i)::type\
Packit 58578d
        BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
Packit 58578d
                i, var) \
Packit 58578d
    ;
Packit 58578d
Packit 58578d
#endif
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_DETAIL_PARAM_DECL(r, id_ty, i, var) \
Packit 58578d
    typedef \
Packit 58578d
        BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
Packit 58578d
                i, var) \
Packit 58578d
        BOOST_SCOPE_EXIT_DETAIL_PARAM_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
Packit 58578d
                i, var) \
Packit 58578d
    ;
Packit 58578d
Packit 58578d
// Traits.
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_TRAITS_OP_CAPTURE(d, captures, this01, capture) \
Packit 58578d
    (BOOST_PP_LIST_APPEND(captures, (capture, BOOST_PP_NIL)), this01)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_TRAITS_OP_THIS(d, captures, this01, this_) \
Packit 58578d
    (captures, 1 /* has this (note, no error if multiple this_) */)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_TRAITS_OP(d, captures_this, capture) \
Packit 58578d
    BOOST_PP_IIF(BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_THISUNDERSCORE_BACK(\
Packit 58578d
            capture), \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_TRAITS_OP_THIS \
Packit 58578d
    , \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_TRAITS_OP_CAPTURE \
Packit 58578d
    )(d, BOOST_PP_TUPLE_ELEM(2, 0, captures_this), \
Packit 58578d
            BOOST_PP_TUPLE_ELEM(2, 1, captures_this), capture)
Packit 58578d
Packit 58578d
// ref_val: & | =
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_TRAITS_ALL_OP(ref_val, traits) \
Packit 58578d
    ( \
Packit 58578d
        BOOST_PP_LIST_APPEND((ref_val, BOOST_PP_NIL), \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
Packit 58578d
    , \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits) \
Packit 58578d
    )
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_TRAITS(captures) \
Packit 58578d
    BOOST_PP_LIST_FOLD_LEFT(BOOST_SCOPE_EXIT_AUX_TRAITS_OP, \
Packit 58578d
            (BOOST_PP_NIL, 0), captures)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_TRAITS_ALL(captures) \
Packit 58578d
    BOOST_SCOPE_EXIT_AUX_TRAITS_ALL_OP(BOOST_PP_LIST_FIRST(captures), \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_TRAITS(BOOST_PP_LIST_REST(captures)))
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits) \
Packit 58578d
    BOOST_PP_TUPLE_ELEM(2, 0, traits)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits) \
Packit 58578d
    BOOST_PP_TUPLE_ELEM(2, 1, traits)
Packit 58578d
Packit 58578d
#ifndef BOOST_NO_CXX11_LAMBDAS
Packit 58578d
Packit 58578d
namespace boost { namespace scope_exit { namespace aux {
Packit 58578d
Packit 58578d
template<typename This = void>
Packit 58578d
struct guard { // With object `this_` (for backward compatibility).
Packit 58578d
    explicit guard(This _this) : this_(_this) {}
Packit 58578d
    ~guard() { if(f_) f_(this_); }
Packit 58578d
    template<typename Lambda>
Packit 58578d
    void operator=(Lambda f) { f_ = f; }
Packit 58578d
private:
Packit 58578d
    This this_;
Packit 58578d
    boost::function<void (This)> f_;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<>
Packit 58578d
struct guard<void> { // Without object `this_` (could capture `this` directly).
Packit 58578d
    ~guard() { if(f_) f_(); }
Packit 58578d
    template<typename Lambda>
Packit 58578d
    void operator=(Lambda f) { f_ = f; }
Packit 58578d
private:
Packit 58578d
    boost::function<void (void)> f_;
Packit 58578d
};
Packit 58578d
Packit 58578d
} } } // namespace
Packit 58578d
    
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_LAMBDA_PARAMS(id) \
Packit 58578d
    BOOST_PP_CAT(boost_se_lambda_params_, id)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_CAPTURE_TYPE(id) \
Packit 58578d
    BOOST_PP_CAT(boost_se_lambda_this_t_, id)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_PARAM_TYPE(id) \
Packit 58578d
    BOOST_PP_CAT(boost_se_lambda_this_capture_t_, id)
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_TYPE(id, ty) \
Packit 58578d
    ty BOOST_SCOPE_EXIT_AUX_LAMBDA_PARAMS(id):: \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_PARAM_TYPE(id)
Packit 58578d
Packit 58578d
// Precondition: HAS_THIS(traits).
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_TYPEDEFS(id, ty, traits) \
Packit 58578d
    BOOST_SCOPE_EXIT_DETAIL_TYPEDEF_TYPEOF_THIS(id, ty, \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_CAPTURE_TYPE(id)) \
Packit 58578d
    /* capture type for workaround GCC internal error (even on later C++11) */ \
Packit 58578d
    struct BOOST_SCOPE_EXIT_AUX_LAMBDA_PARAMS(id) { \
Packit 58578d
        typedef BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_CAPTURE_TYPE(id) \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_PARAM_TYPE(id); \
Packit 58578d
    };
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_IMPL_LAMBDA(id, ty, traits) \
Packit 58578d
    BOOST_PP_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
Packit 58578d
        /* no need for TYPEDEF THIS MSVC workaround on C++11 */ \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_TYPEDEFS \
Packit 58578d
    , \
Packit 58578d
        BOOST_PP_TUPLE_EAT(3) \
Packit 58578d
    )(id, ty, traits) \
Packit 58578d
    ::boost::scope_exit::aux::guard< \
Packit 58578d
        BOOST_PP_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_TYPE \
Packit 58578d
        , \
Packit 58578d
            BOOST_PP_TUPLE_EAT(2) \
Packit 58578d
        )(id, ty) \
Packit 58578d
    > BOOST_SCOPE_EXIT_AUX_GUARD(id) \
Packit 58578d
        BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
Packit 58578d
            (this) \
Packit 58578d
        ) \
Packit 58578d
    ; \
Packit 58578d
    BOOST_SCOPE_EXIT_AUX_GUARD(id) = [ \
Packit 58578d
        BOOST_PP_LIST_ENUM(BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
Packit 58578d
    ]( \
Packit 58578d
        BOOST_PP_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_TYPE \
Packit 58578d
        , \
Packit 58578d
            BOOST_PP_TUPLE_EAT(2) \
Packit 58578d
        )(id, ty) \
Packit 58578d
        BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), this_) \
Packit 58578d
    ) mutable /* can change value captures (as with SCOPE_EXIT) */ -> void
Packit 58578d
Packit 58578d
#endif // Lambdas.
Packit 58578d
Packit 58578d
#if defined(BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS) && \
Packit 58578d
        !defined(BOOST_NO_CXX11_LAMBDAS) // Use lambda for SCOPE_EXIT (not just _ALL).
Packit 58578d
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_IMPL(id, ty, traits) \
Packit 58578d
    BOOST_SCOPE_EXIT_AUX_IMPL_LAMBDA(id, ty, traits)
Packit 58578d
Packit 58578d
#else // Not using lambdas.
Packit 58578d
Packit 58578d
// ty: EMPTY() | typename
Packit 58578d
#define BOOST_SCOPE_EXIT_AUX_IMPL(id, ty, traits) \
Packit 58578d
    BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_DETAIL_TAG_DECL, id, \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
Packit 58578d
    BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_DETAIL_CAPTURE_DECL, (id, ty), \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
Packit 58578d
    BOOST_PP_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
Packit 58578d
        BOOST_SCOPE_EXIT_DETAIL_TYPEDEF_TYPEOF_THIS \
Packit 58578d
    , \
Packit 58578d
        BOOST_PP_TUPLE_EAT(3) \
Packit 58578d
    )(id, ty, BOOST_SCOPE_EXIT_AUX_THIS_CAPTURE_T(id)) \
Packit 58578d
    struct BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id) { \
Packit 58578d
        /* interim capture types to workaround internal errors on old GCC */ \
Packit 58578d
        BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_DETAIL_PARAM_DECL, (id, ty), \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
Packit 58578d
        BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
Packit 58578d
            typedef BOOST_SCOPE_EXIT_AUX_THIS_CAPTURE_T(id) \
Packit 58578d
                    BOOST_SCOPE_EXIT_AUX_THIS_T(id) ; \
Packit 58578d
        ) \
Packit 58578d
        BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_MEMBER, id, \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
Packit 58578d
        BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_THIS_T(id) \
Packit 58578d
                    BOOST_SCOPE_EXIT_DETAIL_PARAM_THIS(id) ; \
Packit 58578d
        ) \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_PARAMS_T_CTOR(id, ty, \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits), \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits)) \
Packit 58578d
    } BOOST_SCOPE_EXIT_AUX_PARAMS(id) \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_PARAMS_INIT(id, \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits), \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits)) \
Packit 58578d
    ; \
Packit 58578d
    ::boost::scope_exit::detail::declared< \
Packit 58578d
        ::boost::scope_exit::detail::resolve< \
Packit 58578d
            sizeof(BOOST_SCOPE_EXIT_AUX_ARGS) \
Packit 58578d
        >::cmp1<0>::cmp2 \
Packit 58578d
    > BOOST_SCOPE_EXIT_AUX_ARGS; \
Packit 58578d
    BOOST_SCOPE_EXIT_AUX_ARGS.value = &BOOST_SCOPE_EXIT_AUX_PARAMS(id); \
Packit 58578d
    struct BOOST_SCOPE_EXIT_AUX_GUARD_T(id) { \
Packit 58578d
        BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id)* boost_se_params_; \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_GUARD_T(id) (void* boost_se_params) \
Packit 58578d
            : boost_se_params_( \
Packit 58578d
                    (BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id)*)boost_se_params) \
Packit 58578d
        {} \
Packit 58578d
        ~BOOST_SCOPE_EXIT_AUX_GUARD_T(id)() { \
Packit 58578d
            boost_se_body( \
Packit 58578d
                BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_ARG, id, \
Packit 58578d
                        BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
Packit 58578d
                BOOST_PP_COMMA_IF(BOOST_PP_BITAND(BOOST_PP_LIST_IS_CONS( \
Packit 58578d
                        BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)), \
Packit 58578d
                        BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits))) \
Packit 58578d
                BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS( \
Packit 58578d
                        traits), \
Packit 58578d
                    boost_se_params_->BOOST_SCOPE_EXIT_DETAIL_PARAM_THIS(id) \
Packit 58578d
                ) \
Packit 58578d
            ); \
Packit 58578d
        } \
Packit 58578d
        static void boost_se_body( \
Packit 58578d
            BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_ARG_DECL, (id, ty), \
Packit 58578d
                    BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
Packit 58578d
            BOOST_PP_COMMA_IF(BOOST_PP_BITAND(BOOST_PP_LIST_IS_CONS( \
Packit 58578d
                    BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)), \
Packit 58578d
                    BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits))) \
Packit 58578d
            BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
Packit 58578d
                ty BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id):: \
Packit 58578d
                        BOOST_SCOPE_EXIT_AUX_THIS_T(id) this_ \
Packit 58578d
            ) \
Packit 58578d
        )
Packit 58578d
Packit 58578d
#endif // Using lambdas.
Packit 58578d
Packit 58578d
// PUBLIC //
Packit 58578d
Packit 58578d
#if defined(BOOST_NO_CXX11_VARIADIC_MACROS) // No variadic macros (sequences only).
Packit 58578d
#   define BOOST_SCOPE_EXIT_ID(id, void_or_seq) \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_IMPL(id, BOOST_PP_EMPTY(), \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_TRAITS( \
Packit 58578d
                        BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(void_or_seq)))
Packit 58578d
#   define BOOST_SCOPE_EXIT_ID_TPL(id, void_or_seq) \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_IMPL(id, typename, \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_TRAITS( \
Packit 58578d
                        BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(void_or_seq)))
Packit 58578d
#   define BOOST_SCOPE_EXIT(void_or_seq) \
Packit 58578d
        BOOST_SCOPE_EXIT_ID(BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, \
Packit 58578d
                void_or_seq)
Packit 58578d
#   define BOOST_SCOPE_EXIT_TPL(void_or_seq) \
Packit 58578d
        BOOST_SCOPE_EXIT_ID_TPL(BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, \
Packit 58578d
                void_or_seq)
Packit 58578d
#   if !defined(BOOST_NO_CXX11_LAMBDAS)
Packit 58578d
#       define BOOST_SCOPE_EXIT_ALL_ID(id, seq) \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_IMPL_LAMBDA(id, \
Packit 58578d
                    /* C++11 allows to use typename outside templates so */ \
Packit 58578d
                    /* always typename here and no need for ..._ALL_TPL */ \
Packit 58578d
                    /* (if a C++11 compiler does not implement this use of */ \
Packit 58578d
                    /* typename, always use `this` instead of `this_`) */ \
Packit 58578d
                    typename, \
Packit 58578d
                    BOOST_SCOPE_EXIT_AUX_TRAITS_ALL( \
Packit 58578d
                            BOOST_SCOPE_EXIT_AUX_PP_NON_VOID_LIST(seq)))
Packit 58578d
#       define BOOST_SCOPE_EXIT_ALL(seq) \
Packit 58578d
            BOOST_SCOPE_EXIT_ALL_ID( \
Packit 58578d
                    BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, seq)
Packit 58578d
#   endif
Packit 58578d
#else // Variadic macros (both sequences and variadic tuples).
Packit 58578d
#   define BOOST_SCOPE_EXIT_ID(id, ...) \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_IMPL(id, BOOST_PP_EMPTY(), \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_TRAITS( \
Packit 58578d
                        BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(__VA_ARGS__)))
Packit 58578d
#   define BOOST_SCOPE_EXIT_ID_TPL(id, ...) \
Packit 58578d
        BOOST_SCOPE_EXIT_AUX_IMPL(id, typename, \
Packit 58578d
                BOOST_SCOPE_EXIT_AUX_TRAITS( \
Packit 58578d
                        BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(__VA_ARGS__)))
Packit 58578d
#   define BOOST_SCOPE_EXIT(...) \
Packit 58578d
        BOOST_SCOPE_EXIT_ID(BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, \
Packit 58578d
                __VA_ARGS__)
Packit 58578d
#   define BOOST_SCOPE_EXIT_TPL(...) \
Packit 58578d
        BOOST_SCOPE_EXIT_ID_TPL(BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, \
Packit 58578d
                __VA_ARGS__)
Packit 58578d
#   if !defined(BOOST_NO_CXX11_LAMBDAS)
Packit 58578d
#       define BOOST_SCOPE_EXIT_ALL_ID(id, ...) \
Packit 58578d
            BOOST_SCOPE_EXIT_AUX_IMPL_LAMBDA(id, \
Packit 58578d
                    /* C++11 allows to use typename outside templates so */ \
Packit 58578d
                    /* always typename here and no need for ..._ALL_TPL */ \
Packit 58578d
                    /* (if a C++11 compiler does not implement this use of */ \
Packit 58578d
                    /* typename, always use `this` instead of `this_`) */ \
Packit 58578d
                    typename, \
Packit 58578d
                    BOOST_SCOPE_EXIT_AUX_TRAITS_ALL( \
Packit 58578d
                            BOOST_SCOPE_EXIT_AUX_PP_NON_VOID_LIST( \
Packit 58578d
                                    __VA_ARGS__)))
Packit 58578d
#       define BOOST_SCOPE_EXIT_ALL(...) \
Packit 58578d
            BOOST_SCOPE_EXIT_ALL_ID( \
Packit 58578d
                    BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, __VA_ARGS__)
Packit 58578d
#   endif
Packit 58578d
#endif // Variadics.
Packit 58578d
Packit 58578d
#if defined(BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS) && \
Packit 58578d
        !defined(BOOST_NO_CXX11_LAMBDAS) // Use lambdas for SCOPE_EXIT (not just ALL).
Packit 58578d
#   define BOOST_SCOPE_EXIT_END_ID(id) \
Packit 58578d
        ; /* lambdas ended with just `;` */
Packit 58578d
#else // Not using lambdas.
Packit 58578d
#   define BOOST_SCOPE_EXIT_END_ID(id) \
Packit 58578d
        } BOOST_SCOPE_EXIT_AUX_GUARD(id)(BOOST_SCOPE_EXIT_AUX_ARGS.value);
Packit 58578d
#endif // Using lambdas.
Packit 58578d
#define BOOST_SCOPE_EXIT_END \
Packit 58578d
    BOOST_SCOPE_EXIT_END_ID(BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER)
Packit 58578d
Packit 58578d
// DOCUMENTATION //
Packit 58578d
Packit 58578d
#else // DOXYGEN
Packit 58578d
Packit 58578d
/** @file
Packit 58578d
@brief Scope exits allow to execute arbitrary code when the enclosing scope
Packit 58578d
exits.
Packit 58578d
*/
Packit 58578d
Packit 58578d
/**
Packit 58578d
@brief This macro declares a scope exit.
Packit 58578d
Packit 58578d
The scope exit declaration schedules the execution of the scope exit body at
Packit 58578d
the exit of the enclosing scope:
Packit 58578d
Packit 58578d
@code
Packit 58578d
    { // Some local scope.
Packit 58578d
        ...
Packit 58578d
        BOOST_SCOPE_EXIT(capture_list) {
Packit 58578d
            ... // Body code.
Packit 58578d
        } BOOST_SCOPE_EXIT_END
Packit 58578d
        ...
Packit 58578d
    }
Packit 58578d
@endcode
Packit 58578d
Packit 58578d
The enclosing scope must be local.
Packit 58578d
If multiple scope exits are declared within the same enclosing scope, the scope
Packit 58578d
exit bodies are executed in the reversed order of their declarations.
Packit 58578d
Note how the end of the scope exit body must be marked by
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_END}.
Packit 58578d
Packit 58578d
@Params
Packit 58578d
@Param{capture_list,
Packit 58578d
On compilers that support variadic macros (see also Boost.Config
Packit 58578d
<c>BOOST_NO_CXX11_VARIADIC_MACROS</c>)\, the capture list syntax is defined by the
Packit 58578d
following grammar:
Packit 58578d
@code
Packit 58578d
    capture_list:
Packit 58578d
            void | capture_tuple | capture_sequence
Packit 58578d
    capture_tuple:
Packit 58578d
            capture\, capture\, ...
Packit 58578d
    capture_sequence:
Packit 58578d
            (capture) (capture) ...
Packit 58578d
    capture:
Packit 58578d
            [&]variable | this_
Packit 58578d
@endcode
Packit 58578d
On compilers that do not support variadic macros\, <c>capture_tuple</c> cannot
Packit 58578d
be used:
Packit 58578d
@code
Packit 58578d
    capture_list:
Packit 58578d
            void | capture_sequence
Packit 58578d
@endcode
Packit 58578d
Furthermore\, if @RefMacro{BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS} is defined on
Packit 58578d
C++11 compilers that support lambda functions (i.e.\, Boost.Config's <c>BOOST_NO_CXX11_LAMBDAS</c> is not defined) then a semicolon <c>;</c> can be used instead of
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_END} and <c>this</c> can be used instead of
Packit 58578d
<c>this_</c>:
Packit 58578d
@code
Packit 58578d
    capture:
Packit 58578d
            [&]variable | this_ | this
Packit 58578d
@endcode
Packit 58578d
Packit 58578d
(Lexical conventions: <c>token1 | token2</c> means either <c>token1</c> or
Packit 58578d
<c>token2</c>; <c>[token]</c> means either <c>token</c> or nothing;
Packit 58578d
<c>{expression}</c> means the tokens resulting from the expression.)
Packit 58578d
}
Packit 58578d
@EndParams
Packit 58578d
Packit 58578d
Note that on compilers that support variadic macros (most of moder compliers
Packit 58578d
and all C++11 compilers), the capture list can be specified as a
Packit 58578d
comma-separated list of tokens (this is the preferred syntax).
Packit 58578d
However, on all compilers the same macro @RefMacro{BOOST_SCOPE_EXIT} also
Packit 58578d
allows to specify the capture list as a Boost.Preprocessor sequence of tokens
Packit 58578d
(for supporting compilers without variadic macros and for backward compatibility with older versions of this library).
Packit 58578d
Packit 58578d
The name <c>variable</c> of each captured variable must be a valid name in the
Packit 58578d
enclosing scope and it must appear exactly once in the capture list.
Packit 58578d
If a capture starts with the ampersand sign <c>&</c>, the corresponding
Packit 58578d
variable will be available by reference within the scope exit body; otherwise,
Packit 58578d
a copy of the variable will be made at the point of the scope exit declaration
Packit 58578d
and that copy will be available inside the scope exit body (in this case, the
Packit 58578d
variable's type must be <c>CopyConstructible</c>).
Packit 58578d
Packit 58578d
From within a member function, the object <c>this</c> can be captured using the
Packit 58578d
special name <c>this_</c> in both the capture list and the scope exit body
Packit 58578d
(using <c>this</c> instead of <c>this_</c> in the scope exit body leads to
Packit 58578d
undefined behaviour).
Packit 58578d
Packit 58578d
It is possible to capture no variable by specifying the capture list as
Packit 58578d
<c>void</c> (regardless of variadic macro support).
Packit 58578d
Packit 58578d
Only variables listed in the capture list, static variables, <c>extern</c>
Packit 58578d
variables, global variables, functions, and enumerations from the enclosing
Packit 58578d
scope can be used inside the scope exit body.
Packit 58578d
Packit 58578d
On various GCC versions the special macro @RefMacro{BOOST_SCOPE_EXIT_TPL} must
Packit 58578d
be used instead of @RefMacro{BOOST_SCOPE_EXIT} within templates (to maximize
Packit 58578d
portability, it is recommended to always use @RefMacro{BOOST_SCOPE_EXIT_TPL}
Packit 58578d
within templates).
Packit 58578d
Packit 58578d
On C++11, it is possible capture all variables in scope without listing their
Packit 58578d
names one-by-one using the macro @RefMacro{BOOST_SCOPE_EXIT_ALL}.
Packit 58578d
Packit 58578d
In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_ID} must be used
Packit 58578d
instead of @RefMacro{BOOST_SCOPE_EXIT} when it is necessary to expand multiple
Packit 58578d
scope exit declarations on the same line.
Packit 58578d
Packit 58578d
@Warning The implementation executes the scope exit body within a destructor
Packit 58578d
thus the scope exit body must never throw in order to comply with STL exception
Packit 58578d
safety requirements.
Packit 58578d
Packit 58578d
@Note The implementation uses Boost.Typeof to automatically deduce the types of
Packit 58578d
the captured variables.
Packit 58578d
In order to compile code in type-of emulation mode, all types must be properly
Packit 58578d
registered with Boost.Typeof (see the
Packit 58578d
@RefSect{getting_started, Getting Started} section).
Packit 58578d
Packit 58578d
@See @RefSect{tutorial, Tutorial} section,
Packit 58578d
@RefSect{getting_started, Getting Started} section,
Packit 58578d
@RefSect{no_variadic_macros, No Variadic Macros} section,
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_TPL}, @RefMacro{BOOST_SCOPE_EXIT_ALL},
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_END}, @RefMacro{BOOST_SCOPE_EXIT_ID}.
Packit 58578d
*/
Packit 58578d
#define BOOST_SCOPE_EXIT(capture_list)
Packit 58578d
Packit 58578d
/**
Packit 58578d
@brief This macro is a workaround for various versions of GCC to declare scope
Packit 58578d
exits within templates.
Packit 58578d
Packit 58578d
Various versions of the GCC compiler do not compile @RefMacro{BOOST_SCOPE_EXIT}
Packit 58578d
inside function templates.
Packit 58578d
As a workaround, @RefMacro{BOOST_SCOPE_EXIT_TPL} should be used instead of
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT} in these cases:
Packit 58578d
Packit 58578d
@code
Packit 58578d
    { // Some local scope.
Packit 58578d
        ...
Packit 58578d
        BOOST_SCOPE_EXIT_TPL(capture_list) {
Packit 58578d
            ... // Body code.
Packit 58578d
        } BOOST_SCOPE_EXIT_END
Packit 58578d
        ...
Packit 58578d
    }
Packit 58578d
@endcode
Packit 58578d
Packit 58578d
The syntax of @RefMacro{BOOST_SCOPE_EXIT_TPL} is the exact same as the one of
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT} (see @RefMacro{BOOST_SCOPE_EXIT} for more
Packit 58578d
information).
Packit 58578d
Packit 58578d
On C++11 compilers, @RefMacro{BOOST_SCOPE_EXIT_TPL} is not needed because
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT} always compiles on GCC versions that support C++11.
Packit 58578d
However, @RefMacro{BOOST_SCOPE_EXIT_TPL} is still provided on C++11 so to write code that is portable between C++03 and C++11 compilers.
Packit 58578d
It is recommended to always use @RefMacro{BOOST_SCOPE_EXIT_TPL} within
Packit 58578d
templates so to maximize portability.
Packit 58578d
Packit 58578d
In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_ID_TPL} must be used
Packit 58578d
instead of @RefMacro{BOOST_SCOPE_EXIT_TPL} when it is necessary to expand
Packit 58578d
multiple scope exit declarations on the same line within templates.
Packit 58578d
Packit 58578d
@Note The issue in compiling scope exit declarations that some GCC versions
Packit 58578d
have is illustrated by the following code (see also
Packit 58578d
GCC bug 37920):
Packit 58578d
@code
Packit 58578d
    template<class T>
Packit 58578d
    void f(T const& x) {
Packit 58578d
        int i = 0;
Packit 58578d
        struct local {
Packit 58578d
            typedef __typeof__(i) typeof_i;
Packit 58578d
            typedef __typeof__(x) typeof_x;
Packit 58578d
        };
Packit 58578d
        typedef local::typeof_i i_type;
Packit 58578d
        typedef local::typeof_x x_type;
Packit 58578d
    }
Packit 58578d
Packit 58578d
    int main(void) { f(0); }
Packit 58578d
@endcode
Packit 58578d
This can be fixed by adding <c>typename</c> in front of <c>local::typeof_i</c>
Packit 58578d
and <c>local::typeof_x</c> (which is the approach followed by the
Packit 58578d
implementation of the @RefMacro{BOOST_SCOPE_EXIT_TPL} macro).
Packit 58578d
Packit 58578d
@Note Although @RefMacro{BOOST_SCOPE_EXIT_TPL} has the same suffix as
Packit 58578d
<c>BOOST_TYPEOF_TPL</c>, it does not follow the Boost.Typeof convention.
Packit 58578d
Packit 58578d
@See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_SCOPE_EXIT},
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_END}, @RefMacro{BOOST_SCOPE_EXIT_ID_TPL}.
Packit 58578d
*/
Packit 58578d
#define BOOST_SCOPE_EXIT_TPL(capture_list)
Packit 58578d
Packit 58578d
/**
Packit 58578d
@brief This macro allows to expand multiple scope exit declarations on the same
Packit 58578d
line.
Packit 58578d
Packit 58578d
This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT} but it can be expanded
Packit 58578d
multiple times on the same line if different identifiers <c>id</c> are provided
Packit 58578d
for each expansion (see @RefMacro{BOOST_SCOPE_EXIT} for more information).
Packit 58578d
Packit 58578d
@Params
Packit 58578d
@Param{id,
Packit 58578d
A unique identifier token which can be concatenated by the preprocessor
Packit 58578d
(<c>__LINE__</c>\, <c>scope_exit_number_1_on_line_123</c>\, a combination of
Packit 58578d
alphanumeric tokens\, etc).
Packit 58578d
}
Packit 58578d
@Param{capture_list,
Packit 58578d
Same as the <c>capture_list</c> parameter of the @RefMacro{BOOST_SCOPE_EXIT}
Packit 58578d
macro.
Packit 58578d
}
Packit 58578d
@EndParams
Packit 58578d
Packit 58578d
@Note This macro can be useful when the scope exit macros are expanded
Packit 58578d
within user-defined macros (because nested macros expand on the same line).
Packit 58578d
On some compilers (e.g., MSVC which supports the non standard
Packit 58578d
<c>__COUNTER__</c> macro) it might not be necessary to use this macro but
Packit 58578d
the use of this macro is always necessary to ensure portability when expanding
Packit 58578d
multiple scope exit declarations on the same line.
Packit 58578d
Packit 58578d
@See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_SCOPE_EXIT},
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_END_ID}, @RefMacro{BOOST_SCOPE_EXIT_ALL_ID},
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_ID_TPL}.
Packit 58578d
*/
Packit 58578d
#define BOOST_SCOPE_EXIT_ID(id, capture_list)
Packit 58578d
Packit 58578d
/**
Packit 58578d
@brief This macro is required to expand multiple scope exit declarations on the
Packit 58578d
same line within templates on various versions of GCC.
Packit 58578d
Packit 58578d
This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT_TPL} but it can be
Packit 58578d
expanded multiple times on the same line if different identifiers <c>id</c> are
Packit 58578d
provided for each expansion (see @RefMacro{BOOST_SCOPE_EXIT_TPL} for more
Packit 58578d
information).
Packit 58578d
As with @RefMacro{BOOST_SCOPE_EXIT_TPL}, it is recommended to always use this
Packit 58578d
macro when expanding scope exits multiple times on the same line within
Packit 58578d
templates.
Packit 58578d
Packit 58578d
@Params
Packit 58578d
@Param{id,
Packit 58578d
A unique identifier token which can be concatenated by the preprocessor
Packit 58578d
(<c>__LINE__</c>\, <c>scope_exit_number_1_on_line_123</c>\, a combination of
Packit 58578d
alphanumeric tokens\, etc).
Packit 58578d
}
Packit 58578d
@Param{capture_list,
Packit 58578d
Same as the <c>capture_list</c> parameter of the
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_TPL} macro.
Packit 58578d
}
Packit 58578d
@EndParams
Packit 58578d
Packit 58578d
@Note This macro can be useful when the scope exit macros are expanded
Packit 58578d
within user-defined macros (because nested macros expand on the same line).
Packit 58578d
On some compilers (e.g., MSVC which supports the non standard
Packit 58578d
<c>__COUNTER__</c> macro) it might not be necessary to use this macro but
Packit 58578d
the use of this macro is always necessary to ensure portability when expanding
Packit 58578d
multiple scope exit declarations on the same line.
Packit 58578d
Packit 58578d
@See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_SCOPE_EXIT_TPL},
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_END_ID}, @RefMacro{BOOST_SCOPE_EXIT_ID},
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_ALL_ID}.
Packit 58578d
*/
Packit 58578d
#define BOOST_SCOPE_EXIT_ID_TPL(id, capture_list)
Packit 58578d
Packit 58578d
/**
Packit 58578d
@brief This macro declares a scope exit that captures all variables in scope
Packit 58578d
(C++11 only).
Packit 58578d
Packit 58578d
This macro accepts a capture list starting with either <c>&</c> or <c>=</c> to capture all variables in scope by reference or value respectively (following the same syntax of C++11 lambdas).
Packit 58578d
A part from that, this macro works like @RefMacro{BOOST_SCOPE_EXIT} (see @RefMacro{BOOST_SCOPE_EXIT} for more information):
Packit 58578d
Packit 58578d
@code
Packit 58578d
    { // Some local scope.
Packit 58578d
        ...
Packit 58578d
        BOOST_SCOPE_EXIT_ALL(capture_list) { // C++11 only.
Packit 58578d
            ... // Body code.
Packit 58578d
        }; // Use `;` instead of `BOOST_SCOPE_EXIT_END` (C++11 only).
Packit 58578d
        ...
Packit 58578d
    }
Packit 58578d
@endcode
Packit 58578d
Packit 58578d
Note how the end of the scope exit body declared by this macro must be marked
Packit 58578d
by a semi-column <c>;</c> (and not by @RefMacro{BOOST_SCOPE_EXIT_END}).
Packit 58578d
Packit 58578d
@Warning This macro is only available on C++11 compilers (specifically, on
Packit 58578d
C++11 compilers that do not define the Boost.Config <c>BOOST_NO_CXX11_LAMBDAS</c>
Packit 58578d
macro).
Packit 58578d
It is not defined on non-C++11 compilers so its use on non-C++11 compilers will generate a compiler error.
Packit 58578d
Packit 58578d
@Params
Packit 58578d
@Param{capture_list,
Packit 58578d
On compilers that support variadic macros (see also Boost.Config
Packit 58578d
<c>BOOST_NO_CXX11_VARIADIC_MACROS</c>)\, the capture list syntax is defined by the
Packit 58578d
following grammar:
Packit 58578d
@code
Packit 58578d
capture_list:
Packit 58578d
        capture_tuple | capture_sequence
Packit 58578d
capture_tuple:
Packit 58578d
        {& | =} [\, capture\, capture\, ...]
Packit 58578d
capture_sequence:
Packit 58578d
        {(&) | (=)} [(capture) (capture) ...]
Packit 58578d
capture:
Packit 58578d
        [&]variable | this_
Packit 58578d
@endcode
Packit 58578d
On compilers that do not support variadic macros\, <c>capture_tuple</c> cannot
Packit 58578d
be used:
Packit 58578d
@code
Packit 58578d
    capture_list:
Packit 58578d
            void | capture_sequence
Packit 58578d
@endcode
Packit 58578d
Furthermore\, on C++11 compilers that support the use of <c>typename</c>
Packit 58578d
outside templates\, also <c>this</c> can be used to capture the object at member
Packit 58578d
function scope:
Packit 58578d
@code
Packit 58578d
    capture:
Packit 58578d
            [&]variable | this_ | this
Packit 58578d
@endcode
Packit 58578d
Packit 58578d
(Lexical conventions: <c>token1 | token2</c> means either <c>token1</c> or
Packit 58578d
<c>token2</c>; <c>[token]</c> means either <c>token</c> or nothing;
Packit 58578d
<c>{expression}</c> means the token resulting from the expression.)
Packit 58578d
}
Packit 58578d
@EndParams
Packit 58578d
Packit 58578d
Note that on compilers with variadic macro support (which should be all C++11
Packit 58578d
compilers), the capture list can be specified as a comma-separated list.
Packit 58578d
On all compilers, the same macro @RefMacro{BOOST_SCOPE_EXIT_ALL} also allows to
Packit 58578d
specify the capture list as a Boost.Preprocessor sequence.
Packit 58578d
Packit 58578d
The capture list must always contain at least the leading <c>&</c> or <c>=</c>
Packit 58578d
so it can never be <c>void</c> (<c>BOOST_SCOPE_EXIT(void)</c> should be used
Packit 58578d
to program scope exits with an empty capture list).
Packit 58578d
Packit 58578d
In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_ALL_ID} must be used
Packit 58578d
instead of @RefMacro{BOOST_SCOPE_EXIT_ALL} when it is necessary to expand
Packit 58578d
multiple scope exit declarations on the same line.
Packit 58578d
Packit 58578d
@Warning This macro capture list follows the exact same syntax of C++11 lambda
Packit 58578d
captures which is unfortunately different from the syntax of
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT} captures (unless programmers define the
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS} macro).
Packit 58578d
For example, like C++11 lambda functions, @RefMacro{BOOST_SCOPE_EXIT_ALL}
Packit 58578d
requires to capture data members by capturing the object <c>this</c> while
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT} allows to capture data members directly and without
Packit 58578d
capturing the object.
Packit 58578d
Packit 58578d
@Warning The implementation executes the scope exit body within a destructor
Packit 58578d
thus the scope exit body must never throw in order to comply with STL exception
Packit 58578d
safety requirements.
Packit 58578d
Packit 58578d
@Note This macro can always be used also within templates (so there is no need
Packit 58578d
for a <c>BOOST_SCOPE_EXIT_ALL_TPL</c> macro).
Packit 58578d
Packit 58578d
@See @RefSect{tutorial, Tutorial} section,
Packit 58578d
@RefSect{no_variadic_macros, No Variadic Macros} section,
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT}, @RefMacro{BOOST_SCOPE_EXIT_ALL_ID}.
Packit 58578d
*/
Packit 58578d
#define BOOST_SCOPE_EXIT_ALL(capture_list)
Packit 58578d
Packit 58578d
/**
Packit 58578d
@brief This macro allows to expand on the same line multiple scope exits that
Packit 58578d
capture all variables in scope (C++11 only).
Packit 58578d
Packit 58578d
This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT_ALL} but it can be
Packit 58578d
expanded multiple times on the same line if different identifiers <c>id</c> are
Packit 58578d
provided for each expansion (see @RefMacro{BOOST_SCOPE_EXIT_ALL} for more
Packit 58578d
information).
Packit 58578d
As with @RefMacro{BOOST_SCOPE_EXIT_ALL}, this macro is only available on C++11
Packit 58578d
compilers (specifically, on C++11 compilers that do not define the
Packit 58578d
Boost.Config <c>BOOST_NO_CXX11_LAMBDAS</c> macro).
Packit 58578d
Packit 58578d
@Params
Packit 58578d
@Param{id,
Packit 58578d
A unique identifier token which can be concatenated by the preprocessor
Packit 58578d
(<c>__LINE__</c>\, <c>scope_exit_number_1_on_line_123</c>\, a combination of
Packit 58578d
alphanumeric tokens\, etc).
Packit 58578d
}
Packit 58578d
@Param{capture_list,
Packit 58578d
Same as the <c>capture_list</c> parameter of the
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_ALL} macro.
Packit 58578d
}
Packit 58578d
@EndParams
Packit 58578d
Packit 58578d
@Note This macro can be useful when the scope exit macros are expanded
Packit 58578d
within user-defined macros (because nested macros expand on the same line).
Packit 58578d
On some compilers (e.g., MSVC which supports the non standard
Packit 58578d
<c>__COUNTER__</c> macro) it might not be necessary to use this macro but
Packit 58578d
the use of this macro is always necessary to ensure portability when expanding
Packit 58578d
multiple scope exit declarations on the same line.
Packit 58578d
Packit 58578d
@See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_SCOPE_EXIT_ALL},
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_ID}.
Packit 58578d
*/
Packit 58578d
#define BOOST_SCOPE_EXIT_ALL_ID(id, capture_list)
Packit 58578d
Packit 58578d
/**
Packit 58578d
@brief This macro marks the end of a scope exit body.
Packit 58578d
Packit 58578d
This macro must follow the closing curly bracket <c>}</c> that ends the body of
Packit 58578d
either @RefMacro{BOOST_SCOPE_EXIT} or @RefMacro{BOOST_SCOPE_EXIT_TPL}:
Packit 58578d
Packit 58578d
@code
Packit 58578d
    { // Some local scope.
Packit 58578d
        ...
Packit 58578d
        BOOST_SCOPE_EXIT(capture_list) {
Packit 58578d
            ... // Body code.
Packit 58578d
        } BOOST_SCOPE_EXIT_END
Packit 58578d
        ...
Packit 58578d
    }
Packit 58578d
@endcode
Packit 58578d
Packit 58578d
In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_END_ID} must be used
Packit 58578d
instead of @RefMacro{BOOST_SCOPE_EXIT_END} when it is necessary to expand
Packit 58578d
multiple scope exit bodies on the same line.
Packit 58578d
Packit 58578d
@Note If programmers define the @RefMacro{BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS}
Packit 58578d
macro on C++11 compilers, a semicolon <c>;</c> can be used instead of this
Packit 58578d
macro.
Packit 58578d
However, to maximize portability, it is recommended to always use
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_END}.
Packit 58578d
Packit 58578d
@See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_SCOPE_EXIT},
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_TPL}, @RefMacro{BOOST_SCOPE_EXIT_END_ID}.
Packit 58578d
*/
Packit 58578d
#define BOOST_SCOPE_EXIT_END
Packit 58578d
Packit 58578d
/**
Packit 58578d
@brief This macro allows to terminate multiple scope exit bodies on the same
Packit 58578d
line.
Packit 58578d
Packit 58578d
This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT_END} but it can be
Packit 58578d
expanded multiple times on the same line if different identifiers <c>id</c> are
Packit 58578d
provided for each expansion (see @RefMacro{BOOST_SCOPE_EXIT_END} for more
Packit 58578d
information).
Packit 58578d
Packit 58578d
@Params
Packit 58578d
@Param{id,
Packit 58578d
A unique identifier token which can be concatenated by the preprocessor
Packit 58578d
(<c>__LINE__</c>\, <c>scope_exit_number_1_on_line_123</c>\, a combination of
Packit 58578d
alphanumeric tokens\, etc).
Packit 58578d
}
Packit 58578d
@EndParams
Packit 58578d
Packit 58578d
@Note This macro can be useful when the scope exit macros are expanded
Packit 58578d
within user-defined macros (because macros all expand on the same line).
Packit 58578d
On some compilers (e.g., MSVC which supports the non standard
Packit 58578d
<c>__COUNTER__</c> macro) it might not be necessary to use this macro but
Packit 58578d
the use of this macro is always necessary to ensure portability when expanding
Packit 58578d
multiple scope exit macros on the same line (because this library can only
Packit 58578d
portably use <c>__LINE__</c> to internally generate unique identifiers).
Packit 58578d
Packit 58578d
@See @RefMacro{BOOST_SCOPE_EXIT_ID}, @RefMacro{BOOST_SCOPE_EXIT_ID_TPL},
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_END}.
Packit 58578d
*/
Packit 58578d
#define BOOST_SCOPE_EXIT_END_ID(id)
Packit 58578d
Packit 58578d
/**
Packit 58578d
@brief Force to use C++11 lambda functions to implement scope exits.
Packit 58578d
Packit 58578d
If programmers define this configuration macro on a C++11 compiler for which
Packit 58578d
the Boost.Config macro <c>BOOST_NO_CXX11_LAMBDAS</c> is not defined, the
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT} and @RefMacro{BOOST_SCOPE_EXIT_TPL} macros will use
Packit 58578d
C++11 lambda functions to declare scope exits.
Packit 58578d
By default this macro is not defined.
Packit 58578d
Packit 58578d
@Warning When scope exits are implemented using lambda functions, the syntax of
Packit 58578d
the capture list follows the exact same syntax of C++11 lambda captures
Packit 58578d
which is in general different from the legacy capture syntax of this library.
Packit 58578d
For example, C++11 lambdas require to capture data members by capturing the
Packit 58578d
object <c>this</c> while this library always allowed to capture data members
Packit 58578d
directly.
Packit 58578d
Therefore, when this configuration macro is defined,
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT} and @RefMacro{BOOST_SCOPE_EXIT_TPL} are no longer
Packit 58578d
backward compatible (and this is why this macro is not defined by default).
Packit 58578d
Packit 58578d
A semicolon <c>;</c> can be used instead of @RefMacro{BOOST_SCOPE_EXIT_END}
Packit 58578d
when this configuration macro is defined (but it is recommended to always use
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_END} so to maximize portability).
Packit 58578d
Packit 58578d
@Note This configuration macro does not control the definition of
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_ALL} which is always and automatically defined on
Packit 58578d
compilers that support C++11 lambda functions.
Packit 58578d
Packit 58578d
@See @RefMacro{BOOST_SCOPE_EXIT}, @RefMacro{BOOST_SCOPE_EXIT_TPL},
Packit 58578d
@RefMacro{BOOST_SCOPE_EXIT_END}.
Packit 58578d
*/
Packit 58578d
#define BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS
Packit 58578d
Packit 58578d
#endif // DOXYGEN
Packit 58578d
Packit 58578d
#endif // #ifndef FILE_boost_scope_exit_hpp_INCLUDED
Packit 58578d