]> rtime.felk.cvut.cz Git - eurobot/public.git/blob - src/boost/boost/scope_exit.hpp
Add subset of boost library headers needed for compilation on PowerPC
[eurobot/public.git] / src / boost / boost / scope_exit.hpp
1 // Copyright Alexander Nasonov 2006-2009
2 //
3 // Distributed under the Boost Software License, Version 1.0. 
4 // (See accompanying file LICENSE_1_0.txt or copy at 
5 // http://www.boost.org/LICENSE_1_0.txt)
6
7 #ifndef FILE_boost_scope_exit_hpp_INCLUDED
8 #define FILE_boost_scope_exit_hpp_INCLUDED
9
10 #include <boost/config.hpp>
11
12 #include <boost/detail/workaround.hpp>
13 #include <boost/preprocessor/cat.hpp>
14 #include <boost/preprocessor/facilities/empty.hpp>
15 #include <boost/preprocessor/punctuation/comma_if.hpp>
16 #include <boost/preprocessor/seq/cat.hpp>
17 #include <boost/preprocessor/seq/for_each_i.hpp>
18 #include <boost/preprocessor/tuple/elem.hpp>
19 #include <boost/typeof/typeof.hpp>
20
21 #if defined(__GNUC__) && !defined(BOOST_INTEL)
22 # define BOOST_SCOPE_EXIT_AUX_GCC (__GNUC__ * 100 + __GNUC_MINOR__)
23 #else
24 # define BOOST_SCOPE_EXIT_AUX_GCC 0
25 #endif
26
27 #if BOOST_WORKAROUND(BOOST_SCOPE_EXIT_AUX_GCC, BOOST_TESTED_AT(413))
28 #define BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
29 #endif
30
31 // Steven Watanabe's trick with a modification suggested by Kim Barrett
32 namespace boost { namespace scope_exit { namespace aux {
33
34     // Type of a local boost_scope_exit_args variable.
35     // First use in a local scope will declare the boost_scope_exit_args
36     // variable, subsequent uses will be resolved as two comparisons
37     // (cmp1 with 0 and cmp2 with boost_scope_exit_args).
38     template<int Dummy = 0>
39     struct declared
40     {
41         void* value;
42         static int const cmp2 = 0;
43         friend void operator>(int, declared const&) {}
44     };
45
46     struct undeclared { declared<> dummy[2]; };
47
48     template<int> struct resolve;
49
50     template<>
51     struct resolve<sizeof(declared<>)>
52     {
53         static const int cmp1 = 0;
54     };
55
56     template<>
57     struct resolve<sizeof(undeclared)>
58     {
59         template<int>
60         struct cmp1
61         {
62             static int const cmp2 = 0;
63         };
64     };
65 } } }
66
67 extern boost::scope_exit::aux::undeclared boost_scope_exit_args; // undefined
68
69
70 namespace boost { namespace scope_exit { namespace aux {
71
72 typedef void (*ref_tag)(int&);
73 typedef void (*val_tag)(int );
74
75 template<class T, class Tag> struct member;
76
77 template<class T>
78 struct member<T,ref_tag>
79 {
80     T& value;
81 #ifndef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
82     member(T& ref) : value(ref) {}
83 #endif
84 };
85
86 template<class T>
87 struct member<T,val_tag>
88 {
89     T value;
90 #ifndef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
91     member(T& val) : value(val) {}
92 #endif
93 };
94
95 template<class T> inline T& deref(T* p, ref_tag) { return *p; }
96 template<class T> inline T& deref(T& r, val_tag) { return  r; }
97
98 template<class T>
99 struct wrapper
100 {
101     typedef T type;
102 };
103
104 template<class T> wrapper<T> wrap(T&);
105
106 } } }
107
108 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
109 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::scope_exit::aux::wrapper, 1)
110
111 #define BOOST_SCOPE_EXIT_AUX_GUARD(id)     BOOST_PP_CAT(boost_se_guard_,    id)
112 #define BOOST_SCOPE_EXIT_AUX_GUARD_T(id)   BOOST_PP_CAT(boost_se_guard_t_,  id)
113 #define BOOST_SCOPE_EXIT_AUX_PARAMS(id)    BOOST_PP_CAT(boost_se_params_,   id)
114 #define BOOST_SCOPE_EXIT_AUX_PARAMS_T(id)  BOOST_PP_CAT(boost_se_params_t_, id)
115
116 #define BOOST_SCOPE_EXIT_AUX_TAG(id, i) \
117     BOOST_PP_SEQ_CAT( (boost_se_tag_)(i)(_)(id) )
118
119 #define BOOST_SCOPE_EXIT_AUX_PARAM(id, i, var) \
120     BOOST_PP_SEQ_CAT( (boost_se_param_)(i)(_)(id) )
121
122 #define BOOST_SCOPE_EXIT_AUX_PARAM_T(id, i, var) \
123     BOOST_PP_SEQ_CAT( (boost_se_param_t_)(i)(_)(id) )
124
125 #define BOOST_SCOPE_EXIT_AUX_CAPTURE_T(id, i, var) \
126     BOOST_PP_SEQ_CAT( (boost_se_capture_t_)(i)(_)(id) )
127
128 #define BOOST_SCOPE_EXIT_AUX_WRAPPED(id, i) \
129     BOOST_PP_SEQ_CAT( (boost_se_wrapped_t_)(i)(_)(id) )
130
131 #define BOOST_SCOPE_EXIT_AUX_DEREF(id, i, var) \
132     boost::scope_exit::aux::deref(var, (BOOST_SCOPE_EXIT_AUX_TAG(id,i))0)
133
134 #define BOOST_SCOPE_EXIT_AUX_MEMBER(r, id, i, var) \
135     boost::scope_exit::aux::member<                \
136         BOOST_SCOPE_EXIT_AUX_PARAM_T(id,i,var),    \
137         BOOST_SCOPE_EXIT_AUX_TAG(id,i)             \
138     > BOOST_SCOPE_EXIT_AUX_PARAM(id,i,var);
139
140 // idty is (id,typename) or (id,BOOST_PP_EMPTY())
141 #define BOOST_SCOPE_EXIT_AUX_ARG_DECL(r, idty, i, var)             \
142     BOOST_PP_COMMA_IF(i) BOOST_PP_TUPLE_ELEM(2,1,idty)             \
143     BOOST_SCOPE_EXIT_AUX_PARAMS_T(BOOST_PP_TUPLE_ELEM(2,0,idty)):: \
144     BOOST_SCOPE_EXIT_AUX_PARAM_T(BOOST_PP_TUPLE_ELEM(2,0,idty), i, var) var
145  
146 #define BOOST_SCOPE_EXIT_AUX_ARG(r, id, i, var) BOOST_PP_COMMA_IF(i) \
147     boost_se_params_->BOOST_SCOPE_EXIT_AUX_PARAM(id,i,var).value
148
149 #define BOOST_SCOPE_EXIT_AUX_TAG_DECL(r, id, i, var) \
150     typedef void (*BOOST_SCOPE_EXIT_AUX_TAG(id,i))(int var);
151
152
153 #ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
154
155 #define BOOST_SCOPE_EXIT_AUX_PARAMS_T_CTOR(id, seq)
156
157 #define BOOST_SCOPE_EXIT_AUX_PARAM_INIT(r, id, i, var) \
158     BOOST_PP_COMMA_IF(i) { BOOST_SCOPE_EXIT_AUX_DEREF(id,i,var) }
159
160 #define BOOST_SCOPE_EXIT_AUX_PARAMS_INIT(id, seq) \
161     = { BOOST_PP_SEQ_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_PARAM_INIT, id, seq) };
162
163 #else
164
165 #define BOOST_SCOPE_EXIT_AUX_CTOR_ARG(r, id, i, var) BOOST_PP_COMMA_IF(i) \
166     BOOST_SCOPE_EXIT_AUX_PARAM_T(id,i,var) & BOOST_PP_CAT(a,i)
167
168 #define BOOST_SCOPE_EXIT_AUX_MEMBER_INIT(r, id, i, var) BOOST_PP_COMMA_IF(i) \
169     BOOST_SCOPE_EXIT_AUX_PARAM(id,i,var) ( BOOST_PP_CAT(a,i) )
170
171 #define BOOST_SCOPE_EXIT_AUX_PARAMS_T_CTOR(id, seq)                        \
172     BOOST_SCOPE_EXIT_AUX_PARAMS_T(id)(                                     \
173         BOOST_PP_SEQ_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_CTOR_ARG, id, seq ) ) \
174     : BOOST_PP_SEQ_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_MEMBER_INIT, id, seq) {}
175
176 #define BOOST_SCOPE_EXIT_AUX_PARAM_INIT(r, id, i, var) \
177     BOOST_PP_COMMA_IF(i) BOOST_SCOPE_EXIT_AUX_DEREF(id,i,var)
178
179 #define BOOST_SCOPE_EXIT_AUX_PARAMS_INIT(id, seq) \
180     ( BOOST_PP_SEQ_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_PARAM_INIT, id, seq) );
181
182 #endif
183
184 #if defined(BOOST_TYPEOF_EMULATION)
185
186 #define BOOST_SCOPE_EXIT_AUX_CAPTURE_DECL(r, idty, i, var)                   \
187     struct BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2,0,idty), i)    \
188         : BOOST_TYPEOF(boost::scope_exit::aux::wrap(                         \
189         BOOST_SCOPE_EXIT_AUX_DEREF(BOOST_PP_TUPLE_ELEM(2,0,idty), i, var)))  \
190     {}; typedef BOOST_PP_TUPLE_ELEM(2,1,idty)                                \
191         BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2,0,idty), i)::type \
192         BOOST_SCOPE_EXIT_AUX_CAPTURE_T(BOOST_PP_TUPLE_ELEM(2,0,idty), i, var);
193
194 #elif defined(BOOST_INTEL)
195
196 #define BOOST_SCOPE_EXIT_AUX_CAPTURE_DECL(r, idty, i, var)                 \
197     typedef BOOST_TYPEOF_KEYWORD(                                          \
198         BOOST_SCOPE_EXIT_AUX_DEREF(BOOST_PP_TUPLE_ELEM(2,0,idty), i, var)) \
199         BOOST_SCOPE_EXIT_AUX_CAPTURE_T(BOOST_PP_TUPLE_ELEM(2,0,idty), i, var);
200
201 #else
202
203 #define BOOST_SCOPE_EXIT_AUX_CAPTURE_DECL(r, idty, i, var)                   \
204     typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap(                       \
205         BOOST_SCOPE_EXIT_AUX_DEREF(BOOST_PP_TUPLE_ELEM(2,0,idty), i, var)))  \
206         BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2,0,idty), i);      \
207     typedef BOOST_PP_TUPLE_ELEM(2,1,idty)                                    \
208         BOOST_SCOPE_EXIT_AUX_WRAPPED(BOOST_PP_TUPLE_ELEM(2,0,idty), i)::type \
209         BOOST_SCOPE_EXIT_AUX_CAPTURE_T(BOOST_PP_TUPLE_ELEM(2,0,idty), i, var);
210
211 #endif
212
213 #define BOOST_SCOPE_EXIT_AUX_PARAM_DECL(r, idty, i, var) \
214     typedef BOOST_SCOPE_EXIT_AUX_CAPTURE_T(              \
215         BOOST_PP_TUPLE_ELEM(2,0,idty), i, var)           \
216         BOOST_SCOPE_EXIT_AUX_PARAM_T(BOOST_PP_TUPLE_ELEM(2,0,idty), i, var);
217
218
219 #define BOOST_SCOPE_EXIT_AUX_IMPL(id, seq, ty)                                 \
220     BOOST_PP_SEQ_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_TAG_DECL, id, seq)            \
221     BOOST_PP_SEQ_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_CAPTURE_DECL, (id,ty), seq)   \
222     struct BOOST_SCOPE_EXIT_AUX_PARAMS_T(id) {                                 \
223         BOOST_PP_SEQ_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_PARAM_DECL, (id,ty), seq) \
224         BOOST_PP_SEQ_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_MEMBER, id, seq)          \
225         BOOST_SCOPE_EXIT_AUX_PARAMS_T_CTOR(id, seq)                            \
226     } BOOST_SCOPE_EXIT_AUX_PARAMS(id) BOOST_SCOPE_EXIT_AUX_PARAMS_INIT(id,seq) \
227     boost::scope_exit::aux::declared< boost::scope_exit::aux::resolve<         \
228         sizeof(boost_scope_exit_args)>::cmp1<0>::cmp2 > boost_scope_exit_args; \
229     boost_scope_exit_args.value = &BOOST_SCOPE_EXIT_AUX_PARAMS(id);            \
230     struct BOOST_SCOPE_EXIT_AUX_GUARD_T(id) {                                  \
231         BOOST_SCOPE_EXIT_AUX_PARAMS_T(id)* boost_se_params_;                   \
232         BOOST_SCOPE_EXIT_AUX_GUARD_T(id) (void* boost_se_params)               \
233             : boost_se_params_(                                                \
234                   (BOOST_SCOPE_EXIT_AUX_PARAMS_T(id)*)boost_se_params)         \
235         {}                                                                     \
236         ~BOOST_SCOPE_EXIT_AUX_GUARD_T(id)() { boost_se_body(                   \
237             BOOST_PP_SEQ_FOR_EACH_I(BOOST_SCOPE_EXIT_AUX_ARG, id, seq) ); }    \
238         static void boost_se_body(BOOST_PP_SEQ_FOR_EACH_I(                     \
239             BOOST_SCOPE_EXIT_AUX_ARG_DECL, (id,ty), seq) )
240
241 #if defined(BOOST_MSVC)
242
243 #define BOOST_SCOPE_EXIT_END } BOOST_SCOPE_EXIT_AUX_GUARD(__COUNTER__) ( \
244     boost_scope_exit_args.value);
245
246 #define BOOST_SCOPE_EXIT(seq) \
247     BOOST_SCOPE_EXIT_AUX_IMPL(__COUNTER__, seq, BOOST_PP_EMPTY())
248
249 #else
250
251 #define BOOST_SCOPE_EXIT_END } BOOST_SCOPE_EXIT_AUX_GUARD(__LINE__) ( \
252     boost_scope_exit_args.value);
253
254 #define BOOST_SCOPE_EXIT(seq) \
255     BOOST_SCOPE_EXIT_AUX_IMPL(__LINE__, seq, BOOST_PP_EMPTY())
256
257 #endif
258
259 #ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
260 #define BOOST_SCOPE_EXIT_TPL(seq) \
261     BOOST_SCOPE_EXIT_AUX_IMPL(__LINE__, seq, typename)
262 #else
263 #define BOOST_SCOPE_EXIT_TPL(seq) BOOST_SCOPE_EXIT(seq)
264 #endif
265
266 #endif // #ifndef FILE_boost_scope_exit_hpp_INCLUDED
267