1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 2f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Licensed under the Apache License, Version 2.0 (the "License"); 3f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// you may not use this file except in compliance with the License. 4f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// You may obtain a copy of the License at 5f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 6f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// http://www.apache.org/licenses/LICENSE-2.0 7f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 8f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Unless required by applicable law or agreed to in writing, software 9f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// distributed under the License is distributed on an "AS IS" BASIS, 10f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// See the License for the specific language governing permissions and 12f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// limitations under the License. 13f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 14f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Copyright 2005-2010 Google, Inc. 15f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Author: jpr@google.com (Jake Ratkiewicz) 16f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This file defines the registration mechanism for new operations. 18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// These operations are designed to enable scripts to work with FST classes 19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// at a high level. 20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// If you have a new arc type and want these operations to work with FSTs 22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// with that arc type, see below for the registration steps 23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// you must take. 24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// These methods are only recommended for use in high-level scripting 26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// applications. Most users should use the lower-level templated versions 27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// corresponding to these. 28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// If you have a new arc type you'd like these operations to work with, 30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// use the REGISTER_FST_OPERATIONS macro defined in fstcsript.h 31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// If you have a custom operation you'd like to define, you need four 33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// components. In the following, assume you want to create a new operation 34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// with the signature 35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// void Foo(const FstClass &ifst, MutableFstClass *ofst); 37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// You need: 39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 1) A way to bundle the args that your new Foo operation will take, as 41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// a single struct. The template structs in arg-packs.h provide a handy 42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// way to do this. In Foo's case, that might look like this: 43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// typedef args::Package<const FstClass &, 45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// MutableFstClass *> FooArgs; 46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Note: this package of args is going to be passed by non-const pointer. 48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 2) A function template that is able to perform Foo, given the args and 50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// arc type. Yours might look like this: 51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// template<class Arc> 53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// void Foo(FooArgs *args) { 54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // Pull out the actual, arc-templated FSTs 55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// const Fst<Arc> &ifst = args->arg1.GetFst<Arc>(); 56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// MutableFst<Arc> *ofst = args->arg2->GetMutableFst<Arc>(); 57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // actually perform foo on ifst and ofst... 59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// } 60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 3) a client-facing function for your operation. This would look like 62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// the following: 63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// void Foo(const FstClass &ifst, MutableFstClass *ofst) { 65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // Check that the arc types of the FSTs match 66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// if (!ArcTypesMatch(ifst, *ofst, "Foo")) return; 67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // package the args 68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// FooArgs args(ifst, ofst); 69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // Finally, call the operation 70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Apply<Operation<FooArgs> >("Foo", ifst->ArcType(), &args); 71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// } 72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The Apply<> function template takes care of the link between 2 and 3, 74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// provided you also have: 75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 4) A registration for your new operation, on the arc types you care about. 77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This can be provided easily by the REGISTER_FST_OPERATION macro in 78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// operations.h: 79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// REGISTER_FST_OPERATION(Foo, StdArc, FooArgs); 81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// REGISTER_FST_OPERATION(Foo, MyArc, FooArgs); 82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // .. etc 83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// That's it! Now when you call Foo(const FstClass &, MutableFstClass *), 86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// it dispatches (in #3) via the Apply<> function to the correct 87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// instantiation of the template function in #2. 88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_SCRIPT_SCRIPT_IMPL_H_ 92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_SCRIPT_SCRIPT_IMPL_H_ 93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This file contains general-purpose templates which are used in the 96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// implementation of the operations. 97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <utility> 100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::pair; using std::make_pair; 101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <string> 102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/script/fst-class.h> 104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/generic-register.h> 105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/script/arg-packs.h> 106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/types.h> 108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst { 110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace script { 111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// A generic register for operations with various kinds of signatures. 114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Needed since every function signature requires a new registration class. 115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The pair<string, string> is understood to be the operation name and arc 116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// type; subclasses (or typedefs) need only provide the operation signature. 117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class OperationSignature> 120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass GenericOperationRegister 121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : public GenericRegister<pair<string, string>, 122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson OperationSignature, 123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson GenericOperationRegister<OperationSignature> > { 124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void RegisterOperation(const string &operation_name, 126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const string &arc_type, 127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson OperationSignature op) { 128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson this->SetEntry(make_pair(operation_name, arc_type), op); 129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson OperationSignature GetOperation( 132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const string &operation_name, const string &arc_type) { 133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return this->GetEntry(make_pair(operation_name, arc_type)); 134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson protected: 137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual string ConvertKeyToSoFilename( 138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const pair<string, string>& key) const { 139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Just use the old-style FST for now. 140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson string legal_type(key.second); // the arc type 141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ConvertToLegalCSymbol(&legal_type); 142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return legal_type + "-arc.so"; 144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Operation package - everything you need to register a new type of operation 149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The ArgPack should be the type that's passed into each wrapped function - 151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// for instance, it might be a struct containing all the args. 152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// It's always passed by pointer, so const members should be used to enforce 153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// constness where it's needed. Return values should be implemented as a 154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// member of ArgPack as well. 155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class ArgPack> 157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct Operation { 158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef ArgPack Args; 159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef void (*OpType)(ArgPack *args); 160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // The register (hash) type 162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef GenericOperationRegister<OpType> Register; 163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // The register-er type 165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef GenericRegisterer<Register> Registerer; 166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Macro for registering new types of operations. 170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define REGISTER_FST_OPERATION(Op, Arc, ArgPack) \ 172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static fst::script::Operation<ArgPack>::Registerer \ 173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson arc_dispatched_operation_ ## ArgPack ## Op ## Arc ## _registerer( \ 174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson make_pair(#Op, Arc::Type()), Op<Arc>) 175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Template function to apply an operation by name 179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class OpReg> 182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid Apply(const string &op_name, const string &arc_type, 183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typename OpReg::Args *args) { 184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typename OpReg::Register *reg = OpReg::Register::GetRegister(); 185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typename OpReg::OpType op = reg->GetOperation(op_name, arc_type); 187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (op == 0) { 189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "No operation found for \"" << op_name << "\" on " 190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson << "arc type " << arc_type; 191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return; 192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson op(args); 195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Helper that logs to ERROR if the arc types of a and b don't match. 199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The op_name is also printed. 200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonbool ArcTypesMatch(const FstClass &a, const FstClass &b, 201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const string &op_name); 202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} // namespace script 204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} // namespace fst 205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif // FST_SCRIPT_SCRIPT_IMPL_H_ 207