Actual source code: petsccxxcomplexfix.h

  1: #ifndef PETSCCXXCOMPLEXFIX_H
  2: #define PETSCCXXCOMPLEXFIX_H

  4: /*
  5:     The pragma below silence all compiler warnings coming from code in this header file.
  6:     In particular, it silences `-Wfloat-equal` warnings in `operator==()` and `operator!=` below.
  7:     Other compilers beyond GCC support this pragma.
  8: */
  9: #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__NEC__)
 10:   #pragma GCC system_header
 11: #endif

 13: /*
 14:      Defines additional operator overloading for the C++ complex class that are "missing" in the standard
 15:      include files. For example, the code fragment

 17:      std::complex<double> c = 22.0;
 18:      c = 11 + c;

 20:      will produce a compile time error such as

 22:      error: no match for 'operator+' (operand types are 'int' and 'std::complex<double>')

 24:      The code fragment

 26:      std::complex<float> c = 22.0;
 27:      c = 11.0 + c;

 29:      will produce a compile time error such as

 31:      error: no match for 'operator+' (operand types are 'double' and 'std::complex<float>')

 33:      This deficiency means one may need to write cumbersome code while working with the C++ complex classes.

 35:      This include file defines a few additional operator overload methods for the C++ complex classes to handle
 36:      these cases naturally within PETSc code.

 38:      This file is included in petscsystypes.h when feasible. In the small number of cases where these additional methods
 39:      may conflict with other code one may add '#define PETSC_SKIP_CXX_COMPLEX_FIX 1' before including any PETSc include
 40:      files to prevent these methods from being provided.
 41: */

 43: #define PETSC_CXX_COMPLEX_FIX(Type) \
 44:   static inline PetscComplex operator+(const PetscComplex &lhs, const Type &rhs) \
 45:   { \
 46:     return const_cast<PetscComplex &>(lhs) + PetscReal(rhs); \
 47:   } \
 48:   static inline PetscComplex operator+(const Type &lhs, const PetscComplex &rhs) \
 49:   { \
 50:     return PetscReal(lhs) + const_cast<PetscComplex &>(rhs); \
 51:   } \
 52:   static inline PetscComplex operator-(const PetscComplex &lhs, const Type &rhs) \
 53:   { \
 54:     return const_cast<PetscComplex &>(lhs) - PetscReal(rhs); \
 55:   } \
 56:   static inline PetscComplex operator-(const Type &lhs, const PetscComplex &rhs) \
 57:   { \
 58:     return PetscReal(lhs) - const_cast<PetscComplex &>(rhs); \
 59:   } \
 60:   static inline PetscComplex operator*(const PetscComplex &lhs, const Type &rhs) \
 61:   { \
 62:     return const_cast<PetscComplex &>(lhs) * PetscReal(rhs); \
 63:   } \
 64:   static inline PetscComplex operator*(const Type &lhs, const PetscComplex &rhs) \
 65:   { \
 66:     return PetscReal(lhs) * const_cast<PetscComplex &>(rhs); \
 67:   } \
 68:   static inline PetscComplex operator/(const PetscComplex &lhs, const Type &rhs) \
 69:   { \
 70:     return const_cast<PetscComplex &>(lhs) / PetscReal(rhs); \
 71:   } \
 72:   static inline PetscComplex operator/(const Type &lhs, const PetscComplex &rhs) \
 73:   { \
 74:     return PetscReal(lhs) / const_cast<PetscComplex &>(rhs); \
 75:   } \
 76:   static inline bool operator==(const PetscComplex &lhs, const Type &rhs) \
 77:   { \
 78:     return const_cast<PetscComplex &>(lhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(lhs).real() == PetscReal(rhs); \
 79:   } \
 80:   static inline bool operator==(const Type &lhs, const PetscComplex &rhs) \
 81:   { \
 82:     return const_cast<PetscComplex &>(rhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(rhs).real() == PetscReal(lhs); \
 83:   } \
 84:   static inline bool operator!=(const PetscComplex &lhs, const Type &rhs) \
 85:   { \
 86:     return const_cast<PetscComplex &>(lhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(lhs).real() != PetscReal(rhs); \
 87:   } \
 88:   static inline bool operator!=(const Type &lhs, const PetscComplex &rhs) \
 89:   { \
 90:     return const_cast<PetscComplex &>(rhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(rhs).real() != PetscReal(lhs); \
 91:   } \
 92: /* PETSC_CXX_COMPLEX_FIX */

 94: /*
 95:     Due to the C++ automatic promotion rules for floating point and integer values only the two cases below
 96:     need to be handled.
 97: */
 98: #if defined(PETSC_USE_REAL_SINGLE)
 99: PETSC_CXX_COMPLEX_FIX(double)
100: #elif defined(PETSC_USE_REAL_DOUBLE)
101: PETSC_CXX_COMPLEX_FIX(PetscInt)
102: #endif /* PETSC_USE_REAL_* */

104: #endif