139829747SLisandro Dalcin #if !defined(PETSCCXXCOMPLEXFIX_H) 239829747SLisandro Dalcin #define PETSCCXXCOMPLEXFIX_H 339829747SLisandro Dalcin 4f636a84aSBarry Smith /* 54cdc28b3SLisandro Dalcin The pragma below silence all compiler warnings comming from code in this header file. 64cdc28b3SLisandro Dalcin In particular, it silences `-Wfloat-equal` warnings in `operator==()` and `operator!=` below. 74cdc28b3SLisandro Dalcin Other compilers beyond GCC support this pragma. 84cdc28b3SLisandro Dalcin */ 977ba14dbSStefano Zampini #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__NEC__) 104cdc28b3SLisandro Dalcin #pragma GCC system_header 114cdc28b3SLisandro Dalcin #endif 124cdc28b3SLisandro Dalcin 134cdc28b3SLisandro Dalcin /* 14f636a84aSBarry Smith Defines additional operator overloading for the C++ complex class that are "missing" in the standard 15f636a84aSBarry Smith include files. For example, the code fragment 16f636a84aSBarry Smith 17f636a84aSBarry Smith std::complex<double> c = 22.0; 18f636a84aSBarry Smith c = 11 + c; 19f636a84aSBarry Smith 20f636a84aSBarry Smith will produce a compile time error such as 21f636a84aSBarry Smith 22f636a84aSBarry Smith error: no match for 'operator+' (operand types are 'int' and 'std::complex<double>') 23f636a84aSBarry Smith 24f636a84aSBarry Smith The code fragment 25f636a84aSBarry Smith 26f636a84aSBarry Smith std::complex<float> c = 22.0; 27f636a84aSBarry Smith c = 11.0 + c; 28f636a84aSBarry Smith 29f636a84aSBarry Smith will produce a compile time error such as 30f636a84aSBarry Smith 31f636a84aSBarry Smith error: no match for 'operator+' (operand types are 'double' and 'std::complex<float>') 32f636a84aSBarry Smith 33f636a84aSBarry Smith This deficiency means one may need to write cumbersome code while working with the C++ complex classes. 34f636a84aSBarry Smith 35f636a84aSBarry Smith This include file defines a few additional operator overload methods for the C++ complex classes to handle 36f636a84aSBarry Smith these cases naturally within PETSc code. 37f636a84aSBarry Smith 38a966371cSJunchao Zhang This file is included in petscsystypes.h when feasible. In the small number of cases where these additional methods 39a966371cSJunchao Zhang may conflict with other code one may add '#define PETSC_SKIP_CXX_COMPLEX_FIX 1' before including any PETSc include 40a966371cSJunchao Zhang files to prevent these methods from being provided. 41f636a84aSBarry Smith */ 42f636a84aSBarry Smith 4339829747SLisandro Dalcin #define PETSC_CXX_COMPLEX_FIX(Type) \ 44*9371c9d4SSatish Balay static inline PetscComplex operator+(const PetscComplex &lhs, const Type &rhs) { \ 45*9371c9d4SSatish Balay return const_cast<PetscComplex &>(lhs) + PetscReal(rhs); \ 46*9371c9d4SSatish Balay } \ 47*9371c9d4SSatish Balay static inline PetscComplex operator+(const Type &lhs, const PetscComplex &rhs) { \ 48*9371c9d4SSatish Balay return PetscReal(lhs) + const_cast<PetscComplex &>(rhs); \ 49*9371c9d4SSatish Balay } \ 50*9371c9d4SSatish Balay static inline PetscComplex operator-(const PetscComplex &lhs, const Type &rhs) { \ 51*9371c9d4SSatish Balay return const_cast<PetscComplex &>(lhs) - PetscReal(rhs); \ 52*9371c9d4SSatish Balay } \ 53*9371c9d4SSatish Balay static inline PetscComplex operator-(const Type &lhs, const PetscComplex &rhs) { \ 54*9371c9d4SSatish Balay return PetscReal(lhs) - const_cast<PetscComplex &>(rhs); \ 55*9371c9d4SSatish Balay } \ 56*9371c9d4SSatish Balay static inline PetscComplex operator*(const PetscComplex &lhs, const Type &rhs) { \ 57*9371c9d4SSatish Balay return const_cast<PetscComplex &>(lhs) * PetscReal(rhs); \ 58*9371c9d4SSatish Balay } \ 59*9371c9d4SSatish Balay static inline PetscComplex operator*(const Type &lhs, const PetscComplex &rhs) { \ 60*9371c9d4SSatish Balay return PetscReal(lhs) * const_cast<PetscComplex &>(rhs); \ 61*9371c9d4SSatish Balay } \ 62*9371c9d4SSatish Balay static inline PetscComplex operator/(const PetscComplex &lhs, const Type &rhs) { \ 63*9371c9d4SSatish Balay return const_cast<PetscComplex &>(lhs) / PetscReal(rhs); \ 64*9371c9d4SSatish Balay } \ 65*9371c9d4SSatish Balay static inline PetscComplex operator/(const Type &lhs, const PetscComplex &rhs) { \ 66*9371c9d4SSatish Balay return PetscReal(lhs) / const_cast<PetscComplex &>(rhs); \ 67*9371c9d4SSatish Balay } \ 68*9371c9d4SSatish Balay static inline bool operator==(const PetscComplex &lhs, const Type &rhs) { \ 69*9371c9d4SSatish Balay return const_cast<PetscComplex &>(lhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(lhs).real() == PetscReal(rhs); \ 70*9371c9d4SSatish Balay } \ 71*9371c9d4SSatish Balay static inline bool operator==(const Type &lhs, const PetscComplex &rhs) { \ 72*9371c9d4SSatish Balay return const_cast<PetscComplex &>(rhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(rhs).real() == PetscReal(lhs); \ 73*9371c9d4SSatish Balay } \ 74*9371c9d4SSatish Balay static inline bool operator!=(const PetscComplex &lhs, const Type &rhs) { \ 75*9371c9d4SSatish Balay return const_cast<PetscComplex &>(lhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(lhs).real() != PetscReal(rhs); \ 76*9371c9d4SSatish Balay } \ 77*9371c9d4SSatish Balay static inline bool operator!=(const Type &lhs, const PetscComplex &rhs) { \ 78*9371c9d4SSatish Balay return const_cast<PetscComplex &>(rhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(rhs).real() != PetscReal(lhs); \ 79*9371c9d4SSatish Balay } \ 8039829747SLisandro Dalcin /* PETSC_CXX_COMPLEX_FIX */ 8139829747SLisandro Dalcin 82f636a84aSBarry Smith /* 83f636a84aSBarry Smith Due to the C++ automatic promotion rules for floating point and integer values only the two cases below 84f636a84aSBarry Smith need to be handled. 85f636a84aSBarry Smith */ 8639829747SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 8739829747SLisandro Dalcin PETSC_CXX_COMPLEX_FIX(double) 8839829747SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE) 8939829747SLisandro Dalcin PETSC_CXX_COMPLEX_FIX(PetscInt) 9039829747SLisandro Dalcin #endif /* PETSC_USE_REAL_* */ 9139829747SLisandro Dalcin 9239829747SLisandro Dalcin #endif 93