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 template<
116  typename T,
117  typename U
118 >
119 constexpr bool decay_equiv_v = decay_equiv< T, U >::value;
120 
121 template< typename T >
122 inline
123 constexpr
124 Datatype
125 determineDatatype()
126 {
127  using DT = Datatype;
128  if( decay_equiv< T, char >::value ){ return DT::CHAR; }
129  else if( decay_equiv< T, unsigned char >::value ){ return DT::UCHAR; }
130  else if( decay_equiv< T, short >::value ){ return DT::SHORT; }
131  else if( decay_equiv< T, int >::value ){ return DT::INT; }
132  else if( decay_equiv< T, long >::value ){ return DT::LONG; }
133  else if( decay_equiv< T, long long >::value ){ return DT::LONGLONG; }
134  else if( decay_equiv< T, unsigned short >::value ){ return DT::USHORT; }
135  else if( decay_equiv< T, unsigned int >::value ){ return DT::UINT; }
136  else if( decay_equiv< T, unsigned long >::value ){ return DT::ULONG; }
137  else if( decay_equiv< T, unsigned long long >::value ){ return DT::ULONGLONG; }
138  else if( decay_equiv< T, float >::value ){ return DT::FLOAT; }
139  else if( decay_equiv< T, double >::value ){ return DT::DOUBLE; }
140  else if( decay_equiv< T, long double >::value ){ return DT::LONG_DOUBLE; }
141  else if( decay_equiv< T, std::complex< float > >::value ){ return DT::CFLOAT; }
142  else if( decay_equiv< T, std::complex< double > >::value ){ return DT::CDOUBLE; }
143  else if( decay_equiv< T, std::complex< long double > >::value ){ return DT::CLONG_DOUBLE; }
144  else if( decay_equiv< T, std::string >::value ){ return DT::STRING; }
145  else if( decay_equiv< T, std::vector< char > >::value ){ return DT::VEC_CHAR; }
146  else if( decay_equiv< T, std::vector< short > >::value ){ return DT::VEC_SHORT; }
147  else if( decay_equiv< T, std::vector< int > >::value ){ return DT::VEC_INT; }
148  else if( decay_equiv< T, std::vector< long > >::value ){ return DT::VEC_LONG; }
149  else if( decay_equiv< T, std::vector< long long > >::value ){ return DT::VEC_LONGLONG; }
150  else if( decay_equiv< T, std::vector< unsigned char > >::value ){ return DT::VEC_UCHAR; }
151  else if( decay_equiv< T, std::vector< unsigned short > >::value ){ return DT::VEC_USHORT; }
152  else if( decay_equiv< T, std::vector< unsigned int > >::value ){ return DT::VEC_UINT; }
153  else if( decay_equiv< T, std::vector< unsigned long > >::value ){ return DT::VEC_ULONG; }
154  else if( decay_equiv< T, std::vector< unsigned long long > >::value ){ return DT::VEC_ULONGLONG; }
155  else if( decay_equiv< T, std::vector< float > >::value ){ return DT::VEC_FLOAT; }
156  else if( decay_equiv< T, std::vector< double > >::value ){ return DT::VEC_DOUBLE; }
157  else if( decay_equiv< T, std::vector< long double > >::value ){ return DT::VEC_LONG_DOUBLE; }
158  else if( decay_equiv< T, std::vector< std::complex< float > > >::value ){ return DT::VEC_CFLOAT; }
159  else if( decay_equiv< T, std::vector< std::complex< double > > >::value ){ return DT::VEC_CDOUBLE; }
160  else if( decay_equiv< T, std::vector< std::complex< long double > > >::value ){ return DT::VEC_CLONG_DOUBLE; }
161  else if( decay_equiv< T, std::vector< std::string > >::value ){ return DT::VEC_STRING; }
162  else if( decay_equiv< T, std::array< double, 7 > >::value ){ return DT::ARR_DBL_7; }
163  else if( decay_equiv< T, bool >::value ){ return DT::BOOL; }
164  else return Datatype::UNDEFINED;
165 }
166 
167 template< typename T >
168 inline
169 constexpr
170 Datatype
171 determineDatatype(std::shared_ptr< T >)
172 {
173  using DT = Datatype;
174  if( decay_equiv< T, char >::value ){ return DT::CHAR; }
175  else if( decay_equiv< T, unsigned char >::value ){ return DT::UCHAR; }
176  else if( decay_equiv< T, short >::value ){ return DT::SHORT; }
177  else if( decay_equiv< T, int >::value ){ return DT::INT; }
178  else if( decay_equiv< T, long >::value ){ return DT::LONG; }
179  else if( decay_equiv< T, long long >::value ){ return DT::LONGLONG; }
180  else if( decay_equiv< T, unsigned short >::value ){ return DT::USHORT; }
181  else if( decay_equiv< T, unsigned int >::value ){ return DT::UINT; }
182  else if( decay_equiv< T, unsigned long >::value ){ return DT::ULONG; }
183  else if( decay_equiv< T, unsigned long long >::value ){ return DT::ULONGLONG; }
184  else if( decay_equiv< T, float >::value ){ return DT::FLOAT; }
185  else if( decay_equiv< T, double >::value ){ return DT::DOUBLE; }
186  else if( decay_equiv< T, long double >::value ){ return DT::LONG_DOUBLE; }
187  else if( decay_equiv< T, std::complex< float > >::value ){ return DT::CFLOAT; }
188  else if( decay_equiv< T, std::complex< double > >::value ){ return DT::CDOUBLE; }
189  else if( decay_equiv< T, std::complex< long double > >::value ){ return DT::CLONG_DOUBLE; }
190  else if( decay_equiv< T, std::string >::value ){ return DT::STRING; }
191  else if( decay_equiv< T, std::vector< char > >::value ){ return DT::VEC_CHAR; }
192  else if( decay_equiv< T, std::vector< short > >::value ){ return DT::VEC_SHORT; }
193  else if( decay_equiv< T, std::vector< int > >::value ){ return DT::VEC_INT; }
194  else if( decay_equiv< T, std::vector< long > >::value ){ return DT::VEC_LONG; }
195  else if( decay_equiv< T, std::vector< long long > >::value ){ return DT::VEC_LONGLONG; }
196  else if( decay_equiv< T, std::vector< unsigned char > >::value ){ return DT::VEC_UCHAR; }
197  else if( decay_equiv< T, std::vector< unsigned short > >::value ){ return DT::VEC_USHORT; }
198  else if( decay_equiv< T, std::vector< unsigned int > >::value ){ return DT::VEC_UINT; }
199  else if( decay_equiv< T, std::vector< unsigned long > >::value ){ return DT::VEC_ULONG; }
200  else if( decay_equiv< T, std::vector< unsigned long long > >::value ){ return DT::VEC_ULONGLONG; }
201  else if( decay_equiv< T, std::vector< float > >::value ){ return DT::VEC_FLOAT; }
202  else if( decay_equiv< T, std::vector< double > >::value ){ return DT::VEC_DOUBLE; }
203  else if( decay_equiv< T, std::vector< long double > >::value ){ return DT::VEC_LONG_DOUBLE; }
204  else if( decay_equiv< T, std::vector< std::complex< float > > >::value ){ return DT::VEC_CFLOAT; }
205  else if( decay_equiv< T, std::vector< std::complex< double > > >::value ){ return DT::VEC_CDOUBLE; }
206  else if( decay_equiv< T, std::vector< std::complex< long double > > >::value ){ return DT::VEC_CLONG_DOUBLE; }
207  else if( decay_equiv< T, std::vector< std::string > >::value ){ return DT::VEC_STRING; }
208  else if( decay_equiv< T, std::array< double, 7 > >::value ){ return DT::ARR_DBL_7; }
209  else if( decay_equiv< T, bool >::value ){ return DT::BOOL; }
210  else return DT::UNDEFINED;
211 }
212 
218 inline size_t
220 {
221  using DT = Datatype;
222  switch( d )
223  {
224  case DT::CHAR:
225  case DT::VEC_CHAR:
226  case DT::STRING:
227  case DT::VEC_STRING:
228  return sizeof(char);
229  case DT::UCHAR:
230  case DT::VEC_UCHAR:
231  return sizeof(unsigned char);
232  // case DT::SCHAR:
233  // case DT::VEC_SCHAR:
234  // return sizeof(signed char);
235  // break;
236  case DT::SHORT:
237  case DT::VEC_SHORT:
238  return sizeof(short);
239  case DT::INT:
240  case DT::VEC_INT:
241  return sizeof(int);
242  case DT::LONG:
243  case DT::VEC_LONG:
244  return sizeof(long);
245  case DT::LONGLONG:
246  case DT::VEC_LONGLONG:
247  return sizeof(long long);
248  case DT::USHORT:
249  case DT::VEC_USHORT:
250  return sizeof(unsigned short);
251  case DT::UINT:
252  case DT::VEC_UINT:
253  return sizeof(unsigned int);
254  case DT::ULONG:
255  case DT::VEC_ULONG:
256  return sizeof(unsigned long);
257  case DT::ULONGLONG:
258  case DT::VEC_ULONGLONG:
259  return sizeof(unsigned long long);
260  case DT::FLOAT:
261  case DT::VEC_FLOAT:
262  return sizeof(float);
263  case DT::DOUBLE:
264  case DT::VEC_DOUBLE:
265  case DT::ARR_DBL_7:
266  return sizeof(double);
267  case DT::LONG_DOUBLE:
268  case DT::VEC_LONG_DOUBLE:
269  return sizeof(long double);
270  break;
271  case DT::CFLOAT:
272  case DT::VEC_CFLOAT:
273  return sizeof(float) * 2;
274  break;
275  case DT::CDOUBLE:
276  case DT::VEC_CDOUBLE:
277  return sizeof(double) * 2;
278  break;
279  case DT::CLONG_DOUBLE:
280  case DT::VEC_CLONG_DOUBLE:
281  return sizeof(long double) * 2;
282  break;
283  case DT::BOOL:
284  return sizeof(bool);
285  case DT::DATATYPE:
286  case DT::UNDEFINED:
287  default:
288  throw std::runtime_error("toBytes: Invalid datatype!");
289  }
290 }
291 
297 inline size_t
299 {
300  return toBytes( d ) * CHAR_BIT;
301 }
302 
308 inline bool
310 {
311  using DT = Datatype;
312 
313  switch( d )
314  {
315  case DT::VEC_CHAR:
316  case DT::VEC_SHORT:
317  case DT::VEC_INT:
318  case DT::VEC_LONG:
319  case DT::VEC_LONGLONG:
320  case DT::VEC_UCHAR:
321  case DT::VEC_USHORT:
322  case DT::VEC_UINT:
323  case DT::VEC_ULONG:
324  case DT::VEC_ULONGLONG:
325  case DT::VEC_FLOAT:
326  case DT::VEC_DOUBLE:
327  case DT::VEC_LONG_DOUBLE:
328  case DT::VEC_CFLOAT:
329  case DT::VEC_CDOUBLE:
330  case DT::VEC_CLONG_DOUBLE:
331  case DT::VEC_STRING:
332  return true;
333  default:
334  return false;
335  }
336 }
337 
345 inline bool
347 {
348  using DT = Datatype;
349 
350  switch( d )
351  {
352  case DT::FLOAT:
353  case DT::VEC_FLOAT:
354  case DT::DOUBLE:
355  case DT::VEC_DOUBLE:
356  case DT::LONG_DOUBLE:
357  case DT::VEC_LONG_DOUBLE:
358  // note: complex floats are not std::is_floating_point
359  return true;
360  break;
361  default:
362  return false;
363  break;
364  }
365 }
366 
374 inline bool
376 {
377  using DT = Datatype;
378 
379  switch( d )
380  {
381  case DT::CFLOAT:
382  case DT::VEC_CFLOAT:
383  case DT::CDOUBLE:
384  case DT::VEC_CDOUBLE:
385  case DT::CLONG_DOUBLE:
386  case DT::VEC_CLONG_DOUBLE:
387  return true;
388  default:
389  return false;
390  }
391 }
392 
400 template< typename T >
401 inline bool
403 {
404  Datatype dtype = determineDatatype< T >();
405 
406  return isFloatingPoint( dtype );
407 }
408 
416 template< typename T >
417 inline bool
419 {
420  Datatype dtype = determineDatatype< T >();
421 
422  return isComplexFloatingPoint(dtype);
423 }
424 
433 inline std::tuple< bool, bool >
435 {
436  using DT = Datatype;
437 
438  switch( d )
439  {
440  case DT::SHORT:
441  case DT::VEC_SHORT:
442  case DT::INT:
443  case DT::VEC_INT:
444  case DT::LONG:
445  case DT::VEC_LONG:
446  case DT::LONGLONG:
447  case DT::VEC_LONGLONG:
448  return std::make_tuple( true, true );
449  case DT::USHORT:
450  case DT::VEC_USHORT:
451  case DT::UINT:
452  case DT::VEC_UINT:
453  case DT::ULONG:
454  case DT::VEC_ULONG:
455  case DT::ULONGLONG:
456  case DT::VEC_ULONGLONG:
457  return std::make_tuple( true, false );
458  default:
459  return std::make_tuple( false, false );
460  }
461 }
462 
471 template< typename T >
472 inline std::tuple< bool, bool >
474 {
475  Datatype dtype = determineDatatype< T >();
476 
477  return isInteger( dtype );
478 }
479 
486 template< typename T_FP >
487 inline bool
489 {
490  // template
491  bool tt_is_fp = isFloatingPoint< T_FP >();
492 
493  // Datatype
494  bool dt_is_fp = isFloatingPoint( d );
495 
496  if(
497  tt_is_fp &&
498  dt_is_fp &&
499  toBits( d ) == toBits( determineDatatype< T_FP >() )
500  )
501  return true;
502  else
503  return false;
504 }
505 
512 template< typename T_CFP >
513 inline bool
515 {
516  // template
517  bool tt_is_cfp = isComplexFloatingPoint< T_CFP >();
518 
519  // Datatype
520  bool dt_is_cfp = isComplexFloatingPoint( d );
521 
522  if(
523  tt_is_cfp &&
524  dt_is_cfp &&
525  toBits( d ) == toBits( determineDatatype< T_CFP >() )
526  )
527  return true;
528  else
529  return false;
530 }
531 
538 template< typename T_Int >
539 inline bool
541 {
542  // template
543  bool tt_is_int, tt_is_sig;
544  std::tie(tt_is_int, tt_is_sig) = isInteger< T_Int >();
545 
546  // Datatype
547  bool dt_is_int, dt_is_sig;
548  std::tie(dt_is_int, dt_is_sig) = isInteger( d );
549 
550  if(
551  tt_is_int &&
552  dt_is_int &&
553  tt_is_sig == dt_is_sig &&
554  toBits( d ) == toBits( determineDatatype< T_Int >() )
555  )
556  return true;
557  else
558  return false;
559 }
560 
567 inline bool
569 {
570  // exact same type
571  if( static_cast<int>(d) == static_cast<int>(e) )
572  return true;
573 
574  bool d_is_vec = isVector( d );
575  bool e_is_vec = isVector( e );
576 
577  // same int
578  bool d_is_int, d_is_sig;
579  std::tie(d_is_int, d_is_sig) = isInteger( d );
580  bool e_is_int, e_is_sig;
581  std::tie(e_is_int, e_is_sig) = isInteger( e );
582  if(
583  d_is_int &&
584  e_is_int &&
585  d_is_vec == e_is_vec &&
586  d_is_sig == e_is_sig &&
587  toBits( d ) == toBits( e )
588  )
589  return true;
590 
591  // same float
592  bool d_is_fp = isFloatingPoint( d );
593  bool e_is_fp = isFloatingPoint( e );
594 
595  if(
596  d_is_fp &&
597  e_is_fp &&
598  d_is_vec == e_is_vec &&
599  toBits( d ) == toBits( e )
600  )
601  return true;
602 
603  // same complex floating point
604  bool d_is_cfp = isComplexFloatingPoint(d);
605  bool e_is_cfp = isComplexFloatingPoint(e);
606 
607  if(
608  d_is_cfp &&
609  e_is_cfp &&
610  d_is_vec == e_is_vec &&
611  toBits( d ) == toBits( e )
612  )
613  return true;
614 
615  return false;
616 }
617 
618 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__)
619 #define OPENPMD_TEMPLATE_OPERATOR operator
620 #else
621 #define OPENPMD_TEMPLATE_OPERATOR template operator
622 #endif
623 
641 template < typename ReturnType = void, typename Action, typename... Args >
642 ReturnType switchType( Datatype dt, Action action, Args &&... args )
643 {
644  switch ( dt )
645  {
646  case Datatype::CHAR:
647  return action.OPENPMD_TEMPLATE_OPERATOR( )< char >(
648  std::forward< Args >( args )... );
649  case Datatype::UCHAR:
650  return action.OPENPMD_TEMPLATE_OPERATOR( )< unsigned char >(
651  std::forward< Args >( args )... );
652  case Datatype::SHORT:
653  return action.OPENPMD_TEMPLATE_OPERATOR( )< short >(
654  std::forward< Args >( args )... );
655  case Datatype::INT:
656  return action.OPENPMD_TEMPLATE_OPERATOR( )< int >(
657  std::forward< Args >( args )... );
658  case Datatype::LONG:
659  return action.OPENPMD_TEMPLATE_OPERATOR( )< long >(
660  std::forward< Args >( args )... );
661  case Datatype::LONGLONG:
662  return action.OPENPMD_TEMPLATE_OPERATOR( )< long long >(
663  std::forward< Args >( args )... );
664  case Datatype::USHORT:
665  return action.OPENPMD_TEMPLATE_OPERATOR( )< unsigned short >(
666  std::forward< Args >( args )... );
667  case Datatype::UINT:
668  return action.OPENPMD_TEMPLATE_OPERATOR( )< unsigned int >(
669  std::forward< Args >( args )... );
670  case Datatype::ULONG:
671  return action.OPENPMD_TEMPLATE_OPERATOR( )< unsigned long >(
672  std::forward< Args >( args )... );
673  case Datatype::ULONGLONG:
674  return action.OPENPMD_TEMPLATE_OPERATOR( )< unsigned long long >(
675  std::forward< Args >( args )... );
676  case Datatype::FLOAT:
677  return action.OPENPMD_TEMPLATE_OPERATOR( )< float >(
678  std::forward< Args >( args )... );
679  case Datatype::DOUBLE:
680  return action.OPENPMD_TEMPLATE_OPERATOR( )< double >(
681  std::forward< Args >( args )... );
682  case Datatype::LONG_DOUBLE:
683  return action.OPENPMD_TEMPLATE_OPERATOR( )< long double >(
684  std::forward< Args >( args )... );
685  case Datatype::CFLOAT:
686  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::complex< float > >(
687  std::forward< Args >( args )... );
688  case Datatype::CDOUBLE:
689  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::complex< double > >(
690  std::forward< Args >( args )... );
691  case Datatype::CLONG_DOUBLE:
692  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::complex< long double > >(
693  std::forward< Args >( args )... );
694  case Datatype::STRING:
695  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::string >(
696  std::forward< Args >( args )... );
697  case Datatype::VEC_CHAR:
698  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< char > >(
699  std::forward< Args >( args )... );
700  case Datatype::VEC_SHORT:
701  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< short > >(
702  std::forward< Args >( args )... );
703  case Datatype::VEC_INT:
704  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< int > >(
705  std::forward< Args >( args )... );
706  case Datatype::VEC_LONG:
707  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< long > >(
708  std::forward< Args >( args )... );
709  case Datatype::VEC_LONGLONG:
710  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< long long > >(
711  std::forward< Args >( args )... );
712  case Datatype::VEC_UCHAR:
713  return action
714  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< unsigned char > >(
715  std::forward< Args >( args )... );
716  case Datatype::VEC_USHORT:
717  return action
718  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< unsigned short > >(
719  std::forward< Args >( args )... );
720  case Datatype::VEC_UINT:
721  return action
722  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< unsigned int > >(
723  std::forward< Args >( args )... );
724  case Datatype::VEC_ULONG:
725  return action
726  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< unsigned long > >(
727  std::forward< Args >( args )... );
728  case Datatype::VEC_ULONGLONG:
729  return action
730  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< unsigned long long > >(
731  std::forward< Args >( args )... );
732  case Datatype::VEC_FLOAT:
733  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< float > >(
734  std::forward< Args >( args )... );
735  case Datatype::VEC_DOUBLE:
736  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< double > >(
737  std::forward< Args >( args )... );
738  case Datatype::VEC_LONG_DOUBLE:
739  return action
740  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< long double > >(
741  std::forward< Args >( args )... );
742  case Datatype::VEC_CFLOAT:
743  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< std::complex< float > > >(
744  std::forward< Args >( args )... );
745  case Datatype::VEC_CDOUBLE:
746  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::vector< std::complex< double > > >(
747  std::forward< Args >( args )... );
748  case Datatype::VEC_CLONG_DOUBLE:
749  return action
750  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< std::complex< long double > > >(
751  std::forward< Args >( args )... );
752  case Datatype::VEC_STRING:
753  return action
754  .OPENPMD_TEMPLATE_OPERATOR( )< std::vector< std::string > >(
755  std::forward< Args >( args )... );
756  case Datatype::ARR_DBL_7:
757  return action.OPENPMD_TEMPLATE_OPERATOR( )< std::array< double, 7 > >(
758  std::forward< Args >( args )... );
759  case Datatype::BOOL:
760  return action.OPENPMD_TEMPLATE_OPERATOR( )< bool >(
761  std::forward< Args >( args )... );
762  case Datatype::DATATYPE:
763  return action.OPENPMD_TEMPLATE_OPERATOR( )< 1000 >(
764  std::forward< Args >( args )... );
765  case Datatype::UNDEFINED:
766  return action.OPENPMD_TEMPLATE_OPERATOR( )< 0 >(
767  std::forward< Args >( args )... );
768  default:
769  throw std::runtime_error(
770  "Internal error: Encountered unknown datatype (switchType) ->" +
771  std::to_string( static_cast< int >( dt ) ) );
772  }
773 }
774 
775 #undef OPENPMD_TEMPLATE_OPERATOR
776 
777 namespace detail {
778  template<typename T>
780  Datatype m_dt = determineDatatype<T>();
781  };
782 
783  template<typename T>
784  struct BasicDatatypeHelper<std::vector<T>> {
785  Datatype m_dt = BasicDatatypeHelper<T>{}.m_dt;
786  };
787 
788  template<typename T, long n>
789  struct BasicDatatypeHelper<std::array<T, n>> {
790  Datatype m_dt = BasicDatatypeHelper<T>{}.m_dt;
791  };
792 
793  struct BasicDatatype {
794  template <typename T>
795  Datatype operator()();
796 
797  template <int n>
798  Datatype operator()();
799  };
800 }
801 
808 
809 Datatype toVectorType(Datatype dt);
810 
811 std::string datatypeToString( Datatype dt );
812 
813 Datatype stringToDatatype( std::string s );
814 
815 std::string datatypeToString( Datatype dt );
816 
817 Datatype stringToDatatype( std::string s );
818 
819 void
820 warnWrongDtype(std::string const& key,
821  Datatype store,
822  Datatype request);
823 
824 std::ostream&
825 operator<<(std::ostream&, openPMD::Datatype const&);
826 
827 } // namespace openPMD
828 
829 #if !defined(_MSC_VER)
830 
842 inline bool
843 operator==( openPMD::Datatype d, openPMD::Datatype e )
844 {
845  return openPMD::isSame(d, e);
846 }
847 
848 inline bool
849 operator!=( openPMD::Datatype d, openPMD::Datatype e )
850 {
851  return !(d == e);
852 }
855 #endif
bool isVector(Datatype d)
Compare if a Datatype is a vector type.
Definition: Datatype.hpp:309
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:488
bool isSameComplexFloatingPoint(Datatype d)
Compare if a Datatype is equivalent to a complex floating point type.
Definition: Datatype.hpp:514
bool isSameInteger(Datatype d)
Compare if a Datatype is equivalent to an integer type.
Definition: Datatype.hpp:540
STL namespace.
std::tuple< bool, bool > isInteger(Datatype d)
Compare if a Datatype is an integer type.
Definition: Datatype.hpp:434
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:375
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:298
Definition: Datatype.hpp:779
ReturnType switchType(Datatype dt, Action action, Args &&... args)
Generalizes switching over an openPMD datatype.
Definition: Datatype.hpp:642
Public definitions of openPMD-api.
Definition: Date.cpp:29
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:219
Definition: Datatype.hpp:793
bool isFloatingPoint(Datatype d)
Compare if a Datatype is a floating point type.
Definition: Datatype.hpp:346
bool isSame(openPMD::Datatype const d, openPMD::Datatype const e)
Comparison for two Datatypes.
Definition: Datatype.hpp:568