Actual source code: petsccxxcomplexfix.h

  1: #pragma once

  3: /* MANSEC = Sys */

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

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

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

 21:      will produce a compile time error such as

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

 25:      The code fragment

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

 30:      will produce a compile time error such as

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

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

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

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

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

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