Actual source code: petsccxxcomplexfix.h

  1: #pragma once

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

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

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

 19:      will produce a compile time error such as

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

 23:      The code fragment

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

 28:      will produce a compile time error such as

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

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

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

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

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

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