xref: /petsc/include/petsccxxcomplexfix.h (revision f636a84a07c92a56499b6befdf6ad0a25fb654d0)
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