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 35namespace fst { 36namespace script { 37namespace args { 38 39// Sentinel value that means "no arg here." 40class 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) 53template<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> 62struct 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 80template<class T1, 81 class T2, 82 class T3, 83 class T4, 84 class T5, 85 class T6, 86 class T7, 87 class T8> 88struct 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 105template<class T1, 106 class T2, 107 class T3, 108 class T4, 109 class T5, 110 class T6, 111 class T7> 112struct 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 129template<class T1, 130 class T2, 131 class T3, 132 class T4, 133 class T5, 134 class T6> 135struct 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 150template<class T1, 151 class T2, 152 class T3, 153 class T4, 154 class T5> 155struct 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 168template<class T1, 169 class T2, 170 class T3, 171 class T4> 172struct 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 184template<class T1, 185 class T2, 186 class T3> 187struct 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) 199template<class T1, 200 class T2> 201struct 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 218template<class Retval, class ArgPackage> 219struct 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. 228template<class Retval, class ArgPackage> 229struct 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