xref: /petsc/include/petsccxxcomplexfix.h (revision a496304597bacff3545e802853d69e8765312868)
1*a4963045SJacob Faibussowitsch #pragma once
239829747SLisandro Dalcin 
3f636a84aSBarry Smith /*
4d5b43468SJose E. Roman     The pragma below silence all compiler warnings coming from code in this header file.
54cdc28b3SLisandro Dalcin     In particular, it silences `-Wfloat-equal` warnings in `operator==()` and `operator!=` below.
64cdc28b3SLisandro Dalcin     Other compilers beyond GCC support this pragma.
74cdc28b3SLisandro Dalcin */
877ba14dbSStefano Zampini #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__NEC__)
94cdc28b3SLisandro Dalcin   #pragma GCC system_header
104cdc28b3SLisandro Dalcin #endif
114cdc28b3SLisandro Dalcin 
124cdc28b3SLisandro Dalcin /*
13f636a84aSBarry Smith      Defines additional operator overloading for the C++ complex class that are "missing" in the standard
14f636a84aSBarry Smith      include files. For example, the code fragment
15f636a84aSBarry Smith 
16f636a84aSBarry Smith      std::complex<double> c = 22.0;
17f636a84aSBarry Smith      c = 11 + c;
18f636a84aSBarry Smith 
19f636a84aSBarry Smith      will produce a compile time error such as
20f636a84aSBarry Smith 
21f636a84aSBarry Smith      error: no match for 'operator+' (operand types are 'int' and 'std::complex<double>')
22f636a84aSBarry Smith 
23f636a84aSBarry Smith      The code fragment
24f636a84aSBarry Smith 
25f636a84aSBarry Smith      std::complex<float> c = 22.0;
26f636a84aSBarry Smith      c = 11.0 + c;
27f636a84aSBarry Smith 
28f636a84aSBarry Smith      will produce a compile time error such as
29f636a84aSBarry Smith 
30f636a84aSBarry Smith      error: no match for 'operator+' (operand types are 'double' and 'std::complex<float>')
31f636a84aSBarry Smith 
32f636a84aSBarry Smith      This deficiency means one may need to write cumbersome code while working with the C++ complex classes.
33f636a84aSBarry Smith 
34f636a84aSBarry Smith      This include file defines a few additional operator overload methods for the C++ complex classes to handle
35f636a84aSBarry Smith      these cases naturally within PETSc code.
36f636a84aSBarry Smith 
37a966371cSJunchao Zhang      This file is included in petscsystypes.h when feasible. In the small number of cases where these additional methods
38a966371cSJunchao Zhang      may conflict with other code one may add '#define PETSC_SKIP_CXX_COMPLEX_FIX 1' before including any PETSc include
39a966371cSJunchao Zhang      files to prevent these methods from being provided.
40f636a84aSBarry Smith */
41f636a84aSBarry Smith 
4239829747SLisandro Dalcin #define PETSC_CXX_COMPLEX_FIX(Type) \
43d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator+(const PetscComplex &lhs, const Type &rhs) \
44d71ae5a4SJacob Faibussowitsch   { \
459371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) + PetscReal(rhs); \
469371c9d4SSatish Balay   } \
47d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator+(const Type &lhs, const PetscComplex &rhs) \
48d71ae5a4SJacob Faibussowitsch   { \
499371c9d4SSatish Balay     return PetscReal(lhs) + const_cast<PetscComplex &>(rhs); \
509371c9d4SSatish Balay   } \
51d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator-(const PetscComplex &lhs, const Type &rhs) \
52d71ae5a4SJacob Faibussowitsch   { \
539371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) - PetscReal(rhs); \
549371c9d4SSatish Balay   } \
55d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator-(const Type &lhs, const PetscComplex &rhs) \
56d71ae5a4SJacob Faibussowitsch   { \
579371c9d4SSatish Balay     return PetscReal(lhs) - const_cast<PetscComplex &>(rhs); \
589371c9d4SSatish Balay   } \
59d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator*(const PetscComplex &lhs, const Type &rhs) \
60d71ae5a4SJacob Faibussowitsch   { \
619371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) * PetscReal(rhs); \
629371c9d4SSatish Balay   } \
63d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator*(const Type &lhs, const PetscComplex &rhs) \
64d71ae5a4SJacob Faibussowitsch   { \
659371c9d4SSatish Balay     return PetscReal(lhs) * const_cast<PetscComplex &>(rhs); \
669371c9d4SSatish Balay   } \
67d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator/(const PetscComplex &lhs, const Type &rhs) \
68d71ae5a4SJacob Faibussowitsch   { \
699371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) / PetscReal(rhs); \
709371c9d4SSatish Balay   } \
71d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator/(const Type &lhs, const PetscComplex &rhs) \
72d71ae5a4SJacob Faibussowitsch   { \
739371c9d4SSatish Balay     return PetscReal(lhs) / const_cast<PetscComplex &>(rhs); \
749371c9d4SSatish Balay   } \
75d71ae5a4SJacob Faibussowitsch   static inline bool operator==(const PetscComplex &lhs, const Type &rhs) \
76d71ae5a4SJacob Faibussowitsch   { \
779371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(lhs).real() == PetscReal(rhs); \
789371c9d4SSatish Balay   } \
79d71ae5a4SJacob Faibussowitsch   static inline bool operator==(const Type &lhs, const PetscComplex &rhs) \
80d71ae5a4SJacob Faibussowitsch   { \
819371c9d4SSatish Balay     return const_cast<PetscComplex &>(rhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(rhs).real() == PetscReal(lhs); \
829371c9d4SSatish Balay   } \
83d71ae5a4SJacob Faibussowitsch   static inline bool operator!=(const PetscComplex &lhs, const Type &rhs) \
84d71ae5a4SJacob Faibussowitsch   { \
859371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(lhs).real() != PetscReal(rhs); \
869371c9d4SSatish Balay   } \
87d71ae5a4SJacob Faibussowitsch   static inline bool operator!=(const Type &lhs, const PetscComplex &rhs) \
88d71ae5a4SJacob Faibussowitsch   { \
899371c9d4SSatish Balay     return const_cast<PetscComplex &>(rhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(rhs).real() != PetscReal(lhs); \
909371c9d4SSatish Balay   } \
9139829747SLisandro Dalcin /* PETSC_CXX_COMPLEX_FIX */
9239829747SLisandro Dalcin 
93f636a84aSBarry Smith /*
94f636a84aSBarry Smith     Due to the C++ automatic promotion rules for floating point and integer values only the two cases below
95f636a84aSBarry Smith     need to be handled.
96f636a84aSBarry Smith */
9739829747SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
9839829747SLisandro Dalcin PETSC_CXX_COMPLEX_FIX(double)
9939829747SLisandro Dalcin #elif defined(PETSC_USE_REAL_DOUBLE)
10039829747SLisandro Dalcin PETSC_CXX_COMPLEX_FIX(PetscInt)
10139829747SLisandro Dalcin #endif /* PETSC_USE_REAL_* */
102