Home | History | Annotate | Download | only in lib
      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(&register_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