]> git.tdb.fi Git - libs/datafile.git/blob - source/type.h
Some refactoring of TextParser logic
[libs/datafile.git] / source / type.h
1 #ifndef MSP_DATAFILE_TYPE_H_
2 #define MSP_DATAFILE_TYPE_H_
3
4 #include <msp/core/inttypes.h>
5 #include <msp/strings/lexicalcast.h>
6
7 namespace Msp {
8 namespace DataFile {
9
10 struct Symbol
11 {
12         std::string name;
13
14         Symbol() { }
15
16         template<typename T>
17         Symbol(const T &n): name(lexical_cast<std::string>(n)) { }
18
19         template<typename T> operator T() const { return lexical_cast<T>(name); }
20 };
21
22 struct IntType
23 {
24         static const char signature = 'i';
25         typedef Int64 Store;
26         typedef Store Load;
27 };
28
29 struct FloatType
30 {
31         static const char signature = 'f';
32         typedef double Store;
33         typedef Store Load;
34 };
35
36 struct BoolType
37 {
38         static const char signature = 'b';
39         typedef bool Store;
40         typedef Store Load;
41 };
42
43 struct StringType
44 {
45         static const char signature = 's';
46         typedef std::string Store;
47         typedef Store Load;
48 };
49
50 struct SymbolType
51 {
52         // For backward compatibility
53         static const char signature = 'e';
54         typedef Symbol Store;
55 };
56
57 const char valid_signatures[] =
58 {
59         IntType::signature,
60         FloatType::signature,
61         BoolType::signature,
62         StringType::signature,
63         SymbolType::signature,
64         0
65 };
66
67 template<typename T>
68 struct HasLoadType
69 {
70         struct Yes { char c[2]; };
71         struct No { char c; };
72
73         template<typename U>
74         static Yes f(typename U::LoadType *);
75         template<typename U>
76         static No f(...);
77
78         enum { value = (sizeof(f<T>(0))==sizeof(Yes)) };
79 };
80
81 template<typename T, bool lt = HasLoadType<T>::value>
82 struct TypeInfo;
83
84 template<>
85 struct TypeInfo<short int, false>: IntType { };
86
87 template<>
88 struct TypeInfo<unsigned short int, false>: IntType { };
89
90 template<>
91 struct TypeInfo<int, false>: IntType { };
92
93 template<>
94 struct TypeInfo<unsigned int, false>: IntType { };
95
96 template<>
97 struct TypeInfo<long int, false>: IntType { };
98
99 template<>
100 struct TypeInfo<unsigned long int, false>: IntType { };
101
102 #if defined(_MSC_VER)
103 template<>
104 struct TypeInfo<__int64, false>: IntType { };
105
106 template<>
107 struct TypeInfo<unsigned __int64, false>: IntType { };
108 #elif defined(__GNUC__)
109 template<>
110 struct TypeInfo<long long int, false>: IntType { };
111
112 template<>
113 struct TypeInfo<unsigned long long int, false>: IntType { };
114 #endif
115
116 template<>
117 struct TypeInfo<float, false>: FloatType { };
118
119 template<>
120 struct TypeInfo<double, false>: FloatType { };
121
122 template<>
123 struct TypeInfo<bool, false>: BoolType { };
124
125 template<>
126 struct TypeInfo<std::string, false>: StringType { };
127
128 template<>
129 struct TypeInfo<char *, false>: StringType { };
130
131 template<>
132 struct TypeInfo<const char *, false>: StringType { };
133
134 template<typename T>
135 struct TypeInfo<const T, false>: TypeInfo<T> { };
136
137 template<typename T>
138 struct TypeInfo<T &, false>: TypeInfo<T> { };
139
140 template<typename T>
141 struct TypeInfo<T, true>: TypeInfo<typename T::LoadType>
142 { typedef typename T::LoadType Load; };
143
144 template<typename T>
145 struct TypeInfo<T, false>: SymbolType
146 { typedef T Load; };
147
148 } // namespace DataFile
149 } // namespace Msp
150
151 #endif