1 
2 // Copyright (C) 2006-2009, 2012 Alexander Nasonov
3 // Copyright (C) 2012 Lorenzo Caminiti
4 // Distributed under the Boost Software License, Version 1.0
5 // (see accompanying file LICENSE_1_0.txt or a copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 // Home at http://www.boost.org/libs/scope_exit
8 
9 #ifndef BOOST_SCOPE_EXIT_HPP
10 #define BOOST_SCOPE_EXIT_HPP
11 
12 #ifndef DOXYGEN
13 
14 #include <boost/config/workaround.hpp>
15 #include <boost/type_traits/integral_constant.hpp>
16 #include <boost/type_traits/enable_if.hpp>
17 #include <boost/function.hpp>
18 #include <boost/typeof/typeof.hpp>
19 #include <boost/config.hpp>
20 #include <boost/preprocessor/cat.hpp>
21 #include <boost/preprocessor/control/iif.hpp>
22 #include <boost/preprocessor/control/expr_iif.hpp>
23 #include <boost/preprocessor/comparison/equal.hpp>
24 #include <boost/preprocessor/logical/bitor.hpp>
25 #include <boost/preprocessor/logical/bitand.hpp>
26 #include <boost/preprocessor/facilities/empty.hpp>
27 #include <boost/preprocessor/facilities/is_empty.hpp>
28 #include <boost/preprocessor/facilities/identity.hpp>
29 #include <boost/preprocessor/punctuation/comma_if.hpp>
30 #include <boost/preprocessor/punctuation/paren_if.hpp>
31 #include <boost/preprocessor/seq/cat.hpp>
32 #include <boost/preprocessor/seq/size.hpp>
33 #include <boost/preprocessor/seq/to_tuple.hpp>
34 #include <boost/preprocessor/tuple/elem.hpp>
35 #include <boost/preprocessor/tuple/eat.hpp>
36 #include <boost/preprocessor/tuple/to_list.hpp>
37 #include <boost/preprocessor/list/append.hpp>
38 #include <boost/preprocessor/list/fold_left.hpp>
39 #include <boost/preprocessor/list/enum.hpp>
40 #include <boost/preprocessor/list/adt.hpp>
41 #include <boost/preprocessor/list/for_each_i.hpp>
42 #include <boost/preprocessor/detail/is_unary.hpp>
43 
44 // PRIVATE/PROTECTED //
45 
46 // NOTE: AUX prefix and aux namespace mark "private" symbols that shall be used
47 // only within this library; DETAIL prefix and detail namespace mark "protected"
48 // symbols that can be used by other Boost libraries but not outside Boost.
49 
50 // WARNING: BOOST_SCOPE_EXIT_AUX_GCC also used by some regression test.
51 #if defined(__GNUC__) && !defined(BOOST_INTEL)
52 #   define BOOST_SCOPE_EXIT_AUX_GCC (__GNUC__ * 100 + __GNUC_MINOR__)
53 #else
54 #   define BOOST_SCOPE_EXIT_AUX_GCC 0
55 #endif
56 
57 #if BOOST_WORKAROUND(BOOST_SCOPE_EXIT_AUX_GCC, BOOST_TESTED_AT(413))
58 #   define BOOST_SCOPE_EXIT_AUX_TPL_GCC_WORKAROUND_01 1
59 #else
60 #   define BOOST_SCOPE_EXIT_AUX_TPL_GCC_WORKAROUND_01 0
61 #endif
62 
63 #if BOOST_MSVC && (BOOST_MSVC <= 1900)
64 #   define BOOST_SCOPE_EXIT_AUX_TYPEOF_THIS_MSVC_WORKAROUND_01 1
65 #else
66 #   define BOOST_SCOPE_EXIT_AUX_TYPEOF_THIS_MSVC_WORKAROUND_01 0
67 #endif
68 
69 // MSVC has problems expanding __LINE__ so use (the non standard) __COUNTER__.
70 #ifdef BOOST_MSVC
71 #   define BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER __COUNTER__
72 #else
73 #   define BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER __LINE__
74 #endif
75 
76 // Preprocessor "keyword" detection.
77 
78 // These are not a local macros, do not #undefine them (these are used by the
79 // ..._BACK macros below).
80 #define this_BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_THISUNDERSCORE_IS (1) /* unary */
81 #define void_BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_VOID_IS (1) /* unary */
82 
83 #define BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_BACK_(token, checking_postfix) \
84     BOOST_PP_IS_UNARY(BOOST_PP_CAT(token, checking_postfix))
85 
86 #define BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_THISUNDERSCORE_BACK(token) \
87     BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_BACK_(token, \
88             BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_THISUNDERSCORE_IS)
89 
90 #define BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_VOID_BACK(token) \
91     BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_BACK_(token, \
92             _BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_VOID_IS)
93 
94 // Preprocessor "void-list".
95 
96 // NOTE: Empty list must always be represented as void (which is also a way to
97 // specify no function parameter) and it can never be empty because (1)
98 // IS_EMPTY(&var) fails (because of the leading non alphanumeric symbol) and
99 // (2) some compilers (MSVC) fail to correctly pass empty macro parameters
100 // even if they support variadic macros. Therefore, always using void to
101 // represent is more portable.
102 
103 // Argument: (token1)...
104 #define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_FROM_SEQ_(unused, seq) \
105     BOOST_PP_TUPLE_TO_LIST(BOOST_PP_SEQ_SIZE(seq), BOOST_PP_SEQ_TO_TUPLE(seq))
106 
107 // Token: void | token1
108 #define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_HANDLE_VOID_( \
109         is_void_macro, token) \
110     BOOST_PP_IIF(is_void_macro(token), \
111         BOOST_PP_NIL \
112     , \
113         (token, BOOST_PP_NIL) \
114     )
115 
116 // Token: (a)(b)... | empty | void | token
117 #define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_HANDLE_SEQ_( \
118         is_void_macro, token) \
119     BOOST_PP_IIF(BOOST_PP_IS_UNARY(token), /* unary paren (a)... */ \
120         BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_FROM_SEQ_ \
121     , \
122         BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_HANDLE_VOID_ \
123     )(is_void_macro, token)
124 
125 #define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_NEVER_(tokens) \
126     0 /* void check always returns false */
127 
128 #ifdef BOOST_NO_CXX11_VARIADIC_MACROS
129 
130 #define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_(is_void_macro, seq) \
131     BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_HANDLE_SEQ_(is_void_macro, seq)
132 
133 // Expand `void | (a)(b)...` to pp-list `NIL | (a, (b, NIL))`.
134 #define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(sign) \
135     BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_( \
136             BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_VOID_BACK, sign)
137 
138 // Expand `(a)(b)...` to pp-list `(a, (b, NIL))`.
139 #define BOOST_SCOPE_EXIT_AUX_PP_NON_VOID_LIST(seq) \
140     BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_( \
141             BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_NEVER_, seq)
142 
143 #else // VARIADICS
144 
145 // FUTURE: Replace this with BOOST_PP_VARIADIC_SIZE when and if
146 // BOOST_PP_VARIAIDCS detection will match !BOOST_NO_CXX11_VARIADIC_MACROS (for
147 // now Boost.Preprocessor and Boost.Config disagree on detecting compiler
148 // variadic support while this VARIADIC_SIZE works on compilers not detected by
149 // PP).
150 #if BOOST_MSVC
151 #   define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_VARIADIC_SIZE_(...) \
152         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,),)
153 #else // MSVC
154 #   define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_VARIADIC_SIZE_(...) \
155         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,)
156 #endif // MSVC
157 #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
158 
159 // Argument: token1, ...
160 #define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_FROM_VARIADIC_(unused, ...) \
161     BOOST_PP_TUPLE_TO_LIST( \
162             BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_VARIADIC_SIZE_( \
163                     __VA_ARGS__), (__VA_ARGS__))
164 
165 #define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_(is_void_macro, ...) \
166     BOOST_PP_IIF(BOOST_PP_EQUAL( \
167             BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_VARIADIC_SIZE_( \
168                     __VA_ARGS__), 1), \
169         BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_HANDLE_SEQ_ \
170     , \
171         BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_FROM_VARIADIC_ \
172     )(is_void_macro, __VA_ARGS__)
173 
174 // Expand `void | (a)(b)... | a, b, ...` to pp-list `NIL | (a, (b, NIL))`.
175 #define BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(...) \
176     BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_( \
177             BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_VOID_BACK, __VA_ARGS__)
178 
179 // Expand `(a)(b)... | a, b, ...` to pp-list `(a, (b, NIL))`.
180 #define BOOST_SCOPE_EXIT_AUX_PP_NON_VOID_LIST(...) \
181     BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_( \
182             BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST_NEVER_, __VA_ARGS__)
183 
184 #endif // VARIADICS
185 
186 // Steven Watanabe's trick with a modification suggested by Kim Barrett
187 namespace boost { namespace scope_exit { namespace detail {
188 
189 // Type of a local BOOST_SCOPE_EXIT_AUX_ARGS variable.
190 // First use in a local scope will declare the BOOST_SCOPE_EXIT_AUX_ARGS
191 // variable, subsequent uses will be resolved as two comparisons
192 // (cmp1 with 0 and cmp2 with BOOST_SCOPE_EXIT_AUX_ARGS).
193 template<int Dummy = 0>
194 struct declared
195 {
196     void* value;
197     static int const cmp2 = 0;
operator >(int,declared const &)198     friend void operator>(int, declared const&) {}
199 };
200 
201 struct undeclared { declared<> dummy[2]; };
202 
203 template<int> struct resolve;
204 
205 template<>
206 struct resolve<sizeof(declared<>)>
207 {
208     static const int cmp1 = 0;
209 };
210 
211 template<>
212 struct resolve<sizeof(undeclared)>
213 {
214     template<int>
215     struct cmp1
216     {
217         static int const cmp2 = 0;
218     };
219 };
220 
221 typedef void (*ref_tag)(int&);
222 typedef void (*val_tag)(int );
223 
224 template<class T, class Tag> struct member;
225 
226 template<class T>
227 struct member<T,ref_tag>
228 {
229     T& value;
230 #if !BOOST_SCOPE_EXIT_AUX_TPL_GCC_WORKAROUND_01
memberboost::scope_exit::detail::member231     member(T& ref) : value(ref) {}
232 #endif
233 };
234 
235 template<class T>
236 struct member<T,val_tag>
237 {
238     T value;
239 #if !BOOST_SCOPE_EXIT_AUX_TPL_GCC_WORKAROUND_01
memberboost::scope_exit::detail::member240     member(T& val) : value(val) {}
241 #endif
242 };
243 
deref(T * p,ref_tag)244 template<class T> inline T& deref(T* p, ref_tag) { return *p; }
deref(T & r,val_tag)245 template<class T> inline T& deref(T& r, val_tag) { return  r; }
246 
247 template<class T>
248 struct wrapper
249 {
250     typedef T type;
251 };
252 
253 template<class T> wrapper<T> wrap(T&);
254 
255 } } } // namespace
256 
257 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
258 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::scope_exit::detail::wrapper, 1)
259 
260 #define BOOST_SCOPE_EXIT_AUX_ARGS boost_scope_exit_aux_args
261 extern boost::scope_exit::detail::undeclared BOOST_SCOPE_EXIT_AUX_ARGS;
262 
263 #define BOOST_SCOPE_EXIT_AUX_GUARD(id)   \
264     BOOST_PP_CAT(boost_se_guard_, id)
265 
266 #define BOOST_SCOPE_EXIT_AUX_GUARD_T(id) \
267     BOOST_PP_CAT(boost_se_guard_t_, id)
268 
269 #define BOOST_SCOPE_EXIT_AUX_PARAMS(id)  \
270     BOOST_PP_CAT(boost_se_params_, id)
271 
272 #define BOOST_SCOPE_EXIT_AUX_THIS_T(id)  \
273     BOOST_PP_CAT(boost_se_this_t_,  id)
274 
275 #define BOOST_SCOPE_EXIT_AUX_THIS_CAPTURE_T(id) \
276     BOOST_PP_CAT(boost_se_this_capture_t_,  id)
277 
278 #define BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id) \
279     BOOST_PP_CAT(boost_se_params_t_, id)
280 
281 #define BOOST_SCOPE_EXIT_DETAIL_TAG(id, i) \
282     BOOST_PP_SEQ_CAT( (boost_se_tag_)(i)(_)(id) )
283 
284 #define BOOST_SCOPE_EXIT_DETAIL_PARAM_THIS(id) \
285     BOOST_PP_SEQ_CAT( (boost_se_param_this_)(id) )
286 
287 #define BOOST_SCOPE_EXIT_DETAIL_PARAM(id, i, var) \
288     BOOST_PP_SEQ_CAT( (boost_se_param_)(i)(_)(id) )
289 
290 #define BOOST_SCOPE_EXIT_DETAIL_PARAM_T(id, i, var) \
291     BOOST_PP_SEQ_CAT( (boost_se_param_t_)(i)(_)(id) )
292 
293 #define BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(id, i, var) \
294     BOOST_PP_SEQ_CAT( (boost_se_capture_t_)(i)(_)(id) )
295 
296 #define BOOST_SCOPE_EXIT_AUX_WRAPPED(id, i) \
297     BOOST_PP_SEQ_CAT( (boost_se_wrapped_t_)(i)(_)(id) )
298 
299 #define BOOST_SCOPE_EXIT_AUX_DEREF(id, i, var) \
300     ::boost::scope_exit::detail::deref(var, \
301             static_cast<BOOST_SCOPE_EXIT_DETAIL_TAG(id, i)>(0))
302 
303 #define BOOST_SCOPE_EXIT_AUX_MEMBER(r, id, i, var) \
304     ::boost::scope_exit::detail::member< \
305         BOOST_SCOPE_EXIT_DETAIL_PARAM_T(id, i, var), \
306         BOOST_SCOPE_EXIT_DETAIL_TAG(id, i) \
307     > BOOST_SCOPE_EXIT_DETAIL_PARAM(id, i, var);
308 
309 #define BOOST_SCOPE_EXIT_AUX_ARG_DECL(r, id_ty, i, var) \
310     BOOST_PP_COMMA_IF(i) \
311     BOOST_PP_TUPLE_ELEM(2, 1, id_ty) \
312     BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty)):: \
313             BOOST_SCOPE_EXIT_DETAIL_PARAM_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
314                     i, var) \
315     var
316 
317 #define BOOST_SCOPE_EXIT_AUX_ARG(r, id, i, var) \
318     BOOST_PP_COMMA_IF(i) \
319     boost_se_params_->BOOST_SCOPE_EXIT_DETAIL_PARAM(id, i, var).value
320 
321 #define BOOST_SCOPE_EXIT_DETAIL_TAG_DECL(r, id, i, var) \
322     typedef void (*BOOST_SCOPE_EXIT_DETAIL_TAG(id, i))(int var);
323 
324 // Adam Butcher's workaround to deduce `this` type on MSVC revision < 10.
325 // Boost.Typeof for VC71's typeid-based workaround does not work to determine
326 // `this` type due to error C2355 being incorrectly reported. The typical
327 // avoidance strategy implemented below is to make an indirect compile-time
328 // constant by assigning an enum and use that as type-index-- this only works
329 // with the sizeof() approach and not with the typeid() approach. Lorenzo
330 // Caminiti extended this approach to work in type-of emulation mode. This code
331 // is very similar (and somewhat of a duplication) of the code in
332 // boost/typeof/msvc/typeof_impl.hpp). However, this code cannot be integrated
333 // into Boost.Typeof because its final API has to be a `typedef ...` and it
334 // cannot be a `typeof(...)`.
335 #if BOOST_SCOPE_EXIT_AUX_TYPEOF_THIS_MSVC_WORKAROUND_01
336 
337 #include <boost/config.hpp>
338 #include <boost/detail/workaround.hpp>
339 #include <boost/type_traits/integral_constant.hpp>
340 #include <boost/type_traits/is_function.hpp>
341 #include <boost/type_traits/enable_if.hpp>
342 
343 #if defined(BOOST_MSVC)
344 #   include <typeinfo>
345 #endif
346 
347 namespace boost { namespace scope_exit { namespace aux {
348         namespace msvc_typeof_this {
349 
350 // compile-time constant code
351 #if defined(BOOST_MSVC) && defined(_MSC_EXTENSIONS)
352 
353 template<int N> struct the_counter;
354 
355 template<typename T,int N = 5 /* for similarity */>
356 struct encode_counter {
__if_existsboost::scope_exit::aux::msvc_typeof_this::encode_counter357     __if_exists(the_counter<N + 256>) {
358         BOOST_STATIC_CONSTANT(unsigned,
359             count=(encode_counter<T,N + 257>::count));
360     }
__if_not_existsboost::scope_exit::aux::msvc_typeof_this::encode_counter361     __if_not_exists(the_counter<N + 256>) {
362         __if_exists(the_counter<N + 64>) {
363             BOOST_STATIC_CONSTANT(unsigned,
364                     count=(encode_counter<T,N + 65>::count));
365         }
366         __if_not_exists(the_counter<N + 64>) {
367             __if_exists(the_counter<N + 16>) {
368                 BOOST_STATIC_CONSTANT(unsigned,
369                         count=(encode_counter<T,N + 17>::count));
370             }
371             __if_not_exists(the_counter<N + 16>) {
372                 __if_exists(the_counter<N + 4>) {
373                     BOOST_STATIC_CONSTANT(unsigned,
374                             count=(encode_counter<T,N + 5>::count));
375                 }
376                 __if_not_exists(the_counter<N + 4>) {
377                     __if_exists(the_counter<N>) {
378                         BOOST_STATIC_CONSTANT(unsigned,
379                                 count=(encode_counter<T,N + 1>::count));
380                     }
381                     __if_not_exists(the_counter<N>) {
382                         BOOST_STATIC_CONSTANT(unsigned,count=N);
383                         typedef the_counter<N> type;
384                     }
385                 }
386             }
387         }
388     }
389 };
390 
391 #else // compile-time constant code
392 
393 template<int N> struct encode_counter : encode_counter<N - 1> {};
394 
395 template<> struct encode_counter<0> {};
396 
397 #endif // compile-time constant code
398 
399 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) // type-of code
400 
401 struct msvc_extract_type_default_param {};
402 
403 template<typename ID, typename T = msvc_extract_type_default_param>
404 struct msvc_extract_type;
405 
406 template<typename ID>
407 struct msvc_extract_type<ID, msvc_extract_type_default_param> {
408     template<bool>
409     struct id2type_impl;
410 
411     typedef id2type_impl<true> id2type;
412 };
413 
414 template<typename ID, typename T>
415 struct msvc_extract_type
416         : msvc_extract_type<ID, msvc_extract_type_default_param> {
417     template<>
418     struct id2type_impl<true> { // VC8.0 specific bug-feature.
419         typedef T type;
420     };
421 
422     template<bool>
423     struct id2type_impl;
424 
425     typedef id2type_impl<true> id2type;
426 };
427 
428 template<typename T, typename ID>
429 struct msvc_register_type : msvc_extract_type<ID, T> {};
430 
431 #else // type-of code
432 
433 template<typename ID>
434 struct msvc_extract_type {
435     struct id2type;
436 };
437 
438 template<typename T, typename ID>
439 struct msvc_register_type : msvc_extract_type<ID> {
440     typedef msvc_extract_type<ID> base_type;
441     struct base_type::id2type { // This uses nice VC6.5 and VC7.1 bug-features.
442         typedef T type;
443     };
444 };
445 
446 #endif // typeof code
447 
448 template<int Id>
449 struct msvc_typeid_wrapper {
450     typedef typename msvc_extract_type<boost::integral_constant<int, Id>
451             >::id2type id2type;
452     typedef typename id2type::type type;
453 };
454 
455 template<>
456 struct msvc_typeid_wrapper<4> {
457     typedef msvc_typeid_wrapper<4> type;
458 };
459 
460 template<typename T>
461 struct encode_type {
462     BOOST_STATIC_CONSTANT(unsigned, value = encode_counter<T>::count);
463     typedef typename msvc_register_type<T,
464             boost::integral_constant<int, value> >::id2type type;
465     BOOST_STATIC_CONSTANT(unsigned, next = value + 1);
466 };
467 
468 template<class T>
469 struct sizer {
470     typedef char(*type)[encode_type<T>::value];
471 };
472 
473 template<typename T>
474 typename boost::enable_if_<
475       !boost::is_function<T>::value
476     , typename sizer<T>::type
477 >::type encode_start(T const&);
478 
479 template<typename T>
480 typename boost::enable_if_<
481       boost::is_function<T>::value
482     , typename sizer<T>::type
483 >::type encode_start(T&);
484 
485 template<typename Organizer, typename T>
486 msvc_register_type<T, Organizer> typeof_register_type(const T&,
487         Organizer* = 0);
488 
489 } } } } // namespace
490 
491 #define BOOST_SCOPE_EXIT_AUX_TYPEDEF_TYPEOF_THIS_INDEX_(id) \
492     BOOST_PP_CAT(boost_se_thistype_index_, id)
493 
494 #define BOOST_SCOPE_EXIT_DETAIL_TYPEDEF_TYPEOF_THIS(id, ty, new_type) \
495     /* unfortunately, we need to go via this enum which causes this to be */ \
496     /* a typedef construct and not a typeof (so this code cannot be */ \
497     /* integrated into Boost.Typeof) */ \
498     enum { \
499         BOOST_SCOPE_EXIT_AUX_TYPEDEF_TYPEOF_THIS_INDEX_(id) = sizeof( \
500             *::boost::scope_exit::aux::msvc_typeof_this::encode_start(this)) \
501     }; \
502     typedef \
503         ty ::boost::scope_exit::aux::msvc_typeof_this::msvc_typeid_wrapper< \
504             BOOST_SCOPE_EXIT_AUX_TYPEDEF_TYPEOF_THIS_INDEX_(id) \
505         >::type \
506         new_type \
507     ;
508 
509 #else // TYPEOF_THIS_MSVC_WORKAROUND
510 
511 #define BOOST_SCOPE_EXIT_DETAIL_TYPEDEF_TYPEOF_THIS(id, ty, new_type) \
512     typedef /* trailing `EMPTY()` handles empty `ty` */ \
513         BOOST_PP_IIF(BOOST_PP_IS_EMPTY(ty BOOST_PP_EMPTY()), \
514             BOOST_TYPEOF \
515         , \
516             BOOST_TYPEOF_TPL \
517         )(this) \
518         new_type \
519     ;
520 
521 #endif // TYPEOF_THIS_MSVC_WORKAROUND
522 
523 #if BOOST_SCOPE_EXIT_AUX_TPL_GCC_WORKAROUND_01
524 
525 #define BOOST_SCOPE_EXIT_AUX_PARAMS_T_CTOR(id, ty, captures, has_this) \
526     /* expand to nothing */
527 
528 #define BOOST_SCOPE_EXIT_DETAIL_PARAM_INIT(r, id, i, var) \
529     BOOST_PP_COMMA_IF(i) { BOOST_SCOPE_EXIT_AUX_DEREF(id, i, var) }
530 
531 #define BOOST_SCOPE_EXIT_AUX_PARAMS_INIT(id, captures, has_this) \
532     BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(has_this, \
533             BOOST_PP_LIST_IS_CONS(captures)), \
534         = { \
535     ) \
536     BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_DETAIL_PARAM_INIT, id, captures) \
537     BOOST_PP_COMMA_IF(BOOST_PP_BITAND(BOOST_PP_LIST_IS_CONS(captures), \
538             has_this)) \
539     BOOST_PP_EXPR_IIF(has_this, this) /* no extra {...} needed here */ \
540     BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(has_this, \
541             BOOST_PP_LIST_IS_CONS(captures)), \
542         } /* trailing `;` will be added by the caller */ \
543     )
544 
545 #else // TPL_GCC_WORKAROUND
546 
547 #define BOOST_SCOPE_EXIT_AUX_CTOR_ARG(r, id, i, var) \
548     BOOST_PP_COMMA_IF(i) \
549     BOOST_SCOPE_EXIT_DETAIL_PARAM_T(id, i, var) & BOOST_PP_CAT(a, i)
550 
551 #define BOOST_SCOPE_EXIT_AUX_MEMBER_INIT(r, id, i, var) \
552     BOOST_PP_COMMA_IF(i) \
553     BOOST_SCOPE_EXIT_DETAIL_PARAM(id, i, var) ( BOOST_PP_CAT(a, i) )
554 
555 #define BOOST_SCOPE_EXIT_AUX_CTOR_ARG_THIS_NAME(id) \
556     BOOST_PP_CAT(boost_se_this_arg_, id)
557 
558 #define BOOST_SCOPE_EXIT_AUX_CTOR_ARG_THIS(id, ty, comma01) \
559     BOOST_PP_COMMA_IF(comma01) \
560     ty BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id)::BOOST_SCOPE_EXIT_AUX_THIS_T(id) \
561             BOOST_SCOPE_EXIT_AUX_CTOR_ARG_THIS_NAME(id) /* ptr so no & */
562 
563 #define BOOST_SCOPE_EXIT_AUX_MEMBER_THIS_INIT(id, comma01) \
564     BOOST_PP_COMMA_IF(comma01) \
565     BOOST_SCOPE_EXIT_DETAIL_PARAM_THIS(id)( \
566             BOOST_SCOPE_EXIT_AUX_CTOR_ARG_THIS_NAME(id))
567 
568 #define BOOST_SCOPE_EXIT_AUX_PARAMS_T_CTOR(id, ty, captures, has_this) \
569     BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id)( \
570         BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_CTOR_ARG, id, captures) \
571         BOOST_PP_IIF(has_this, \
572             BOOST_SCOPE_EXIT_AUX_CTOR_ARG_THIS \
573         , \
574             BOOST_PP_TUPLE_EAT(3) \
575         )(id, ty, BOOST_PP_LIST_IS_CONS(captures)) \
576     ) \
577         BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(BOOST_PP_LIST_IS_CONS(captures), \
578                 has_this), \
579             : \
580         ) \
581         BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_MEMBER_INIT, id, \
582                 captures) \
583         BOOST_PP_IIF(has_this, \
584             BOOST_SCOPE_EXIT_AUX_MEMBER_THIS_INIT \
585         , \
586             BOOST_PP_TUPLE_EAT(2) \
587         )(id, BOOST_PP_LIST_IS_CONS(captures)) \
588     {}
589 
590 #define BOOST_SCOPE_EXIT_DETAIL_PARAM_INIT(r, id, i, var) \
591     BOOST_PP_COMMA_IF(i) BOOST_SCOPE_EXIT_AUX_DEREF(id,i,var)
592 
593 #define BOOST_SCOPE_EXIT_AUX_PARAMS_INIT(id, captures, has_this) \
594     BOOST_PP_LPAREN_IF(BOOST_PP_BITOR(has_this, \
595             BOOST_PP_LIST_IS_CONS(captures))) \
596     BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_DETAIL_PARAM_INIT, id, captures) \
597     BOOST_PP_COMMA_IF(BOOST_PP_BITAND(BOOST_PP_LIST_IS_CONS(captures), \
598             has_this)) \
599     BOOST_PP_EXPR_IIF(has_this, this) \
600     BOOST_PP_RPAREN_IF(BOOST_PP_BITOR(has_this, \
601             BOOST_PP_LIST_IS_CONS(captures)))
602 
603 #endif // TPL_GCC_WORKAROUND
604 
605 #if defined(BOOST_TYPEOF_EMULATION)
606 
607 #define BOOST_SCOPE_EXIT_DETAIL_CAPTURE_DECL(r, id_ty, i, var) \
608     struct BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), i) \
609         /* no need to use TYPEOF_TPL here because it's within inheritance */ \
610         : BOOST_TYPEOF(::boost::scope_exit::detail::wrap( \
611                 BOOST_SCOPE_EXIT_AUX_DEREF(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
612                         i, var))) \
613     {}; \
614     typedef BOOST_PP_TUPLE_ELEM(2, 1, id_ty) \
615         BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), i)::type\
616         BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
617                 i, var) \
618     ;
619 
620 #elif defined(BOOST_INTEL)
621 
622 #define BOOST_SCOPE_EXIT_DETAIL_CAPTURE_DECL(r, id_ty, i, var) \
623     typedef \
624         /* no TYPEOF_TPL here because uses TYPEOF_KEYWORD directly */ \
625         BOOST_TYPEOF_KEYWORD(BOOST_SCOPE_EXIT_AUX_DEREF( \
626                 BOOST_PP_TUPLE_ELEM(2, 0, id_ty), i, var)) \
627         BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
628                 i, var) \
629     ;
630 
631 #else
632 
633 #define BOOST_SCOPE_EXIT_DETAIL_CAPTURE_DECL(r, id_ty, i, var) \
634     typedef \
635         /* no need to use TYPEOF_TPL here because it's a typedef */ \
636         BOOST_TYPEOF(::boost::scope_exit::detail::wrap( \
637                 BOOST_SCOPE_EXIT_AUX_DEREF(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
638                         i, var))) \
639         BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), i) \
640     ; \
641     typedef BOOST_PP_TUPLE_ELEM(2, 1, id_ty) \
642         BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), i)::type\
643         BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
644                 i, var) \
645     ;
646 
647 #endif
648 
649 #define BOOST_SCOPE_EXIT_DETAIL_PARAM_DECL(r, id_ty, i, var) \
650     typedef \
651         BOOST_SCOPE_EXIT_DETAIL_CAPTURE_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
652                 i, var) \
653         BOOST_SCOPE_EXIT_DETAIL_PARAM_T(BOOST_PP_TUPLE_ELEM(2, 0, id_ty), \
654                 i, var) \
655     ;
656 
657 // Traits.
658 
659 #define BOOST_SCOPE_EXIT_AUX_TRAITS_OP_CAPTURE(d, captures, this01, capture) \
660     (BOOST_PP_LIST_APPEND(captures, (capture, BOOST_PP_NIL)), this01)
661 
662 #define BOOST_SCOPE_EXIT_AUX_TRAITS_OP_THIS(d, captures, this01, this_) \
663     (captures, 1 /* has this (note, no error if multiple this_) */)
664 
665 #define BOOST_SCOPE_EXIT_AUX_TRAITS_OP(d, captures_this, capture) \
666     BOOST_PP_IIF(BOOST_SCOPE_EXIT_AUX_PP_KEYWORD_IS_THISUNDERSCORE_BACK(\
667             capture), \
668         BOOST_SCOPE_EXIT_AUX_TRAITS_OP_THIS \
669     , \
670         BOOST_SCOPE_EXIT_AUX_TRAITS_OP_CAPTURE \
671     )(d, BOOST_PP_TUPLE_ELEM(2, 0, captures_this), \
672             BOOST_PP_TUPLE_ELEM(2, 1, captures_this), capture)
673 
674 // ref_val: & | =
675 #define BOOST_SCOPE_EXIT_AUX_TRAITS_ALL_OP(ref_val, traits) \
676     ( \
677         BOOST_PP_LIST_APPEND((ref_val, BOOST_PP_NIL), \
678                 BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
679     , \
680         BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits) \
681     )
682 
683 #define BOOST_SCOPE_EXIT_AUX_TRAITS(captures) \
684     BOOST_PP_LIST_FOLD_LEFT(BOOST_SCOPE_EXIT_AUX_TRAITS_OP, \
685             (BOOST_PP_NIL, 0), captures)
686 
687 #define BOOST_SCOPE_EXIT_AUX_TRAITS_ALL(captures) \
688     BOOST_SCOPE_EXIT_AUX_TRAITS_ALL_OP(BOOST_PP_LIST_FIRST(captures), \
689             BOOST_SCOPE_EXIT_AUX_TRAITS(BOOST_PP_LIST_REST(captures)))
690 
691 #define BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits) \
692     BOOST_PP_TUPLE_ELEM(2, 0, traits)
693 
694 #define BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits) \
695     BOOST_PP_TUPLE_ELEM(2, 1, traits)
696 
697 #ifndef BOOST_NO_CXX11_LAMBDAS
698 
699 namespace boost { namespace scope_exit { namespace aux {
700 
701 template<typename This = void>
702 struct guard { // With object `this_` (for backward compatibility).
guardboost::scope_exit::aux::guard703     explicit guard(This _this) : this_(_this) {}
~guardboost::scope_exit::aux::guard704     ~guard() { if(f_) f_(this_); }
705     template<typename Lambda>
operator =boost::scope_exit::aux::guard706     void operator=(Lambda f) { f_ = f; }
707 private:
708     This this_;
709     boost::function<void (This)> f_;
710 };
711 
712 template<>
713 struct guard<void> { // Without object `this_` (could capture `this` directly).
~guardboost::scope_exit::aux::guard714     ~guard() { if(f_) f_(); }
715     template<typename Lambda>
operator =boost::scope_exit::aux::guard716     void operator=(Lambda f) { f_ = f; }
717 private:
718     boost::function<void (void)> f_;
719 };
720 
721 } } } // namespace
722 
723 #define BOOST_SCOPE_EXIT_AUX_LAMBDA_PARAMS(id) \
724     BOOST_PP_CAT(boost_se_lambda_params_, id)
725 
726 #define BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_CAPTURE_TYPE(id) \
727     BOOST_PP_CAT(boost_se_lambda_this_t_, id)
728 
729 #define BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_PARAM_TYPE(id) \
730     BOOST_PP_CAT(boost_se_lambda_this_capture_t_, id)
731 
732 #define BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_TYPE(id, ty) \
733     ty BOOST_SCOPE_EXIT_AUX_LAMBDA_PARAMS(id):: \
734             BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_PARAM_TYPE(id)
735 
736 // Precondition: HAS_THIS(traits).
737 #define BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_TYPEDEFS(id, ty, traits) \
738     BOOST_SCOPE_EXIT_DETAIL_TYPEDEF_TYPEOF_THIS(id, ty, \
739             BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_CAPTURE_TYPE(id)) \
740     /* capture type for workaround GCC internal error (even on later C++11) */ \
741     struct BOOST_SCOPE_EXIT_AUX_LAMBDA_PARAMS(id) { \
742         typedef BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_CAPTURE_TYPE(id) \
743                 BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_PARAM_TYPE(id); \
744     };
745 
746 #define BOOST_SCOPE_EXIT_AUX_IMPL_LAMBDA(id, ty, traits) \
747     BOOST_PP_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
748         /* no need for TYPEDEF THIS MSVC workaround on C++11 */ \
749         BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_TYPEDEFS \
750     , \
751         BOOST_PP_TUPLE_EAT(3) \
752     )(id, ty, traits) \
753     ::boost::scope_exit::aux::guard< \
754         BOOST_PP_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
755             BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_TYPE \
756         , \
757             BOOST_PP_TUPLE_EAT(2) \
758         )(id, ty) \
759     > BOOST_SCOPE_EXIT_AUX_GUARD(id) \
760         BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
761             (this) \
762         ) \
763     ; \
764     BOOST_SCOPE_EXIT_AUX_GUARD(id) = [ \
765         BOOST_PP_LIST_ENUM(BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
766     ]( \
767         BOOST_PP_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
768             BOOST_SCOPE_EXIT_AUX_LAMBDA_THIS_TYPE \
769         , \
770             BOOST_PP_TUPLE_EAT(2) \
771         )(id, ty) \
772         BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), this_) \
773     ) mutable /* can change value captures (as with SCOPE_EXIT) */ -> void
774 
775 #endif // Lambdas.
776 
777 #if defined(BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS) && \
778         !defined(BOOST_NO_CXX11_LAMBDAS) // Use lambda for SCOPE_EXIT (not just _ALL).
779 
780 #define BOOST_SCOPE_EXIT_AUX_IMPL(id, ty, traits) \
781     BOOST_SCOPE_EXIT_AUX_IMPL_LAMBDA(id, ty, traits)
782 
783 #else // Not using lambdas.
784 
785 // ty: EMPTY() | typename
786 #define BOOST_SCOPE_EXIT_AUX_IMPL(id, ty, traits) \
787     BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_DETAIL_TAG_DECL, id, \
788             BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
789     BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_DETAIL_CAPTURE_DECL, (id, ty), \
790             BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
791     BOOST_PP_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
792         BOOST_SCOPE_EXIT_DETAIL_TYPEDEF_TYPEOF_THIS \
793     , \
794         BOOST_PP_TUPLE_EAT(3) \
795     )(id, ty, BOOST_SCOPE_EXIT_AUX_THIS_CAPTURE_T(id)) \
796     struct BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id) { \
797         /* interim capture types to workaround internal errors on old GCC */ \
798         BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_DETAIL_PARAM_DECL, (id, ty), \
799                 BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
800         BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
801             typedef BOOST_SCOPE_EXIT_AUX_THIS_CAPTURE_T(id) \
802                     BOOST_SCOPE_EXIT_AUX_THIS_T(id) ; \
803         ) \
804         BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_MEMBER, id, \
805                 BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
806         BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
807             BOOST_SCOPE_EXIT_AUX_THIS_T(id) \
808                     BOOST_SCOPE_EXIT_DETAIL_PARAM_THIS(id) ; \
809         ) \
810         BOOST_SCOPE_EXIT_AUX_PARAMS_T_CTOR(id, ty, \
811                 BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits), \
812                 BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits)) \
813     } BOOST_SCOPE_EXIT_AUX_PARAMS(id) \
814         BOOST_SCOPE_EXIT_AUX_PARAMS_INIT(id, \
815                 BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits), \
816                 BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits)) \
817     ; \
818     ::boost::scope_exit::detail::declared< \
819         ::boost::scope_exit::detail::resolve< \
820             sizeof(BOOST_SCOPE_EXIT_AUX_ARGS) \
821         >::cmp1<0>::cmp2 \
822     > BOOST_SCOPE_EXIT_AUX_ARGS; \
823     BOOST_SCOPE_EXIT_AUX_ARGS.value = &BOOST_SCOPE_EXIT_AUX_PARAMS(id); \
824     struct BOOST_SCOPE_EXIT_AUX_GUARD_T(id) { \
825         BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id)* boost_se_params_; \
826         BOOST_SCOPE_EXIT_AUX_GUARD_T(id) (void* boost_se_params) \
827             : boost_se_params_( \
828                     (BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id)*)boost_se_params) \
829         {} \
830         ~BOOST_SCOPE_EXIT_AUX_GUARD_T(id)() { \
831             boost_se_body( \
832                 BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_ARG, id, \
833                         BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
834                 BOOST_PP_COMMA_IF(BOOST_PP_BITAND(BOOST_PP_LIST_IS_CONS( \
835                         BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)), \
836                         BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits))) \
837                 BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS( \
838                         traits), \
839                     boost_se_params_->BOOST_SCOPE_EXIT_DETAIL_PARAM_THIS(id) \
840                 ) \
841             ); \
842         } \
843         static void boost_se_body( \
844             BOOST_PP_LIST_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_ARG_DECL, (id, ty), \
845                     BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)) \
846             BOOST_PP_COMMA_IF(BOOST_PP_BITAND(BOOST_PP_LIST_IS_CONS( \
847                     BOOST_SCOPE_EXIT_AUX_TRAITS_CAPTURES(traits)), \
848                     BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits))) \
849             BOOST_PP_EXPR_IIF(BOOST_SCOPE_EXIT_AUX_TRAITS_HAS_THIS(traits), \
850                 ty BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id):: \
851                         BOOST_SCOPE_EXIT_AUX_THIS_T(id) this_ \
852             ) \
853         )
854 
855 #endif // Using lambdas.
856 
857 // PUBLIC //
858 
859 #if defined(BOOST_NO_CXX11_VARIADIC_MACROS) // No variadic macros (sequences only).
860 #   define BOOST_SCOPE_EXIT_ID(id, void_or_seq) \
861         BOOST_SCOPE_EXIT_AUX_IMPL(id, BOOST_PP_EMPTY(), \
862                 BOOST_SCOPE_EXIT_AUX_TRAITS( \
863                         BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(void_or_seq)))
864 #   define BOOST_SCOPE_EXIT_ID_TPL(id, void_or_seq) \
865         BOOST_SCOPE_EXIT_AUX_IMPL(id, typename, \
866                 BOOST_SCOPE_EXIT_AUX_TRAITS( \
867                         BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(void_or_seq)))
868 #   define BOOST_SCOPE_EXIT(void_or_seq) \
869         BOOST_SCOPE_EXIT_ID(BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, \
870                 void_or_seq)
871 #   define BOOST_SCOPE_EXIT_TPL(void_or_seq) \
872         BOOST_SCOPE_EXIT_ID_TPL(BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, \
873                 void_or_seq)
874 #   if !defined(BOOST_NO_CXX11_LAMBDAS)
875 #       define BOOST_SCOPE_EXIT_ALL_ID(id, seq) \
876             BOOST_SCOPE_EXIT_AUX_IMPL_LAMBDA(id, \
877                     /* C++11 allows to use typename outside templates so */ \
878                     /* always typename here and no need for ..._ALL_TPL */ \
879                     /* (if a C++11 compiler does not implement this use of */ \
880                     /* typename, always use `this` instead of `this_`) */ \
881                     typename, \
882                     BOOST_SCOPE_EXIT_AUX_TRAITS_ALL( \
883                             BOOST_SCOPE_EXIT_AUX_PP_NON_VOID_LIST(seq)))
884 #       define BOOST_SCOPE_EXIT_ALL(seq) \
885             BOOST_SCOPE_EXIT_ALL_ID( \
886                     BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, seq)
887 #   endif
888 #else // Variadic macros (both sequences and variadic tuples).
889 #   define BOOST_SCOPE_EXIT_ID(id, ...) \
890         BOOST_SCOPE_EXIT_AUX_IMPL(id, BOOST_PP_EMPTY(), \
891                 BOOST_SCOPE_EXIT_AUX_TRAITS( \
892                         BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(__VA_ARGS__)))
893 #   define BOOST_SCOPE_EXIT_ID_TPL(id, ...) \
894         BOOST_SCOPE_EXIT_AUX_IMPL(id, typename, \
895                 BOOST_SCOPE_EXIT_AUX_TRAITS( \
896                         BOOST_SCOPE_EXIT_AUX_PP_VOID_LIST(__VA_ARGS__)))
897 #   define BOOST_SCOPE_EXIT(...) \
898         BOOST_SCOPE_EXIT_ID(BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, \
899                 __VA_ARGS__)
900 #   define BOOST_SCOPE_EXIT_TPL(...) \
901         BOOST_SCOPE_EXIT_ID_TPL(BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, \
902                 __VA_ARGS__)
903 #   if !defined(BOOST_NO_CXX11_LAMBDAS)
904 #       define BOOST_SCOPE_EXIT_ALL_ID(id, ...) \
905             BOOST_SCOPE_EXIT_AUX_IMPL_LAMBDA(id, \
906                     /* C++11 allows to use typename outside templates so */ \
907                     /* always typename here and no need for ..._ALL_TPL */ \
908                     /* (if a C++11 compiler does not implement this use of */ \
909                     /* typename, always use `this` instead of `this_`) */ \
910                     typename, \
911                     BOOST_SCOPE_EXIT_AUX_TRAITS_ALL( \
912                             BOOST_SCOPE_EXIT_AUX_PP_NON_VOID_LIST( \
913                                     __VA_ARGS__)))
914 #       define BOOST_SCOPE_EXIT_ALL(...) \
915             BOOST_SCOPE_EXIT_ALL_ID( \
916                     BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER, __VA_ARGS__)
917 #   endif
918 #endif // Variadics.
919 
920 #if defined(BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS) && \
921         !defined(BOOST_NO_CXX11_LAMBDAS) // Use lambdas for SCOPE_EXIT (not just ALL).
922 #   define BOOST_SCOPE_EXIT_END_ID(id) \
923         ; /* lambdas ended with just `;` */
924 #else // Not using lambdas.
925 #   define BOOST_SCOPE_EXIT_END_ID(id) \
926         } BOOST_SCOPE_EXIT_AUX_GUARD(id)(BOOST_SCOPE_EXIT_AUX_ARGS.value);
927 #endif // Using lambdas.
928 #define BOOST_SCOPE_EXIT_END \
929     BOOST_SCOPE_EXIT_END_ID(BOOST_SCOPE_EXIT_AUX_PP_LINE_COUNTER)
930 
931 // DOCUMENTATION //
932 
933 #else // DOXYGEN
934 
935 /** @file
936 @brief Scope exits allow to execute arbitrary code when the enclosing scope
937 exits.
938 */
939 
940 /**
941 @brief This macro declares a scope exit.
942 
943 The scope exit declaration schedules the execution of the scope exit body at
944 the exit of the enclosing scope:
945 
946 @code
947     { // Some local scope.
948         ...
949         BOOST_SCOPE_EXIT(capture_list) {
950             ... // Body code.
951         } BOOST_SCOPE_EXIT_END
952         ...
953     }
954 @endcode
955 
956 The enclosing scope must be local.
957 If multiple scope exits are declared within the same enclosing scope, the scope
958 exit bodies are executed in the reversed order of their declarations.
959 Note how the end of the scope exit body must be marked by
960 @RefMacro{BOOST_SCOPE_EXIT_END}.
961 
962 @Params
963 @Param{capture_list,
964 On compilers that support variadic macros (see also Boost.Config
965 <c>BOOST_NO_CXX11_VARIADIC_MACROS</c>)\, the capture list syntax is defined by the
966 following grammar:
967 @code
968     capture_list:
969             void | capture_tuple | capture_sequence
970     capture_tuple:
971             capture\, capture\, ...
972     capture_sequence:
973             (capture) (capture) ...
974     capture:
975             [&]variable | this_
976 @endcode
977 On compilers that do not support variadic macros\, <c>capture_tuple</c> cannot
978 be used:
979 @code
980     capture_list:
981             void | capture_sequence
982 @endcode
983 Furthermore\, if @RefMacro{BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS} is defined on
984 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
985 @RefMacro{BOOST_SCOPE_EXIT_END} and <c>this</c> can be used instead of
986 <c>this_</c>:
987 @code
988     capture:
989             [&]variable | this_ | this
990 @endcode
991 
992 (Lexical conventions: <c>token1 | token2</c> means either <c>token1</c> or
993 <c>token2</c>; <c>[token]</c> means either <c>token</c> or nothing;
994 <c>{expression}</c> means the tokens resulting from the expression.)
995 }
996 @EndParams
997 
998 Note that on compilers that support variadic macros (most of moder compliers
999 and all C++11 compilers), the capture list can be specified as a
1000 comma-separated list of tokens (this is the preferred syntax).
1001 However, on all compilers the same macro @RefMacro{BOOST_SCOPE_EXIT} also
1002 allows to specify the capture list as a Boost.Preprocessor sequence of tokens
1003 (for supporting compilers without variadic macros and for backward compatibility with older versions of this library).
1004 
1005 The name <c>variable</c> of each captured variable must be a valid name in the
1006 enclosing scope and it must appear exactly once in the capture list.
1007 If a capture starts with the ampersand sign <c>&</c>, the corresponding
1008 variable will be available by reference within the scope exit body; otherwise,
1009 a copy of the variable will be made at the point of the scope exit declaration
1010 and that copy will be available inside the scope exit body (in this case, the
1011 variable's type must be <c>CopyConstructible</c>).
1012 
1013 From within a member function, the object <c>this</c> can be captured using the
1014 special name <c>this_</c> in both the capture list and the scope exit body
1015 (using <c>this</c> instead of <c>this_</c> in the scope exit body leads to
1016 undefined behaviour).
1017 
1018 It is possible to capture no variable by specifying the capture list as
1019 <c>void</c> (regardless of variadic macro support).
1020 
1021 Only variables listed in the capture list, static variables, <c>extern</c>
1022 variables, global variables, functions, and enumerations from the enclosing
1023 scope can be used inside the scope exit body.
1024 
1025 On various GCC versions the special macro @RefMacro{BOOST_SCOPE_EXIT_TPL} must
1026 be used instead of @RefMacro{BOOST_SCOPE_EXIT} within templates (to maximize
1027 portability, it is recommended to always use @RefMacro{BOOST_SCOPE_EXIT_TPL}
1028 within templates).
1029 
1030 On C++11, it is possible capture all variables in scope without listing their
1031 names one-by-one using the macro @RefMacro{BOOST_SCOPE_EXIT_ALL}.
1032 
1033 In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_ID} must be used
1034 instead of @RefMacro{BOOST_SCOPE_EXIT} when it is necessary to expand multiple
1035 scope exit declarations on the same line.
1036 
1037 @Warning The implementation executes the scope exit body within a destructor
1038 thus the scope exit body must never throw in order to comply with STL exception
1039 safety requirements.
1040 
1041 @Note The implementation uses Boost.Typeof to automatically deduce the types of
1042 the captured variables.
1043 In order to compile code in type-of emulation mode, all types must be properly
1044 registered with Boost.Typeof (see the
1045 @RefSect{getting_started, Getting Started} section).
1046 
1047 @See @RefSect{tutorial, Tutorial} section,
1048 @RefSect{getting_started, Getting Started} section,
1049 @RefSect{no_variadic_macros, No Variadic Macros} section,
1050 @RefMacro{BOOST_SCOPE_EXIT_TPL}, @RefMacro{BOOST_SCOPE_EXIT_ALL},
1051 @RefMacro{BOOST_SCOPE_EXIT_END}, @RefMacro{BOOST_SCOPE_EXIT_ID}.
1052 */
1053 #define BOOST_SCOPE_EXIT(capture_list)
1054 
1055 /**
1056 @brief This macro is a workaround for various versions of GCC to declare scope
1057 exits within templates.
1058 
1059 Various versions of the GCC compiler do not compile @RefMacro{BOOST_SCOPE_EXIT}
1060 inside function templates.
1061 As a workaround, @RefMacro{BOOST_SCOPE_EXIT_TPL} should be used instead of
1062 @RefMacro{BOOST_SCOPE_EXIT} in these cases:
1063 
1064 @code
1065     { // Some local scope.
1066         ...
1067         BOOST_SCOPE_EXIT_TPL(capture_list) {
1068             ... // Body code.
1069         } BOOST_SCOPE_EXIT_END
1070         ...
1071     }
1072 @endcode
1073 
1074 The syntax of @RefMacro{BOOST_SCOPE_EXIT_TPL} is the exact same as the one of
1075 @RefMacro{BOOST_SCOPE_EXIT} (see @RefMacro{BOOST_SCOPE_EXIT} for more
1076 information).
1077 
1078 On C++11 compilers, @RefMacro{BOOST_SCOPE_EXIT_TPL} is not needed because
1079 @RefMacro{BOOST_SCOPE_EXIT} always compiles on GCC versions that support C++11.
1080 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.
1081 It is recommended to always use @RefMacro{BOOST_SCOPE_EXIT_TPL} within
1082 templates so to maximize portability.
1083 
1084 In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_ID_TPL} must be used
1085 instead of @RefMacro{BOOST_SCOPE_EXIT_TPL} when it is necessary to expand
1086 multiple scope exit declarations on the same line within templates.
1087 
1088 @Note The issue in compiling scope exit declarations that some GCC versions
1089 have is illustrated by the following code (see also
1090 <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37920">GCC bug 37920</a>):
1091 @code
1092     template<class T>
1093     void f(T const& x) {
1094         int i = 0;
1095         struct local {
1096             typedef __typeof__(i) typeof_i;
1097             typedef __typeof__(x) typeof_x;
1098         };
1099         typedef local::typeof_i i_type;
1100         typedef local::typeof_x x_type;
1101     }
1102 
1103     int main(void) { f(0); }
1104 @endcode
1105 This can be fixed by adding <c>typename</c> in front of <c>local::typeof_i</c>
1106 and <c>local::typeof_x</c> (which is the approach followed by the
1107 implementation of the @RefMacro{BOOST_SCOPE_EXIT_TPL} macro).
1108 
1109 @Note Although @RefMacro{BOOST_SCOPE_EXIT_TPL} has the same suffix as
1110 <c>BOOST_TYPEOF_TPL</c>, it does not follow the Boost.Typeof convention.
1111 
1112 @See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_SCOPE_EXIT},
1113 @RefMacro{BOOST_SCOPE_EXIT_END}, @RefMacro{BOOST_SCOPE_EXIT_ID_TPL}.
1114 */
1115 #define BOOST_SCOPE_EXIT_TPL(capture_list)
1116 
1117 /**
1118 @brief This macro allows to expand multiple scope exit declarations on the same
1119 line.
1120 
1121 This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT} but it can be expanded
1122 multiple times on the same line if different identifiers <c>id</c> are provided
1123 for each expansion (see @RefMacro{BOOST_SCOPE_EXIT} for more information).
1124 
1125 @Params
1126 @Param{id,
1127 A unique identifier token which can be concatenated by the preprocessor
1128 (<c>__LINE__</c>\, <c>scope_exit_number_1_on_line_123</c>\, a combination of
1129 alphanumeric tokens\, etc).
1130 }
1131 @Param{capture_list,
1132 Same as the <c>capture_list</c> parameter of the @RefMacro{BOOST_SCOPE_EXIT}
1133 macro.
1134 }
1135 @EndParams
1136 
1137 @Note This macro can be useful when the scope exit macros are expanded
1138 within user-defined macros (because nested macros expand on the same line).
1139 On some compilers (e.g., MSVC which supports the non standard
1140 <c>__COUNTER__</c> macro) it might not be necessary to use this macro but
1141 the use of this macro is always necessary to ensure portability when expanding
1142 multiple scope exit declarations on the same line.
1143 
1144 @See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_SCOPE_EXIT},
1145 @RefMacro{BOOST_SCOPE_EXIT_END_ID}, @RefMacro{BOOST_SCOPE_EXIT_ALL_ID},
1146 @RefMacro{BOOST_SCOPE_EXIT_ID_TPL}.
1147 */
1148 #define BOOST_SCOPE_EXIT_ID(id, capture_list)
1149 
1150 /**
1151 @brief This macro is required to expand multiple scope exit declarations on the
1152 same line within templates on various versions of GCC.
1153 
1154 This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT_TPL} but it can be
1155 expanded multiple times on the same line if different identifiers <c>id</c> are
1156 provided for each expansion (see @RefMacro{BOOST_SCOPE_EXIT_TPL} for more
1157 information).
1158 As with @RefMacro{BOOST_SCOPE_EXIT_TPL}, it is recommended to always use this
1159 macro when expanding scope exits multiple times on the same line within
1160 templates.
1161 
1162 @Params
1163 @Param{id,
1164 A unique identifier token which can be concatenated by the preprocessor
1165 (<c>__LINE__</c>\, <c>scope_exit_number_1_on_line_123</c>\, a combination of
1166 alphanumeric tokens\, etc).
1167 }
1168 @Param{capture_list,
1169 Same as the <c>capture_list</c> parameter of the
1170 @RefMacro{BOOST_SCOPE_EXIT_TPL} macro.
1171 }
1172 @EndParams
1173 
1174 @Note This macro can be useful when the scope exit macros are expanded
1175 within user-defined macros (because nested macros expand on the same line).
1176 On some compilers (e.g., MSVC which supports the non standard
1177 <c>__COUNTER__</c> macro) it might not be necessary to use this macro but
1178 the use of this macro is always necessary to ensure portability when expanding
1179 multiple scope exit declarations on the same line.
1180 
1181 @See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_SCOPE_EXIT_TPL},
1182 @RefMacro{BOOST_SCOPE_EXIT_END_ID}, @RefMacro{BOOST_SCOPE_EXIT_ID},
1183 @RefMacro{BOOST_SCOPE_EXIT_ALL_ID}.
1184 */
1185 #define BOOST_SCOPE_EXIT_ID_TPL(id, capture_list)
1186 
1187 /**
1188 @brief This macro declares a scope exit that captures all variables in scope
1189 (C++11 only).
1190 
1191 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).
1192 A part from that, this macro works like @RefMacro{BOOST_SCOPE_EXIT} (see @RefMacro{BOOST_SCOPE_EXIT} for more information):
1193 
1194 @code
1195     { // Some local scope.
1196         ...
1197         BOOST_SCOPE_EXIT_ALL(capture_list) { // C++11 only.
1198             ... // Body code.
1199         }; // Use `;` instead of `BOOST_SCOPE_EXIT_END` (C++11 only).
1200         ...
1201     }
1202 @endcode
1203 
1204 Note how the end of the scope exit body declared by this macro must be marked
1205 by a semi-column <c>;</c> (and not by @RefMacro{BOOST_SCOPE_EXIT_END}).
1206 
1207 @Warning This macro is only available on C++11 compilers (specifically, on
1208 C++11 compilers that do not define the Boost.Config <c>BOOST_NO_CXX11_LAMBDAS</c>
1209 macro).
1210 It is not defined on non-C++11 compilers so its use on non-C++11 compilers will generate a compiler error.
1211 
1212 @Params
1213 @Param{capture_list,
1214 On compilers that support variadic macros (see also Boost.Config
1215 <c>BOOST_NO_CXX11_VARIADIC_MACROS</c>)\, the capture list syntax is defined by the
1216 following grammar:
1217 @code
1218 capture_list:
1219         capture_tuple | capture_sequence
1220 capture_tuple:
1221         {& | =} [\, capture\, capture\, ...]
1222 capture_sequence:
1223         {(&) | (=)} [(capture) (capture) ...]
1224 capture:
1225         [&]variable | this_
1226 @endcode
1227 On compilers that do not support variadic macros\, <c>capture_tuple</c> cannot
1228 be used:
1229 @code
1230     capture_list:
1231             void | capture_sequence
1232 @endcode
1233 Furthermore\, on C++11 compilers that support the use of <c>typename</c>
1234 outside templates\, also <c>this</c> can be used to capture the object at member
1235 function scope:
1236 @code
1237     capture:
1238             [&]variable | this_ | this
1239 @endcode
1240 
1241 (Lexical conventions: <c>token1 | token2</c> means either <c>token1</c> or
1242 <c>token2</c>; <c>[token]</c> means either <c>token</c> or nothing;
1243 <c>{expression}</c> means the token resulting from the expression.)
1244 }
1245 @EndParams
1246 
1247 Note that on compilers with variadic macro support (which should be all C++11
1248 compilers), the capture list can be specified as a comma-separated list.
1249 On all compilers, the same macro @RefMacro{BOOST_SCOPE_EXIT_ALL} also allows to
1250 specify the capture list as a Boost.Preprocessor sequence.
1251 
1252 The capture list must always contain at least the leading <c>&</c> or <c>=</c>
1253 so it can never be <c>void</c> (<c>BOOST_SCOPE_EXIT(void)</c> should be used
1254 to program scope exits with an empty capture list).
1255 
1256 In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_ALL_ID} must be used
1257 instead of @RefMacro{BOOST_SCOPE_EXIT_ALL} when it is necessary to expand
1258 multiple scope exit declarations on the same line.
1259 
1260 @Warning This macro capture list follows the exact same syntax of C++11 lambda
1261 captures which is unfortunately different from the syntax of
1262 @RefMacro{BOOST_SCOPE_EXIT} captures (unless programmers define the
1263 @RefMacro{BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS} macro).
1264 For example, like C++11 lambda functions, @RefMacro{BOOST_SCOPE_EXIT_ALL}
1265 requires to capture data members by capturing the object <c>this</c> while
1266 @RefMacro{BOOST_SCOPE_EXIT} allows to capture data members directly and without
1267 capturing the object.
1268 
1269 @Warning The implementation executes the scope exit body within a destructor
1270 thus the scope exit body must never throw in order to comply with STL exception
1271 safety requirements.
1272 
1273 @Note This macro can always be used also within templates (so there is no need
1274 for a <c>BOOST_SCOPE_EXIT_ALL_TPL</c> macro).
1275 
1276 @See @RefSect{tutorial, Tutorial} section,
1277 @RefSect{no_variadic_macros, No Variadic Macros} section,
1278 @RefMacro{BOOST_SCOPE_EXIT}, @RefMacro{BOOST_SCOPE_EXIT_ALL_ID}.
1279 */
1280 #define BOOST_SCOPE_EXIT_ALL(capture_list)
1281 
1282 /**
1283 @brief This macro allows to expand on the same line multiple scope exits that
1284 capture all variables in scope (C++11 only).
1285 
1286 This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT_ALL} but it can be
1287 expanded multiple times on the same line if different identifiers <c>id</c> are
1288 provided for each expansion (see @RefMacro{BOOST_SCOPE_EXIT_ALL} for more
1289 information).
1290 As with @RefMacro{BOOST_SCOPE_EXIT_ALL}, this macro is only available on C++11
1291 compilers (specifically, on C++11 compilers that do not define the
1292 Boost.Config <c>BOOST_NO_CXX11_LAMBDAS</c> macro).
1293 
1294 @Params
1295 @Param{id,
1296 A unique identifier token which can be concatenated by the preprocessor
1297 (<c>__LINE__</c>\, <c>scope_exit_number_1_on_line_123</c>\, a combination of
1298 alphanumeric tokens\, etc).
1299 }
1300 @Param{capture_list,
1301 Same as the <c>capture_list</c> parameter of the
1302 @RefMacro{BOOST_SCOPE_EXIT_ALL} macro.
1303 }
1304 @EndParams
1305 
1306 @Note This macro can be useful when the scope exit macros are expanded
1307 within user-defined macros (because nested macros expand on the same line).
1308 On some compilers (e.g., MSVC which supports the non standard
1309 <c>__COUNTER__</c> macro) it might not be necessary to use this macro but
1310 the use of this macro is always necessary to ensure portability when expanding
1311 multiple scope exit declarations on the same line.
1312 
1313 @See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_SCOPE_EXIT_ALL},
1314 @RefMacro{BOOST_SCOPE_EXIT_ID}.
1315 */
1316 #define BOOST_SCOPE_EXIT_ALL_ID(id, capture_list)
1317 
1318 /**
1319 @brief This macro marks the end of a scope exit body.
1320 
1321 This macro must follow the closing curly bracket <c>}</c> that ends the body of
1322 either @RefMacro{BOOST_SCOPE_EXIT} or @RefMacro{BOOST_SCOPE_EXIT_TPL}:
1323 
1324 @code
1325     { // Some local scope.
1326         ...
1327         BOOST_SCOPE_EXIT(capture_list) {
1328             ... // Body code.
1329         } BOOST_SCOPE_EXIT_END
1330         ...
1331     }
1332 @endcode
1333 
1334 In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_END_ID} must be used
1335 instead of @RefMacro{BOOST_SCOPE_EXIT_END} when it is necessary to expand
1336 multiple scope exit bodies on the same line.
1337 
1338 @Note If programmers define the @RefMacro{BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS}
1339 macro on C++11 compilers, a semicolon <c>;</c> can be used instead of this
1340 macro.
1341 However, to maximize portability, it is recommended to always use
1342 @RefMacro{BOOST_SCOPE_EXIT_END}.
1343 
1344 @See @RefSect{tutorial, Tutorial} section, @RefMacro{BOOST_SCOPE_EXIT},
1345 @RefMacro{BOOST_SCOPE_EXIT_TPL}, @RefMacro{BOOST_SCOPE_EXIT_END_ID}.
1346 */
1347 #define BOOST_SCOPE_EXIT_END
1348 
1349 /**
1350 @brief This macro allows to terminate multiple scope exit bodies on the same
1351 line.
1352 
1353 This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT_END} but it can be
1354 expanded multiple times on the same line if different identifiers <c>id</c> are
1355 provided for each expansion (see @RefMacro{BOOST_SCOPE_EXIT_END} for more
1356 information).
1357 
1358 @Params
1359 @Param{id,
1360 A unique identifier token which can be concatenated by the preprocessor
1361 (<c>__LINE__</c>\, <c>scope_exit_number_1_on_line_123</c>\, a combination of
1362 alphanumeric tokens\, etc).
1363 }
1364 @EndParams
1365 
1366 @Note This macro can be useful when the scope exit macros are expanded
1367 within user-defined macros (because macros all expand on the same line).
1368 On some compilers (e.g., MSVC which supports the non standard
1369 <c>__COUNTER__</c> macro) it might not be necessary to use this macro but
1370 the use of this macro is always necessary to ensure portability when expanding
1371 multiple scope exit macros on the same line (because this library can only
1372 portably use <c>__LINE__</c> to internally generate unique identifiers).
1373 
1374 @See @RefMacro{BOOST_SCOPE_EXIT_ID}, @RefMacro{BOOST_SCOPE_EXIT_ID_TPL},
1375 @RefMacro{BOOST_SCOPE_EXIT_END}.
1376 */
1377 #define BOOST_SCOPE_EXIT_END_ID(id)
1378 
1379 /**
1380 @brief Force to use C++11 lambda functions to implement scope exits.
1381 
1382 If programmers define this configuration macro on a C++11 compiler for which
1383 the Boost.Config macro <c>BOOST_NO_CXX11_LAMBDAS</c> is not defined, the
1384 @RefMacro{BOOST_SCOPE_EXIT} and @RefMacro{BOOST_SCOPE_EXIT_TPL} macros will use
1385 C++11 lambda functions to declare scope exits.
1386 By default this macro is not defined.
1387 
1388 @Warning When scope exits are implemented using lambda functions, the syntax of
1389 the capture list follows the exact same syntax of C++11 lambda captures
1390 which is in general different from the legacy capture syntax of this library.
1391 For example, C++11 lambdas require to capture data members by capturing the
1392 object <c>this</c> while this library always allowed to capture data members
1393 directly.
1394 Therefore, when this configuration macro is defined,
1395 @RefMacro{BOOST_SCOPE_EXIT} and @RefMacro{BOOST_SCOPE_EXIT_TPL} are no longer
1396 backward compatible (and this is why this macro is not defined by default).
1397 
1398 A semicolon <c>;</c> can be used instead of @RefMacro{BOOST_SCOPE_EXIT_END}
1399 when this configuration macro is defined (but it is recommended to always use
1400 @RefMacro{BOOST_SCOPE_EXIT_END} so to maximize portability).
1401 
1402 @Note This configuration macro does not control the definition of
1403 @RefMacro{BOOST_SCOPE_EXIT_ALL} which is always and automatically defined on
1404 compilers that support C++11 lambda functions.
1405 
1406 @See @RefMacro{BOOST_SCOPE_EXIT}, @RefMacro{BOOST_SCOPE_EXIT_TPL},
1407 @RefMacro{BOOST_SCOPE_EXIT_END}.
1408 */
1409 #define BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS
1410 
1411 #endif // DOXYGEN
1412 
1413 #endif // BOOST_SCOPE_EXIT_HPP
1414 
1415