types.cpp

00001 #include <set>
00002 #include "types.h"
00003 //#include "types_size.h"
00004 
00005 #include <stdio.h>
00006 
00007 namespace storage
00008 {
00009 
00010   const TYPES TypeTraits<bool>::id = T_BOOL;
00011 #ifndef _MSC_VER
00012   const TYPES TypeTraits<wchar_t>::id = T_WCHART;
00013 #endif
00014   const TYPES TypeTraits<char>::id = T_CHAR;
00015   const TYPES TypeTraits<signed char>::id = T_SIGNED_CHAR;
00016   const TYPES TypeTraits<unsigned char>::id = T_UNSIGNED_CHAR;
00017   const TYPES TypeTraits<short>::id = T_SHORT;
00018   const TYPES TypeTraits<unsigned short>::id = T_UNSIGNED_SHORT;
00019   const TYPES TypeTraits<int>::id = T_INT;
00020   const TYPES TypeTraits<unsigned int>::id = T_UNSIGNED_INT;
00021   const TYPES TypeTraits<long>::id = T_LONG;
00022   const TYPES TypeTraits<unsigned long>::id = T_UNSIGNED_LONG;
00023   const TYPES TypeTraits<long long>::id = T_LONG_LONG;
00024   const TYPES TypeTraits<unsigned long long>::id = T_UNSIGNED_LONG_LONG;
00025   const TYPES TypeTraits<float>::id = T_FLOAT;
00026   const TYPES TypeTraits<double>::id = T_DOUBLE;
00027   const TYPES TypeTraits<long double>::id = T_LONG_DOUBLE;
00028   const TYPES TypeTraits<std::string>::id = T_STRING;
00029   const TYPES TypeTraits<QString>::id = T_STRING;
00030 
00031   const QString TypeTraits<bool>::name = "bool";
00032 #ifndef _MSC_VER
00033   const QString TypeTraits<wchar_t>::name = "wchar_t";
00034 #endif
00035   const QString TypeTraits<char>::name = "char";
00036   const QString TypeTraits<signed char>::name = "signed_char";
00037   const QString TypeTraits<unsigned char>::name = "unsigned_char";
00038   const QString TypeTraits<short>::name = "short";
00039   const QString TypeTraits<unsigned short>::name = "unsigned_short";
00040   const QString TypeTraits<int>::name = "int";
00041   const QString TypeTraits<unsigned int>::name = "unsigned_int";
00042   const QString TypeTraits<long>::name = "long";
00043   const QString TypeTraits<unsigned long>::name = "unsigned_long";
00044   const QString TypeTraits<long long>::name = "long_long";
00045   const QString TypeTraits<unsigned long long>::name = "long_long";
00046   const QString TypeTraits<float>::name = "float";
00047   const QString TypeTraits<double>::name = "double";
00048   const QString TypeTraits<long double>::name = "long_double";
00049   const QString TypeTraits<std::string>::name = "string";
00050   const QString TypeTraits<QString>::name = "string";
00051 
00052   const NUMBER_CLASS TypeTraits<bool>::type = NOT_A_NUMBER;
00053 #ifndef _MSC_VER
00054   const NUMBER_CLASS TypeTraits<wchar_t>::type = CHAR;
00055 #endif
00056   const NUMBER_CLASS TypeTraits<char>::type = CHAR;
00057   const NUMBER_CLASS TypeTraits<signed char>::type = SIGNED_INTEGER;
00058   const NUMBER_CLASS TypeTraits<unsigned char>::type = UNSIGNED_INTEGER;
00059   const NUMBER_CLASS TypeTraits<short>::type = SIGNED_INTEGER;
00060   const NUMBER_CLASS TypeTraits<unsigned short>::type = UNSIGNED_INTEGER;
00061   const NUMBER_CLASS TypeTraits<int>::type = SIGNED_INTEGER;
00062   const NUMBER_CLASS TypeTraits<unsigned int>::type = UNSIGNED_INTEGER;
00063   const NUMBER_CLASS TypeTraits<long>::type = SIGNED_INTEGER;
00064   const NUMBER_CLASS TypeTraits<unsigned long>::type = UNSIGNED_INTEGER;
00065   const NUMBER_CLASS TypeTraits<long long>::type = SIGNED_INTEGER;
00066   const NUMBER_CLASS TypeTraits<unsigned long long>::type = UNSIGNED_INTEGER;
00067   const NUMBER_CLASS TypeTraits<float>::type = FLOATING_POINT;
00068   const NUMBER_CLASS TypeTraits<double>::type = FLOATING_POINT;
00069   const NUMBER_CLASS TypeTraits<long double>::type = FLOATING_POINT;
00070   const NUMBER_CLASS TypeTraits<QString>::type = NOT_A_NUMBER;
00071   const NUMBER_CLASS TypeTraits<std::string>::type = NOT_A_NUMBER;
00072 
00073 
00074   // sizes of the different types
00075 #define SBO sizeof(bool)
00076 #define SWC sizeof(wchar_t)
00077 #define SCH sizeof(char)
00078 #define SSC sizeof(signed char)
00079 #define SUC sizeof(unsigned char)
00080 #define SSH sizeof(short)
00081 #define SUS sizeof(unsigned short)
00082 #define SIN sizeof(int)
00083 #define SUI sizeof(unsigned int)
00084 #define SLO sizeof(long)
00085 #define SUL sizeof(unsigned long)
00086 #define SLL sizeof(long long)
00087 #define ULL sizeof(unsigned long long)
00088 #define SFL sizeof(float)
00089 #define SDB sizeof(double)
00090 #define SLD sizeof(long double)
00091 
00092   static bool conversion_matrix[NB_STORAGE_TYPES][NB_STORAGE_TYPES] = {
00093    //  bool      wchar   char   schar  uchar     short   ushort      int       uint      long     ulong     llong    ullong    float   double   ldouble  string
00094     {  true,     true,   true,  true,  true,     true,     true,     true,     true,     true,     true,     true,     true,    true,    true,    true,   true }, // bool
00095     { false,     true,  false, false, false, SWC<=SSH, SWC<=SUS, SWC<=SIN, SWC<=SUI, SWC<=SLO, SWC<=SUL, SWC<=SLL, SWC<=ULL,   false,   false,   false,   true }, // wchar_t
00096     { false,     true,   true,  true,  true,     true,     true,     true,     true,     true,     true,     true,     true,    true,    true,    true,   true }, // char
00097     { false,     true,   true,  true,  true,     true,     true,     true,     true,     true,     true,     true,     true,    true,    true,    true,   true }, // signed char
00098     { false,     true,   true, false,  true,     true,     true,     true,     true,     true,     true,     true,     true,    true,    true,    true,   true }, // unsigned char
00099     { false, SSH<=SWC,  false, false, false,     true,     true,     true,     true,     true,     true,     true,     true, SSH<SFL, SSH<SDB, SSH<SLD,   true }, // short
00100     { false, SUS<=SWC,  false, false, false,    false,     true,  SUS<SIN,     true,  SUS<SLO,     true,  SUS<SLL,     true, SUS<SFL, SUS<SDB, SUS<SLD,   true }, // unsigned short
00101     { false, SIN<=SWC,  false, false, false,    false,    false,     true,     true,     true,     true,     true,     true, SIN<SFL, SIN<SDB, SIN<SLD,   true }, // int
00102     { false, SUI<=SWC,  false, false, false,    false,    false,    false,     true,  SUS<SLO,     true,  SUS<SLL,     true, SUI<SFL, SUI<SDB, SUI<SLD,   true }, // unsigned int
00103     { false, SLO<=SWC,  false, false, false,    false,    false,    false,    false,     true,     true,     true,     true, SLO<SFL, SLO<SDB, SLO<SLD,   true }, // long
00104     { false, SUL<=SWC,  false, false, false,    false,    false,    false,    false,    false,     true,  SUL<SLL,     true, SUL<SFL, SUL<SDB, SUL<SLD,   true }, // unsigned long
00105     { false, SLL<=SWC,  false, false, false,    false,    false,    false,    false,    false,    false,     true,     true, SLL<SFL, SLL<SDB, SLL<SLD,   true }, // long long
00106     { false, ULL<=SWC,  false, false, false,    false,    false,    false,    false,    false,    false,    false,     true, ULL<SFL, ULL<SDB, ULL<SLD,   true }, // unsigned long long
00107     { false,    false,  false, false, false,    false,    false,    false,    false,    false,    false,    false,    false,    true,    true,    true,   true }, // float
00108     { false,    false,  false, false, false,    false,    false,    false,    false,    false,    false,    false,    false,   false,    true,    true,   true }, // double
00109     { false,    false,  false, false, false,    false,    false,    false,    false,    false,    false,    false,    false,   false,   false,    true,   true }, // long double
00110     {  true,     true,   true,  true,  true,     true,     true,     true,     true,     true,     true,     true,     true,    true,    true,    true,   true }  // string
00111   };
00112 
00113   bool isStrictConversion(TYPES from, TYPES to)
00114   {
00115     return conversion_matrix[from][to];
00116   }
00117 
00118   static QString* make_types()
00119   {
00120     static QString result[NB_STORAGE_TYPES];
00121 #define CREATE_TYPE_ENTRY(id, type) result[id] = TypeTraits<type>::name;
00122     FOR_ALL_TYPEIDS(CREATE_TYPE_ENTRY)
00123 #undef CREATE_TYPE_ENTRY
00124     return result;
00125   };
00126 
00127 
00128   static QString const* const type_names = make_types();
00129 
00130   TYPES typename_to_id(const QString& name)
00131   {
00132     for(int i = T_BOOL ; i <= T_STRING ; ++i)
00133     {
00134       if(type_names[i] == name)
00135         return (TYPES)i;
00136     }
00137     return T_INVALID;
00138   }
00139 
00140   const QString& typeid_to_name(TYPES id)
00141   {
00142     if(id == T_INVALID)
00143       return TypeTraits<void>::name;
00144     return type_names[id];
00145   }
00146 
00147   static std::set<QString> set_true_values()
00148   {
00149     std::set<QString> s;
00150     s.insert("true");
00151     s.insert("1");
00152     s.insert("yes");
00153     s.insert("y");
00154     s.insert("t");
00155     return s;
00156   }
00157 
00158   static std::set<QString> set_false_values()
00159   {
00160     std::set<QString> s;
00161     s.insert("false");
00162     s.insert("0");
00163     s.insert("no");
00164     s.insert("n");
00165     s.insert("f");
00166     return s;
00167   }
00168 
00169   static std::set<QString> true_values = set_true_values();
00170   static std::set<QString> false_values = set_false_values();
00171 
00172   bool ConvertType<bool,QString>::operator()(const bool& c, QString &str) const
00173   {
00174     if(c)
00175       str = "True";
00176     else
00177       str = "False";
00178     return true;
00179   }
00180 
00181 #ifndef _MSC_VER
00182   bool ConvertType<wchar_t,QString>::operator()(const wchar_t& c, QString &str) const
00183   {
00184     str = QString::fromWCharArray(&c, 1);
00185     return true;
00186   }
00187 #endif
00188 
00189   bool ConvertType<char,QString>::operator()(const char& c, QString &str) const
00190   {
00191     str = QString(1, c);
00192     return true;
00193   }
00194 
00195   bool ConvertType<signed char,QString>::operator()(const signed char& c, QString &str) const
00196   {
00197     str = QString(1, c);
00198     return true;
00199   }
00200 
00201   bool ConvertType<unsigned char,QString>::operator()(const unsigned char& c, QString &str) const
00202   {
00203     str = QString(1, c);
00204     return true;
00205   }
00206 
00207   bool ConvertType<short,QString>::operator()(const short& c, QString &str) const
00208   {
00209     str = QString::number(c);
00210     return true;
00211   }
00212 
00213   bool ConvertType<unsigned short,QString>::operator()(const unsigned short& c, QString &str) const
00214   {
00215     str = QString::number(c);
00216     return true;
00217   }
00218 
00219   bool ConvertType<int,QString>::operator()(const int& c, QString &str) const
00220   {
00221     str = QString::number(c);
00222     return true;
00223   }
00224 
00225   bool ConvertType<unsigned int,QString>::operator()(const unsigned int& c, QString &str) const
00226   {
00227     str = QString::number(c);
00228     return true;
00229   }
00230 
00231   bool ConvertType<long,QString>::operator()(const long& c, QString &str) const
00232   {
00233     str = QString::number(c);
00234     return true;
00235   }
00236 
00237   bool ConvertType<unsigned long,QString>::operator()(const unsigned long& c, QString &str) const
00238   {
00239     str = QString::number(c);
00240     return true;
00241   }
00242 
00243   bool ConvertType<long long,QString>::operator()(const long long& c, QString &str) const
00244   {
00245     str = QString::number(c);
00246     return true;
00247   }
00248 
00249   bool ConvertType<unsigned long long,QString>::operator()(const unsigned long long& c, QString &str) const
00250   {
00251     str = QString::number(c);
00252     return true;
00253   }
00254   bool ConvertType<float,QString>::operator()(const float& c, QString &str) const
00255   {
00256     str = QString::number(c, 'g', 20).trimmed();
00257     return true;
00258   }
00259 
00260   bool ConvertType<double,QString>::operator()(const double& c, QString &str) const
00261   {
00262     str = QString::number(c, 'g', 20).trimmed();
00263     return true;
00264   }
00265 
00266   bool ConvertType<long double,QString>::operator()(const long double& c, QString &str) const
00267   {
00268     static char buf[100];
00269     ::snprintf(buf, 100, "%-20.20Lg", c);
00270     str = QString::fromAscii(buf).trimmed();
00271     return true;
00272   }
00273 
00274   bool ConvertType<std::string,QString>::operator()(const std::string& c, QString &str) const
00275   {
00276     str = QString::fromStdString(c);
00277     return true;
00278   }
00279 
00280   bool ConvertType<QString,bool>::operator()(const QString& str, bool& c) const
00281   {
00282     QString lstr = str.toLower();
00283     if(true_values.find(lstr) != true_values.end())
00284     {
00285       c = true;
00286       return true;
00287     }
00288     else if(false_values.find(lstr) != false_values.end())
00289     {
00290       c = false;
00291       return true;
00292     }
00293     return false;
00294   }
00295 
00296 #ifndef _MSC_VER
00297   bool ConvertType<QString,wchar_t>::operator()(const QString& str, wchar_t& c) const
00298   {
00299     if(str.isEmpty())
00300       return false;
00301     c = str.toStdWString()[0];
00302     return true;
00303   }
00304 #endif
00305 
00306   bool ConvertType<QString,char>::operator()(const QString& str, char& c) const
00307   {
00308     if(str.isEmpty())
00309       return false;
00310     c = str.toStdString()[0];
00311     return true;
00312   }
00313 
00314   bool ConvertType<QString,signed char>::operator()(const QString& str, signed char& c) const
00315   {
00316     if(str.isEmpty())
00317       return false;
00318     c = str.toStdString()[0];
00319     return true;
00320   }
00321 
00322   bool ConvertType<QString,unsigned char>::operator()(const QString& str, unsigned char& c) const
00323   {
00324     if(str.isEmpty())
00325       return false;
00326     c = str.toStdString()[0];
00327     return true;
00328   }
00329 
00330   bool ConvertType<QString,short>::operator()(const QString& str, short& c) const
00331   {
00332     bool ok;
00333     c = str.toShort(&ok);
00334     return ok;
00335   }
00336 
00337   bool ConvertType<QString,unsigned short>::operator()(const QString& str, unsigned short& c) const
00338   {
00339     bool ok;
00340     c = str.toUShort(&ok);
00341     return ok;
00342   }
00343 
00344   bool ConvertType<QString,int>::operator()(const QString& str, int& c) const
00345   {
00346     bool ok;
00347     c = str.toInt(&ok);
00348     return ok;
00349   }
00350 
00351   bool ConvertType<QString,unsigned int>::operator()(const QString& str, unsigned int& c) const
00352   {
00353     bool ok;
00354     c = str.toUInt(&ok);
00355     return ok;
00356   }
00357 
00358   bool ConvertType<QString,long>::operator()(const QString& str, long& c) const
00359   {
00360     bool ok;
00361     c = str.toLong(&ok);
00362     return ok;
00363   }
00364 
00365   bool ConvertType<QString,unsigned long>::operator()(const QString& str, unsigned long& c) const
00366   {
00367     bool ok;
00368     c = str.toULong(&ok);
00369     return ok;
00370   }
00371 
00372   bool ConvertType<QString,long long>::operator()(const QString& str, long long& c) const
00373   {
00374     bool ok;
00375     c = str.toLongLong(&ok);
00376     return ok;
00377   }
00378 
00379   bool ConvertType<QString,unsigned long long>::operator()(const QString& str, unsigned long long& c) const
00380   {
00381     bool ok;
00382     c = str.toULongLong(&ok);
00383     return ok;
00384   }
00385 
00386   bool ConvertType<QString,float>::operator()(const QString& str, float& c) const
00387   {
00388     bool ok;
00389     c = str.toFloat(&ok);
00390     return ok;
00391   }
00392 
00393   bool ConvertType<QString,double>::operator()(const QString& str, double& c) const
00394   {
00395     bool ok;
00396     c = str.toDouble(&ok);
00397     return ok;
00398   }
00399 
00400   bool ConvertType<QString,long double>::operator()(const QString& str, long double& c) const
00401   {
00402     QByteArray content = str.toAscii();
00403     const char* data = content.data();
00404     int nb_success = ::sscanf(data, "%Lg", &c);
00405     return nb_success == 1;
00406   }
00407 
00408   bool ConvertType<QString,std::string>::operator()(const QString& str, std::string& c) const
00409   {
00410     c = str.toStdString();
00411     return true;
00412   }
00413 
00414 #define CONVERT_TO_STDSTRING(type) \
00415   bool ConvertType<type,std::string>::operator()(const type& c, std::string& str) const \
00416   { \
00417     QString sstr; \
00418     bool result = convert_type(c, sstr); \
00419     if(result) \
00420     { \
00421       str = sstr.toStdString(); \
00422       return true; \
00423     } \
00424     return false; \
00425   }
00426 #define CONVERT_FROM_STDSTRING(type) \
00427   bool ConvertType<std::string,type>::operator()(const std::string& str, type& c) const \
00428   { \
00429     QString sstr = QString::fromStdString(str); \
00430     return convert_type(sstr, c); \
00431   }
00432 
00433   FOR_ALL_TYPES_NOSTRING(CONVERT_TO_STDSTRING);
00434   FOR_ALL_TYPES_NOSTRING(CONVERT_FROM_STDSTRING);
00435 
00436 #undef CONVERT_TO_STDSTRING
00437 #undef CONVERT_FROM_STDSTRING
00438 
00439   static TYPES type_by_capacity[4][6] =
00440   { { T_INVALID, T_INVALID, T_INVALID, T_INVALID, T_INVALID, T_INVALID }, // SIGNED_INTEGER
00441     { T_INVALID, T_INVALID, T_INVALID, T_INVALID, T_INVALID, T_INVALID }, // UNSIGNED_INTEGER
00442     { T_INVALID, T_INVALID, T_INVALID, T_INVALID, T_INVALID, T_INVALID }, // FLOATING_POINT
00443     { T_INVALID, T_INVALID, T_INVALID, T_INVALID, T_INVALID, T_INVALID }  // CHAR
00444   };
00445 
00446 //  static TYPES test_types[4][6] =
00447 //  { {   INT8,   INT16,   INT32,   INT64,   INT96,   INT128 }, // SIGNED_INTEGER
00448 //    {  UINT8,  UINT16,  UINT32,  UINT64,  UINT96,  UINT128 }, // UNSIGNED_INTEGER
00449 //    { FLOAT8, FLOAT16, FLOAT32, FLOAT64, FLOAT96, FLOAT128 }, // FLOATING_POINT
00450 //    {  CHAR8,  CHAR16,  CHAR32,  CHAR64,  CHAR96,  CHAR128 }  // CHAR
00451 //  };
00452 
00453 
00454   static bool find_integer_types()
00455   {
00456 #define FIT_TYPE(cat, typ, enu) \
00457     if(sizeof(typ) == 1) type_by_capacity[cat][0] = enu;\
00458     else if(sizeof(typ) == 2) type_by_capacity[cat][1] = enu;\
00459     else if(sizeof(typ) == 4) type_by_capacity[cat][2] = enu;\
00460     else if(sizeof(typ) == 8) type_by_capacity[cat][3] = enu;\
00461     else if(sizeof(typ) == 12) type_by_capacity[cat][4] = enu;\
00462     else if(sizeof(typ) == 16) type_by_capacity[cat][5] = enu
00463     FIT_TYPE(FLOATING_POINT, long double, T_LONG_DOUBLE);
00464     FIT_TYPE(FLOATING_POINT, double, T_DOUBLE);
00465     FIT_TYPE(FLOATING_POINT, float, T_FLOAT);
00466     FIT_TYPE(UNSIGNED_INTEGER, unsigned long long, T_UNSIGNED_LONG_LONG);
00467     FIT_TYPE(UNSIGNED_INTEGER, unsigned long, T_UNSIGNED_LONG);
00468     FIT_TYPE(UNSIGNED_INTEGER, unsigned int, T_UNSIGNED_INT);
00469     FIT_TYPE(UNSIGNED_INTEGER, unsigned short, T_UNSIGNED_SHORT);
00470     FIT_TYPE(UNSIGNED_INTEGER, unsigned char, T_UNSIGNED_CHAR);
00471     FIT_TYPE(SIGNED_INTEGER, long long, T_LONG_LONG);
00472     FIT_TYPE(SIGNED_INTEGER, long, T_LONG);
00473     FIT_TYPE(SIGNED_INTEGER, int, T_INT);
00474     FIT_TYPE(SIGNED_INTEGER, short, T_SHORT);
00475     FIT_TYPE(SIGNED_INTEGER, signed char, T_SIGNED_CHAR);
00476     FIT_TYPE(CHAR, wchar_t, T_WCHART);
00477     FIT_TYPE(CHAR, char, T_CHAR);
00478 //    fprintf(stdout, "Testiong types\n");
00479 //    bool result = true;
00480 //    for(unsigned int i = 0 ; i < 4 ; ++i)
00481 //      for(unsigned int j = 0 ; j < 6 ; ++j)
00482 //        if(type_by_capacity[i][j] != test_types[i][j])
00483 //        {
00484 //          result = false;
00485 //          fprintf(stdout, "Size %u for category %u is %u in computed and %u in precompiled\n", j, i, type_by_capacity[i][j], test_types[i][j]);
00486 //        }
00487 //    fprintf(stdout, "All types are ok\n");
00488     return true;
00489   }
00490 
00491   static bool check_types = find_integer_types();
00492 
00493   TYPES find_type(NUMBER_CLASS klass, size_t bytes)
00494   {
00495     int nb_cap;
00496     if(klass == NOT_A_NUMBER)
00497       return T_INVALID;
00498     if(bytes == 1)
00499       nb_cap = 0;
00500     else if(bytes == 2)
00501       nb_cap = 1;
00502     else if(bytes == 4)
00503       nb_cap = 2;
00504     else if(bytes == 8)
00505       nb_cap = 3;
00506     else if(bytes == 12)
00507       nb_cap = 4;
00508     else if(bytes == 16)
00509       nb_cap = 5;
00510     else
00511       return T_INVALID;
00512     return type_by_capacity[klass][nb_cap];
00513   }
00514 
00515 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:37:52 2013 for VVE by  doxygen 1.6.3