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