1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// pair-weight.h
2f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
3f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Licensed under the Apache License, Version 2.0 (the "License");
4f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// you may not use this file except in compliance with the License.
5f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// You may obtain a copy of the License at
6f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
7f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//     http://www.apache.org/licenses/LICENSE-2.0
8f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
9f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Unless required by applicable law or agreed to in writing, software
10f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// distributed under the License is distributed on an "AS IS" BASIS,
11f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// See the License for the specific language governing permissions and
13f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// limitations under the License.
14f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
15f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Copyright 2005-2010 Google, Inc.
16f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Author: shumash@google.com (Masha Maria Shugrina)
17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \file
19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Pair weight templated base class for weight classes that
20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// contain two weights (e.g. Product, Lexicographic)
21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_PAIR_WEIGHT_H_
23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_PAIR_WEIGHT_H_
24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <climits>
26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <stack>
27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <string>
28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/weight.h>
30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonDECLARE_string(fst_weight_parentheses);
33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonDECLARE_string(fst_weight_separator);
34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst {
36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class W1, class W2> class PairWeight;
38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W1, class W2>
39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonistream &operator>>(istream &strm, PairWeight<W1, W2> &w);
40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class W1, class W2>
42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass PairWeight {
43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  friend istream &operator>><W1, W2>(istream&, PairWeight<W1, W2>&);
45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef PairWeight<typename W1::ReverseWeight,
47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                     typename W2::ReverseWeight>
48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ReverseWeight;
49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  PairWeight() {}
51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  PairWeight(const PairWeight& w) : value1_(w.value1_), value2_(w.value2_) {}
53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  PairWeight(W1 w1, W2 w2) : value1_(w1), value2_(w2) {}
55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const PairWeight<W1, W2> &Zero() {
57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    static const PairWeight<W1, W2> zero(W1::Zero(), W2::Zero());
58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return zero;
59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const PairWeight<W1, W2> &One() {
62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    static const PairWeight<W1, W2> one(W1::One(), W2::One());
63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return one;
64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const PairWeight<W1, W2> &NoWeight() {
67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    static const PairWeight<W1, W2> no_weight(W1::NoWeight(), W2::NoWeight());
68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return no_weight;
69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  istream &Read(istream &strm) {
72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    value1_.Read(strm);
73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return value2_.Read(strm);
74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ostream &Write(ostream &strm) const {
77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    value1_.Write(strm);
78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return value2_.Write(strm);
79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  PairWeight<W1, W2> &operator=(const PairWeight<W1, W2> &w) {
82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    value1_ = w.Value1();
83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    value2_ = w.Value2();
84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return *this;
85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool Member() const { return value1_.Member() && value2_.Member(); }
88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t Hash() const {
90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    size_t h1 = value1_.Hash();
91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    size_t h2 = value2_.Hash();
92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    const int lshift = 5;
93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    const int rshift = CHAR_BIT * sizeof(size_t) - 5;
94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return h1 << lshift ^ h1 >> rshift ^ h2;
95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  PairWeight<W1, W2> Quantize(float delta = kDelta) const {
98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return PairWeight<W1, W2>(value1_.Quantize(delta),
99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                                 value2_.Quantize(delta));
100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ReverseWeight Reverse() const {
103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return ReverseWeight(value1_.Reverse(), value2_.Reverse());
104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const W1& Value1() const { return value1_; }
107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const W2& Value2() const { return value2_; }
109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson protected:
111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetValue1(const W1 &w) { value1_ = w; }
112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void SetValue2(const W2 &w) { value2_ = w; }
113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Reads PairWeight when there are not parentheses around pair terms
115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  inline static istream &ReadNoParen(
116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      istream &strm, PairWeight<W1, W2>& w, char separator) {
117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    int c;
118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    do {
119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      c = strm.get();
120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } while (isspace(c));
121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    string s1;
123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    while (c != separator) {
124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (c == EOF) {
125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        strm.clear(std::ios::badbit);
126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        return strm;
127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      s1 += c;
129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      c = strm.get();
130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    istringstream strm1(s1);
132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    W1 w1 = W1::Zero();
133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    strm1 >> w1;
134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // read second element
136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    W2 w2 = W2::Zero();
137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    strm >> w2;
138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    w = PairWeight<W1, W2>(w1, w2);
140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return strm;
141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Reads PairWeight when there are parentheses around pair terms
144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  inline static istream &ReadWithParen(
145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      istream &strm, PairWeight<W1, W2>& w,
146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      char separator, char open_paren, char close_paren) {
147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    int c;
148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    do {
149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      c = strm.get();
150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } while (isspace(c));
151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (c != open_paren) {
152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      FSTERROR() << " is fst_weight_parentheses flag set correcty? ";
153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      strm.clear(std::ios::failbit);
154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return strm;
155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    c = strm.get();
157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // read first element
159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    stack<int> parens;
160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    string s1;
161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    while (c != separator || !parens.empty()) {
162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (c == EOF) {
163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        strm.clear(std::ios::badbit);
164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        return strm;
165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      s1 += c;
167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      // if parens encountered before separator, they must be matched
168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (c == open_paren) {
169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        parens.push(1);
170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else if (c == close_paren) {
171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        // Fail for mismatched parens
172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (parens.empty()) {
173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          strm.clear(std::ios::failbit);
174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          return strm;
175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        }
176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        parens.pop();
177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      c = strm.get();
179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    istringstream strm1(s1);
181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    W1 w1 = W1::Zero();
182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    strm1 >> w1;
183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // read second element
185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    string s2;
186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    c = strm.get();
187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    while (c != EOF) {
188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      s2 += c;
189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      c = strm.get();
190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (s2.empty() || (s2[s2.size() - 1] != close_paren)) {
192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      FSTERROR() << " is fst_weight_parentheses flag set correcty? ";
193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      strm.clear(std::ios::failbit);
194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return strm;
195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    s2.erase(s2.size() - 1, 1);
198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    istringstream strm2(s2);
199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    W2 w2 = W2::Zero();
200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    strm2 >> w2;
201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    w = PairWeight<W1, W2>(w1, w2);
203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return strm;
204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  W1 value1_;
208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  W2 value2_;
209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W1, class W2>
213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool operator==(const PairWeight<W1, W2> &w,
214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                       const PairWeight<W1, W2> &v) {
215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return w.Value1() == v.Value1() && w.Value2() == v.Value2();
216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W1, class W2>
219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool operator!=(const PairWeight<W1, W2> &w1,
220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                       const PairWeight<W1, W2> &w2) {
221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return w1.Value1() != w2.Value1() || w1.Value2() != w2.Value2();
222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W1, class W2>
226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool ApproxEqual(const PairWeight<W1, W2> &w1,
227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                        const PairWeight<W1, W2> &w2,
228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                        float delta = kDelta) {
229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return ApproxEqual(w1.Value1(), w2.Value1(), delta) &&
230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ApproxEqual(w1.Value2(), w2.Value2(), delta);
231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W1, class W2>
234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline ostream &operator<<(ostream &strm, const PairWeight<W1, W2> &w) {
235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if(FLAGS_fst_weight_separator.size() != 1) {
236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    FSTERROR() << "FLAGS_fst_weight_separator.size() is not equal to 1";
237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    strm.clear(std::ios::badbit);
238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return strm;
239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  char separator = FLAGS_fst_weight_separator[0];
241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (FLAGS_fst_weight_parentheses.empty())
242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return strm << w.Value1() << separator << w.Value2();
243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (FLAGS_fst_weight_parentheses.size() != 2) {
245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    FSTERROR() << "FLAGS_fst_weight_parentheses.size() is not equal to 2";
246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    strm.clear(std::ios::badbit);
247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return strm;
248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  char open_paren = FLAGS_fst_weight_parentheses[0];
250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  char close_paren = FLAGS_fst_weight_parentheses[1];
251f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm << open_paren << w.Value1() << separator
252f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson              << w.Value2() << close_paren ;
253f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
254f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
255f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W1, class W2>
256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline istream &operator>>(istream &strm, PairWeight<W1, W2> &w) {
257f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if(FLAGS_fst_weight_separator.size() != 1) {
258f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    FSTERROR() << "FLAGS_fst_weight_separator.size() is not equal to 1";
259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    strm.clear(std::ios::badbit);
260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return strm;
261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  char separator = FLAGS_fst_weight_separator[0];
263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool read_parens = !FLAGS_fst_weight_parentheses.empty();
264f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (read_parens) {
265f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (FLAGS_fst_weight_parentheses.size() != 2) {
266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      FSTERROR() << "FLAGS_fst_weight_parentheses.size() is not equal to 2";
267f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      strm.clear(std::ios::badbit);
268f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return strm;
269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return PairWeight<W1, W2>::ReadWithParen(
271f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        strm, w, separator, FLAGS_fst_weight_parentheses[0],
272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        FLAGS_fst_weight_parentheses[1]);
273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  } else {
274f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return PairWeight<W1, W2>::ReadNoParen(strm, w, separator);
275f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
276f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
278f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}  // namespace fst
279f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif  // FST_LIB_PAIR_WEIGHT_H_
281