File indexing completed on 2024-11-15 09:31:26
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_SPIRIT_CLASSIC_PHOENIX_CLOSURES_HPP
0010 #define BOOST_SPIRIT_CLASSIC_PHOENIX_CLOSURES_HPP
0011
0012
0013 #include <boost/spirit/home/classic/phoenix/actor.hpp>
0014 #include <boost/assert.hpp>
0015
0016 #ifdef PHOENIX_THREADSAFE
0017 #include <boost/thread/tss.hpp>
0018 #include <boost/thread/once.hpp>
0019 #endif
0020
0021
0022 namespace phoenix {
0023
0024 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0025 #pragma warning(push)
0026 #pragma warning(disable:4512)
0027 #endif
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 namespace impl
0152 {
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165 #ifndef PHOENIX_THREADSAFE
0166 template <typename FrameT>
0167 struct closure_frame_holder
0168 {
0169 typedef FrameT frame_t;
0170 typedef frame_t *frame_ptr;
0171
0172 closure_frame_holder() : frame(0) {}
0173
0174 frame_ptr &get() { return frame; }
0175 void set(frame_t *f) { frame = f; }
0176
0177 private:
0178 frame_ptr frame;
0179
0180
0181 closure_frame_holder(closure_frame_holder const &);
0182 closure_frame_holder &operator=(closure_frame_holder const &);
0183 };
0184 #else
0185 template <typename FrameT>
0186 struct closure_frame_holder
0187 {
0188 typedef FrameT frame_t;
0189 typedef frame_t *frame_ptr;
0190
0191 closure_frame_holder() : tsp_frame() {}
0192
0193 frame_ptr &get()
0194 {
0195 if (!tsp_frame.get())
0196 tsp_frame.reset(new frame_ptr(0));
0197 return *tsp_frame;
0198 }
0199 void set(frame_ptr f)
0200 {
0201 *tsp_frame = f;
0202 }
0203
0204 private:
0205 boost::thread_specific_ptr<frame_ptr> tsp_frame;
0206
0207
0208 closure_frame_holder(closure_frame_holder const &);
0209 closure_frame_holder &operator=(closure_frame_holder const &);
0210 };
0211 #endif
0212 }
0213
0214
0215
0216
0217
0218
0219 template <typename ClosureT>
0220 class closure_frame : public ClosureT::tuple_t {
0221
0222 public:
0223
0224 closure_frame(ClosureT const& clos)
0225 : ClosureT::tuple_t(), save(clos.frame.get()), frame(clos.frame)
0226 { clos.frame.set(this); }
0227
0228 template <typename TupleT>
0229 closure_frame(ClosureT const& clos, TupleT const& init)
0230 : ClosureT::tuple_t(init), save(clos.frame.get()), frame(clos.frame)
0231 { clos.frame.set(this); }
0232
0233 ~closure_frame()
0234 { frame.set(save); }
0235
0236 private:
0237
0238 closure_frame(closure_frame const&);
0239 closure_frame& operator=(closure_frame const&);
0240
0241 closure_frame* save;
0242 impl::closure_frame_holder<closure_frame>& frame;
0243 };
0244
0245
0246
0247
0248
0249
0250 template <int N, typename ClosureT>
0251 class closure_member {
0252
0253 public:
0254
0255 typedef typename ClosureT::tuple_t tuple_t;
0256
0257 closure_member()
0258 : frame(ClosureT::closure_frame_holder_ref()) {}
0259
0260 template <typename TupleT>
0261 struct result {
0262
0263 typedef typename tuple_element<
0264 N, typename ClosureT::tuple_t
0265 >::rtype type;
0266 };
0267
0268 template <typename TupleT>
0269 typename tuple_element<N, typename ClosureT::tuple_t>::rtype
0270 eval(TupleT const& ) const
0271 {
0272 using namespace std;
0273 BOOST_ASSERT(frame.get() != 0);
0274 tuple_index<N> const idx;
0275 return (*frame.get())[idx];
0276 }
0277
0278 private:
0279 impl::closure_frame_holder<typename ClosureT::closure_frame_t> &frame;
0280 };
0281
0282
0283
0284
0285
0286
0287 template <
0288 typename T0 = nil_t
0289 , typename T1 = nil_t
0290 , typename T2 = nil_t
0291
0292 #if PHOENIX_LIMIT > 3
0293 , typename T3 = nil_t
0294 , typename T4 = nil_t
0295 , typename T5 = nil_t
0296
0297 #if PHOENIX_LIMIT > 6
0298 , typename T6 = nil_t
0299 , typename T7 = nil_t
0300 , typename T8 = nil_t
0301
0302 #if PHOENIX_LIMIT > 9
0303 , typename T9 = nil_t
0304 , typename T10 = nil_t
0305 , typename T11 = nil_t
0306
0307 #if PHOENIX_LIMIT > 12
0308 , typename T12 = nil_t
0309 , typename T13 = nil_t
0310 , typename T14 = nil_t
0311
0312 #endif
0313 #endif
0314 #endif
0315 #endif
0316 >
0317 class closure {
0318
0319 public:
0320
0321 typedef tuple<
0322 T0, T1, T2
0323 #if PHOENIX_LIMIT > 3
0324 , T3, T4, T5
0325 #if PHOENIX_LIMIT > 6
0326 , T6, T7, T8
0327 #if PHOENIX_LIMIT > 9
0328 , T9, T10, T11
0329 #if PHOENIX_LIMIT > 12
0330 , T12, T13, T14
0331 #endif
0332 #endif
0333 #endif
0334 #endif
0335 > tuple_t;
0336
0337 typedef closure<
0338 T0, T1, T2
0339 #if PHOENIX_LIMIT > 3
0340 , T3, T4, T5
0341 #if PHOENIX_LIMIT > 6
0342 , T6, T7, T8
0343 #if PHOENIX_LIMIT > 9
0344 , T9, T10, T11
0345 #if PHOENIX_LIMIT > 12
0346 , T12, T13, T14
0347 #endif
0348 #endif
0349 #endif
0350 #endif
0351 > self_t;
0352
0353 typedef closure_frame<self_t> closure_frame_t;
0354
0355 closure()
0356 : frame() { closure_frame_holder_ref(&frame); }
0357
0358 typedef actor<closure_member<0, self_t> > member1;
0359 typedef actor<closure_member<1, self_t> > member2;
0360 typedef actor<closure_member<2, self_t> > member3;
0361
0362 #if PHOENIX_LIMIT > 3
0363 typedef actor<closure_member<3, self_t> > member4;
0364 typedef actor<closure_member<4, self_t> > member5;
0365 typedef actor<closure_member<5, self_t> > member6;
0366
0367 #if PHOENIX_LIMIT > 6
0368 typedef actor<closure_member<6, self_t> > member7;
0369 typedef actor<closure_member<7, self_t> > member8;
0370 typedef actor<closure_member<8, self_t> > member9;
0371
0372 #if PHOENIX_LIMIT > 9
0373 typedef actor<closure_member<9, self_t> > member10;
0374 typedef actor<closure_member<10, self_t> > member11;
0375 typedef actor<closure_member<11, self_t> > member12;
0376
0377 #if PHOENIX_LIMIT > 12
0378 typedef actor<closure_member<12, self_t> > member13;
0379 typedef actor<closure_member<13, self_t> > member14;
0380 typedef actor<closure_member<14, self_t> > member15;
0381
0382 #endif
0383 #endif
0384 #endif
0385 #endif
0386
0387 #if !defined(__MWERKS__) || (__MWERKS__ > 0x3002)
0388 private:
0389 #endif
0390
0391 closure(closure const&);
0392 closure& operator=(closure const&);
0393
0394 #if !defined(__MWERKS__) || (__MWERKS__ > 0x3002)
0395 template <int N, typename ClosureT>
0396 friend class closure_member;
0397
0398 template <typename ClosureT>
0399 friend class closure_frame;
0400 #endif
0401
0402 typedef impl::closure_frame_holder<closure_frame_t> holder_t;
0403
0404 #ifdef PHOENIX_THREADSAFE
0405 static boost::thread_specific_ptr<holder_t*> &
0406 tsp_frame_instance()
0407 {
0408 static boost::thread_specific_ptr<holder_t*> the_instance;
0409 return the_instance;
0410 }
0411
0412 static void
0413 tsp_frame_instance_init()
0414 {
0415 tsp_frame_instance();
0416 }
0417 #endif
0418
0419 static holder_t &
0420 closure_frame_holder_ref(holder_t* holder_ = 0)
0421 {
0422 #ifdef PHOENIX_THREADSAFE
0423 #ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
0424 static boost::once_flag been_here = BOOST_ONCE_INIT;
0425 #else
0426 static boost::once_flag been_here;
0427 #endif
0428 boost::call_once(been_here, tsp_frame_instance_init);
0429 boost::thread_specific_ptr<holder_t*> &tsp_frame = tsp_frame_instance();
0430 if (!tsp_frame.get())
0431 tsp_frame.reset(new holder_t *(0));
0432 holder_t *& holder = *tsp_frame;
0433 #else
0434 static holder_t* holder = 0;
0435 #endif
0436 if (holder_ != 0)
0437 holder = holder_;
0438 return *holder;
0439 }
0440
0441 mutable holder_t frame;
0442 };
0443
0444 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0445 #pragma warning(pop)
0446 #endif
0447
0448 }
0449
0450
0451 #endif