1 #if !defined(PETSCCXXCOMPLEXFIX_H) 2 #define PETSCCXXCOMPLEXFIX_H 3 #if defined(__cplusplus) && defined(PETSC_HAVE_COMPLEX) && defined(PETSC_HAVE_CXX_COMPLEX) 4 5 /* 6 Defines additional operator overloading for the C++ complex class that are "missing" in the standard 7 include files. For example, the code fragment 8 9 std::complex<double> c = 22.0; 10 c = 11 + c; 11 12 will produce a compile time error such as 13 14 error: no match for 'operator+' (operand types are 'int' and 'std::complex<double>') 15 16 The code fragment 17 18 std::complex<float> c = 22.0; 19 c = 11.0 + c; 20 21 will produce a compile time error such as 22 23 error: no match for 'operator+' (operand types are 'double' and 'std::complex<float>') 24 25 This deficiency means one may need to write cumbersome code while working with the C++ complex classes. 26 27 This include file defines a few additional operator overload methods for the C++ complex classes to handle 28 these cases naturally within PETSc code. 29 30 This file is included automatically by PETSc include files. In the small number of cases where these additional methods 31 may conflict with other code one may add 32 33 #define PETSC_SKIP_CXX_COMPLEX_FIX 34 35 before including any PETSc include files to prevent these methods from being provided. 36 */ 37 38 #define PETSC_CXX_COMPLEX_FIX(Type) \ 39 static inline PetscComplex operator+(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) + PetscReal(rhs); } \ 40 static inline PetscComplex operator+(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) + const_cast<PetscComplex&>(rhs); } \ 41 static inline PetscComplex operator-(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) - PetscReal(rhs); } \ 42 static inline PetscComplex operator-(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) - const_cast<PetscComplex&>(rhs); } \ 43 static inline PetscComplex operator*(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) * PetscReal(rhs); } \ 44 static inline PetscComplex operator*(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) * const_cast<PetscComplex&>(rhs); } \ 45 static inline PetscComplex operator/(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) / PetscReal(rhs); } \ 46 static inline PetscComplex operator/(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) / const_cast<PetscComplex&>(rhs); } \ 47 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); } \ 48 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); } \ 49 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); } \ 50 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); } \ 51 /* PETSC_CXX_COMPLEX_FIX */ 52 53 /* 54 Due to the C++ automatic promotion rules for floating point and integer values only the two cases below 55 need to be handled. 56 */ 57 #if defined(PETSC_USE_REAL_SINGLE) 58 PETSC_CXX_COMPLEX_FIX(double) 59 #elif defined(PETSC_USE_REAL_DOUBLE) 60 PETSC_CXX_COMPLEX_FIX(PetscInt) 61 #endif /* PETSC_USE_REAL_* */ 62 63 #endif /* __cplusplus && PETSC_HAVE_COMPLEX && PETSC_HAVE_CXX_COMPLEX */ 64 #endif 65