139829747SLisandro Dalcin #if !defined(PETSCCXXCOMPLEXFIX_H) 239829747SLisandro Dalcin #define PETSCCXXCOMPLEXFIX_H 339829747SLisandro Dalcin #if defined(__cplusplus) && defined(PETSC_HAVE_COMPLEX) && defined(PETSC_HAVE_CXX_COMPLEX) 439829747SLisandro Dalcin 5*f636a84aSBarry Smith /* 6*f636a84aSBarry Smith Defines additional operator overloading for the C++ complex class that are "missing" in the standard 7*f636a84aSBarry Smith include files. For example, the code fragment 8*f636a84aSBarry Smith 9*f636a84aSBarry Smith std::complex<double> c = 22.0; 10*f636a84aSBarry Smith c = 11 + c; 11*f636a84aSBarry Smith 12*f636a84aSBarry Smith will produce a compile time error such as 13*f636a84aSBarry Smith 14*f636a84aSBarry Smith error: no match for 'operator+' (operand types are 'int' and 'std::complex<double>') 15*f636a84aSBarry Smith 16*f636a84aSBarry Smith The code fragment 17*f636a84aSBarry Smith 18*f636a84aSBarry Smith std::complex<float> c = 22.0; 19*f636a84aSBarry Smith c = 11.0 + c; 20*f636a84aSBarry Smith 21*f636a84aSBarry Smith will produce a compile time error such as 22*f636a84aSBarry Smith 23*f636a84aSBarry Smith error: no match for 'operator+' (operand types are 'double' and 'std::complex<float>') 24*f636a84aSBarry Smith 25*f636a84aSBarry Smith This deficiency means one may need to write cumbersome code while working with the C++ complex classes. 26*f636a84aSBarry Smith 27*f636a84aSBarry Smith This include file defines a few additional operator overload methods for the C++ complex classes to handle 28*f636a84aSBarry Smith these cases naturally within PETSc code. 29*f636a84aSBarry Smith 30*f636a84aSBarry Smith This file is included automatically by PETSc include files. In the small number of cases where these additional methods 31*f636a84aSBarry Smith may conflict with other code one may add 32*f636a84aSBarry Smith 33*f636a84aSBarry Smith #define PETSC_SKIP_CXX_COMPLEX_FIX 34*f636a84aSBarry Smith 35*f636a84aSBarry Smith before including any PETSc include files to prevent these methods from being provided. 36*f636a84aSBarry Smith */ 37*f636a84aSBarry Smith 3839829747SLisandro Dalcin #define PETSC_CXX_COMPLEX_FIX(Type) \ 3939829747SLisandro Dalcin static inline PetscComplex operator+(const PetscComplex& lhs, const Type& rhs) { return lhs + PetscReal(rhs); } \ 4039829747SLisandro Dalcin static inline PetscComplex operator+(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) + rhs; } \ 4139829747SLisandro Dalcin static inline PetscComplex operator-(const PetscComplex& lhs, const Type& rhs) { return lhs - PetscReal(rhs); } \ 4239829747SLisandro Dalcin static inline PetscComplex operator-(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) - rhs; } \ 4339829747SLisandro Dalcin static inline PetscComplex operator*(const PetscComplex& lhs, const Type& rhs) { return lhs * PetscReal(rhs); } \ 4439829747SLisandro Dalcin static inline PetscComplex operator*(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) * rhs; } \ 4539829747SLisandro Dalcin static inline PetscComplex operator/(const PetscComplex& lhs, const Type& rhs) { return lhs / PetscReal(rhs); } \ 4639829747SLisandro Dalcin static inline PetscComplex operator/(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) / rhs; } \ 4739829747SLisandro Dalcin static inline bool operator==(const PetscComplex& lhs, const Type& rhs) { return lhs.imag() == PetscReal(0) && lhs.real() == PetscReal(rhs); } \ 4839829747SLisandro Dalcin static inline bool operator==(const Type& lhs, const PetscComplex& rhs) { return rhs.imag() == PetscReal(0) && rhs.real() == PetscReal(lhs); } \ 4939829747SLisandro Dalcin static inline bool operator!=(const PetscComplex& lhs, const Type& rhs) { return lhs.imag() != PetscReal(0) || lhs.real() != PetscReal(rhs); } \ 5039829747SLisandro Dalcin static inline bool operator!=(const Type& lhs, const PetscComplex& rhs) { return rhs.imag() != PetscReal(0) || rhs.real() != PetscReal(lhs); } \ 5139829747SLisandro Dalcin /* PETSC_CXX_COMPLEX_FIX */ 5239829747SLisandro Dalcin 53*f636a84aSBarry Smith /* 54*f636a84aSBarry Smith Due to the C++ automatic promotion rules for floating point and integer values only the two cases below 55*f636a84aSBarry Smith need to be handled. 56*f636a84aSBarry Smith */ 5739829747SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 5839829747SLisandro Dalcin PETSC_CXX_COMPLEX_FIX(double) 5939829747SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE) 6039829747SLisandro Dalcin PETSC_CXX_COMPLEX_FIX(PetscInt) 6139829747SLisandro Dalcin #endif /* PETSC_USE_REAL_* */ 6239829747SLisandro Dalcin 6339829747SLisandro Dalcin #endif /* __cplusplus && PETSC_HAVE_COMPLEX && PETSC_HAVE_CXX_COMPLEX */ 6439829747SLisandro Dalcin #endif 65