1 /**
2  * @file datatype.h
3  *
4  * @section LICENSE
5  *
6  * The MIT License
7  *
8  * @copyright Copyright (c) 2017-2021 TileDB, Inc.
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to deal
12  * in the Software without restriction, including without limitation the rights
13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  * copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26  * THE SOFTWARE.
27  *
28  * @section DESCRIPTION
29  *
30  * This defines the tiledb Datatype enum that maps to tiledb_datatype_t C-api
31  * enum.
32  */
33 
34 #ifndef TILEDB_DATATYPE_H
35 #define TILEDB_DATATYPE_H
36 
37 #include "tiledb/common/status.h"
38 #include "tiledb/sm/misc/constants.h"
39 
40 #include <cassert>
41 
42 using namespace tiledb::common;
43 
44 namespace tiledb {
45 namespace sm {
46 
47 /** Defines a datatype. */
48 enum class Datatype : uint8_t {
49 #define TILEDB_DATATYPE_ENUM(id) id
50 #include "tiledb/sm/c_api/tiledb_enum.h"
51 #undef TILEDB_DATATYPE_ENUM
52 };
53 
54 /** Returns the datatype size. */
datatype_size(Datatype type)55 inline uint64_t datatype_size(Datatype type) {
56   switch (type) {
57     case Datatype::INT32:
58       return sizeof(int);
59     case Datatype::INT64:
60       return sizeof(int64_t);
61     case Datatype::FLOAT32:
62       return sizeof(float);
63     case Datatype::FLOAT64:
64       return sizeof(double);
65     case Datatype::CHAR:
66       return sizeof(char);
67     case Datatype::INT8:
68       return sizeof(int8_t);
69     case Datatype::UINT8:
70       return sizeof(uint8_t);
71     case Datatype::INT16:
72       return sizeof(int16_t);
73     case Datatype::UINT16:
74       return sizeof(uint16_t);
75     case Datatype::UINT32:
76       return sizeof(uint32_t);
77     case Datatype::UINT64:
78       return sizeof(uint64_t);
79     case Datatype::STRING_ASCII:
80       return sizeof(uint8_t);
81     case Datatype::STRING_UTF8:
82       return sizeof(uint8_t);
83     case Datatype::STRING_UTF16:
84       return sizeof(uint16_t);
85     case Datatype::STRING_UTF32:
86       return sizeof(uint32_t);
87     case Datatype::STRING_UCS2:
88       return sizeof(uint16_t);
89     case Datatype::STRING_UCS4:
90       return sizeof(uint32_t);
91     case Datatype::ANY:
92       return sizeof(uint8_t);
93     case Datatype::DATETIME_YEAR:
94     case Datatype::DATETIME_MONTH:
95     case Datatype::DATETIME_WEEK:
96     case Datatype::DATETIME_DAY:
97     case Datatype::DATETIME_HR:
98     case Datatype::DATETIME_MIN:
99     case Datatype::DATETIME_SEC:
100     case Datatype::DATETIME_MS:
101     case Datatype::DATETIME_US:
102     case Datatype::DATETIME_NS:
103     case Datatype::DATETIME_PS:
104     case Datatype::DATETIME_FS:
105     case Datatype::DATETIME_AS:
106     case Datatype::TIME_HR:
107     case Datatype::TIME_MIN:
108     case Datatype::TIME_SEC:
109     case Datatype::TIME_MS:
110     case Datatype::TIME_US:
111     case Datatype::TIME_NS:
112     case Datatype::TIME_PS:
113     case Datatype::TIME_FS:
114     case Datatype::TIME_AS:
115       return sizeof(int64_t);
116   }
117 
118   assert(false);
119   return 0;
120 }
121 
122 /** Returns the string representation of the input datatype. */
datatype_str(Datatype type)123 inline const std::string& datatype_str(Datatype type) {
124   switch (type) {
125     case Datatype::INT32:
126       return constants::int32_str;
127     case Datatype::INT64:
128       return constants::int64_str;
129     case Datatype::FLOAT32:
130       return constants::float32_str;
131     case Datatype::FLOAT64:
132       return constants::float64_str;
133     case Datatype::CHAR:
134       return constants::char_str;
135     case Datatype::INT8:
136       return constants::int8_str;
137     case Datatype::UINT8:
138       return constants::uint8_str;
139     case Datatype::INT16:
140       return constants::int16_str;
141     case Datatype::UINT16:
142       return constants::uint16_str;
143     case Datatype::UINT32:
144       return constants::uint32_str;
145     case Datatype::UINT64:
146       return constants::uint64_str;
147     case Datatype::STRING_ASCII:
148       return constants::string_ascii_str;
149     case Datatype::STRING_UTF8:
150       return constants::string_utf8_str;
151     case Datatype::STRING_UTF16:
152       return constants::string_utf16_str;
153     case Datatype::STRING_UTF32:
154       return constants::string_utf32_str;
155     case Datatype::STRING_UCS2:
156       return constants::string_ucs2_str;
157     case Datatype::STRING_UCS4:
158       return constants::string_ucs4_str;
159     case Datatype::ANY:
160       return constants::any_str;
161     case Datatype::DATETIME_YEAR:
162       return constants::datetime_year_str;
163     case Datatype::DATETIME_MONTH:
164       return constants::datetime_month_str;
165     case Datatype::DATETIME_WEEK:
166       return constants::datetime_week_str;
167     case Datatype::DATETIME_DAY:
168       return constants::datetime_day_str;
169     case Datatype::DATETIME_HR:
170       return constants::datetime_hr_str;
171     case Datatype::DATETIME_MIN:
172       return constants::datetime_min_str;
173     case Datatype::DATETIME_SEC:
174       return constants::datetime_sec_str;
175     case Datatype::DATETIME_MS:
176       return constants::datetime_ms_str;
177     case Datatype::DATETIME_US:
178       return constants::datetime_us_str;
179     case Datatype::DATETIME_NS:
180       return constants::datetime_ns_str;
181     case Datatype::DATETIME_PS:
182       return constants::datetime_ps_str;
183     case Datatype::DATETIME_FS:
184       return constants::datetime_fs_str;
185     case Datatype::DATETIME_AS:
186       return constants::datetime_as_str;
187     case Datatype::TIME_HR:
188       return constants::time_hr_str;
189     case Datatype::TIME_MIN:
190       return constants::time_min_str;
191     case Datatype::TIME_SEC:
192       return constants::time_sec_str;
193     case Datatype::TIME_MS:
194       return constants::time_ms_str;
195     case Datatype::TIME_US:
196       return constants::time_us_str;
197     case Datatype::TIME_NS:
198       return constants::time_ns_str;
199     case Datatype::TIME_PS:
200       return constants::time_ps_str;
201     case Datatype::TIME_FS:
202       return constants::time_fs_str;
203     case Datatype::TIME_AS:
204       return constants::time_as_str;
205     default:
206       return constants::empty_str;
207   }
208 }
209 
210 /** Returns the datatype given a string representation. */
datatype_enum(const std::string & datatype_str,Datatype * datatype)211 inline Status datatype_enum(
212     const std::string& datatype_str, Datatype* datatype) {
213   if (datatype_str == constants::int32_str)
214     *datatype = Datatype::INT32;
215   else if (datatype_str == constants::int64_str)
216     *datatype = Datatype::INT64;
217   else if (datatype_str == constants::float32_str)
218     *datatype = Datatype::FLOAT32;
219   else if (datatype_str == constants::float64_str)
220     *datatype = Datatype::FLOAT64;
221   else if (datatype_str == constants::char_str)
222     *datatype = Datatype::CHAR;
223   else if (datatype_str == constants::int8_str)
224     *datatype = Datatype::INT8;
225   else if (datatype_str == constants::uint8_str)
226     *datatype = Datatype::UINT8;
227   else if (datatype_str == constants::int16_str)
228     *datatype = Datatype::INT16;
229   else if (datatype_str == constants::uint16_str)
230     *datatype = Datatype::UINT16;
231   else if (datatype_str == constants::uint32_str)
232     *datatype = Datatype::UINT32;
233   else if (datatype_str == constants::uint64_str)
234     *datatype = Datatype::UINT64;
235   else if (datatype_str == constants::string_ascii_str)
236     *datatype = Datatype::STRING_ASCII;
237   else if (datatype_str == constants::string_utf8_str)
238     *datatype = Datatype::STRING_UTF8;
239   else if (datatype_str == constants::string_utf16_str)
240     *datatype = Datatype::STRING_UTF16;
241   else if (datatype_str == constants::string_utf32_str)
242     *datatype = Datatype::STRING_UTF32;
243   else if (datatype_str == constants::string_ucs2_str)
244     *datatype = Datatype::STRING_UCS2;
245   else if (datatype_str == constants::string_ucs4_str)
246     *datatype = Datatype::STRING_UCS4;
247   else if (datatype_str == constants::any_str)
248     *datatype = Datatype::ANY;
249   else if (datatype_str == constants::datetime_year_str)
250     *datatype = Datatype::DATETIME_YEAR;
251   else if (datatype_str == constants::datetime_month_str)
252     *datatype = Datatype::DATETIME_MONTH;
253   else if (datatype_str == constants::datetime_week_str)
254     *datatype = Datatype::DATETIME_WEEK;
255   else if (datatype_str == constants::datetime_day_str)
256     *datatype = Datatype::DATETIME_DAY;
257   else if (datatype_str == constants::datetime_hr_str)
258     *datatype = Datatype::DATETIME_HR;
259   else if (datatype_str == constants::datetime_min_str)
260     *datatype = Datatype::DATETIME_MIN;
261   else if (datatype_str == constants::datetime_sec_str)
262     *datatype = Datatype::DATETIME_SEC;
263   else if (datatype_str == constants::datetime_ms_str)
264     *datatype = Datatype::DATETIME_MS;
265   else if (datatype_str == constants::datetime_us_str)
266     *datatype = Datatype::DATETIME_US;
267   else if (datatype_str == constants::datetime_ns_str)
268     *datatype = Datatype::DATETIME_NS;
269   else if (datatype_str == constants::datetime_ps_str)
270     *datatype = Datatype::DATETIME_PS;
271   else if (datatype_str == constants::datetime_fs_str)
272     *datatype = Datatype::DATETIME_FS;
273   else if (datatype_str == constants::datetime_as_str)
274     *datatype = Datatype::DATETIME_AS;
275   else if (datatype_str == constants::time_hr_str)
276     *datatype = Datatype::TIME_HR;
277   else if (datatype_str == constants::time_min_str)
278     *datatype = Datatype::TIME_MIN;
279   else if (datatype_str == constants::time_sec_str)
280     *datatype = Datatype::TIME_SEC;
281   else if (datatype_str == constants::time_ms_str)
282     *datatype = Datatype::TIME_MS;
283   else if (datatype_str == constants::time_us_str)
284     *datatype = Datatype::TIME_US;
285   else if (datatype_str == constants::time_ns_str)
286     *datatype = Datatype::TIME_NS;
287   else if (datatype_str == constants::time_ps_str)
288     *datatype = Datatype::TIME_PS;
289   else if (datatype_str == constants::time_fs_str)
290     *datatype = Datatype::TIME_FS;
291   else if (datatype_str == constants::time_as_str)
292     *datatype = Datatype::TIME_AS;
293   else {
294     return Status::Error("Invalid Datatype " + datatype_str);
295   }
296   return Status::Ok();
297 }
298 
299 /** Returns true if the input datatype is a string type. */
datatype_is_string(Datatype type)300 inline bool datatype_is_string(Datatype type) {
301   return (
302       type == Datatype::STRING_ASCII || type == Datatype::STRING_UTF8 ||
303       type == Datatype::STRING_UTF16 || type == Datatype::STRING_UTF32 ||
304       type == Datatype::STRING_UCS2 || type == Datatype::STRING_UCS4);
305 }
306 
307 /** Returns true if the input datatype is an integer type. */
datatype_is_integer(Datatype type)308 inline bool datatype_is_integer(Datatype type) {
309   return (
310       type == Datatype::INT8 || type == Datatype::UINT8 ||
311       type == Datatype::INT16 || type == Datatype::UINT16 ||
312       type == Datatype::INT32 || type == Datatype::UINT32 ||
313       type == Datatype::INT64 || type == Datatype::UINT64);
314 }
315 
316 /** Returns true if the input datatype is a real type. */
datatype_is_real(Datatype type)317 inline bool datatype_is_real(Datatype type) {
318   return (type == Datatype::FLOAT32 || type == Datatype::FLOAT64);
319 }
320 
321 /** Returns true if the input datatype is a datetime type. */
datatype_is_datetime(Datatype type)322 inline bool datatype_is_datetime(Datatype type) {
323   return (
324       type == Datatype::DATETIME_YEAR || type == Datatype::DATETIME_MONTH ||
325       type == Datatype::DATETIME_WEEK || type == Datatype::DATETIME_DAY ||
326       type == Datatype::DATETIME_HR || type == Datatype::DATETIME_MIN ||
327       type == Datatype::DATETIME_SEC || type == Datatype::DATETIME_MS ||
328       type == Datatype::DATETIME_US || type == Datatype::DATETIME_NS ||
329       type == Datatype::DATETIME_PS || type == Datatype::DATETIME_FS ||
330       type == Datatype::DATETIME_AS);
331 }
332 
333 /** Returns true if the input datatype is a time type. */
datatype_is_time(Datatype type)334 inline bool datatype_is_time(Datatype type) {
335   return (
336       type == Datatype::TIME_HR || type == Datatype::TIME_MIN ||
337       type == Datatype::TIME_SEC || type == Datatype::TIME_MS ||
338       type == Datatype::TIME_US || type == Datatype::TIME_NS ||
339       type == Datatype::TIME_PS || type == Datatype::TIME_FS ||
340       type == Datatype::TIME_AS);
341 }
342 
343 }  // namespace sm
344 }  // namespace tiledb
345 
346 #endif  // TILEDB_DATATYPE_H
347