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 { 80 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: 92 static FlagRegister<T> *GetRegister() { 93 pthread_once(®ister_init_, &FlagRegister<T>::Init); 94 return register_; 95 } 96 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 } 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 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 } 120 bool SetFlag(const string &val, string *address) const { 121 *address = val; 122 return true; 123 } 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 } 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 } 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 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 153 void ShowDefault(bool default_value) const { 154 std::cout << ", default = "; 155 std::cout << (default_value ? "true" : "false"); 156 } 157 void ShowDefault(const string &default_value) const { 158 std::cout << ", default = "; 159 std::cout << "\"" << default_value << "\""; 160 } 161 template<typename V> void ShowDefault(const V& default_value) const { 162 std::cout << ", default = "; 163 std::cout << default_value; 164 } 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: 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: 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: 245 LogMessage(const string &type) : fatal_(type == "FATAL") { 246 std::cerr << type << ": "; 247 } 248 ~LogMessage() { 249 std::cerr << endl; 250 if(fatal_) 251 exit(1); 252 } 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> 269 inline To down_cast(From* f) { 270 return static_cast<To>(f); 271 } 272 273 // Bitcasting 274 template <class Dest, class 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