Actual source code: petsccxxcomplexfix.h
1: #ifndef PETSCCXXCOMPLEXFIX_H
2: #define PETSCCXXCOMPLEXFIX_H
4: /*
5: The pragma below silence all compiler warnings coming from code in this header file.
6: In particular, it silences `-Wfloat-equal` warnings in `operator==()` and `operator!=` below.
7: Other compilers beyond GCC support this pragma.
8: */
9: #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__NEC__)
10: #pragma GCC system_header
11: #endif
13: /*
14: Defines additional operator overloading for the C++ complex class that are "missing" in the standard
15: include files. For example, the code fragment
17: std::complex<double> c = 22.0;
18: c = 11 + c;
20: will produce a compile time error such as
22: error: no match for 'operator+' (operand types are 'int' and 'std::complex<double>')
24: The code fragment
26: std::complex<float> c = 22.0;
27: c = 11.0 + c;
29: will produce a compile time error such as
31: error: no match for 'operator+' (operand types are 'double' and 'std::complex<float>')
33: This deficiency means one may need to write cumbersome code while working with the C++ complex classes.
35: This include file defines a few additional operator overload methods for the C++ complex classes to handle
36: these cases naturally within PETSc code.
38: This file is included in petscsystypes.h when feasible. In the small number of cases where these additional methods
39: may conflict with other code one may add '#define PETSC_SKIP_CXX_COMPLEX_FIX 1' before including any PETSc include
40: files to prevent these methods from being provided.
41: */
43: #define PETSC_CXX_COMPLEX_FIX(Type) \
44: static inline PetscComplex operator+(const PetscComplex &lhs, const Type &rhs) \
45: { \
46: return const_cast<PetscComplex &>(lhs) + PetscReal(rhs); \
47: } \
48: static inline PetscComplex operator+(const Type &lhs, const PetscComplex &rhs) \
49: { \
50: return PetscReal(lhs) + const_cast<PetscComplex &>(rhs); \
51: } \
52: static inline PetscComplex operator-(const PetscComplex &lhs, const Type &rhs) \
53: { \
54: return const_cast<PetscComplex &>(lhs) - PetscReal(rhs); \
55: } \
56: static inline PetscComplex operator-(const Type &lhs, const PetscComplex &rhs) \
57: { \
58: return PetscReal(lhs) - const_cast<PetscComplex &>(rhs); \
59: } \
60: static inline PetscComplex operator*(const PetscComplex &lhs, const Type &rhs) \
61: { \
62: return const_cast<PetscComplex &>(lhs) * PetscReal(rhs); \
63: } \
64: static inline PetscComplex operator*(const Type &lhs, const PetscComplex &rhs) \
65: { \
66: return PetscReal(lhs) * const_cast<PetscComplex &>(rhs); \
67: } \
68: static inline PetscComplex operator/(const PetscComplex &lhs, const Type &rhs) \
69: { \
70: return const_cast<PetscComplex &>(lhs) / PetscReal(rhs); \
71: } \
72: static inline PetscComplex operator/(const Type &lhs, const PetscComplex &rhs) \
73: { \
74: return PetscReal(lhs) / const_cast<PetscComplex &>(rhs); \
75: } \
76: static inline bool operator==(const PetscComplex &lhs, const Type &rhs) \
77: { \
78: return const_cast<PetscComplex &>(lhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(lhs).real() == PetscReal(rhs); \
79: } \
80: static inline bool operator==(const Type &lhs, const PetscComplex &rhs) \
81: { \
82: return const_cast<PetscComplex &>(rhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(rhs).real() == PetscReal(lhs); \
83: } \
84: static inline bool operator!=(const PetscComplex &lhs, const Type &rhs) \
85: { \
86: return const_cast<PetscComplex &>(lhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(lhs).real() != PetscReal(rhs); \
87: } \
88: static inline bool operator!=(const Type &lhs, const PetscComplex &rhs) \
89: { \
90: return const_cast<PetscComplex &>(rhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(rhs).real() != PetscReal(lhs); \
91: } \
92: /* PETSC_CXX_COMPLEX_FIX */
94: /*
95: Due to the C++ automatic promotion rules for floating point and integer values only the two cases below
96: need to be handled.
97: */
98: #if defined(PETSC_USE_REAL_SINGLE)
99: PETSC_CXX_COMPLEX_FIX(double)
100: #elif defined(PETSC_USE_REAL_DOUBLE)
101: PETSC_CXX_COMPLEX_FIX(PetscInt)
102: #endif /* PETSC_USE_REAL_* */
104: #endif