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