util.h revision dfd8b8327b93660601d016cdc6f29f433b45a8d8
1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// util.h
2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Licensed under the Apache License, Version 2.0 (the "License");
4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// you may not use this file except in compliance with the License.
5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// You may obtain a copy of the License at
6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//     http://www.apache.org/licenses/LICENSE-2.0
8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Unless required by applicable law or agreed to in writing, software
10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// distributed under the License is distributed on an "AS IS" BASIS,
11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// See the License for the specific language governing permissions and
13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// limitations under the License.
14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Copyright 2005-2010 Google, Inc.
16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Author: riley@google.com (Michael Riley)
17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// \file
19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// FST utility inline definitions.
20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifndef FST_LIB_UTIL_H__
22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define FST_LIB_UTIL_H__
23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <unordered_map>
25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengusing std::tr1::unordered_map;
26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengusing std::tr1::unordered_multimap;
27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <unordered_set>
28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengusing std::tr1::unordered_set;
29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengusing std::tr1::unordered_multiset;
30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <list>
31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <map>
32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <set>
33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sstream>
34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <string>
35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <vector>
36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengusing std::vector;
37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <fst/compat.h>
40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <fst/types.h>
41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <iostream>
43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <fstream>
44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sstream>
45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// UTILITY FOR ERROR HANDLING
48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengDECLARE_bool(fst_error_fatal);
51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define FSTERROR() (FLAGS_fst_error_fatal ? LOG(FATAL) : LOG(ERROR))
53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengnamespace fst {
55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// UTILITIES FOR TYPE I/O
58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Read some types from an input stream.
61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Generic case.
63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename T>
64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline istream &ReadType(istream &strm, T *t) {
65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return t->Read(strm);
66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Fixed size, contiguous memory read.
69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define READ_POD_TYPE(T)                                    \
70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline istream &ReadType(istream &strm, T *t) {             \
71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm.read(reinterpret_cast<char *>(t), sizeof(T)); \
72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(bool);
75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(char);
76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(signed char);
77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(unsigned char);
78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(short);
79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(unsigned short);
80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(int);
81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(unsigned int);
82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(long);
83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(unsigned long);
84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(long long);
85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(unsigned long long);
86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(float);
87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_POD_TYPE(double);
88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// String case.
90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline istream &ReadType(istream &strm, string *s) {
91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  s->clear();
92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  int32 ns = 0;
93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  strm.read(reinterpret_cast<char *>(&ns), sizeof(ns));
94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  for (int i = 0; i < ns; ++i) {
95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    char c;
96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    strm.read(&c, 1);
97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    *s += c;
98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  }
99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm;
100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Pair case.
103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename S, typename T>
104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline istream &ReadType(istream &strm, pair<S, T> *p) {
105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  ReadType(strm, &p->first);
106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  ReadType(strm, &p->second);
107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm;
108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename S, typename T>
111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline istream &ReadType(istream &strm, pair<const S, T> *p) {
112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  ReadType(strm, const_cast<S *>(&p->first));
113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  ReadType(strm, &p->second);
114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm;
115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// General case - no-op.
118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename C>
119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid StlReserve(C *c, int64 n) {}
120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Specialization for vectors.
122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename S, typename T>
123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid StlReserve(vector<S, T> *c, int64 n) {
124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  c->reserve(n);
125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// STL sequence container.
128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define READ_STL_SEQ_TYPE(C)                             \
129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename S, typename T>                        \
130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline istream &ReadType(istream &strm, C<S, T> *c) {    \
131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  c->clear();                                            \
132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  int64 n = 0;                                           \
133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  strm.read(reinterpret_cast<char *>(&n), sizeof(n));    \
134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  StlReserve(c, n);                                      \
135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  for (ssize_t i = 0; i < n; ++i) {                      \
136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    typename C<S, T>::value_type value;                  \
137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    ReadType(strm, &value);                              \
138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    c->insert(c->end(), value);                          \
139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  }                                                      \
140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm;                                           \
141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_STL_SEQ_TYPE(vector);
144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_STL_SEQ_TYPE(list);
145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// STL associative container.
147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define READ_STL_ASSOC_TYPE(C)                           \
148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename S, typename T, typename U>            \
149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline istream &ReadType(istream &strm, C<S, T, U> *c) { \
150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  c->clear();                                            \
151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  int64 n = 0;                                           \
152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  strm.read(reinterpret_cast<char *>(&n), sizeof(n));    \
153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  for (ssize_t i = 0; i < n; ++i) {                      \
154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    typename C<S, T, U>::value_type value;               \
155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    ReadType(strm, &value);                              \
156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    c->insert(value);                                    \
157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  }                                                      \
158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm;                                           \
159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_STL_ASSOC_TYPE(set);
162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_STL_ASSOC_TYPE(unordered_set);
163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_STL_ASSOC_TYPE(map);
164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengREAD_STL_ASSOC_TYPE(unordered_map);
165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Write some types to an output stream.
167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Generic case.
169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename T>
170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline ostream &WriteType(ostream &strm, const T t) {
171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  t.Write(strm);
172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm;
173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Fixed size, contiguous memory write.
176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define WRITE_POD_TYPE(T)                                           \
177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline ostream &WriteType(ostream &strm, const T t) {               \
178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm.write(reinterpret_cast<const char *>(&t), sizeof(T)); \
179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(bool);
182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(char);
183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(signed char);
184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(unsigned char);
185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(short);
186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(unsigned short);
187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(int);
188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(unsigned int);
189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(long);
190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(unsigned long);
191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(long long);
192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(unsigned long long);
193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(float);
194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_POD_TYPE(double);
195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// String case.
197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline ostream &WriteType(ostream &strm, const string &s) {
198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  int32 ns = s.size();
199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  strm.write(reinterpret_cast<const char *>(&ns), sizeof(ns));
200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm.write(s.data(), ns);
201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Pair case.
204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename S, typename T>
205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline ostream &WriteType(ostream &strm, const pair<S, T> &p) {
206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  WriteType(strm, p.first);
207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  WriteType(strm, p.second);
208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm;
209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// STL sequence container.
212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define WRITE_STL_SEQ_TYPE(C)                                                \
213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename S, typename T>                                            \
214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline ostream &WriteType(ostream &strm, const C<S, T> &c) {                 \
215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  int64 n = c.size();                                                        \
216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  strm.write(reinterpret_cast<char *>(&n), sizeof(n));                       \
217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  for (typename C<S, T>::const_iterator it = c.begin();                      \
218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng       it != c.end(); ++it)                                                  \
219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng     WriteType(strm, *it);                                                   \
220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm;                                                               \
221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_STL_SEQ_TYPE(vector);
224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_STL_SEQ_TYPE(list);
225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// STL associative container.
227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define WRITE_STL_ASSOC_TYPE(C)                                              \
228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename S, typename T, typename U>                                \
229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenginline ostream &WriteType(ostream &strm, const C<S, T, U> &c) {              \
230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  int64 n = c.size();                                                        \
231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  strm.write(reinterpret_cast<char *>(&n), sizeof(n));                       \
232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  for (typename C<S, T, U>::const_iterator it = c.begin();                   \
233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng       it != c.end(); ++it)                                                  \
234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng     WriteType(strm, *it);                                                   \
235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return strm;                                                               \
236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_STL_ASSOC_TYPE(set);
239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_STL_ASSOC_TYPE(unordered_set);
240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_STL_ASSOC_TYPE(map);
241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWRITE_STL_ASSOC_TYPE(unordered_map);
242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Utilities for converting between int64 or Weight and string.
244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint64 StrToInt64(const string &s, const string &src, size_t nline,
246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng                 bool allow_negative, bool *error = 0);
247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename Weight>
249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengWeight StrToWeight(const string &s, const string &src, size_t nline) {
250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  Weight w;
251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  istringstream strm(s);
252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  strm >> w;
253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  if (!strm) {
254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    FSTERROR() << "StrToWeight: Bad weight = \"" << s
255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng               << "\", source = " << src << ", line = " << nline;
256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    return Weight::NoWeight();
257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  }
258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return w;
259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid Int64ToStr(int64 n, string *s);
262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename Weight>
264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid WeightToStr(Weight w, string *s) {
265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  ostringstream strm;
266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  strm.precision(9);
267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  strm << w;
268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  s->append(strm.str().data(), strm.str().size());
269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Utilities for reading/writing label pairs
272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Returns true on success
274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename Label>
275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool ReadLabelPairs(const string& filename,
276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng                    vector<pair<Label, Label> >* pairs,
277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng                    bool allow_negative = false) {
278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  ifstream strm(filename.c_str());
279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  if (!strm) {
281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    LOG(ERROR) << "ReadLabelPairs: Can't open file: " << filename;
282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    return false;
283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  }
284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  const int kLineLen = 8096;
286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  char line[kLineLen];
287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  size_t nline = 0;
288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  pairs->clear();
290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  while (strm.getline(line, kLineLen)) {
291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    ++nline;
292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    vector<char *> col;
293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    SplitToVector(line, "\n\t ", &col, true);
294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    if (col.size() == 0 || col[0][0] == '\0')  // empty line
295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng      continue;
296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    if (col.size() != 2) {
297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng      LOG(ERROR) << "ReadLabelPairs: Bad number of columns, "
298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng                 << "file = " << filename << ", line = " << nline;
299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng      return false;
300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    }
301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    bool err;
303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    Label frmlabel = StrToInt64(col[0], filename, nline, allow_negative, &err);
304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    if (err) return false;
305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    Label tolabel = StrToInt64(col[1], filename, nline, allow_negative, &err);
306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    if (err) return false;
307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    pairs->push_back(make_pair(frmlabel, tolabel));
308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  }
309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return true;
310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Returns true on success
313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <typename Label>
314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool WriteLabelPairs(const string& filename,
315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng                     const vector<pair<Label, Label> >& pairs) {
316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  ostream *strm = &cout;
317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  if (!filename.empty()) {
318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    strm = new ofstream(filename.c_str());
319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    if (!*strm) {
320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng      LOG(ERROR) << "WriteLabelPairs: Can't open file: " << filename;
321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng      return false;
322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    }
323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  }
324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  for (ssize_t n = 0; n < pairs.size(); ++n)
326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    *strm << pairs[n].first << "\t" << pairs[n].second << "\n";
327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  if (!*strm) {
329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    LOG(ERROR) << "WriteLabelPairs: Write failed: "
330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng               << (filename.empty() ? "standard output" : filename);
331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    return false;
332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  }
333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  if (strm != &cout)
334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    delete strm;
335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  return true;
336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Utilities for converting a type name to a legal C symbol.
339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid ConvertToLegalCSymbol(string *s);
341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// UTILITIES FOR STREAM I/O
345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool AlignInput(istream &strm, int align);
348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool AlignOutput(ostream &strm, int align);
349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// UTILITIES FOR PROTOCOL BUFFER I/O
352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng//
353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// An associative container for which testing membership is
356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// faster than an STL set if members are restricted to an interval
357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// that excludes most non-members. A 'Key' must have ==, !=, and < defined.
358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// Element 'NoKey' should be a key that marks an uninitialized key and
359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// is otherwise unused. 'Find()' returns an STL const_iterator to the match
360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng// found, otherwise it equals 'End()'.
361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtemplate <class Key, Key NoKey>
362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengclass CompactSet {
363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengpublic:
364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  typedef typename set<Key>::const_iterator const_iterator;
365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  CompactSet()
367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    : min_key_(NoKey),
368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng      max_key_(NoKey) { }
369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  CompactSet(const CompactSet<Key, NoKey> &compact_set)
371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    : set_(compact_set.set_),
372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng      min_key_(compact_set.min_key_),
373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng      max_key_(compact_set.max_key_) { }
374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  void Insert(Key key) {
376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    set_.insert(key);
377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    if (min_key_ == NoKey || key < min_key_)
378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng      min_key_ = key;
379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    if (max_key_ == NoKey || max_key_ < key)
380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng        max_key_ = key;
381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  }
382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  void Clear() {
384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    set_.clear();
385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    min_key_ = max_key_ = NoKey;
386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  }
387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  const_iterator Find(Key key) const {
389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    if (min_key_ == NoKey ||
390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng        key < min_key_ || max_key_ < key)
391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng      return set_.end();
392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng    else
393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng      return set_.find(key);
394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  }
395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  const_iterator Begin() const { return set_.begin(); }
397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  const_iterator End() const { return set_.end(); }
399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprivate:
401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  set<Key> set_;
402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  Key min_key_;
403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  Key max_key_;
404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng  void operator=(const CompactSet<Key, NoKey> &);  //disallow
406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}  // namespace fst
409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif  // FST_LIB_UTIL_H__
411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng