Home | History | Annotate | Download | only in script
      1 
      2 // Licensed under the Apache License, Version 2.0 (the "License");
      3 // you may not use this file except in compliance with the License.
      4 // You may obtain a copy of the License at
      5 //
      6 //     http://www.apache.org/licenses/LICENSE-2.0
      7 //
      8 // Unless required by applicable law or agreed to in writing, software
      9 // distributed under the License is distributed on an "AS IS" BASIS,
     10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     11 // See the License for the specific language governing permissions and
     12 // limitations under the License.
     13 //
     14 // Copyright 2005-2010 Google, Inc.
     15 // Author: jpr (at) google.com (Jake Ratkiewicz)
     16 
     17 // Convenience templates for defining arg packs for the FstClass operations.
     18 
     19 // See operation-templates.h for a discussion about why these are needed; the
     20 // short story is that all FstClass operations must be implemented by a version
     21 // that takes one argument, most likely a struct bundling all the
     22 // logical arguments together. These template structs provide convenient ways
     23 // to specify these bundles (e.g. by means of appropriate typedefs).
     24 
     25 // The ArgPack template is sufficient for bundling together all the args for
     26 // a particular function. The function is assumed to be void-returning. If
     27 // you want a space for a return value, use the WithReturnValue template
     28 // as follows:
     29 
     30 // WithReturnValue<bool, ArgPack<...> >
     31 
     32 #ifndef FST_SCRIPT_ARG_PACKS_H_
     33 #define FST_SCRIPT_ARG_PACKS_H_
     34 
     35 namespace fst {
     36 namespace script {
     37 namespace args {
     38 
     39 // Sentinel value that means "no arg here."
     40 class none_type { };
     41 
     42 // Base arg pack template class. Specializations follow that allow
     43 // fewer numbers of arguments (down to 2). If the maximum number of arguments
     44 // increases, you will need to change three things:
     45 //   1) Add more template parameters to this template
     46 //   2) Add more specializations to allow fewer numbers of parameters than
     47 //      the new max.
     48 //   3) Add extra none_types to all existing specializations to fill
     49 //      the new slots.
     50 
     51 
     52 // 9 args (max)
     53 template<class T1,
     54          class T2 = none_type,
     55          class T3 = none_type,
     56          class T4 = none_type,
     57          class T5 = none_type,
     58          class T6 = none_type,
     59          class T7 = none_type,
     60          class T8 = none_type,
     61          class T9 = none_type>
     62 struct Package {
     63   T1 arg1;
     64   T2 arg2;
     65   T3 arg3;
     66   T4 arg4;
     67   T5 arg5;
     68   T6 arg6;
     69   T7 arg7;
     70   T8 arg8;
     71   T9 arg9;
     72 
     73   Package(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6,
     74           T7 arg7, T8 arg8, T9 arg9) :
     75       arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5),
     76       arg6(arg6), arg7(arg7), arg8(arg8), arg9(arg9) { }
     77 };
     78 
     79 // 8 args
     80 template<class T1,
     81          class T2,
     82          class T3,
     83          class T4,
     84          class T5,
     85          class T6,
     86          class T7,
     87          class T8>
     88 struct Package<T1, T2, T3, T4, T5, T6, T7, T8, none_type> {
     89   T1 arg1;
     90   T2 arg2;
     91   T3 arg3;
     92   T4 arg4;
     93   T5 arg5;
     94   T6 arg6;
     95   T7 arg7;
     96   T8 arg8;
     97 
     98   Package(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6,
     99           T7 arg7, T8 arg8) :
    100       arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5),
    101       arg6(arg6), arg7(arg7), arg8(arg8) { }
    102 };
    103 
    104 // 7 args
    105 template<class T1,
    106          class T2,
    107          class T3,
    108          class T4,
    109          class T5,
    110          class T6,
    111          class T7>
    112 struct Package<T1, T2, T3, T4, T5, T6, T7,
    113                none_type, none_type> {
    114   T1 arg1;
    115   T2 arg2;
    116   T3 arg3;
    117   T4 arg4;
    118   T5 arg5;
    119   T6 arg6;
    120   T7 arg7;
    121 
    122   Package(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6,
    123           T7 arg7) :
    124       arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5),
    125       arg6(arg6), arg7(arg7) { }
    126 };
    127 
    128 // 6 args
    129 template<class T1,
    130          class T2,
    131          class T3,
    132          class T4,
    133          class T5,
    134          class T6>
    135 struct Package<T1, T2, T3, T4, T5, T6, none_type,
    136                none_type, none_type> {
    137   T1 arg1;
    138   T2 arg2;
    139   T3 arg3;
    140   T4 arg4;
    141   T5 arg5;
    142   T6 arg6;
    143 
    144   Package(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) :
    145       arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5),
    146       arg6(arg6) { }
    147 };
    148 
    149 // 5 args
    150 template<class T1,
    151          class T2,
    152          class T3,
    153          class T4,
    154          class T5>
    155 struct Package<T1, T2, T3, T4, T5, none_type, none_type,
    156                none_type, none_type> {
    157   T1 arg1;
    158   T2 arg2;
    159   T3 arg3;
    160   T4 arg4;
    161   T5 arg5;
    162 
    163   Package(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) :
    164       arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5) { }
    165 };
    166 
    167 // 4 args
    168 template<class T1,
    169          class T2,
    170          class T3,
    171          class T4>
    172 struct Package<T1, T2, T3, T4, none_type, none_type,
    173                none_type, none_type, none_type> {
    174   T1 arg1;
    175   T2 arg2;
    176   T3 arg3;
    177   T4 arg4;
    178 
    179   Package(T1 arg1, T2 arg2, T3 arg3, T4 arg4) :
    180       arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4) { }
    181 };
    182 
    183 // 3 args
    184 template<class T1,
    185          class T2,
    186          class T3>
    187 struct Package<T1, T2, T3, none_type, none_type,
    188                none_type, none_type, none_type,
    189                none_type> {
    190   T1 arg1;
    191   T2 arg2;
    192   T3 arg3;
    193 
    194   Package(T1 arg1, T2 arg2, T3 arg3) :
    195       arg1(arg1), arg2(arg2), arg3(arg3) { }
    196 };
    197 
    198 // 2 args (minimum)
    199 template<class T1,
    200          class T2>
    201 struct Package<T1, T2, none_type, none_type,
    202                none_type, none_type, none_type,
    203                none_type, none_type> {
    204   T1 arg1;
    205   T2 arg2;
    206 
    207   Package(T1 arg1, T2 arg2) :
    208       arg1(arg1), arg2(arg2) { }
    209 };
    210 
    211 // Tack this on to an existing arg pack to add a return value.
    212 // The syntax for accessing the args is then slightly more stilted,
    213 // as you must do an extra member access (since the args are stored
    214 // as a member of this class).
    215 // The alternative is to declare another slew of templates for functions
    216 // that return a value, analogous to the above.
    217 
    218 template<class Retval, class ArgPackage>
    219 struct WithReturnValue {
    220   Retval retval;
    221   const ArgPackage &args;
    222 
    223   explicit WithReturnValue(const ArgPackage &args) : args(args) { }
    224 };
    225 
    226 // We don't want to store a reference to a reference, if ArgPackage is
    227 // already some reference type.
    228 template<class Retval, class ArgPackage>
    229 struct WithReturnValue<Retval, ArgPackage&> {
    230   Retval retval;
    231   const ArgPackage &args;
    232 
    233   explicit WithReturnValue(const ArgPackage &args) : args(args) { }
    234 };
    235 
    236 }  // namespace args
    237 }  // namespace script
    238 }  // namespace fst
    239 
    240 #endif  // FST_SCRIPT_ARG_PACKS_H_
    241