00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef ACEDIA_RULE_BUILDER_H
00031 #define ACEDIA_RULE_BUILDER_H
00032
00033 #include "anyarray.hpp"
00034 #include "acedia_preprocessor.hpp"
00035 #include "acedia_details.hpp"
00036
00037 #include <boost/function.hpp>
00038 #include <boost/static_assert.hpp>
00039
00040 #define ACEDIA_STATIC_INVOKE_SIG inline static void invoke(F &f, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5 ,const T6 &v6 ,const T7 &v7 ,const T8 &v8 ,const T9 &v9)
00041
00042 namespace acedia
00043 {
00044
00045 class AnyArray;
00046
00047
00048
00049
00050 namespace details
00051 {
00052 class ContinuationInvoker
00053 {
00054 AnyArrayProcessor *processor;
00055
00056 const AnyArray * const anyArray;
00057
00058 public:
00059
00060 ContinuationInvoker(AnyArrayProcessor *p,
00061 const AnyArray * const arr) throw() :
00062 processor(p), anyArray(arr)
00063 {
00064 }
00065
00066 inline void operator()() { (*processor)(*anyArray); }
00067 };
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 class InvokeRule
00078 {
00079
00080 mutable AnyArrayProcessor *head;
00081
00082 public:
00083
00084 InvokeRule() : head(NULL) { }
00085
00086
00087 InvokeRule(const InvokeRule &other) : head(other.head)
00088 {
00089 other.head = NULL;
00090 }
00091
00092 ~InvokeRule() { if (head) delete head; }
00093
00094 void push(AnyArrayProcessor *pc)
00095 {
00096 if (head) head->passThrough(pc);
00097 else head = pc;
00098 }
00099
00100
00101 bool tryInvoke(const AnyArray &arr) { return (*head)(arr); }
00102
00103 };
00104
00105
00106 template<int N, ACEDIA_DEF_WITH_DEFAULT_T1_TO_T9()>
00107 struct PatternChecker : public AnyArrayProcessor
00108 {
00109
00110 PatternChecker() { }
00111
00112 explicit PatternChecker(AnyArrayProcessor *next) { setNext(next); }
00113
00114 static bool doesMatch(const AnyArray &arr)
00115 {
00116 static MetaClass *mClasses[9] = {
00117 details::MetaClassImpl<T1>::instance(),
00118 details::MetaClassImpl<T2>::instance(),
00119 details::MetaClassImpl<T3>::instance(),
00120 details::MetaClassImpl<T4>::instance(),
00121 details::MetaClassImpl<T5>::instance(),
00122 details::MetaClassImpl<T6>::instance(),
00123 details::MetaClassImpl<T7>::instance(),
00124 details::MetaClassImpl<T8>::instance(),
00125 details::MetaClassImpl<T9>::instance()
00126 };
00127 if (arr.length() != N) return false;
00128 for (int i = 0; i < N; ++i)
00129 {
00130 if (arr.metaClassAt(i) != mClasses[i]) return false;
00131 }
00132 return true;
00133 }
00134
00135 virtual bool operator()(const AnyArray &arr)
00136 {
00137 return hasNext() && doesMatch(arr) && (*next)(arr);
00138 }
00139
00140 virtual ContinuationInvoker *matchingInvoker(const AnyArray &arr)
00141 {
00142 return (hasNext() && doesMatch(arr))
00143 ? next->matchingInvoker(arr)
00144 : NULL;
00145 }
00146
00147 };
00148
00149
00150 template<int N, int O, class F, ACEDIA_DEF_WITH_DEFAULT_T1_TO_T9()>
00151 struct InvokeHelper { };
00152
00153 template<int O, class F, ACEDIA_DEF_T1_TO_T9()>
00154 struct InvokeHelper<0, O, F, ACEDIA_GET_T1_TO_T9()>
00155 {
00156 inline static void invoke(F& f, const AnyArray&)
00157 {
00158 f();
00159 }
00160 };
00161
00162 template<int O, class F, ACEDIA_DEF_T1_TO_T9()>
00163 struct InvokeHelper<1, O, F, ACEDIA_GET_T1_TO_T9()>
00164 {
00165 inline static void invoke(F& f, const AnyArray &arr)
00166 {
00167 f(arr.uncheckedValueAt<T1>(0+O));
00168 }
00169 };
00170
00171 template<int O, class F, ACEDIA_DEF_T1_TO_T9()>
00172 struct InvokeHelper<2, O, F, ACEDIA_GET_T1_TO_T9()>
00173 {
00174 inline static void invoke(F& f, const AnyArray &arr)
00175 {
00176 f(arr.uncheckedValueAt<T1>(0+O),
00177 arr.uncheckedValueAt<T2>(1+O));
00178 }
00179 };
00180
00181 template<int O, class F, ACEDIA_DEF_T1_TO_T9()>
00182 struct InvokeHelper<3, O, F, ACEDIA_GET_T1_TO_T9()>
00183 {
00184 inline static void invoke(F& f, const AnyArray &arr)
00185 {
00186 f(arr.uncheckedValueAt<T1>(0+O),
00187 arr.uncheckedValueAt<T2>(1+O),
00188 arr.uncheckedValueAt<T3>(2+O));
00189 }
00190 };
00191
00192 template<int O, class F, ACEDIA_DEF_T1_TO_T9()>
00193 struct InvokeHelper<4, O, F, ACEDIA_GET_T1_TO_T9()>
00194 {
00195 inline static void invoke(F& f, const AnyArray &arr)
00196 {
00197 f(arr.uncheckedValueAt<T1>(0+O),
00198 arr.uncheckedValueAt<T2>(1+O),
00199 arr.uncheckedValueAt<T3>(2+O),
00200 arr.uncheckedValueAt<T4>(3+O));
00201 }
00202 };
00203
00204 template<int O, class F, ACEDIA_DEF_T1_TO_T9()>
00205 struct InvokeHelper<5, O, F, ACEDIA_GET_T1_TO_T9()>
00206 {
00207 inline static void invoke(F& f, const AnyArray &arr)
00208 {
00209 f(arr.uncheckedValueAt<T1>(0+O),
00210 arr.uncheckedValueAt<T2>(1+O),
00211 arr.uncheckedValueAt<T3>(2+O),
00212 arr.uncheckedValueAt<T4>(3+O),
00213 arr.uncheckedValueAt<T5>(4+O));
00214 }
00215 };
00216
00217 template<int O, class F, ACEDIA_DEF_T1_TO_T9()>
00218 struct InvokeHelper<6, O, F, ACEDIA_GET_T1_TO_T9()>
00219 {
00220 inline static void invoke(F& f, const AnyArray &arr)
00221 {
00222 f(arr.uncheckedValueAt<T1>(0+O),
00223 arr.uncheckedValueAt<T2>(1+O),
00224 arr.uncheckedValueAt<T3>(2+O),
00225 arr.uncheckedValueAt<T4>(3+O),
00226 arr.uncheckedValueAt<T5>(4+O),
00227 arr.uncheckedValueAt<T6>(5+O));
00228 }
00229 };
00230
00231 template<int O, class F, ACEDIA_DEF_T1_TO_T9()>
00232 struct InvokeHelper<7, O, F, ACEDIA_GET_T1_TO_T9()>
00233 {
00234 inline static void invoke(F& f, const AnyArray &arr)
00235 {
00236 f(arr.uncheckedValueAt<T1>(0+O),
00237 arr.uncheckedValueAt<T2>(1+O),
00238 arr.uncheckedValueAt<T3>(2+O),
00239 arr.uncheckedValueAt<T4>(3+O),
00240 arr.uncheckedValueAt<T5>(4+O),
00241 arr.uncheckedValueAt<T6>(5+O),
00242 arr.uncheckedValueAt<T7>(6+O));
00243 }
00244 };
00245
00246 template<int O, class F, ACEDIA_DEF_T1_TO_T9()>
00247 struct InvokeHelper<8, O, F, ACEDIA_GET_T1_TO_T9()>
00248 {
00249 inline static void invoke(F& f, const AnyArray &arr)
00250 {
00251 f(arr.uncheckedValueAt<T1>(0+O),
00252 arr.uncheckedValueAt<T2>(1+O),
00253 arr.uncheckedValueAt<T3>(2+O),
00254 arr.uncheckedValueAt<T4>(3+O),
00255 arr.uncheckedValueAt<T5>(4+O),
00256 arr.uncheckedValueAt<T6>(5+O),
00257 arr.uncheckedValueAt<T7>(6+O),
00258 arr.uncheckedValueAt<T8>(7+O));
00259 }
00260 };
00261
00262 template<int O, class F, ACEDIA_DEF_T1_TO_T9()>
00263 struct InvokeHelper<9, O, F, ACEDIA_GET_T1_TO_T9()>
00264 {
00265 inline static void invoke(F& f, const AnyArray &arr)
00266 {
00267 f(arr.uncheckedValueAt<T1>(0+O),
00268 arr.uncheckedValueAt<T2>(1+O),
00269 arr.uncheckedValueAt<T3>(2+O),
00270 arr.uncheckedValueAt<T4>(3+O),
00271 arr.uncheckedValueAt<T5>(4+O),
00272 arr.uncheckedValueAt<T6>(5+O),
00273 arr.uncheckedValueAt<T7>(6+O),
00274 arr.uncheckedValueAt<T8>(7+O),
00275 arr.uncheckedValueAt<T9>(8+O));
00276 }
00277 };
00278
00279
00280
00281
00282
00283
00284
00285
00286 template<int N, int O = 0, ACEDIA_DEF_WITH_DEFAULT_T1_TO_T9()>
00287 struct InvokeFunctor : public AnyArrayProcessor
00288 {
00289
00290 typedef typename util::ResultOf
00291 <N,
00292 boost::function0<void>,
00293 boost::function1<void,T1>,
00294 boost::function2<void,T1,T2>,
00295 boost::function3<void,T1,T2,T3>,
00296 boost::function4<void,T1,T2,T3,T4>,
00297 boost::function5<void,T1,T2,T3,T4,T5>,
00298 boost::function6<void,T1,T2,T3,T4,T5,T6>,
00299 boost::function7<void,T1,T2,T3,T4,T5,T6,T7>,
00300 boost::function8<void,T1,T2,T3,T4,T5,T6,T7,T8>,
00301 boost::function9<void,T1,T2,T3,T4,T5,T6,T7,T8,T9>
00302 >::type
00303 F;
00304
00305 InvokeFunctor(const F &func) : f(func) { }
00306
00307 protected:
00308
00309 F f;
00310
00311 inline void invoke(const AnyArray& arr)
00312 {
00313
00314
00315 InvokeHelper<N,O,F,ACEDIA_GET_T1_TO_T9()>::invoke(f, arr);
00316 }
00317
00318 virtual bool operator()(const AnyArray &arr)
00319 {
00320 invoke(arr);
00321 return true;
00322 }
00323
00324 virtual ContinuationInvoker *matchingInvoker(const AnyArray &arr)
00325 {
00326 return new ContinuationInvoker(this, &arr);
00327 }
00328
00329 };
00330
00331 struct IGuardFunctor
00332 {
00333 virtual ~IGuardFunctor();
00334 };
00335
00336 }
00337
00338 template<typename T>
00339 struct GuardFunctor : public details::IGuardFunctor
00340 {
00341
00342 virtual bool operator()(const T &value) = 0;
00343 };
00344
00345 namespace details {
00346
00347 template<int POS, ACEDIA_DEF_WITH_DEFAULT_T1_TO_T9()>
00348 struct GuardEvaluater
00349 {
00350 typedef typename util::ResultOf<POS,ACEDIA_GET_T1_TO_T9()>::type MY_T;
00351 inline static bool evaluate(const AnyArray &arr, IGuardFunctor **gArr)
00352 {
00353 return (gArr[POS]
00354 ? (*reinterpret_cast<GuardFunctor<MY_T>*>(gArr[POS]))(arr.uncheckedValueAt<MY_T>(POS))
00355 : true)
00356 && GuardEvaluater<POS-1, ACEDIA_GET_T1_TO_T9()>
00357 ::evaluate(arr,gArr);
00358 }
00359 };
00360
00361
00362 template<ACEDIA_DEF_T1_TO_T9()>
00363 struct GuardEvaluater<0,ACEDIA_GET_T1_TO_T9()>
00364 {
00365 inline static bool evaluate(const AnyArray &arr, IGuardFunctor **gArr)
00366 {
00367 return gArr[0]
00368 ? (*reinterpret_cast<GuardFunctor<T1>*>
00369 (gArr[0]))(arr.uncheckedValueAt<T1>(0))
00370 : true;
00371 }
00372 };
00373
00374 template<int N, ACEDIA_DEF_WITH_DEFAULT_T1_TO_T9()>
00375 class Guard : public AnyArrayProcessor
00376 {
00377
00378 BOOST_STATIC_ASSERT(N > 0);
00379
00380 private:
00381
00382 IGuardFunctor *gArr[9];
00383
00384 public:
00385
00386 Guard(GuardFunctor<T1> *g1, GuardFunctor<T2> *g2 = NULL,
00387 GuardFunctor<T3> *g3 = NULL, GuardFunctor<T4> *g4 = NULL,
00388 GuardFunctor<T5> *g5 = NULL, GuardFunctor<T4> *g6 = NULL,
00389 GuardFunctor<T7> *g7 = NULL, GuardFunctor<T4> *g8 = NULL,
00390 GuardFunctor<T9> *g9 = NULL)
00391 {
00392 gArr[0] = g1; gArr[1] = g2; gArr[2] = g3;
00393 gArr[3] = g4; gArr[4] = g5; gArr[5] = g6;
00394 gArr[6] = g7; gArr[7] = g8; gArr[8] = g9;
00395 for (int i = 0; i < N; ++i) assert(NULL != gArr[i]);
00396 }
00397
00398 ~Guard()
00399 {
00400 for (int i = 0; i < N; ++i) if (gArr[i]) delete gArr[i];
00401 }
00402
00403 virtual bool operator()(const AnyArray &arr)
00404 {
00405 return hasNext()
00406 && GuardEvaluater<N, ACEDIA_GET_T1_TO_T9()>::evaluate(arr, gArr)
00407 && (*next)(arr);
00408 }
00409
00410 virtual ContinuationInvoker *matchingInvoker(const AnyArray &arr)
00411 {
00412 return (hasNext()
00413 && GuardEvaluater<N, ACEDIA_GET_T1_TO_T9()>::evaluate(arr, gArr))
00414 ? next->matchingInvoker(arr)
00415 : NULL;
00416 }
00417
00418 };
00419
00420 }
00421
00422
00423
00424
00425
00426 struct GuardBuilder0 { };
00427
00428 template<class RB, typename T1>
00429 struct GuardBuilder1
00430 {
00431 virtual ~GuardBuilder1() { }
00432 RB &guard(GuardFunctor<T1> *g1)
00433 {
00434
00435 return dynamic_cast<RB*>(this)
00436 ->passThrough(new details::Guard<1,T1>(g1));
00437 }
00438 };
00439
00440 template<class RB, ACEDIA_DEF_T1_TO_TX(2)>
00441 struct GuardBuilder2
00442 {
00443 RB &guard(GuardFunctor<T1> *g1, GuardFunctor<T2> *g2)
00444 {
00445 return dynamic_cast<RB*>(this)
00446 ->passThrough(new details::Guard<2,T1,T2>(g1,g2));
00447 }
00448 };
00449
00450 template<class RB, ACEDIA_DEF_T1_TO_TX(3)>
00451 struct GuardBuilder3
00452 {
00453 RB &guard(GuardFunctor<T1> *g1,GuardFunctor<T2> *g2,GuardFunctor<T3> *g3)
00454 {
00455 return dynamic_cast<RB*>(this)
00456 ->passThrough(new details::Guard<3,T1,T2,T3>(g1,g2,g3));
00457 }
00458 };
00459
00460 template<class RB, ACEDIA_DEF_T1_TO_TX(4)>
00461 struct GuardBuilder4
00462 {
00463 RB &guard(GuardFunctor<T1> *g1,GuardFunctor<T2> *g2,GuardFunctor<T3> *g3,
00464 GuardFunctor<T4> *g4)
00465 {
00466 return dynamic_cast<RB*>(this)
00467 ->passThrough(new details::Guard<4,T1,T2,T3,T4>(g1,g2,g3,g4));
00468 }
00469 };
00470
00471 template<class RB, ACEDIA_DEF_T1_TO_TX(5)>
00472 struct GuardBuilder5
00473 {
00474 RB &guard(GuardFunctor<T1> *g1,GuardFunctor<T2> *g2,GuardFunctor<T3> *g3,
00475 GuardFunctor<T4> *g4,GuardFunctor<T5> *g5)
00476 {
00477 return dynamic_cast<RB*>(this)
00478 ->passThrough(new details::Guard<5,ACEDIA_GET_T1_TO_TX(5)>(
00479 g1,g2,g3,g4,g5));
00480 }
00481 };
00482
00483 template<class RB, ACEDIA_DEF_T1_TO_TX(6)>
00484 struct GuardBuilder6
00485 {
00486 RB &guard(GuardFunctor<T1> *g1,GuardFunctor<T2> *g2,GuardFunctor<T3> *g3,
00487 GuardFunctor<T4> *g4,GuardFunctor<T5> *g5,GuardFunctor<T6> *g6)
00488 {
00489 return dynamic_cast<RB*>(this)
00490 ->passThrough(new details::Guard<6,ACEDIA_GET_T1_TO_TX(6)>(
00491 g1,g2,g3,g4,g5,g6));
00492 }
00493 };
00494
00495 template<class RB, ACEDIA_DEF_T1_TO_TX(7)>
00496 struct GuardBuilder7
00497 {
00498 RB &guard(GuardFunctor<T1> *g1,GuardFunctor<T2> *g2,GuardFunctor<T3> *g3,
00499 GuardFunctor<T4> *g4,GuardFunctor<T5> *g5,GuardFunctor<T6> *g6,
00500 GuardFunctor<T7> *g7)
00501 {
00502 return dynamic_cast<RB*>(this)
00503 ->passThrough(new details::Guard<7,ACEDIA_GET_T1_TO_TX(7)>(
00504 g1,g2,g3,g4,g5,g6,g7));
00505 }
00506 };
00507
00508
00509 template<class RB, ACEDIA_DEF_T1_TO_TX(8)>
00510 struct GuardBuilder8
00511 {
00512 RB &guard(GuardFunctor<T1> *g1,GuardFunctor<T2> *g2,GuardFunctor<T3> *g3,
00513 GuardFunctor<T4> *g4,GuardFunctor<T5> *g5,GuardFunctor<T6> *g6,
00514 GuardFunctor<T7> *g7,GuardFunctor<T8> *g8)
00515 {
00516 return dynamic_cast<RB*>(this)
00517 ->passThrough(new details::Guard<8,ACEDIA_GET_T1_TO_TX(8)>(
00518 g1,g2,g3,g4,g5,g6,g7,g8));
00519 }
00520 };
00521
00522 template<class RB, ACEDIA_DEF_T1_TO_TX(9)>
00523 struct GuardBuilder9
00524 {
00525 RB &guard(GuardFunctor<T1> *g1,GuardFunctor<T2> *g2,GuardFunctor<T3> *g3,
00526 GuardFunctor<T4> *g4,GuardFunctor<T5> *g5,GuardFunctor<T6> *g6,
00527 GuardFunctor<T7> *g7,GuardFunctor<T8> *g8,GuardFunctor<T9> *g9)
00528 {
00529 return dynamic_cast<RB*>(this)
00530 ->passThrough(new details::Guard<9,ACEDIA_GET_T1_TO_TX(9)>(
00531 g1,g2,g3,g4,g5,g6,g7,g8,g9));
00532 }
00533 };
00534
00535
00536 struct IRuleBuilder { };
00537
00538 class RuleBuilderBase
00539 {
00540
00541 protected:
00542
00543 details::AnyArrayProcessor *proc;
00544
00545 public:
00546
00547 RuleBuilderBase(details::AnyArrayProcessor *processor);
00548
00549 details::AnyArrayProcessor *passThroughAndClear(details::AnyArrayProcessor *nProc);
00550
00551
00552 details::AnyArrayProcessor* operator>>(void (*voidFunction)());
00553
00554 };
00555
00556
00557
00558 template<int N, int O, ACEDIA_DEF_WITH_DEFAULT_T1_TO_T9()>
00559 struct RuleBuilder : public util::ResultOf
00560 <N,
00561 RuleBuilderBase,
00562 RuleBuilder<0,O+1>,
00563 RuleBuilder<1,O+1,T2>,
00564 RuleBuilder<2,O+1,T2,T3>,
00565 RuleBuilder<3,O+1,T2,T3,T4>,
00566 RuleBuilder<4,O+1,T2,T3,T4,T5>,
00567 RuleBuilder<5,O+1,T2,T3,T4,T5,T6>,
00568 RuleBuilder<6,O+1,T2,T3,T4,T5,T6,T7>,
00569 RuleBuilder<7,O+1,T2,T3,T4,T5,T6,T7,T8>
00570 >::type,
00571 public virtual util::IfElseType
00572 <O,
00573 GuardBuilder0,
00574 typename util::ResultOf
00575 <N,
00576 GuardBuilder0,
00577 GuardBuilder1<RuleBuilder<N,O,ACEDIA_GET_T1_TO_T9()>,T1>,
00578 GuardBuilder2<RuleBuilder<N,O,ACEDIA_GET_T1_TO_T9()>,T1,T2>,
00579 GuardBuilder3<RuleBuilder<N,O,ACEDIA_GET_T1_TO_T9()>,T1,T2,T3>,
00580 GuardBuilder4<RuleBuilder<N,O,ACEDIA_GET_T1_TO_T9()>,T1,T2,T3,T4>,
00581 GuardBuilder5<RuleBuilder<N,O,ACEDIA_GET_T1_TO_T9()>,T1,T2,T3,T4,T5>,
00582 GuardBuilder6<RuleBuilder<N,O,ACEDIA_GET_T1_TO_T9()>,T1,T2,T3,T4,T5,T6>,
00583 GuardBuilder7<RuleBuilder<N,O,ACEDIA_GET_T1_TO_T9()>,T1,T2,T3,T4,T5,T6,T7>,
00584 GuardBuilder8<RuleBuilder<N,O,ACEDIA_GET_T1_TO_T9()>,T1,T2,T3,T4,T5,T6,T7,T8>,
00585 GuardBuilder9<RuleBuilder<N,O,ACEDIA_GET_T1_TO_T9()>,T1,T2,T3,T4,T5,T6,T7,T8,T9>
00586 >::type
00587 >::type
00588 {
00589
00590 BOOST_STATIC_ASSERT(N >= 0);
00591 BOOST_STATIC_ASSERT(O >= 0);
00592
00593 typedef
00594 typename util::ResultOf
00595 <N,
00596 RuleBuilderBase,
00597 RuleBuilder<0,O+1>,
00598 RuleBuilder<1,O+1,T2>,
00599 RuleBuilder<2,O+1,T2,T3>,
00600 RuleBuilder<3,O+1,T2,T3,T4>,
00601 RuleBuilder<4,O+1,T2,T3,T4,T5>,
00602 RuleBuilder<5,O+1,T2,T3,T4,T5,T6>,
00603 RuleBuilder<6,O+1,T2,T3,T4,T5,T6,T7>,
00604 RuleBuilder<7,O+1,T2,T3,T4,T5,T6,T7,T8>
00605 >::type
00606 Base;
00607
00608 using Base::operator>>;
00609
00610 RuleBuilder(details::AnyArrayProcessor *pc) : Base(pc) { }
00611
00612 inline details::AnyArrayProcessor* operator>>(
00613 const typename util::ResultOf
00614 <N,
00615 boost::function0<void>,
00616 boost::function1<void,T1>,
00617 boost::function2<void,T1,T2>,
00618 boost::function3<void,T1,T2,T3>,
00619 boost::function4<void,T1,T2,T3,T4>,
00620 boost::function5<void,T1,T2,T3,T4,T5>,
00621 boost::function6<void,T1,T2,T3,T4,T5,T6>,
00622 boost::function7<void,T1,T2,T3,T4,T5,T6,T7>,
00623 boost::function8<void,T1,T2,T3,T4,T5,T6,T7,T8>,
00624 boost::function9<void,T1,T2,T3,T4,T5,T6,T7,T8,T9>
00625 >::type
00626 &f)
00627 {
00628 return passThroughAndClear(new details::InvokeFunctor<N,O,ACEDIA_GET_T1_TO_T9()>(f));
00629 }
00630
00631 inline RuleBuilder &passThrough(details::AnyArrayProcessor *nProc)
00632 {
00633 this->proc->passThrough(nProc);
00634 return *this;
00635 }
00636
00637 };
00638
00639 template<typename T>
00640 struct SingleRuleBuilder : public RuleBuilder<1,0,T>
00641 {
00642
00643 typedef RuleBuilder<1,0,T> Base;
00644
00645 using Base::operator>>;
00646
00647 SingleRuleBuilder(details::AnyArrayProcessor *pc) : Base(pc) { }
00648
00649 typename util::UnboxUtil<T>::UnboxedRuleBuilder unbox()
00650 {
00651 details::AnyArrayProcessor *pc = this->proc;
00652 this->proc = NULL;
00653 return util::UnboxUtil<T>::doUnbox(pc);
00654 }
00655
00656 };
00657
00658 }
00659
00660 #endif // ACEDIA_RULE_BUILDER_H