xref: /petsc/include/petsccxxcomplexfix.h (revision d5b43468fb8780a8feea140ccd6fa3e6a50411cc)
16524c165SJacob Faibussowitsch #ifndef PETSCCXXCOMPLEXFIX_H
239829747SLisandro Dalcin #define PETSCCXXCOMPLEXFIX_H
339829747SLisandro Dalcin 
4f636a84aSBarry Smith /*
5*d5b43468SJose E. Roman     The pragma below silence all compiler warnings coming 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 */
977ba14dbSStefano Zampini #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__NEC__)
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 
38a966371cSJunchao Zhang      This file is included in petscsystypes.h when feasible. In the small number of cases where these additional methods
39a966371cSJunchao Zhang      may conflict with other code one may add '#define PETSC_SKIP_CXX_COMPLEX_FIX 1' before including any PETSc include
40a966371cSJunchao Zhang      files to prevent these methods from being provided.
41f636a84aSBarry Smith */
42f636a84aSBarry Smith 
4339829747SLisandro Dalcin #define PETSC_CXX_COMPLEX_FIX(Type) \
44d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator+(const PetscComplex &lhs, const Type &rhs) \
45d71ae5a4SJacob Faibussowitsch   { \
469371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) + PetscReal(rhs); \
479371c9d4SSatish Balay   } \
48d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator+(const Type &lhs, const PetscComplex &rhs) \
49d71ae5a4SJacob Faibussowitsch   { \
509371c9d4SSatish Balay     return PetscReal(lhs) + const_cast<PetscComplex &>(rhs); \
519371c9d4SSatish Balay   } \
52d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator-(const PetscComplex &lhs, const Type &rhs) \
53d71ae5a4SJacob Faibussowitsch   { \
549371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) - PetscReal(rhs); \
559371c9d4SSatish Balay   } \
56d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator-(const Type &lhs, const PetscComplex &rhs) \
57d71ae5a4SJacob Faibussowitsch   { \
589371c9d4SSatish Balay     return PetscReal(lhs) - const_cast<PetscComplex &>(rhs); \
599371c9d4SSatish Balay   } \
60d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator*(const PetscComplex &lhs, const Type &rhs) \
61d71ae5a4SJacob Faibussowitsch   { \
629371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) * PetscReal(rhs); \
639371c9d4SSatish Balay   } \
64d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator*(const Type &lhs, const PetscComplex &rhs) \
65d71ae5a4SJacob Faibussowitsch   { \
669371c9d4SSatish Balay     return PetscReal(lhs) * const_cast<PetscComplex &>(rhs); \
679371c9d4SSatish Balay   } \
68d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator/(const PetscComplex &lhs, const Type &rhs) \
69d71ae5a4SJacob Faibussowitsch   { \
709371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) / PetscReal(rhs); \
719371c9d4SSatish Balay   } \
72d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator/(const Type &lhs, const PetscComplex &rhs) \
73d71ae5a4SJacob Faibussowitsch   { \
749371c9d4SSatish Balay     return PetscReal(lhs) / const_cast<PetscComplex &>(rhs); \
759371c9d4SSatish Balay   } \
76d71ae5a4SJacob Faibussowitsch   static inline bool operator==(const PetscComplex &lhs, const Type &rhs) \
77d71ae5a4SJacob Faibussowitsch   { \
789371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(lhs).real() == PetscReal(rhs); \
799371c9d4SSatish Balay   } \
80d71ae5a4SJacob Faibussowitsch   static inline bool operator==(const Type &lhs, const PetscComplex &rhs) \
81d71ae5a4SJacob Faibussowitsch   { \
829371c9d4SSatish Balay     return const_cast<PetscComplex &>(rhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(rhs).real() == PetscReal(lhs); \
839371c9d4SSatish Balay   } \
84d71ae5a4SJacob Faibussowitsch   static inline bool operator!=(const PetscComplex &lhs, const Type &rhs) \
85d71ae5a4SJacob Faibussowitsch   { \
869371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(lhs).real() != PetscReal(rhs); \
879371c9d4SSatish Balay   } \
88d71ae5a4SJacob Faibussowitsch   static inline bool operator!=(const Type &lhs, const PetscComplex &rhs) \
89d71ae5a4SJacob Faibussowitsch   { \
909371c9d4SSatish Balay     return const_cast<PetscComplex &>(rhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(rhs).real() != PetscReal(lhs); \
919371c9d4SSatish Balay   } \
9239829747SLisandro Dalcin /* PETSC_CXX_COMPLEX_FIX */
9339829747SLisandro Dalcin 
94f636a84aSBarry Smith /*
95f636a84aSBarry Smith     Due to the C++ automatic promotion rules for floating point and integer values only the two cases below
96f636a84aSBarry Smith     need to be handled.
97f636a84aSBarry Smith */
9839829747SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
9939829747SLisandro Dalcin PETSC_CXX_COMPLEX_FIX(double)
10039829747SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
10139829747SLisandro Dalcin PETSC_CXX_COMPLEX_FIX(PetscInt)
10239829747SLisandro Dalcin #endif /* PETSC_USE_REAL_* */
10339829747SLisandro Dalcin 
10439829747SLisandro Dalcin #endif
105