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 */ 94cdc28b3SLisandro Dalcin #if defined(__GNUC__) && (__GNUC__ >= 4) 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 38*a966371cSJunchao Zhang This file is included in petscsystypes.h when feasible. In the small number of cases where these additional methods 39*a966371cSJunchao Zhang may conflict with other code one may add '#define PETSC_SKIP_CXX_COMPLEX_FIX 1' before including any PETSc include 40*a966371cSJunchao Zhang files to prevent these methods from being provided. 41f636a84aSBarry Smith */ 42f636a84aSBarry Smith 4302c9f0b5SLisandro Dalcin #if defined(__GNUC__) && (__GNUC__ >= 4) 4402c9f0b5SLisandro Dalcin #pragma GCC system_header 4502c9f0b5SLisandro Dalcin #endif 4602c9f0b5SLisandro Dalcin 4739829747SLisandro Dalcin #define PETSC_CXX_COMPLEX_FIX(Type) \ 48d4baf660SLisandro Dalcin static inline PetscComplex operator+(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) + PetscReal(rhs); } \ 49d4baf660SLisandro Dalcin static inline PetscComplex operator+(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) + const_cast<PetscComplex&>(rhs); } \ 50d4baf660SLisandro Dalcin static inline PetscComplex operator-(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) - PetscReal(rhs); } \ 51d4baf660SLisandro Dalcin static inline PetscComplex operator-(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) - const_cast<PetscComplex&>(rhs); } \ 52d4baf660SLisandro Dalcin static inline PetscComplex operator*(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) * PetscReal(rhs); } \ 53d4baf660SLisandro Dalcin static inline PetscComplex operator*(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) * const_cast<PetscComplex&>(rhs); } \ 54d4baf660SLisandro Dalcin static inline PetscComplex operator/(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) / PetscReal(rhs); } \ 55d4baf660SLisandro Dalcin static inline PetscComplex operator/(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) / const_cast<PetscComplex&>(rhs); } \ 56b6f7a5a8SLisandro Dalcin static inline bool operator==(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs).imag() == PetscReal(0) && const_cast<PetscComplex&>(lhs).real() == PetscReal(rhs); } \ 57b6f7a5a8SLisandro Dalcin static inline bool operator==(const Type& lhs, const PetscComplex& rhs) { return const_cast<PetscComplex&>(rhs).imag() == PetscReal(0) && const_cast<PetscComplex&>(rhs).real() == PetscReal(lhs); } \ 58b6f7a5a8SLisandro Dalcin static inline bool operator!=(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs).imag() != PetscReal(0) || const_cast<PetscComplex&>(lhs).real() != PetscReal(rhs); } \ 59b6f7a5a8SLisandro Dalcin static inline bool operator!=(const Type& lhs, const PetscComplex& rhs) { return const_cast<PetscComplex&>(rhs).imag() != PetscReal(0) || const_cast<PetscComplex&>(rhs).real() != PetscReal(lhs); } \ 6039829747SLisandro Dalcin /* PETSC_CXX_COMPLEX_FIX */ 6139829747SLisandro Dalcin 62f636a84aSBarry Smith /* 63f636a84aSBarry Smith Due to the C++ automatic promotion rules for floating point and integer values only the two cases below 64f636a84aSBarry Smith need to be handled. 65f636a84aSBarry Smith */ 6639829747SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 6739829747SLisandro Dalcin PETSC_CXX_COMPLEX_FIX(double) 6839829747SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE) 6939829747SLisandro Dalcin PETSC_CXX_COMPLEX_FIX(PetscInt) 7039829747SLisandro Dalcin #endif /* PETSC_USE_REAL_* */ 7139829747SLisandro Dalcin 7239829747SLisandro Dalcin #endif 73