Actual source code: petsccxxcomplexfix.h
1: #pragma once
3: /* MANSEC = Sys */
5: /*
6: The pragma below silence all compiler warnings coming 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) && !defined(__NEC__)
11: #pragma GCC system_header
12: #endif
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
18: std::complex<double> c = 22.0;
19: c = 11 + c;
21: will produce a compile time error such as
23: error: no match for 'operator+' (operand types are 'int' and 'std::complex<double>')
25: The code fragment
27: std::complex<float> c = 22.0;
28: c = 11.0 + c;
30: will produce a compile time error such as
32: error: no match for 'operator+' (operand types are 'double' and 'std::complex<float>')
34: This deficiency means one may need to write cumbersome code while working with the C++ complex classes.
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.
39: This file is included in petscsystypes.h when feasible. In the small number of cases where these additional methods
40: may conflict with other code one may add '#define PETSC_SKIP_CXX_COMPLEX_FIX 1' before including any PETSc include
41: files to prevent these methods from being provided.
42: */
44: #define PETSC_CXX_COMPLEX_FIX(Type) \
45: static inline PetscComplex operator+(const PetscComplex &lhs, const Type &rhs) \
46: { \
47: return lhs + PetscReal(rhs); \
48: } \
49: static inline PetscComplex operator+(const Type &lhs, const PetscComplex &rhs) \
50: { \
51: return PetscReal(lhs) + rhs; \
52: } \
53: static inline PetscComplex operator-(const PetscComplex &lhs, const Type &rhs) \
54: { \
55: return lhs - PetscReal(rhs); \
56: } \
57: static inline PetscComplex operator-(const Type &lhs, const PetscComplex &rhs) \
58: { \
59: return PetscReal(lhs) - rhs; \
60: } \
61: static inline PetscComplex operator*(const PetscComplex &lhs, const Type &rhs) \
62: { \
63: return lhs * PetscReal(rhs); \
64: } \
65: static inline PetscComplex operator*(const Type &lhs, const PetscComplex &rhs) \
66: { \
67: return PetscReal(lhs) * rhs; \
68: } \
69: static inline PetscComplex operator/(const PetscComplex &lhs, const Type &rhs) \
70: { \
71: return lhs / PetscReal(rhs); \
72: } \
73: static inline PetscComplex operator/(const Type &lhs, const PetscComplex &rhs) \
74: { \
75: return PetscReal(lhs) / rhs; \
76: } \
77: static inline bool operator==(const PetscComplex &lhs, const Type &rhs) \
78: { \
79: return lhs.imag() == PetscReal(0) && lhs.real() == PetscReal(rhs); \
80: } \
81: static inline bool operator==(const Type &lhs, const PetscComplex &rhs) \
82: { \
83: return rhs.imag() == PetscReal(0) && rhs.real() == PetscReal(lhs); \
84: } \
85: static inline bool operator!=(const PetscComplex &lhs, const Type &rhs) \
86: { \
87: return lhs.imag() != PetscReal(0) || lhs.real() != PetscReal(rhs); \
88: } \
89: static inline bool operator!=(const Type &lhs, const PetscComplex &rhs) \
90: { \
91: return rhs.imag() != PetscReal(0) || rhs.real() != PetscReal(lhs); \
92: } \
93: /* PETSC_CXX_COMPLEX_FIX */
95: // In PETSc, a quad precision PetscComplex is a C type even with clanguage=cxx, therefore no C++ operator overloading needed for it.
96: #if !defined(PETSC_USE_REAL___FLOAT128)
98: // Provide operator overloading for 'PetscComplex .op. (an integer type or a real type but not PetscReal)'.
99: //
100: // We enumerate all C/C++ POD (Plain Old Data) types to provide exact overload resolution, to keep the precision change
101: // in the Type to PetscReal conversion intact, as intended by users performing these mixed precision operations.
102: #if !defined(PETSC_USE_REAL___FP16) && defined(PETSC_HAVE_REAL___FP16)
103: PETSC_CXX_COMPLEX_FIX(__fp16)
104: #endif
106: #if !defined(PETSC_USE_REAL_SINGLE)
107: PETSC_CXX_COMPLEX_FIX(float)
108: #endif
110: #if !defined(PETSC_USE_REAL_DOUBLE)
111: PETSC_CXX_COMPLEX_FIX(double)
112: #endif
114: PETSC_CXX_COMPLEX_FIX(long double)
116: #if defined(PETSC_HAVE_REAL___FLOAT128)
117: PETSC_CXX_COMPLEX_FIX(__float128)
118: #endif
120: PETSC_CXX_COMPLEX_FIX(signed char)
121: PETSC_CXX_COMPLEX_FIX(short)
122: PETSC_CXX_COMPLEX_FIX(int)
123: PETSC_CXX_COMPLEX_FIX(long)
124: PETSC_CXX_COMPLEX_FIX(long long)
126: PETSC_CXX_COMPLEX_FIX(unsigned char)
127: PETSC_CXX_COMPLEX_FIX(unsigned short)
128: PETSC_CXX_COMPLEX_FIX(unsigned int)
129: PETSC_CXX_COMPLEX_FIX(unsigned long)
130: PETSC_CXX_COMPLEX_FIX(unsigned long long)
132: #endif