1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// util.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: riley@google.com (Michael Riley)
17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \file
19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// FST utility inline definitions.
20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_UTIL_H__
22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_UTIL_H__
23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
243da1eb108d36da35333b2d655202791af854996bPrzemyslaw Szczepaniak#include <tr1/unordered_map>
25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_map;
26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_multimap;
273da1eb108d36da35333b2d655202791af854996bPrzemyslaw Szczepaniak#include <tr1/unordered_set>
28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_set;
29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_multiset;
30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <list>
31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <map>
32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <set>
33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <sstream>
34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <string>
35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <vector>
36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::vector;
37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/compat.h>
40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/types.h>
41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <iostream>
43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fstream>
44dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin#include <sstream>
45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// UTILITY FOR ERROR HANDLING
48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonDECLARE_bool(fst_error_fatal);
51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FSTERROR() (FLAGS_fst_error_fatal ? LOG(FATAL) : LOG(ERROR))
53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst {
55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// UTILITIES FOR TYPE I/O
58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Read some types from an input stream.
61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Generic case.
63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename T>
64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline istream &ReadType(istream &strm, T *t) {
65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return t->Read(strm);
66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Fixed size, contiguous memory read.
69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define READ_POD_TYPE(T)                                    \
70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline istream &ReadType(istream &strm, T *t) {             \
71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm.read(reinterpret_cast<char *>(t), sizeof(T)); \
72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(bool);
75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(char);
76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(signed char);
77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(unsigned char);
78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(short);
79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(unsigned short);
80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(int);
81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(unsigned int);
82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(long);
83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(unsigned long);
84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(long long);
85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(unsigned long long);
86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(float);
87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_POD_TYPE(double);
88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// String case.
90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline istream &ReadType(istream &strm, string *s) {
91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  s->clear();
92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int32 ns = 0;
93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  strm.read(reinterpret_cast<char *>(&ns), sizeof(ns));
94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (int i = 0; i < ns; ++i) {
95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    char c;
96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    strm.read(&c, 1);
97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    *s += c;
98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm;
100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Pair case.
103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename S, typename T>
104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline istream &ReadType(istream &strm, pair<S, T> *p) {
105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ReadType(strm, &p->first);
106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ReadType(strm, &p->second);
107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm;
108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename S, typename T>
111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline istream &ReadType(istream &strm, pair<const S, T> *p) {
112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ReadType(strm, const_cast<S *>(&p->first));
113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ReadType(strm, &p->second);
114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm;
115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// General case - no-op.
118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename C>
119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid StlReserve(C *c, int64 n) {}
120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialization for vectors.
122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename S, typename T>
123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid StlReserve(vector<S, T> *c, int64 n) {
124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  c->reserve(n);
125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// STL sequence container.
128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define READ_STL_SEQ_TYPE(C)                             \
129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename S, typename T>                        \
130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline istream &ReadType(istream &strm, C<S, T> *c) {    \
131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  c->clear();                                            \
132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 n = 0;                                           \
133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  strm.read(reinterpret_cast<char *>(&n), sizeof(n));    \
134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StlReserve(c, n);                                      \
135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (ssize_t i = 0; i < n; ++i) {                      \
136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    typename C<S, T>::value_type value;                  \
137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ReadType(strm, &value);                              \
138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    c->insert(c->end(), value);                          \
139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }                                                      \
140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm;                                           \
141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_STL_SEQ_TYPE(vector);
144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_STL_SEQ_TYPE(list);
145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// STL associative container.
147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define READ_STL_ASSOC_TYPE(C)                           \
148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename S, typename T, typename U>            \
149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline istream &ReadType(istream &strm, C<S, T, U> *c) { \
150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  c->clear();                                            \
151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 n = 0;                                           \
152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  strm.read(reinterpret_cast<char *>(&n), sizeof(n));    \
153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (ssize_t i = 0; i < n; ++i) {                      \
154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    typename C<S, T, U>::value_type value;               \
155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ReadType(strm, &value);                              \
156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    c->insert(value);                                    \
157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }                                                      \
158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm;                                           \
159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_STL_ASSOC_TYPE(set);
162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_STL_ASSOC_TYPE(unordered_set);
163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_STL_ASSOC_TYPE(map);
164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonREAD_STL_ASSOC_TYPE(unordered_map);
165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Write some types to an output stream.
167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Generic case.
169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename T>
170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline ostream &WriteType(ostream &strm, const T t) {
171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  t.Write(strm);
172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm;
173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Fixed size, contiguous memory write.
176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define WRITE_POD_TYPE(T)                                           \
177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline ostream &WriteType(ostream &strm, const T t) {               \
178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm.write(reinterpret_cast<const char *>(&t), sizeof(T)); \
179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(bool);
182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(char);
183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(signed char);
184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(unsigned char);
185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(short);
186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(unsigned short);
187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(int);
188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(unsigned int);
189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(long);
190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(unsigned long);
191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(long long);
192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(unsigned long long);
193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(float);
194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_POD_TYPE(double);
195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// String case.
197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline ostream &WriteType(ostream &strm, const string &s) {
198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int32 ns = s.size();
199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  strm.write(reinterpret_cast<const char *>(&ns), sizeof(ns));
200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm.write(s.data(), ns);
201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Pair case.
204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename S, typename T>
205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline ostream &WriteType(ostream &strm, const pair<S, T> &p) {
206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  WriteType(strm, p.first);
207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  WriteType(strm, p.second);
208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm;
209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// STL sequence container.
212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define WRITE_STL_SEQ_TYPE(C)                                                \
213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename S, typename T>                                            \
214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline ostream &WriteType(ostream &strm, const C<S, T> &c) {                 \
215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 n = c.size();                                                        \
216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  strm.write(reinterpret_cast<char *>(&n), sizeof(n));                       \
217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (typename C<S, T>::const_iterator it = c.begin();                      \
218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson       it != c.end(); ++it)                                                  \
219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson     WriteType(strm, *it);                                                   \
220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm;                                                               \
221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_STL_SEQ_TYPE(vector);
224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_STL_SEQ_TYPE(list);
225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// STL associative container.
227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define WRITE_STL_ASSOC_TYPE(C)                                              \
228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename S, typename T, typename U>                                \
229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline ostream &WriteType(ostream &strm, const C<S, T, U> &c) {              \
230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 n = c.size();                                                        \
231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  strm.write(reinterpret_cast<char *>(&n), sizeof(n));                       \
232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (typename C<S, T, U>::const_iterator it = c.begin();                   \
233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson       it != c.end(); ++it)                                                  \
234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson     WriteType(strm, *it);                                                   \
235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return strm;                                                               \
236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_STL_ASSOC_TYPE(set);
239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_STL_ASSOC_TYPE(unordered_set);
240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_STL_ASSOC_TYPE(map);
241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWRITE_STL_ASSOC_TYPE(unordered_map);
242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Utilities for converting between int64 or Weight and string.
244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonint64 StrToInt64(const string &s, const string &src, size_t nline,
246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 bool allow_negative, bool *error = 0);
247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename Weight>
249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonWeight StrToWeight(const string &s, const string &src, size_t nline) {
250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight w;
251f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  istringstream strm(s);
252f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  strm >> w;
253f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (!strm) {
254f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    FSTERROR() << "StrToWeight: Bad weight = \"" << s
255f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson               << "\", source = " << src << ", line = " << nline;
256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return Weight::NoWeight();
257f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
258f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return w;
259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid Int64ToStr(int64 n, string *s);
262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename Weight>
264f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid WeightToStr(Weight w, string *s) {
265f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ostringstream strm;
266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  strm.precision(9);
267f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  strm << w;
268dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin  s->append(strm.str().data(), strm.str().size());
269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
2715b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin// Utilities for reading/writing integer pairs (typically labels)
272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Returns true on success
2745b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkintemplate <typename I>
2755b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkinbool ReadIntPairs(const string& filename,
2765b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin                    vector<pair<I, I> >* pairs,
277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                    bool allow_negative = false) {
278f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ifstream strm(filename.c_str());
279f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (!strm) {
2815b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    LOG(ERROR) << "ReadIntPairs: Can't open file: " << filename;
282f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return false;
283f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
284f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
285f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const int kLineLen = 8096;
286f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  char line[kLineLen];
287f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  size_t nline = 0;
288f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
289f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  pairs->clear();
290f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  while (strm.getline(line, kLineLen)) {
291f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    ++nline;
292f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    vector<char *> col;
293f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    SplitToVector(line, "\n\t ", &col, true);
2945b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    // empty line or comment?
2955b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    if (col.size() == 0 || col[0][0] == '\0' || col[0][0] == '#')
296f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      continue;
297f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (col.size() != 2) {
2985b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin      LOG(ERROR) << "ReadIntPairs: Bad number of columns, "
299f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                 << "file = " << filename << ", line = " << nline;
300f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return false;
301f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
302f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
303f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    bool err;
3045b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    I i1 = StrToInt64(col[0], filename, nline, allow_negative, &err);
305f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (err) return false;
3065b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    I i2 = StrToInt64(col[1], filename, nline, allow_negative, &err);
307f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (err) return false;
3085b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    pairs->push_back(make_pair(i1, i2));
309f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
310f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return true;
311f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
312f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
313f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Returns true on success
3145b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkintemplate <typename I>
3155b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkinbool WriteIntPairs(const string& filename,
3165b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin                   const vector<pair<I, I> >& pairs) {
317dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin  ostream *strm = &cout;
318f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (!filename.empty()) {
319f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    strm = new ofstream(filename.c_str());
320f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!*strm) {
3215b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin      LOG(ERROR) << "WriteIntPairs: Can't open file: " << filename;
322f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return false;
323f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
324f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
325f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
326f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (ssize_t n = 0; n < pairs.size(); ++n)
327f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    *strm << pairs[n].first << "\t" << pairs[n].second << "\n";
328f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
329f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (!*strm) {
3305b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    LOG(ERROR) << "WriteIntPairs: Write failed: "
331f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson               << (filename.empty() ? "standard output" : filename);
332f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return false;
333f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
334dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin  if (strm != &cout)
335f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    delete strm;
336f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  return true;
337f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
338f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
3395b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin// Utilities for reading/writing label pairs
3405b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin
3415b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkintemplate <typename Label>
3425b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkinbool ReadLabelPairs(const string& filename,
3435b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin                    vector<pair<Label, Label> >* pairs,
3445b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin                    bool allow_negative = false) {
3455b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin  return ReadIntPairs(filename, pairs, allow_negative);
3465b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin}
3475b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin
3485b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkintemplate <typename Label>
3495b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkinbool WriteLabelPairs(const string& filename,
3505b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin                     vector<pair<Label, Label> >& pairs) {
3515b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin  return WriteIntPairs(filename, pairs);
3525b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin}
3535b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin
354f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Utilities for converting a type name to a legal C symbol.
355f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
356f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid ConvertToLegalCSymbol(string *s);
357f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
358f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
359f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
360f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// UTILITIES FOR STREAM I/O
361f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
362f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
3635b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkinbool AlignInput(istream &strm);
3645b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkinbool AlignOutput(ostream &strm);
365f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
366f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
367f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// UTILITIES FOR PROTOCOL BUFFER I/O
368f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
369f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
370f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
371f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// An associative container for which testing membership is
372f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// faster than an STL set if members are restricted to an interval
373f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// that excludes most non-members. A 'Key' must have ==, !=, and < defined.
374f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Element 'NoKey' should be a key that marks an uninitialized key and
375f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// is otherwise unused. 'Find()' returns an STL const_iterator to the match
376f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// found, otherwise it equals 'End()'.
377f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class Key, Key NoKey>
378f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass CompactSet {
379f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonpublic:
380f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename set<Key>::const_iterator const_iterator;
381f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
382f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  CompactSet()
383f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : min_key_(NoKey),
384f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      max_key_(NoKey) { }
385f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
386f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  CompactSet(const CompactSet<Key, NoKey> &compact_set)
387f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : set_(compact_set.set_),
388f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      min_key_(compact_set.min_key_),
389f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      max_key_(compact_set.max_key_) { }
390f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
391f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Insert(Key key) {
392f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    set_.insert(key);
393f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (min_key_ == NoKey || key < min_key_)
394f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      min_key_ = key;
395f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (max_key_ == NoKey || max_key_ < key)
396f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        max_key_ = key;
397f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
398f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
3995b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin  void Erase(Key key) {
4005b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    set_.erase(key);
4015b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    if (set_.empty()) {
4025b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin        min_key_ = max_key_ = NoKey;
4035b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    } else if (key == min_key_) {
4045b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin      ++min_key_;
4055b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    } else if (key == max_key_) {
4065b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin      --max_key_;
4075b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    }
4085b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin  }
4095b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin
410f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void Clear() {
411f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    set_.clear();
412f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    min_key_ = max_key_ = NoKey;
413f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
414f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
415f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const_iterator Find(Key key) const {
416f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (min_key_ == NoKey ||
417f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        key < min_key_ || max_key_ < key)
418f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return set_.end();
419f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    else
420f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return set_.find(key);
421f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
422f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
4235b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin  bool Member(Key key) const {
4245b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    if (min_key_ == NoKey || key < min_key_ || max_key_ < key) {
4255b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin      return false;   // out of range
4265b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    } else if (min_key_ != NoKey && max_key_ + 1 == min_key_ + set_.size()) {
4275b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin      return true;    // dense range
4285b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    } else {
4295b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin      return set_.find(key) != set_.end();
4305b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin    }
4315b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin  }
4325b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin
433f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const_iterator Begin() const { return set_.begin(); }
434f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
435f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const_iterator End() const { return set_.end(); }
436f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
4375b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin  // All stored keys are greater than or equal to this value.
4385b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin  Key LowerBound() const { return min_key_; }
4395b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin
4405b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin  // All stored keys are less than or equal to this value.
4415b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin  Key UpperBound() const { return max_key_; }
4425b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin
443f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonprivate:
444f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  set<Key> set_;
445f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Key min_key_;
446f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Key max_key_;
447f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
448f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void operator=(const CompactSet<Key, NoKey> &);  //disallow
449f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
450f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
451f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}  // namespace fst
452f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
453f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif  // FST_LIB_UTIL_H__
454