Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / scope_exit.hpp
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
188 namespace 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).
194 template<int Dummy = 0>
195 struct declared
196 {
197     void* value;
198     static int const cmp2 = 0;
199     friend void operator>(int, declared const&) {}
200 };
201
202 struct undeclared { declared<> dummy[2]; };
203
204 template<int> struct resolve;
205
206 template<>
207 struct resolve<sizeof(declared<>)>
208 {
209     static const int cmp1 = 0;
210 };
211
212 template<>
213 struct resolve<sizeof(undeclared)>
214 {
215     template<int>
216     struct cmp1
217     {
218         static int const cmp2 = 0;
219     };
220 };
221
222 typedef void (*ref_tag)(int&);
223 typedef void (*val_tag)(int );
224
225 template<class T, class Tag> struct member;
226
227 template<class T>
228 struct 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
236 template<class T>
237 struct 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
245 template<class T> inline T& deref(T* p, ref_tag) { return *p; }
246 template<class T> inline T& deref(T& r, val_tag) { return  r; }
247
248 template<class T>
249 struct wrapper
250 {
251     typedef T type;
252 };
253
254 template<class T> wrapper<T> wrap(T&);
255
256 } } } // namespace
257
258 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
259 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::scope_exit::detail::wrapper, 1)
260
261 #define BOOST_SCOPE_EXIT_AUX_ARGS boost_scope_exit_aux_args
262 extern 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
348 namespace 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
354 template<int N> struct the_counter;
355
356 template<typename T,int N = 5 /* for similarity */>
357 struct 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     
394 template<int N> struct encode_counter : encode_counter<N - 1> {};
395
396 template<> struct encode_counter<0> {};
397
398 #endif // compile-time constant code
399
400 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) // type-of code
401
402 struct msvc_extract_type_default_param {};
403
404 template<typename ID, typename T = msvc_extract_type_default_param>
405 struct msvc_extract_type;
406
407 template<typename ID>
408 struct 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
415 template<typename ID, typename T>
416 struct 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
429 template<typename T, typename ID>
430 struct msvc_register_type : msvc_extract_type<ID, T> {};
431
432 #else // type-of code
433
434 template<typename ID>
435 struct msvc_extract_type {
436     struct id2type;
437 };
438
439 template<typename T, typename ID>
440 struct 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
449 template<int Id>
450 struct msvc_typeid_wrapper {
451     typedef typename msvc_extract_type<boost::mpl::int_<Id>
452             >::id2type id2type;
453     typedef typename id2type::type type;
454 };
455
456 template<>
457 struct msvc_typeid_wrapper<4> {
458     typedef msvc_typeid_wrapper<4> type;
459 };
460
461 template<typename T>
462 struct 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
469 template<class T>
470 struct sizer {
471     typedef char(*type)[encode_type<T>::value];
472 };
473
474 template<typename T>
475 typename boost::disable_if<
476       typename boost::is_function<T>::type
477     , typename sizer<T>::type
478 >::type encode_start(T const&);
479
480 template<typename T>
481 typename boost::enable_if<
482       typename boost::is_function<T>::type
483     , typename sizer<T>::type
484 >::type encode_start(T&);
485
486 template<typename Organizer, typename T>
487 msvc_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
700 namespace boost { namespace scope_exit { namespace aux {
701
702 template<typename This = void>
703 struct 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; }
708 private:
709     This this_;
710     boost::function<void (This)> f_;
711 };
712
713 template<>
714 struct 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; }
718 private:
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
938 exits.
939 */
940
941 /**
942 @brief This macro declares a scope exit.
943
944 The scope exit declaration schedules the execution of the scope exit body at
945 the 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
957 The enclosing scope must be local.
958 If multiple scope exits are declared within the same enclosing scope, the scope
959 exit bodies are executed in the reversed order of their declarations.
960 Note 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,
965 On 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
967 following 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
978 On compilers that do not support variadic macros\, <c>capture_tuple</c> cannot
979 be used:
980 @code
981     capture_list:
982             void | capture_sequence
983 @endcode
984 Furthermore\, if @RefMacro{BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS} is defined on
985 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
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
999 Note that on compilers that support variadic macros (most of moder compliers
1000 and all C++11 compilers), the capture list can be specified as a
1001 comma-separated list of tokens (this is the preferred syntax).
1002 However, on all compilers the same macro @RefMacro{BOOST_SCOPE_EXIT} also
1003 allows 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
1006 The name <c>variable</c> of each captured variable must be a valid name in the
1007 enclosing scope and it must appear exactly once in the capture list.
1008 If a capture starts with the ampersand sign <c>&</c>, the corresponding
1009 variable will be available by reference within the scope exit body; otherwise,
1010 a copy of the variable will be made at the point of the scope exit declaration
1011 and that copy will be available inside the scope exit body (in this case, the
1012 variable's type must be <c>CopyConstructible</c>).
1013
1014 From within a member function, the object <c>this</c> can be captured using the
1015 special 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
1017 undefined behaviour).
1018
1019 It is possible to capture no variable by specifying the capture list as
1020 <c>void</c> (regardless of variadic macro support).
1021
1022 Only variables listed in the capture list, static variables, <c>extern</c>
1023 variables, global variables, functions, and enumerations from the enclosing
1024 scope can be used inside the scope exit body.
1025
1026 On various GCC versions the special macro @RefMacro{BOOST_SCOPE_EXIT_TPL} must
1027 be used instead of @RefMacro{BOOST_SCOPE_EXIT} within templates (to maximize
1028 portability, it is recommended to always use @RefMacro{BOOST_SCOPE_EXIT_TPL}
1029 within templates).
1030
1031 On C++11, it is possible capture all variables in scope without listing their
1032 names one-by-one using the macro @RefMacro{BOOST_SCOPE_EXIT_ALL}.
1033
1034 In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_ID} must be used
1035 instead of @RefMacro{BOOST_SCOPE_EXIT} when it is necessary to expand multiple
1036 scope exit declarations on the same line.
1037
1038 @Warning The implementation executes the scope exit body within a destructor
1039 thus the scope exit body must never throw in order to comply with STL exception
1040 safety requirements.
1041
1042 @Note The implementation uses Boost.Typeof to automatically deduce the types of
1043 the captured variables.
1044 In order to compile code in type-of emulation mode, all types must be properly
1045 registered 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
1058 exits within templates.
1059
1060 Various versions of the GCC compiler do not compile @RefMacro{BOOST_SCOPE_EXIT}
1061 inside function templates.
1062 As 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
1075 The 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
1077 information).
1078
1079 On 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.
1081 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.
1082 It is recommended to always use @RefMacro{BOOST_SCOPE_EXIT_TPL} within
1083 templates so to maximize portability.
1084
1085 In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_ID_TPL} must be used
1086 instead of @RefMacro{BOOST_SCOPE_EXIT_TPL} when it is necessary to expand
1087 multiple scope exit declarations on the same line within templates.
1088
1089 @Note The issue in compiling scope exit declarations that some GCC versions
1090 have 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
1106 This can be fixed by adding <c>typename</c> in front of <c>local::typeof_i</c>
1107 and <c>local::typeof_x</c> (which is the approach followed by the
1108 implementation 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
1120 line.
1121
1122 This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT} but it can be expanded
1123 multiple times on the same line if different identifiers <c>id</c> are provided
1124 for each expansion (see @RefMacro{BOOST_SCOPE_EXIT} for more information).
1125
1126 @Params
1127 @Param{id,
1128 A 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
1130 alphanumeric tokens\, etc).
1131 }
1132 @Param{capture_list,
1133 Same as the <c>capture_list</c> parameter of the @RefMacro{BOOST_SCOPE_EXIT}
1134 macro.
1135 }
1136 @EndParams
1137
1138 @Note This macro can be useful when the scope exit macros are expanded
1139 within user-defined macros (because nested macros expand on the same line).
1140 On 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
1142 the use of this macro is always necessary to ensure portability when expanding
1143 multiple 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
1153 same line within templates on various versions of GCC.
1154
1155 This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT_TPL} but it can be
1156 expanded multiple times on the same line if different identifiers <c>id</c> are
1157 provided for each expansion (see @RefMacro{BOOST_SCOPE_EXIT_TPL} for more
1158 information).
1159 As with @RefMacro{BOOST_SCOPE_EXIT_TPL}, it is recommended to always use this
1160 macro when expanding scope exits multiple times on the same line within
1161 templates.
1162
1163 @Params
1164 @Param{id,
1165 A 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
1167 alphanumeric tokens\, etc).
1168 }
1169 @Param{capture_list,
1170 Same 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
1176 within user-defined macros (because nested macros expand on the same line).
1177 On 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
1179 the use of this macro is always necessary to ensure portability when expanding
1180 multiple 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
1192 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).
1193 A 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
1205 Note how the end of the scope exit body declared by this macro must be marked
1206 by 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
1209 C++11 compilers that do not define the Boost.Config <c>BOOST_NO_CXX11_LAMBDAS</c>
1210 macro).
1211 It 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,
1215 On 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
1217 following grammar:
1218 @code
1219 capture_list:
1220         capture_tuple | capture_sequence
1221 capture_tuple:
1222         {& | =} [\, capture\, capture\, ...]
1223 capture_sequence:
1224         {(&) | (=)} [(capture) (capture) ...]
1225 capture:
1226         [&]variable | this_
1227 @endcode
1228 On compilers that do not support variadic macros\, <c>capture_tuple</c> cannot
1229 be used:
1230 @code
1231     capture_list:
1232             void | capture_sequence
1233 @endcode
1234 Furthermore\, on C++11 compilers that support the use of <c>typename</c>
1235 outside templates\, also <c>this</c> can be used to capture the object at member
1236 function 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
1248 Note that on compilers with variadic macro support (which should be all C++11
1249 compilers), the capture list can be specified as a comma-separated list.
1250 On all compilers, the same macro @RefMacro{BOOST_SCOPE_EXIT_ALL} also allows to
1251 specify the capture list as a Boost.Preprocessor sequence.
1252
1253 The capture list must always contain at least the leading <c>&</c> or <c>=</c>
1254 so it can never be <c>void</c> (<c>BOOST_SCOPE_EXIT(void)</c> should be used
1255 to program scope exits with an empty capture list).
1256
1257 In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_ALL_ID} must be used
1258 instead of @RefMacro{BOOST_SCOPE_EXIT_ALL} when it is necessary to expand
1259 multiple scope exit declarations on the same line.
1260
1261 @Warning This macro capture list follows the exact same syntax of C++11 lambda
1262 captures 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).
1265 For example, like C++11 lambda functions, @RefMacro{BOOST_SCOPE_EXIT_ALL}
1266 requires 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
1268 capturing the object.
1269
1270 @Warning The implementation executes the scope exit body within a destructor
1271 thus the scope exit body must never throw in order to comply with STL exception
1272 safety requirements.
1273
1274 @Note This macro can always be used also within templates (so there is no need
1275 for 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
1285 capture all variables in scope (C++11 only).
1286
1287 This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT_ALL} but it can be
1288 expanded multiple times on the same line if different identifiers <c>id</c> are
1289 provided for each expansion (see @RefMacro{BOOST_SCOPE_EXIT_ALL} for more
1290 information).
1291 As with @RefMacro{BOOST_SCOPE_EXIT_ALL}, this macro is only available on C++11
1292 compilers (specifically, on C++11 compilers that do not define the
1293 Boost.Config <c>BOOST_NO_CXX11_LAMBDAS</c> macro).
1294
1295 @Params
1296 @Param{id,
1297 A 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
1299 alphanumeric tokens\, etc).
1300 }
1301 @Param{capture_list,
1302 Same 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
1308 within user-defined macros (because nested macros expand on the same line).
1309 On 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
1311 the use of this macro is always necessary to ensure portability when expanding
1312 multiple 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
1322 This macro must follow the closing curly bracket <c>}</c> that ends the body of
1323 either @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
1335 In general, the special macro @RefMacro{BOOST_SCOPE_EXIT_END_ID} must be used
1336 instead of @RefMacro{BOOST_SCOPE_EXIT_END} when it is necessary to expand
1337 multiple scope exit bodies on the same line.
1338
1339 @Note If programmers define the @RefMacro{BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS}
1340 macro on C++11 compilers, a semicolon <c>;</c> can be used instead of this
1341 macro.
1342 However, 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
1352 line.
1353
1354 This macro is equivalent to @RefMacro{BOOST_SCOPE_EXIT_END} but it can be
1355 expanded multiple times on the same line if different identifiers <c>id</c> are
1356 provided for each expansion (see @RefMacro{BOOST_SCOPE_EXIT_END} for more
1357 information).
1358
1359 @Params
1360 @Param{id,
1361 A 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
1363 alphanumeric tokens\, etc).
1364 }
1365 @EndParams
1366
1367 @Note This macro can be useful when the scope exit macros are expanded
1368 within user-defined macros (because macros all expand on the same line).
1369 On 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
1371 the use of this macro is always necessary to ensure portability when expanding
1372 multiple scope exit macros on the same line (because this library can only
1373 portably 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
1383 If programmers define this configuration macro on a C++11 compiler for which
1384 the 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
1386 C++11 lambda functions to declare scope exits.
1387 By default this macro is not defined.
1388
1389 @Warning When scope exits are implemented using lambda functions, the syntax of
1390 the capture list follows the exact same syntax of C++11 lambda captures
1391 which is in general different from the legacy capture syntax of this library.
1392 For example, C++11 lambdas require to capture data members by capturing the
1393 object <c>this</c> while this library always allowed to capture data members
1394 directly.
1395 Therefore, when this configuration macro is defined,
1396 @RefMacro{BOOST_SCOPE_EXIT} and @RefMacro{BOOST_SCOPE_EXIT_TPL} are no longer
1397 backward compatible (and this is why this macro is not defined by default).
1398
1399 A semicolon <c>;</c> can be used instead of @RefMacro{BOOST_SCOPE_EXIT_END}
1400 when 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
1405 compilers 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