openPMD-api
Datatype.hpp
1 /* Copyright 2017-2020 Fabian Koller, Franz Poeschel, Axel Huebl
2  *
3  * This file is part of openPMD-api.
4  *
5  * openPMD-api is free software: you can redistribute it and/or modify
6  * it under the terms of of either the GNU General Public License or
7  * the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * openPMD-api is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License and the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * and the GNU Lesser General Public License along with openPMD-api.
19  * If not, see <http://www.gnu.org/licenses/>.
20  */
21 #pragma once
22 
23 #include <array>
24 #include <cstdint>
25 #include <iosfwd>
26 #include <memory>
27 #include <type_traits>
28 #include <vector>
29 #include <tuple>
30 #include <climits>
31 #include <map>
32 #include <stdexcept>
33 #include <string>
34 #include <complex>
35 
36 
37 
38 namespace openPMD
39 {
42 enum class Datatype : int
43 {
44  CHAR = 0, UCHAR, // SCHAR,
45  SHORT, INT, LONG, LONGLONG,
46  USHORT, UINT, ULONG, ULONGLONG,
47  FLOAT, DOUBLE, LONG_DOUBLE,
48  CFLOAT, CDOUBLE, CLONG_DOUBLE,
49  STRING,
50  VEC_CHAR,
51  VEC_SHORT,
52  VEC_INT,
53  VEC_LONG,
54  VEC_LONGLONG,
55  VEC_UCHAR,
56  VEC_USHORT,
57  VEC_UINT,
58  VEC_ULONG,
59  VEC_ULONGLONG,
60  VEC_FLOAT,
61  VEC_DOUBLE,
62  VEC_LONG_DOUBLE,
63  VEC_CFLOAT,
64  VEC_CDOUBLE,
65  VEC_CLONG_DOUBLE,
66  VEC_STRING,
67  ARR_DBL_7,
68 
69  BOOL,
70 
71  DATATYPE = 1000,
72 
73  UNDEFINED
74 }; // Datatype
75 
81 extern std::vector< Datatype > openPMD_Datatypes;
82 
92 template<
93  typename T,
94  typename U
95 >
96 struct decay_equiv :
97  std::is_same<
98  typename std::remove_pointer<
99  typename std::remove_cv<
100  typename std::decay<
101  typename std::remove_all_extents< T >::type
102  >::type
103  >::type
104  >::type,
105  typename std::remove_pointer<
106  typename std::remove_cv<
107  typename std::decay<
108  typename std::remove_all_extents< U >::type
109  >::type
110  >::type
111  >::type
112  >::type
113 { };
114 
115 #if __cplusplus >= 201402L
116 template<
117  typename T,
118  typename U
119 >
120 constexpr bool decay_equiv_v = decay_equiv< T, U >::value;
121 #endif
122 
123 template< typename T >
124 inline
125 #if __cplusplus >= 201402L
126 constexpr
127 #endif
128 Datatype
129 determineDatatype()
130 {
131  using DT = Datatype;
132  if( decay_equiv< T, char >::value ){ return DT::CHAR; }
133  else if( decay_equiv< T, unsigned char >::value ){ return DT::UCHAR; }
134  else if( decay_equiv< T, short >::value ){ return DT::SHORT; }
135  else if( decay_equiv< T, int >::value ){ return DT::INT; }
136  else if( decay_equiv< T, long >::value ){ return DT::LONG; }
137  else if( decay_equiv< T, long long >::value ){ return DT::LONGLONG; }
138  else if( decay_equiv< T, unsigned short >::value ){ return DT::USHORT; }
139  else if( decay_equiv< T, unsigned int >::value ){ return DT::UINT; }
140  else if( decay_equiv< T, unsigned long >::value ){ return DT::ULONG; }
141  else if( decay_equiv< T, unsigned long long >::value ){ return DT::ULONGLONG; }
142  else if( decay_equiv< T, float >::value ){ return DT::FLOAT; }
143  else if( decay_equiv< T, double >::value ){ return DT::DOUBLE; }
144  else if( decay_equiv< T, long double >::value ){ return DT::LONG_DOUBLE; }
145  else if( decay_equiv< T, std::complex< float > >::value ){ return DT::CFLOAT; }
146  else if( decay_equiv< T, std::complex< double > >::value ){ return DT::CDOUBLE; }
147  else if( decay_equiv< T, std::complex< long double > >::value ){ return DT::CLONG_DOUBLE; }
148  else if( decay_equiv< T, std::string >::value ){ return DT::STRING; }
149  else if( decay_equiv< T, std::vector< char > >::value ){ return DT::VEC_CHAR; }
150  else if( decay_equiv< T, std::vector< short > >::value ){ return DT::VEC_SHORT; }
151  else if( decay_equiv< T, std::vector< int > >::value ){ return DT::VEC_INT; }
152  else if( decay_equiv< T, std::vector< long > >::value ){ return DT::VEC_LONG; }
153  else if( decay_equiv< T, std::vector< long long > >::value ){ return DT::VEC_LONGLONG; }
154  else if( decay_equiv< T, std::vector< unsigned char > >::value ){ return DT::VEC_UCHAR; }
155  else if( decay_equiv< T, std::vector< unsigned short > >::value ){ return DT::VEC_USHORT; }
156  else if( decay_equiv< T, std::vector< unsigned int > >::value ){ return DT::VEC_UINT; }
157  else if( decay_equiv< T, std::vector< unsigned long > >::value ){ return DT::VEC_ULONG; }
158  else if( decay_equiv< T, std::vector< unsigned long long > >::value ){ return DT::VEC_ULONGLONG; }
159  else if( decay_equiv< T, std::vector< float > >::value ){ return DT::VEC_FLOAT; }
160  else if( decay_equiv< T, std::vector< double > >::value ){ return DT::VEC_DOUBLE; }
161  else if( decay_equiv< T, std::vector< long double > >::value ){ return DT::VEC_LONG_DOUBLE; }
162  else if( decay_equiv< T, std::vector< std::complex< float > > >::value ){ return DT::VEC_CFLOAT; }
163  else if( decay_equiv< T, std::vector< std::complex< double > > >::value ){ return DT::VEC_CDOUBLE; }
164  else if( decay_equiv< T, std::vector< std::complex< long double > > >::value ){ return DT::VEC_CLONG_DOUBLE; }
165  else if( decay_equiv< T, std::vector< std::string > >::value ){ return DT::VEC_STRING; }
166  else if( decay_equiv< T, std::array< double, 7 > >::value ){ return DT::ARR_DBL_7; }
167  else if( decay_equiv< T, bool >::value ){ return DT::BOOL; }
168  else return Datatype::UNDEFINED;
169 }
170 
171 template< typename T >
172 inline
173 #if __cplusplus >= 201402L
174 constexpr
175 #endif
176 Datatype
177 determineDatatype(std::shared_ptr< T >)
178 {
179  using DT = Datatype;
180  if( decay_equiv< T, char >::value ){ return DT::CHAR; }
181  else if( decay_equiv< T, unsigned char >::value ){ return DT::UCHAR; }
182  else if( decay_equiv< T, short >::value ){ return DT::SHORT; }
183  else if( decay_equiv< T, int >::value ){ return DT::INT; }
184  else if( decay_equiv< T, long >::value ){ return DT::LONG; }
185  else if( decay_equiv< T, long long >::value ){ return DT::LONGLONG; }
186  else if( decay_equiv< T, unsigned short >::value ){ return DT::USHORT; }
187  else if( decay_equiv< T, unsigned int >::value ){ return DT::UINT; }
188  else if( decay_equiv< T, unsigned long >::value ){ return DT::ULONG; }
189  else if( decay_equiv< T, unsigned long long >::value ){ return DT::ULONGLONG; }
190  else if( decay_equiv< T, float >::value ){ return DT::FLOAT; }
191  else if( decay_equiv< T, double >::value ){ return DT::DOUBLE; }
192  else if( decay_equiv< T, long double >::value ){ return DT::LONG_DOUBLE; }
193  else if( decay_equiv< T, std::complex< float > >::value ){ return DT::CFLOAT; }
194  else if( decay_equiv< T, std::complex< double > >::value ){ return DT::CDOUBLE; }
195  else if( decay_equiv< T, std::complex< long double > >::value ){ return DT::CLONG_DOUBLE; }
196  else if( decay_equiv< T, std::string >::value ){ return DT::STRING; }
197  else if( decay_equiv< T, std::vector< char > >::value ){ return DT::VEC_CHAR; }
198  else if( decay_equiv< T, std::vector< short > >::value ){ return DT::VEC_SHORT; }
199  else if( decay_equiv< T, std::vector< int > >::value ){ return DT::VEC_INT; }
200  else if( decay_equiv< T, std::vector< long > >::value ){ return DT::VEC_LONG; }
201  else if( decay_equiv< T, std::vector< long long > >::value ){ return DT::VEC_LONGLONG; }
202  else if( decay_equiv< T, std::vector< unsigned char > >::value ){ return DT::VEC_UCHAR; }
203  else if( decay_equiv< T, std::vector< unsigned short > >::value ){ return DT::VEC_USHORT; }
204  else if( decay_equiv< T, std::vector< unsigned int > >::value ){ return DT::VEC_UINT; }
205  else if( decay_equiv< T, std::vector< unsigned long > >::value ){ return DT::VEC_ULONG; }
206  else if( decay_equiv< T, std::vector< unsigned long long > >::value ){ return DT::VEC_ULONGLONG; }
207  else if( decay_equiv< T, std::vector< float > >::value ){ return DT::VEC_FLOAT; }
208  else if( decay_equiv< T, std::vector< double > >::value ){ return DT::VEC_DOUBLE; }
209  else if( decay_equiv< T, std::vector< long double > >::value ){ return DT::VEC_LONG_DOUBLE; }
210  else if( decay_equiv< T, std::vector< std::complex< float > > >::value ){ return DT::VEC_CFLOAT; }
211  else if( decay_equiv< T, std::vector< std::complex< double > > >::value ){ return DT::VEC_CDOUBLE; }
212  else if( decay_equiv< T, std::vector< std::complex< long double > > >::value ){ return DT::VEC_CLONG_DOUBLE; }
213  else if( decay_equiv< T, std::vector< std::string > >::value ){ return DT::VEC_STRING; }
214  else if( decay_equiv< T, std::array< double, 7 > >::value ){ return DT::ARR_DBL_7; }
215  else if( decay_equiv< T, bool >::value ){ return DT::BOOL; }
216  else return DT::UNDEFINED;
217 }
218 
224 inline size_t
226 {
227  using DT = Datatype;
228  switch( d )
229  {
230  case DT::CHAR:
231  case DT::VEC_CHAR:
232  case DT::STRING:
233  case DT::VEC_STRING:
234  return sizeof(char);
235  case DT::UCHAR:
236  case DT::VEC_UCHAR:
237  return sizeof(unsigned char);
238  // case DT::SCHAR:
239  // case DT::VEC_SCHAR:
240  // return sizeof(signed char);
241  // break;
242  case DT::SHORT:
243  case DT::VEC_SHORT:
244  return sizeof(short);
245  case DT::INT:
246  case DT::VEC_INT:
247  return sizeof(int);
248  case DT::LONG:
249  case DT::VEC_LONG:
250  return sizeof(long);
251  case DT::LONGLONG:
252  case DT::VEC_LONGLONG:
253  return sizeof(long long);
254  case DT::USHORT:
255  case DT::VEC_USHORT:
256  return sizeof(unsigned short);
257  case DT::UINT:
258  case DT::VEC_UINT:
259  return sizeof(unsigned int);
260  case DT::ULONG:
261  case DT::VEC_ULONG:
262  return sizeof(unsigned long);
263  case DT::ULONGLONG:
264  case DT::VEC_ULONGLONG:
265  return sizeof(unsigned long long);
266  case DT::FLOAT:
267  case DT::VEC_FLOAT:
268  return sizeof(float);
269  case DT::DOUBLE:
270  case DT::VEC_DOUBLE:
271  case DT::ARR_DBL_7:
272  return sizeof(double);
273  case DT::LONG_DOUBLE:
274  case DT::VEC_LONG_DOUBLE:
275  return sizeof(long double);
276  break;
277  case DT::CFLOAT:
278  case DT::VEC_CFLOAT:
279  return sizeof(float) * 2;
280  break;
281  case DT::CDOUBLE:
282  case DT::VEC_CDOUBLE:
283  return sizeof(double) * 2;
284  break;
285  case DT::CLONG_DOUBLE:
286  case DT::VEC_CLONG_DOUBLE:
287  return sizeof(long double) * 2;
288  break;
289  case DT::BOOL:
290  return sizeof(bool);
291  case DT::DATATYPE:
292  case DT::UNDEFINED:
293  default:
294  throw std::runtime_error("toBytes: Invalid datatype!");
295  }
296 }
297 
303 inline size_t
305 {
306  return toBytes( d ) * CHAR_BIT;
307 }
308 
314 inline bool
316 {
317  using DT = Datatype;
318 
319  switch( d )
320  {
321  case DT::VEC_CHAR:
322  case DT::VEC_SHORT:
323  case DT::VEC_INT:
324  case DT::VEC_LONG:
325  case DT::VEC_LONGLONG:
326  case DT::VEC_UCHAR:
327  case DT::VEC_USHORT:
328  case DT::VEC_UINT:
329  case DT::VEC_ULONG:
330  case DT::VEC_ULONGLONG:
331  case DT::VEC_FLOAT:
332  case DT::VEC_DOUBLE:
333  case DT::VEC_LONG_DOUBLE:
334  case DT::VEC_CFLOAT:
335  case DT::VEC_CDOUBLE:
336  case DT::VEC_CLONG_DOUBLE:
337  case DT::VEC_STRING:
338  return true;
339  default:
340  return false;
341  }
342 }
343 
351 inline bool
353 {
354  using DT = Datatype;
355 
356  switch( d )
357  {
358  case DT::FLOAT:
359  case DT::VEC_FLOAT:
360  case DT::DOUBLE:
361  case DT::VEC_DOUBLE:
362  case DT::LONG_DOUBLE:
363  case DT::VEC_LONG_DOUBLE:
364  // note: complex floats are not std::is_floating_point
365  return true;
366  break;
367  default:
368  return false;
369  break;
370  }
371 }
372 
380 inline bool
382 {
383  using DT = Datatype;
384 
385  switch( d )
386  {
387  case DT::CFLOAT:
388  case DT::VEC_CFLOAT:
389  case DT::CDOUBLE:
390  case DT::VEC_CDOUBLE:
391  case DT::CLONG_DOUBLE:
392  case DT::VEC_CLONG_DOUBLE:
393  return true;
394  default:
395  return false;
396  }
397 }
398 
406 template< typename T >
407 inline bool
409 {
410  Datatype dtype = determineDatatype< T >();
411 
412  return isFloatingPoint( dtype );
413 }
414 
422 template< typename T >
423 inline bool
425 {
426  Datatype dtype = determineDatatype< T >();
427 
428  return isComplexFloatingPoint(dtype);
429 }
430 
439 inline std::tuple< bool, bool >
441 {
442  using DT = Datatype;
443 
444  switch( d )
445  {
446  case DT::SHORT:
447  case DT::VEC_SHORT:
448  case DT::INT:
449  case DT::VEC_INT:
450  case DT::LONG:
451  case DT::VEC_LONG:
452  case DT::LONGLONG:
453  case DT::VEC_LONGLONG:
454  return std::make_tuple( true, true );
455  case DT::USHORT:
456  case DT::VEC_USHORT:
457  case DT::UINT:
458  case DT::VEC_UINT:
459  case DT::ULONG:
460  case DT::VEC_ULONG:
461  case DT::ULONGLONG:
462  case DT::VEC_ULONGLONG:
463  return std::make_tuple( true, false );
464  default:
465  return std::make_tuple( false, false );
466  }
467 }
468 
477 template< typename T >
478 inline std::tuple< bool, bool >
480 {
481  Datatype dtype = determineDatatype< T >();
482 
483  return isInteger( dtype );
484 }
485 
492 template< typename T_FP >
493 inline bool
495 {
496  // template
497  bool tt_is_fp = isFloatingPoint< T_FP >();
498 
499  // Datatype
500  bool dt_is_fp = isFloatingPoint( d );
501 
502  if(
503  tt_is_fp &&
504  dt_is_fp &&
505  toBits( d ) == toBits( determineDatatype< T_FP >() )
506  )
507  return true;
508  else
509  return false;
510 }
511 
518 template< typename T_CFP >
519 inline bool
521 {
522  // template
523  bool tt_is_cfp = isComplexFloatingPoint< T_CFP >();
524 
525  // Datatype
526  bool dt_is_cfp = isComplexFloatingPoint( d );
527 
528  if(
529  tt_is_cfp &&
530  dt_is_cfp &&
531  toBits( d ) == toBits( determineDatatype< T_CFP >() )
532  )
533  return true;
534  else
535  return false;
536 }
537 
544 template< typename T_Int >
545 inline bool
547 {
548  // template
549  bool tt_is_int, tt_is_sig;
550  std::tie(tt_is_int, tt_is_sig) = isInteger< T_Int >();
551 
552  // Datatype
553  bool dt_is_int, dt_is_sig;
554  std::tie(dt_is_int, dt_is_sig) = isInteger( d );
555 
556  if(
557  tt_is_int &&
558  dt_is_int &&
559  tt_is_sig == dt_is_sig &&
560  toBits( d ) == toBits( determineDatatype< T_Int >() )
561  )
562  return true;
563  else
564  return false;
565 }
566 
573 inline bool
575 {
576  // exact same type
577  if( static_cast<int>(d) == static_cast<int>(e) )
578  return true;
579 
580  bool d_is_vec = isVector( d );
581  bool e_is_vec = isVector( e );
582 
583  // same int
584  bool d_is_int, d_is_sig;
585  std::tie(d_is_int, d_is_sig) = isInteger( d );
586  bool e_is_int, e_is_sig;
587  std::tie(e_is_int, e_is_sig) = isInteger( e );
588  if(
589  d_is_int &&
590  e_is_int &&
591  d_is_vec == e_is_vec &&
592  d_is_sig == e_is_sig &&
593  toBits( d ) == toBits( e )
594  )
595  return true;
596 
597  // same float
598  bool d_is_fp = isFloatingPoint( d );
599  bool e_is_fp = isFloatingPoint( e );
600 
601  if(
602  d_is_fp &&
603  e_is_fp &&
604  d_is_vec == e_is_vec &&
605  toBits( d ) == toBits( e )
606  )
607  return true;
608 
609  // same complex floating point
610  bool d_is_cfp = isComplexFloatingPoint(d);
611  bool e_is_cfp = isComplexFloatingPoint(e);
612 
613  if(
614  d_is_cfp &&
615  e_is_cfp &&
616  d_is_vec == e_is_vec &&
617  toBits( d ) == toBits( e )
618  )
619  return true;
620 
621  return false;
622 }
623 
624 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
625 #define OPENPMD_TEMPLATE_OPERATOR operator
626 #else
627 #define OPENPMD_TEMPLATE_OPERATOR template operator
628 #endif
629 
647 template < typename ReturnType = void, typename Action, typename... Args >
648 ReturnType switchType( Datatype dt, Action action, Args &&... args )
649 {
650  switch ( dt )
651  {
652  case Datatype::CHAR:
653  return action.OPENPMD_TEMPLATE_OPERATOR( )< char >(
654  std::forward< Args >( args )... );
655  case Datatype::UCHAR:
656  return action.OPENPMD_TEMPLATE_OPERATOR( )< unsigned char >(
657  std::forward< Args >( args )... );
658  case Datatype::SHORT:
659  return action.OPENPMD_TEMPLATE_OPERATOR( )< short >(
660  std::forward< Args >( args )... );
661  case Datatype::INT:
662  return action.OPENPMD_TEMPLATE_OPERATOR( )< int >(
663  std::forward< Args >( args )... );
664  case Datatype::LONG:
665  return action.OPENPMD_TEMPLATE_OPERATOR( )< long >(
666  std::forward< Args >( args )... );
667  case Datatype::LONGLONG:
668  return action.OPENPMD_TEMPLATE_OPERATOR( )< long long >(
669  std::forward< Args >( args )... );
670  case Datatype::USHORT:
671  return action.OPENPMD_TEMPLATE_OPERATOR( )< unsigned short >(
672  std::forward< Args >( args )... );
673  case Datatype::UINT:
674  return action.OPENPMD_TEMPLATE_OPERATOR( )< unsigned int >(
675  std::forward< Args >( args )... );
676  case Datatype::ULONG:
677  return action.OPENPMD_TEMPLATE_OPERATOR( )< unsigned long >(
678  std::forward< Args >( args )... );
679  case Datatype::ULONGLONG:
680  return action.OPENPMD_TEMPLATE_OPERATOR( )< unsigned long long >(
681  std::forward< Args >( args )... );
682  case Datatype::FLOAT:
683  return action.OPENPMD_TEMPLATE_OPERATOR( )< float >(
684  std::forward< Args >( args )... );
685  case Datatype::DOUBLE:
686  return action.OPENPMD_TEMPLATE_OPERATOR( )< double >(
687  std::forward< Args >( args )... );
688  case Datatype::LONG_DOUBLE:
689  return action.OPENPMD_TEMPLATE_OPERATOR( )< long double >(
690  std::forward< Args >( args )... );
691  case Datatype::CFLOAT:
692  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::complex< float > >(
693  std::forward< Args >( args )... );
694  case Datatype::CDOUBLE:
695  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::complex< double > >(
696  std::forward< Args >( args )... );
697  case Datatype::CLONG_DOUBLE:
698  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::complex< long double > >(
699  std::forward< Args >( args )... );
700  case Datatype::STRING:
701  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::string >(
702  std::forward< Args >( args )... );
703  case Datatype::VEC_CHAR:
704  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< char > >(
705  std::forward< Args >( args )... );
706  case Datatype::VEC_SHORT:
707  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< short > >(
708  std::forward< Args >( args )... );
709  case Datatype::VEC_INT:
710  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< int > >(
711  std::forward< Args >( args )... );
712  case Datatype::VEC_LONG:
713  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< long > >(
714  std::forward< Args >( args )... );
715  case Datatype::VEC_LONGLONG:
716  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< long long > >(
717  std::forward< Args >( args )... );
718  case Datatype::VEC_UCHAR:
719  return action
720  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< unsigned char > >(
721  std::forward< Args >( args )... );
722  case Datatype::VEC_USHORT:
723  return action
724  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< unsigned short > >(
725  std::forward< Args >( args )... );
726  case Datatype::VEC_UINT:
727  return action
728  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< unsigned int > >(
729  std::forward< Args >( args )... );
730  case Datatype::VEC_ULONG:
731  return action
732  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< unsigned long > >(
733  std::forward< Args >( args )... );
734  case Datatype::VEC_ULONGLONG:
735  return action
736  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< unsigned long long > >(
737  std::forward< Args >( args )... );
738  case Datatype::VEC_FLOAT:
739  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< float > >(
740  std::forward< Args >( args )... );
741  case Datatype::VEC_DOUBLE:
742  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< double > >(
743  std::forward< Args >( args )... );
744  case Datatype::VEC_LONG_DOUBLE:
745  return action
746  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< long double > >(
747  std::forward< Args >( args )... );
748  case Datatype::VEC_CFLOAT:
749  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< std::complex< float > > >(
750  std::forward< Args >( args )... );
751  case Datatype::VEC_CDOUBLE:
752  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< std::complex< double > > >(
753  std::forward< Args >( args )... );
754  case Datatype::VEC_CLONG_DOUBLE:
755  return action
756  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< std::complex< long double > > >(
757  std::forward< Args >( args )... );
758  case Datatype::VEC_STRING:
759  return action
760  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< std::string > >(
761  std::forward< Args >( args )... );
762  case Datatype::ARR_DBL_7:
763  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::array< double, 7 > >(
764  std::forward< Args >( args )... );
765  case Datatype::BOOL:
766  return action.OPENPMD_TEMPLATE_OPERATOR( )< bool >(
767  std::forward< Args >( args )... );
768  case Datatype::DATATYPE:
769  return action.OPENPMD_TEMPLATE_OPERATOR( )< 1000 >(
770  std::forward< Args >( args )... );
771  case Datatype::UNDEFINED:
772  return action.OPENPMD_TEMPLATE_OPERATOR( )< 0 >(
773  std::forward< Args >( args )... );
774  default:
775  throw std::runtime_error(
776  "Internal error: Encountered unknown datatype (switchType) ->" +
777  std::to_string( static_cast< int >( dt ) ) );
778  }
779 }
780 
781 #undef OPENPMD_TEMPLATE_OPERATOR
782 
783 namespace detail {
784  template<typename T>
786  Datatype m_dt = determineDatatype<T>();
787  };
788 
789  template<typename T>
790  struct BasicDatatypeHelper<std::vector<T>> {
791  Datatype m_dt = BasicDatatypeHelper<T>{}.m_dt;
792  };
793 
794  template<typename T, long n>
795  struct BasicDatatypeHelper<std::array<T, n>> {
796  Datatype m_dt = BasicDatatypeHelper<T>{}.m_dt;
797  };
798 
799  struct BasicDatatype {
800  template <typename T>
801  Datatype operator()();
802 
803  template <int n>
804  Datatype operator()();
805  };
806 }
807 
814 
815 Datatype toVectorType(Datatype dt);
816 
817 std::string datatypeToString( Datatype dt );
818 
819 Datatype stringToDatatype( std::string s );
820 
821 std::string datatypeToString( Datatype dt );
822 
823 Datatype stringToDatatype( std::string s );
824 
825 void
826 warnWrongDtype(std::string const& key,
827  Datatype store,
828  Datatype request);
829 
830 std::ostream&
831 operator<<(std::ostream&, openPMD::Datatype const&);
832 
833 } // namespace openPMD
834 
835 #if !defined(_MSC_VER)
836 
848 inline bool
849 operator==( openPMD::Datatype d, openPMD::Datatype e )
850 {
851  return openPMD::isSame(d, e);
852 }
853 
854 inline bool
855 operator!=( openPMD::Datatype d, openPMD::Datatype e )
856 {
857  return !(d == e);
858 }
861 #endif
bool isVector(Datatype d)
Compare if a Datatype is a vector type.
Definition: Datatype.hpp:315
std::vector< Datatype > openPMD_Datatypes
All openPMD datatypes defined in Datatype, listed in order in a vector.
Definition: Datatype.cpp:345
bool isSameFloatingPoint(Datatype d)
Compare if a Datatype is equivalent to a floating point type.
Definition: Datatype.hpp:494
bool isSameComplexFloatingPoint(Datatype d)
Compare if a Datatype is equivalent to a complex floating point type.
Definition: Datatype.hpp:520
bool isSameInteger(Datatype d)
Compare if a Datatype is equivalent to an integer type.
Definition: Datatype.hpp:546
STL namespace.
std::tuple< bool, bool > isInteger(Datatype d)
Compare if a Datatype is an integer type.
Definition: Datatype.hpp:440
Fundamental equivalence check for two given types T and U.
Definition: Datatype.hpp:96
bool isComplexFloatingPoint(Datatype d)
Compare if a Datatype is a complex floating point type.
Definition: Datatype.hpp:381
Datatype
Concrete datatype of an object available at runtime.
Definition: Datatype.hpp:42
Definition: Container.cpp:51
size_t toBits(Datatype d)
Return number of bits representing a Datatype.
Definition: Datatype.hpp:304
Definition: Datatype.hpp:785
ReturnType switchType(Datatype dt, Action action, Args &&... args)
Generalizes switching over an openPMD datatype.
Definition: Datatype.hpp:648
Public definitions of openPMD-api.
Definition: Date.cpp:28
Datatype basicDatatype(Datatype dt)
basicDatatype Strip openPMD Datatype of std::vector, std::array et.
Definition: Datatype.cpp:387
size_t toBytes(Datatype d)
Return number of bytes representing a Datatype.
Definition: Datatype.hpp:225
Definition: Datatype.hpp:799
bool isFloatingPoint(Datatype d)
Compare if a Datatype is a floating point type.
Definition: Datatype.hpp:352
bool isSame(openPMD::Datatype const d, openPMD::Datatype const e)
Comparison for two Datatypes.
Definition: Datatype.hpp:574