• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // compat.h
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 //
16 // \file
17 // Google compatibility declarations and inline definitions.
18 
19 #ifndef FST_COMPAT_H__
20 #define FST_COMPAT_H__
21 
22 // for STL
23 #include <cassert>
24 #include <cstdio>
25 #include <iostream>
26 #include <map>
27 #include <string>
28 #include <vector>
29 
30 #include <ext/hash_map>
31 #include <fcntl.h>
32 #include <pthread.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <unistd.h>
36 
37 // exact size types
38 typedef short int16;
39 typedef int int32;
40 typedef long long int64;
41 
42 typedef unsigned short uint16;
43 typedef unsigned int uint32;
44 typedef unsigned long long uint64;
45 
46 using namespace std;
47 
48 // make copy constructor and operator= private
49 #define DISALLOW_EVIL_CONSTRUCTORS(type)    \
50   type(const type&);                        \
51   void operator=(const type&)
52 
53 // thread control
54 class Mutex {
55  public:
56   Mutex();
57 
58  private:
59   DISALLOW_EVIL_CONSTRUCTORS(Mutex);
60 };
61 
62 class MutexLock {
63  public:
64   MutexLock(Mutex *);
65 
66  private:
67   DISALLOW_EVIL_CONSTRUCTORS(MutexLock);
68 };
69 
70 
71 // flags
72 #define DECLARE_bool(name) extern bool FLAGS_ ## name
73 #define DECLARE_string(name) extern string FLAGS_ ## name
74 #define DECLARE_int32(name) extern int32 FLAGS_ ## name
75 #define DECLARE_int64(name) extern int64 FLAGS_ ## name
76 #define DECLARE_double(name) extern double FLAGS_ ## name
77 
78 template <typename T>
79 struct FlagDescription {
FlagDescriptionFlagDescription80   FlagDescription(T *addr, const char *doc, const char *type, const T val)
81       : address(addr), doc_string(doc), type_name(type), default_value(val) {}
82 
83   T *address;
84   const char *doc_string;
85   const char *type_name;
86   const T default_value;
87 };
88 
89 template <typename T>
90 class FlagRegister {
91  public:
GetRegister()92   static FlagRegister<T> *GetRegister() {
93     pthread_once(&register_init_, &FlagRegister<T>::Init);
94     return register_;
95   }
96 
GetFlagDescription(const string & name)97   const FlagDescription<T> &GetFlagDescription(const string &name) const {
98     MutexLock l(register_lock_);
99     typename map< string, FlagDescription<T> >::const_iterator it =
100       flag_table_.find(name);
101     return it != flag_table_.end() ? it->second : 0;
102   }
SetDescription(const string & name,const FlagDescription<T> & desc)103   void SetDescription(const string &name, const FlagDescription<T> &desc) {
104     MutexLock l(register_lock_);
105     flag_table_.insert(make_pair(name, desc));
106   }
107 
SetFlag(const string & val,bool * address)108   bool SetFlag(const string &val, bool *address) const {
109     if (val == "true" || val == "1" || val.empty()) {
110       *address = true;
111       return true;
112     } else if (val == "false" || val == "0") {
113       *address = false;
114       return true;
115     }
116     else {
117       return false;
118     }
119   }
SetFlag(const string & val,string * address)120   bool SetFlag(const string &val, string *address) const {
121     *address = val;
122     return true;
123   }
SetFlag(const string & val,int32 * address)124   bool SetFlag(const string &val, int32 *address) const {
125     char *p = 0;
126     *address = strtol(val.c_str(), &p, 0);
127     return !val.empty() && *p == '\0';
128   }
SetFlag(const string & val,int64 * address)129   bool SetFlag(const string &val, int64 *address) const {
130     char *p = 0;
131     *address = strtoll(val.c_str(), &p, 0);
132     return !val.empty() && *p == '\0';
133   }
SetFlag(const string & val,double * address)134   bool SetFlag(const string &val, double *address) const {
135     char *p = 0;
136     *address = strtod(val.c_str(), &p);
137     return !val.empty() && *p == '\0';
138   }
139 
InitFlag(const string & arg,const string & val)140   bool InitFlag(const string &arg, const string &val) const {
141     for (typename map< string, FlagDescription<T> >::const_iterator it =
142            flag_table_.begin();
143          it != flag_table_.end();
144          ++it) {
145       const string &name = it->first;
146       const FlagDescription<T> &desc = it->second;
147       if (arg == name)
148         return SetFlag(val, desc.address);
149     }
150     return false;
151   }
152 
ShowDefault(bool default_value)153   void ShowDefault(bool default_value) const {
154     std::cout << ", default = ";
155     std::cout << (default_value ? "true" : "false");
156   }
ShowDefault(const string & default_value)157   void ShowDefault(const string &default_value) const {
158     std::cout << ", default = ";
159     std::cout << "\"" << default_value << "\"";
160   }
ShowDefault(const V & default_value)161   template<typename V> void ShowDefault(const V& default_value) const {
162     std::cout << ", default = ";
163     std::cout << default_value;
164   }
ShowUsage()165   void ShowUsage() const {
166     for (typename map< string, FlagDescription<T> >::const_iterator it =
167            flag_table_.begin();
168          it != flag_table_.end();
169          ++it) {
170       const string &name = it->first;
171       const FlagDescription<T> &desc = it->second;
172       std::cout << "    --" << name
173            << ": type = " << desc.type_name;
174       ShowDefault(desc.default_value);
175       std::cout << "\n      " << desc.doc_string  << "\n";
176     }
177   }
178 
179  private:
Init()180   static void Init() {
181     register_lock_ = new Mutex;
182     register_ = new FlagRegister<T>;
183   }
184   static pthread_once_t register_init_;   // ensures only called once
185   static Mutex* register_lock_;           // multithreading lock
186   static FlagRegister<T> *register_;
187 
188   map< string, FlagDescription<T> > flag_table_;
189 };
190 
191 template <class T>
192 pthread_once_t FlagRegister<T>::register_init_ = PTHREAD_ONCE_INIT;
193 
194 template <class T>
195 Mutex *FlagRegister<T>::register_lock_ = 0;
196 
197 template <class T>
198 FlagRegister<T> *FlagRegister<T>::register_ = 0;
199 
200 
201 template <typename T>
202 class FlagRegisterer {
203  public:
FlagRegisterer(const string & name,const FlagDescription<T> & desc)204   FlagRegisterer(const string &name, const FlagDescription<T> &desc) {
205     FlagRegister<T> *registr = FlagRegister<T>::GetRegister();
206     registr->SetDescription(name, desc);
207   }
208 
209  private:
210   DISALLOW_EVIL_CONSTRUCTORS(FlagRegisterer);
211 };
212 
213 
214 #define DEFINE_VAR(type, name, value, doc)                                \
215   type FLAGS_ ## name = value;                                            \
216   static FlagRegisterer<type>                                             \
217   name ## _flags_registerer(#name, FlagDescription<type>(&FLAGS_ ## name, \
218                                                          doc,             \
219                                                          #type,           \
220                                                          value))
221 
222 #define DEFINE_bool(name, value, doc) DEFINE_VAR(bool, name, value, doc)
223 #define DEFINE_string(name, value, doc) DEFINE_VAR(string, name, value, doc)
224 #define DEFINE_int32(name, value, doc) DEFINE_VAR(int32, name, value, doc)
225 #define DEFINE_int64(name, value, doc) DEFINE_VAR(int64, name, value, doc)
226 #define DEFINE_double(name, value, doc) DEFINE_VAR(double, name, value, doc)
227 
228 void InitFst(const char *usage, int *argc, char ***argv, bool remove_flags);
229 
230 void ShowUsage();
231 
232 
233 // checking
234 #define CHECK(x) assert(x)
235 #define CHECK_EQ(x, y) assert((x) == (y))
236 
237 // logging
238 DECLARE_int32(v);
239 
240 // tmp directory
241 DECLARE_string(tmpdir);
242 
243 class LogMessage {
244  public:
LogMessage(const string & type)245   LogMessage(const string &type) : fatal_(type == "FATAL") {
246     std::cerr << type << ": ";
247   }
~LogMessage()248   ~LogMessage() {
249     std::cerr << endl;
250     if(fatal_)
251       exit(1);
252   }
stream()253   ostream &stream() { return std::cerr; }
254 
255  private:
256   bool fatal_;
257 };
258 
259 #define LOG(type) LogMessage(#type).stream()
260 #define VLOG(level) if ((level) <= FLAGS_v) LOG(INFO)
261 
262 
263 // string utilities
264 void SplitToVector(char *line, const char *delim,
265                    vector<char *> *vec, bool omit_empty_strings);
266 
267 // Downcasting
268 template<typename To, typename From>
down_cast(From * f)269 inline To down_cast(From* f) {
270   return static_cast<To>(f);
271 }
272 
273 // Bitcasting
274 template <class Dest, class Source>
bit_cast(const Source & source)275 inline Dest bit_cast(const Source& source) {
276   // Compile time assertion: sizeof(Dest) == sizeof(Source)
277   // A compile error here means your Dest and Source have different sizes.
278   typedef char VerifySizesAreEqual [sizeof(Dest) == sizeof(Source) ? 1 :
279                                     -1];
280   Dest dest;
281   memcpy(&dest, &source, sizeof(dest));
282   return dest;
283 }
284 
285 // MD5 checksums
286 class MD5 {
287  public:
288   MD5();
289   void Reset();
290   void Update(void const *data, int size);
291   string Digest();
292 
293  private:
294   DISALLOW_EVIL_CONSTRUCTORS(MD5);
295 };
296 
297 // Hashing functions
298 namespace __gnu_cxx {
299 
300 template<> struct hash<int64> {
301   size_t operator()(int64 x) const {
302     return x;
303   }
304 };
305 
306 template<> struct hash<string> {
307   size_t operator()(const string &s) const {
308     return __stl_hash_string(s.c_str());
309   }
310 };
311 
312 }  // namespace __gnu_cxx
313 
314 #endif  // FST_COMPAT_H__
315