text: /*
   * Distributed under the OSI-approved Apache License, Version 2.0.  See
   * accompanying file Copyright.txt for details.
   *
   * ADIOSMacros.h : a set of helper macros used internally
   *
   * Created on: March 23, 2017
   *     Author: Chuck Atkins chuck.atkins@kitware.com
   *             William F Godoy godoywf@ornl.gov
   */
  
  #ifndef ADIOS2_ADIOSMACROS_H
  #define ADIOS2_ADIOSMACROS_H
  
  #include <string>
  
  #include "adios2/common/ADIOSTypes.h"
  
  /**
   <pre>
   The ADIOS_FOREACH_TYPE_1ARG macro assumes the given argument is a macro which
   takes a single argument that is a type and then inserts the given MACRO for
   each of the known primitive types
  
   An example of this might be to instantiate a template function for each
   known type.  For example:
  
     template<typename T> int foo() { // some implementation of foo  }
  
     #define instantiate_foo(T) template int foo<T>();
     ADIOS_FOREACH_TYPE_1ARG(instantiate_foo)
     #undef instantiate_foo
   </pre>
  */
  #define ADIOS2_FOREACH_ATTRIBUTE_PRIMITIVE_STDTYPE_1ARG(MACRO)                 \
      MACRO(char)                                                                \
      MACRO(int8_t)                                                              \
      MACRO(int16_t)                                                             \
      MACRO(int32_t)                                                             \
      MACRO(int64_t)                                                             \
      MACRO(uint8_t)                                                             \
      MACRO(uint16_t)                                                            \
      MACRO(uint32_t)                                                            \
      MACRO(uint64_t)                                                            \
      MACRO(float)                                                               \
      MACRO(double)                                                              \
      MACRO(long double)
  
  #define ADIOS2_FOREACH_PRIMITIVE_STDTYPE_1ARG(MACRO)                           \
      ADIOS2_FOREACH_ATTRIBUTE_PRIMITIVE_STDTYPE_1ARG(MACRO)                     \
      MACRO(std::complex<float>)                                                 \
      MACRO(std::complex<double>)
  
  #define ADIOS2_FOREACH_ATTRIBUTE_STDTYPE_1ARG(MACRO)                           \
      MACRO(std::string)                                                         \
      ADIOS2_FOREACH_PRIMITIVE_STDTYPE_1ARG(MACRO)
  
  #define ADIOS2_FOREACH_STDTYPE_1ARG(MACRO)                                     \
      MACRO(std::string)                                                         \
      ADIOS2_FOREACH_PRIMITIVE_STDTYPE_1ARG(MACRO)
  
  #define ADIOS2_FOREACH_TYPE_1ARG(MACRO)                                        \
      MACRO(std::string)                                                         \
      MACRO(char)                                                                \
      MACRO(signed char)                                                         \
      MACRO(unsigned char)                                                       \
      MACRO(short)                                                               \
      MACRO(unsigned short)                                                      \
      MACRO(int)                                                                 \
      MACRO(unsigned int)                                                        \
      MACRO(long int)                                                            \
      MACRO(long long int)                                                       \
      MACRO(unsigned long int)                                                   \
      MACRO(unsigned long long int)                                              \
      MACRO(float)                                                               \
      MACRO(double)                                                              \
      MACRO(long double)                                                         \
      MACRO(std::complex<float>)                                                 \
      MACRO(std::complex<double>)
  
  #define ADIOS2_FOREACH_PRIMITIVE_TYPE_1ARG(MACRO)                              \
      MACRO(char)                                                                \
      MACRO(signed char)                                                         \
      MACRO(unsigned char)                                                       \
      MACRO(short)                                                               \
      MACRO(unsigned short)                                                      \
      MACRO(int)                                                                 \
      MACRO(unsigned int)                                                        \
      MACRO(long int)                                                            \
      MACRO(long long int)                                                       \
      MACRO(unsigned long int)                                                   \
      MACRO(unsigned long long int)                                              \
      MACRO(float)                                                               \
      MACRO(double)                                                              \
      MACRO(long double)                                                         \
      MACRO(std::complex<float>)                                                 \
      MACRO(std::complex<double>)
  
  #define ADIOS2_FOREACH_COMPLEX_PRIMITIVE_TYPE_1ARG(MACRO)                      \
      MACRO(float)                                                               \
      MACRO(double)                                                              \
      MACRO(long double)
  
  #define ADIOS2_FOREACH_CHAR_TYPE_1ARG(MACRO)                                   \
      MACRO(char)                                                                \
      MACRO(signed char)                                                         \
      MACRO(unsigned char)
  
  #define ADIOS2_FOREACH_NUMERIC_TYPE_1ARG(MACRO)                                \
      MACRO(short)                                                               \
      MACRO(unsigned short)                                                      \
      MACRO(int)                                                                 \
      MACRO(unsigned int)                                                        \
      MACRO(long int)                                                            \
      MACRO(long long int)                                                       \
      MACRO(unsigned long int)                                                   \
      MACRO(unsigned long long int)                                              \
      MACRO(float)                                                               \
      MACRO(double)                                                              \
      MACRO(long double)                                                         \
      MACRO(std::complex<float>)                                                 \
      MACRO(std::complex<double>)
  
  #define ADIOS2_FOREACH_ZFP_TYPE_1ARG(MACRO)                                    \
      MACRO(int32_t)                                                             \
      MACRO(int64_t)                                                             \
      MACRO(float)                                                               \
      MACRO(double)                                                              \
      MACRO(std::complex<float>)                                                 \
      MACRO(std::complex<double>)
  
  #define ADIOS2_FOREACH_SZ_TYPE_1ARG(MACRO)                                     \
      MACRO(float)                                                               \
      MACRO(double)                                                              \
      MACRO(std::complex<float>)                                                 \
      MACRO(std::complex<double>)
  
  #define ADIOS2_FOREACH_SIRIUS_TYPE_1ARG(MACRO) MACRO(float)
  
  #define ADIOS2_FOREACH_LIBPRESSIO_TYPE_1ARG(MACRO)                             \
      MACRO(uint8_t)                                                             \
      MACRO(uint16_t)                                                            \
      MACRO(uint32_t)                                                            \
      MACRO(uint64_t)                                                            \
      MACRO(int8_t)                                                              \
      MACRO(int16_t)                                                             \
      MACRO(int32_t)                                                             \
      MACRO(int64_t)                                                             \
      MACRO(float)                                                               \
      MACRO(double)
  
  #define ADIOS2_FOREACH_MGARD_TYPE_1ARG(MACRO) MACRO(double)
  
  #define ADIOS2_FOREACH_ATTRIBUTE_TYPE_1ARG(MACRO)                              \
      MACRO(std::string)                                                         \
      MACRO(char)                                                                \
      MACRO(signed char)                                                         \
      MACRO(unsigned char)                                                       \
      MACRO(short)                                                               \
      MACRO(unsigned short)                                                      \
      MACRO(int)                                                                 \
      MACRO(unsigned int)                                                        \
      MACRO(long int)                                                            \
      MACRO(unsigned long int)                                                   \
      MACRO(long long int)                                                       \
      MACRO(unsigned long long int)                                              \
      MACRO(float)                                                               \
      MACRO(double)                                                              \
      MACRO(long double)                                                         \
      MACRO(std::complex<float>)                                                 \
      MACRO(std::complex<double>)
  
  #define ADIOS2_FOREACH_ATTRIBUTE_PRIMITIVE_TYPE_1ARG(MACRO)                    \
      MACRO(char)                                                                \
      MACRO(signed char)                                                         \
      MACRO(unsigned char)                                                       \
      MACRO(short)                                                               \
      MACRO(unsigned short)                                                      \
      MACRO(int)                                                                 \
      MACRO(unsigned int)                                                        \
      MACRO(long int)                                                            \
      MACRO(unsigned long int)                                                   \
      MACRO(long long int)                                                       \
      MACRO(unsigned long long int)                                              \
      MACRO(float)                                                               \
      MACRO(double)                                                              \
      MACRO(long double)                                                         \
      MACRO(std::complex<float>)                                                 \
      MACRO(std::complex<double>)
  
  /**
   <pre>
   The ADIOS2_FOREACH_STDTYPE_2ARGS macro assumes the given argument is a macro
   which takes two arguments, the first being a type, and the second being a
   label for that type, i.e. std::complex<float> and CFloat.
  
   An example of this might be to define a virtual method for each known
   type, and since the method is virtual then it cannot be a template.
   For example:
  
     #define declare_foo(T,L) virtual const T& foo_## L (std::string bar);
     ADIOS2_FOREACH_STDTYPE_2ARGS(declare_foo)
     #undef declare_foo
  
     is equivalent to:
  
     virtual           char& foo_Char(std::string bar);
     virtual unsigned  char& foo_UChar(std::string bar);
     virtual          short& foo_Short(std::string bar);
     virtual unsigned short& foo_UShort(std::string bar);
     ...
     virtual std::complex<double>& foo_CDouble(std::string bar);
    </pre>
  */
  #define ADIOS2_FOREACH_ATTRIBUTE_STDTYPE_2ARGS(MACRO)                          \
      MACRO(std::string, string)                                                 \
      MACRO(int8_t, int8)                                                        \
      MACRO(char, char)                                                          \
      MACRO(uint8_t, uint8)                                                      \
      MACRO(int16_t, int16)                                                      \
      MACRO(uint16_t, uint16)                                                    \
      MACRO(int32_t, int32)                                                      \
      MACRO(uint32_t, uint32)                                                    \
      MACRO(int64_t, int64)                                                      \
      MACRO(uint64_t, uint64)                                                    \
      MACRO(float, float)                                                        \
      MACRO(double, double)                                                      \
      MACRO(long double, ldouble)                                                \
      MACRO(std::complex<float>, cfloat)                                         \
      MACRO(std::complex<double>, cdouble)
  
  #define ADIOS2_FOREACH_PRIMITVE_STDTYPE_2ARGS(MACRO)                           \
      MACRO(int8_t, int8)                                                        \
      MACRO(char, char)                                                          \
      MACRO(uint8_t, uint8)                                                      \
      MACRO(int16_t, int16)                                                      \
      MACRO(uint16_t, uint16)                                                    \
      MACRO(int32_t, int32)                                                      \
      MACRO(uint32_t, uint32)                                                    \
      MACRO(int64_t, int64)                                                      \
      MACRO(uint64_t, uint64)                                                    \
      MACRO(float, float)                                                        \
      MACRO(double, double)                                                      \
      MACRO(long double, ldouble)                                                \
      MACRO(std::complex<float>, cfloat)                                         \
      MACRO(std::complex<double>, cdouble)
  
  #define ADIOS2_FOREACH_STDTYPE_2ARGS(MACRO)                                    \
      ADIOS2_FOREACH_ATTRIBUTE_STDTYPE_2ARGS(MACRO)
  
  #define ADIOS2_CLASS_iterator                                                  \
      class iterator                                                             \
      {                                                                          \
      public:                                                                    \
          typedef iterator self_type;                                            \
          typedef T value_type;                                                  \
          typedef T &reference;                                                  \
          typedef T *pointer;                                                    \
          typedef std::forward_iterator_tag iterator_category;                   \
          typedef int difference_type;                                           \
          iterator(pointer ptr) : ptr_(ptr) {}                                   \
          self_type operator++()                                                 \
          {                                                                      \
              self_type i = *this;                                               \
              ptr_++;                                                            \
              return i;                                                          \
          }                                                                      \
          self_type operator++(int junk)                                         \
          {                                                                      \
              ptr_++;                                                            \
              return *this;                                                      \
          }                                                                      \
          reference operator*() { return *ptr_; }                                \
          pointer operator->() { return ptr_; }                                  \
          bool operator==(const self_type &rhs) { return ptr_ == rhs.ptr_; }     \
          bool operator!=(const self_type &rhs) { return ptr_ != rhs.ptr_; }     \
                                                                                 \
      private:                                                                   \
          pointer ptr_;                                                          \
      }
  
  #define ADIOS2_iterators_functions(DATA_FUNCTION, SIZE_FUNCTION)               \
      iterator begin() noexcept { return iterator(DATA_FUNCTION); }              \
      iterator end() noexcept { return iterator(DATA_FUNCTION + SIZE_FUNCTION); }
  
  #endif /* ADIOS2_ADIOSMACROS_H */
  