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@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 PackagePackage73 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