xref: /petsc/include/petsccxxcomplexfix.h (revision c4762a1b19cd2af06abeed90e8f9d34fb975dd94)
1 #if !defined(PETSCCXXCOMPLEXFIX_H)
2 #define PETSCCXXCOMPLEXFIX_H
3 #if defined(__cplusplus) && defined(PETSC_HAVE_COMPLEX) && defined(PETSC_HAVE_CXX_COMPLEX)
4 
5 /*
6     The pragma below silence all compiler warnings comming from code in this header file.
7     In particular, it silences `-Wfloat-equal` warnings in `operator==()` and `operator!=` below.
8     Other compilers beyond GCC support this pragma.
9 */
10 #if defined(__GNUC__) && (__GNUC__ >= 4)
11 #pragma GCC system_header
12 #endif
13 
14 /*
15      Defines additional operator overloading for the C++ complex class that are "missing" in the standard
16      include files. For example, the code fragment
17 
18      std::complex<double> c = 22.0;
19      c = 11 + c;
20 
21      will produce a compile time error such as
22 
23      error: no match for 'operator+' (operand types are 'int' and 'std::complex<double>')
24 
25      The code fragment
26 
27      std::complex<float> c = 22.0;
28      c = 11.0 + c;
29 
30      will produce a compile time error such as
31 
32      error: no match for 'operator+' (operand types are 'double' and 'std::complex<float>')
33 
34      This deficiency means one may need to write cumbersome code while working with the C++ complex classes.
35 
36      This include file defines a few additional operator overload methods for the C++ complex classes to handle
37      these cases naturally within PETSc code.
38 
39      This file is included automatically by PETSc include files. In the small number of cases where these additional methods
40      may conflict with other code one may add
41 
42      #define PETSC_SKIP_CXX_COMPLEX_FIX
43 
44      before including any PETSc include files to prevent these methods from being provided.
45 */
46 
47 #if defined(__GNUC__) && (__GNUC__ >= 4)
48 #pragma GCC system_header
49 #endif
50 
51 #define PETSC_CXX_COMPLEX_FIX(Type) \
52 static inline PetscComplex operator+(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) + PetscReal(rhs); } \
53 static inline PetscComplex operator+(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) + const_cast<PetscComplex&>(rhs); } \
54 static inline PetscComplex operator-(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) - PetscReal(rhs); } \
55 static inline PetscComplex operator-(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) - const_cast<PetscComplex&>(rhs); } \
56 static inline PetscComplex operator*(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) * PetscReal(rhs); } \
57 static inline PetscComplex operator*(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) * const_cast<PetscComplex&>(rhs); } \
58 static inline PetscComplex operator/(const PetscComplex& lhs, const Type& rhs) { return const_cast<PetscComplex&>(lhs) / PetscReal(rhs); } \
59 static inline PetscComplex operator/(const Type& lhs, const PetscComplex& rhs) { return PetscReal(lhs) / const_cast<PetscComplex&>(rhs); } \
60 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); } \
61 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); } \
62 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); } \
63 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); } \
64 /* PETSC_CXX_COMPLEX_FIX */
65 
66 /*
67     Due to the C++ automatic promotion rules for floating point and integer values only the two cases below
68     need to be handled.
69 */
70 #if defined(PETSC_USE_REAL_SINGLE)
71 PETSC_CXX_COMPLEX_FIX(double)
72 #elif defined(PETSC_USE_REAL_DOUBLE)
73 PETSC_CXX_COMPLEX_FIX(PetscInt)
74 #endif /* PETSC_USE_REAL_* */
75 
76 #endif /* __cplusplus && PETSC_HAVE_COMPLEX && PETSC_HAVE_CXX_COMPLEX */
77 #endif
78