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