atlas
DataType.h
1 /*
2  * (C) Copyright 2013 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation
8  * nor does it submit to any jurisdiction.
9  */
10 
11 #pragma once
12 
13 #include <string>
14 
15 //------------------------------------------------------------------------------------------------------
16 
17 // For type safety we want to use std::byte for the DataType "BYTE", but it is a C++17 feature.
18 // Backport std::byte here without any operations
19 #if __cplusplus >= 201703L
20 #include <cstddef>
21 #else
22 namespace std {
23 #ifdef _CRAYC
24 struct byte {
25  unsigned char byte_;
26 };
27 #else
28 enum class byte : unsigned char
29 {
30 };
31 #endif
32 } // namespace std
33 #endif
34 
35 //------------------------------------------------------------------------------------------------------
36 
37 namespace atlas {
38 namespace array {
39 
40 class DataType {
41 public:
42  typedef long kind_t;
43  static const kind_t KIND_BYTE = 1;
44  static const kind_t KIND_INT32 = -4;
45  static const kind_t KIND_INT64 = -8;
46  static const kind_t KIND_REAL32 = 4;
47  static const kind_t KIND_REAL64 = 8;
48  static const kind_t KIND_UINT64 = -16;
49 
50  template <typename DATATYPE>
51  static DataType create();
52 
53  static DataType byte() { return DataType( KIND_BYTE ); }
54  static DataType int32() { return DataType( KIND_INT32 ); }
55  static DataType int64() { return DataType( KIND_INT64 ); }
56  static DataType real32() { return DataType( KIND_REAL32 ); }
57  static DataType real64() { return DataType( KIND_REAL64 ); }
58  static DataType uint64() { return DataType( KIND_UINT64 ); }
59 
60  template <typename DATATYPE>
61  static kind_t kind();
62  template <typename DATATYPE>
63  static kind_t kind( const DATATYPE& );
64 
65  template <typename DATATYPE>
66  static std::string str();
67  template <typename DATATYPE>
68  static std::string str( const DATATYPE );
69 
70  static kind_t str_to_kind( const std::string& );
71  static std::string kind_to_str( kind_t );
72  static bool kind_valid( kind_t );
73 
74 private:
75  static std::string byte_str() { return "byte"; }
76  static std::string int32_str() { return "int32"; }
77  static std::string int64_str() { return "int64"; }
78  static std::string real32_str() { return "real32"; }
79  static std::string real64_str() { return "real64"; }
80  static std::string uint64_str() { return "uint64"; }
81 
82  [[noreturn]] static void throw_not_recognised( kind_t );
83  [[noreturn]] static void throw_not_recognised( std::string datatype );
84 
85 public:
86  DataType( const std::string& );
87  DataType( long );
88  DataType( const DataType& );
89  std::string str() const { return kind_to_str( kind_ ); }
90  kind_t kind() const { return kind_; }
91  size_t size() const { return ( kind_ == KIND_UINT64 ) ? 8 : std::abs( kind_ ); }
92 
93  friend bool operator==( DataType dt1, DataType dt2 );
94  friend bool operator!=( DataType dt1, DataType dt2 );
95  friend bool operator==( DataType dt, kind_t kind );
96  friend bool operator!=( DataType dt, kind_t kind );
97  friend bool operator==( kind_t kind, DataType dt );
98  friend bool operator!=( kind_t kind, DataType dt2 );
99 
100 private:
101  kind_t kind_;
102 };
103 
104 template <>
105 inline std::string DataType::str<std::byte>() {
106  return byte_str();
107 }
108 template <>
109 inline std::string DataType::str<const std::byte>() {
110  return byte_str();
111 }
112 template <>
113 inline std::string DataType::str<int>() {
114  static_assert( sizeof( int ) == 4, "" );
115  return int32_str();
116 }
117 template <>
118 inline std::string DataType::str<const int>() {
119  static_assert( sizeof( int ) == 4, "" );
120  return int32_str();
121 }
122 template <>
123 inline std::string DataType::str<long>() {
124  static_assert( sizeof( long ) == 8, "" );
125  return int64_str();
126 }
127 template <>
128 inline std::string DataType::str<const long>() {
129  static_assert( sizeof( long ) == 8, "" );
130  return int64_str();
131 }
132 template <>
133 inline std::string DataType::str<long long>() {
134  static_assert( sizeof( long long ) == 8, "" );
135  return int64_str();
136 }
137 template <>
138 inline std::string DataType::str<const long long>() {
139  static_assert( sizeof( long long ) == 8, "" );
140  return int64_str();
141 }
142 template <>
143 inline std::string DataType::str<float>() {
144  static_assert( sizeof( float ) == 4, "" );
145  return real32_str();
146 }
147 template <>
148 inline std::string DataType::str<const float>() {
149  static_assert( sizeof( float ) == 4, "" );
150  return real32_str();
151 }
152 template <>
153 inline std::string DataType::str<double>() {
154  static_assert( sizeof( double ) == 8, "" );
155  return real64_str();
156 }
157 template <>
158 inline std::string DataType::str<const double>() {
159  static_assert( sizeof( double ) == 8, "" );
160  return real64_str();
161 }
162 template <>
163 inline std::string DataType::str<unsigned long>() {
164  static_assert( sizeof( unsigned long ) == 8, "" );
165  return uint64_str();
166 }
167 template <>
168 inline std::string DataType::str<const unsigned long>() {
169  static_assert( sizeof( unsigned long ) == 8, "" );
170  return uint64_str();
171 }
172 
173 template <>
174 inline std::string DataType::str<unsigned long long>() {
175  static_assert( sizeof( unsigned long long ) == 8, "" );
176  return uint64_str();
177 }
178 template <>
179 inline std::string DataType::str<const unsigned long long>() {
180  static_assert( sizeof( unsigned long long ) == 8, "" );
181  return uint64_str();
182 }
183 template <>
184 inline std::string DataType::str( const int& ) {
185  return str<int>();
186 }
187 template <>
188 inline std::string DataType::str( const long& ) {
189  return str<long>();
190 }
191 template <>
192 inline std::string DataType::str( const long long& ) {
193  return str<long long>();
194 }
195 template <>
196 inline std::string DataType::str( const unsigned long& ) {
197  return str<unsigned long>();
198 }
199 template <>
200 inline std::string DataType::str( const unsigned long long& ) {
201  return str<unsigned long>();
202 }
203 template <>
204 inline std::string DataType::str( const float& ) {
205  return str<float>();
206 }
207 template <>
208 inline std::string DataType::str( const double& ) {
209  return str<double>();
210 }
211 template <>
212 inline DataType::kind_t DataType::kind<std::byte>() {
213  static_assert( sizeof( std::byte ) == 1, "" );
214  return KIND_BYTE;
215 }
216 template <>
217 inline DataType::kind_t DataType::kind<const std::byte>() {
218  static_assert( sizeof( std::byte ) == 1, "" );
219  return KIND_BYTE;
220 }
221 template <>
222 inline DataType::kind_t DataType::kind<int>() {
223  static_assert( sizeof( int ) == 4, "" );
224  return KIND_INT32;
225 }
226 template <>
227 inline DataType::kind_t DataType::kind<const int>() {
228  static_assert( sizeof( int ) == 4, "" );
229  return KIND_INT32;
230 }
231 template <>
232 inline DataType::kind_t DataType::kind<long>() {
233  static_assert( sizeof( long ) == 8, "" );
234  return KIND_INT64;
235 }
236 template <>
237 inline DataType::kind_t DataType::kind<const long>() {
238  static_assert( sizeof( long ) == 8, "" );
239  return KIND_INT64;
240 }
241 template <>
242 inline DataType::kind_t DataType::kind<long long>() {
243  static_assert( sizeof( long long ) == 8, "" );
244  return KIND_INT64;
245 }
246 template <>
247 inline DataType::kind_t DataType::kind<const long long>() {
248  static_assert( sizeof( long long ) == 8, "" );
249  return KIND_INT64;
250 }
251 template <>
252 inline DataType::kind_t DataType::kind<unsigned long>() {
253  static_assert( sizeof( unsigned long ) == 8, "" );
254  return KIND_UINT64;
255 }
256 template <>
257 inline DataType::kind_t DataType::kind<const unsigned long>() {
258  static_assert( sizeof( unsigned long ) == 8, "" );
259  return KIND_UINT64;
260 }
261 template <>
262 inline DataType::kind_t DataType::kind<unsigned long long>() {
263  static_assert( sizeof( unsigned long long ) == 8, "" );
264  return KIND_UINT64;
265 }
266 template <>
267 inline DataType::kind_t DataType::kind<const unsigned long long>() {
268  static_assert( sizeof( unsigned long long ) == 8, "" );
269  return KIND_UINT64;
270 }
271 template <>
272 inline DataType::kind_t DataType::kind<float>() {
273  static_assert( sizeof( float ) == 4, "" );
274  return KIND_REAL32;
275 }
276 template <>
277 inline DataType::kind_t DataType::kind<const float>() {
278  static_assert( sizeof( float ) == 4, "" );
279  return KIND_REAL32;
280 }
281 template <>
282 inline DataType::kind_t DataType::kind<double>() {
283  static_assert( sizeof( double ) == 8, "" );
284  return KIND_REAL64;
285 }
286 template <>
287 inline DataType::kind_t DataType::kind<const double>() {
288  static_assert( sizeof( double ) == 8, "" );
289  return KIND_REAL64;
290 }
291 template <>
292 inline DataType::kind_t DataType::kind( const int& ) {
293  return kind<int>();
294 }
295 template <>
296 inline DataType::kind_t DataType::kind( const long& ) {
297  return kind<long>();
298 }
299 template <>
300 inline DataType::kind_t DataType::kind( const unsigned long& ) {
301  return kind<unsigned long>();
302 }
303 template <>
304 inline DataType::kind_t DataType::kind( const float& ) {
305  return kind<float>();
306 }
307 template <>
308 inline DataType::kind_t DataType::kind( const double& ) {
309  return kind<double>();
310 }
311 
312 inline DataType::kind_t DataType::str_to_kind( const std::string& datatype ) {
313  if ( datatype == "int32" )
314  return KIND_INT32;
315  else if ( datatype == "int64" )
316  return KIND_INT64;
317  else if ( datatype == "uint64" )
318  return KIND_UINT64;
319  else if ( datatype == "real32" )
320  return KIND_REAL32;
321  else if ( datatype == "real64" )
322  return KIND_REAL64;
323  else if ( datatype == "byte" ) {
324  return KIND_BYTE;
325  }
326  else {
327  throw_not_recognised( datatype );
328  }
329 }
330 inline std::string DataType::kind_to_str( kind_t kind ) {
331  switch ( kind ) {
332  case KIND_INT32:
333  return int32_str();
334  case KIND_INT64:
335  return int64_str();
336  case KIND_UINT64:
337  return uint64_str();
338  case KIND_REAL32:
339  return real32_str();
340  case KIND_REAL64:
341  return real64_str();
342  case KIND_BYTE:
343  return byte_str();
344  default:
345  throw_not_recognised( kind );
346  }
347 }
348 inline bool DataType::kind_valid( kind_t kind ) {
349  switch ( kind ) {
350  case KIND_BYTE:
351  case KIND_INT32:
352  case KIND_INT64:
353  case KIND_UINT64:
354  case KIND_REAL32:
355  case KIND_REAL64:
356  return true;
357  default:
358  return false;
359  }
360 }
361 
362 inline DataType::DataType( const DataType& other ) : kind_( other.kind_ ) {}
363 
364 inline DataType::DataType( const std::string& datatype ) : kind_( str_to_kind( datatype ) ) {}
365 
366 inline DataType::DataType( long kind ) : kind_( kind ) {}
367 
368 inline bool operator==( DataType dt1, DataType dt2 ) {
369  return dt1.kind_ == dt2.kind_;
370 }
371 
372 inline bool operator!=( DataType dt1, DataType dt2 ) {
373  return dt1.kind_ != dt2.kind_;
374 }
375 
376 inline bool operator==( DataType dt, DataType::kind_t kind ) {
377  return dt.kind_ == kind;
378 }
379 
380 inline bool operator!=( DataType dt, DataType::kind_t kind ) {
381  return dt.kind_ != kind;
382 }
383 
384 inline bool operator==( DataType::kind_t kind, DataType dt ) {
385  return dt.kind_ == kind;
386 }
387 
388 inline bool operator!=( DataType::kind_t kind, DataType dt ) {
389  return dt.kind_ != kind;
390 }
391 
392 template <typename DATATYPE>
393 inline DataType DataType::create() {
394  return DataType( DataType::kind<DATATYPE>() );
395 }
396 
397 template <typename DATATYPE>
398 inline DataType make_datatype() {
399  return DataType( DataType::kind<DATATYPE>() );
400 }
401 
402 //------------------------------------------------------------------------------------------------------
403 
404 } // namespace array
405 } // namespace atlas
Definition: DataType.h:22
Definition: DataType.h:40
Contains all atlas classes and methods.
Definition: atlas-grids.cc:33