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

source code of boost/boost/scope_exit.hpp