xref: /petsc/include/petsccxxcomplexfix.h (revision 108513bb137b9f0d1bab34f0886b67147f6d5f68)
1a4963045SJacob Faibussowitsch #pragma once
239829747SLisandro Dalcin 
31850900dSBarry Smith /* MANSEC = Sys */
41850900dSBarry Smith 
5f636a84aSBarry Smith /*
6d5b43468SJose E. Roman     The pragma below silence all compiler warnings coming from code in this header file.
74cdc28b3SLisandro Dalcin     In particular, it silences `-Wfloat-equal` warnings in `operator==()` and `operator!=` below.
84cdc28b3SLisandro Dalcin     Other compilers beyond GCC support this pragma.
94cdc28b3SLisandro Dalcin */
1077ba14dbSStefano Zampini #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__NEC__)
114cdc28b3SLisandro Dalcin   #pragma GCC system_header
124cdc28b3SLisandro Dalcin #endif
134cdc28b3SLisandro Dalcin 
144cdc28b3SLisandro Dalcin /*
15f636a84aSBarry Smith      Defines additional operator overloading for the C++ complex class that are "missing" in the standard
16f636a84aSBarry Smith      include files. For example, the code fragment
17f636a84aSBarry Smith 
18f636a84aSBarry Smith      std::complex<double> c = 22.0;
19f636a84aSBarry Smith      c = 11 + c;
20f636a84aSBarry Smith 
21f636a84aSBarry Smith      will produce a compile time error such as
22f636a84aSBarry Smith 
23f636a84aSBarry Smith      error: no match for 'operator+' (operand types are 'int' and 'std::complex<double>')
24f636a84aSBarry Smith 
25f636a84aSBarry Smith      The code fragment
26f636a84aSBarry Smith 
27f636a84aSBarry Smith      std::complex<float> c = 22.0;
28f636a84aSBarry Smith      c = 11.0 + c;
29f636a84aSBarry Smith 
30f636a84aSBarry Smith      will produce a compile time error such as
31f636a84aSBarry Smith 
32f636a84aSBarry Smith      error: no match for 'operator+' (operand types are 'double' and 'std::complex<float>')
33f636a84aSBarry Smith 
34f636a84aSBarry Smith      This deficiency means one may need to write cumbersome code while working with the C++ complex classes.
35f636a84aSBarry Smith 
36f636a84aSBarry Smith      This include file defines a few additional operator overload methods for the C++ complex classes to handle
37f636a84aSBarry Smith      these cases naturally within PETSc code.
38f636a84aSBarry Smith 
39a966371cSJunchao Zhang      This file is included in petscsystypes.h when feasible. In the small number of cases where these additional methods
40a966371cSJunchao Zhang      may conflict with other code one may add '#define PETSC_SKIP_CXX_COMPLEX_FIX 1' before including any PETSc include
41a966371cSJunchao Zhang      files to prevent these methods from being provided.
42f636a84aSBarry Smith */
43f636a84aSBarry Smith 
4439829747SLisandro Dalcin #define PETSC_CXX_COMPLEX_FIX(Type) \
45d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator+(const PetscComplex &lhs, const Type &rhs) \
46d71ae5a4SJacob Faibussowitsch   { \
479371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) + PetscReal(rhs); \
489371c9d4SSatish Balay   } \
49d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator+(const Type &lhs, const PetscComplex &rhs) \
50d71ae5a4SJacob Faibussowitsch   { \
519371c9d4SSatish Balay     return PetscReal(lhs) + const_cast<PetscComplex &>(rhs); \
529371c9d4SSatish Balay   } \
53d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator-(const PetscComplex &lhs, const Type &rhs) \
54d71ae5a4SJacob Faibussowitsch   { \
559371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) - PetscReal(rhs); \
569371c9d4SSatish Balay   } \
57d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator-(const Type &lhs, const PetscComplex &rhs) \
58d71ae5a4SJacob Faibussowitsch   { \
599371c9d4SSatish Balay     return PetscReal(lhs) - const_cast<PetscComplex &>(rhs); \
609371c9d4SSatish Balay   } \
61d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator*(const PetscComplex &lhs, const Type &rhs) \
62d71ae5a4SJacob Faibussowitsch   { \
639371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) * PetscReal(rhs); \
649371c9d4SSatish Balay   } \
65d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator*(const Type &lhs, const PetscComplex &rhs) \
66d71ae5a4SJacob Faibussowitsch   { \
679371c9d4SSatish Balay     return PetscReal(lhs) * const_cast<PetscComplex &>(rhs); \
689371c9d4SSatish Balay   } \
69d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator/(const PetscComplex &lhs, const Type &rhs) \
70d71ae5a4SJacob Faibussowitsch   { \
719371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs) / PetscReal(rhs); \
729371c9d4SSatish Balay   } \
73d71ae5a4SJacob Faibussowitsch   static inline PetscComplex operator/(const Type &lhs, const PetscComplex &rhs) \
74d71ae5a4SJacob Faibussowitsch   { \
759371c9d4SSatish Balay     return PetscReal(lhs) / const_cast<PetscComplex &>(rhs); \
769371c9d4SSatish Balay   } \
77d71ae5a4SJacob Faibussowitsch   static inline bool operator==(const PetscComplex &lhs, const Type &rhs) \
78d71ae5a4SJacob Faibussowitsch   { \
799371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(lhs).real() == PetscReal(rhs); \
809371c9d4SSatish Balay   } \
81d71ae5a4SJacob Faibussowitsch   static inline bool operator==(const Type &lhs, const PetscComplex &rhs) \
82d71ae5a4SJacob Faibussowitsch   { \
839371c9d4SSatish Balay     return const_cast<PetscComplex &>(rhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(rhs).real() == PetscReal(lhs); \
849371c9d4SSatish Balay   } \
85d71ae5a4SJacob Faibussowitsch   static inline bool operator!=(const PetscComplex &lhs, const Type &rhs) \
86d71ae5a4SJacob Faibussowitsch   { \
879371c9d4SSatish Balay     return const_cast<PetscComplex &>(lhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(lhs).real() != PetscReal(rhs); \
889371c9d4SSatish Balay   } \
89d71ae5a4SJacob Faibussowitsch   static inline bool operator!=(const Type &lhs, const PetscComplex &rhs) \
90d71ae5a4SJacob Faibussowitsch   { \
919371c9d4SSatish Balay     return const_cast<PetscComplex &>(rhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(rhs).real() != PetscReal(lhs); \
929371c9d4SSatish Balay   } \
9339829747SLisandro Dalcin /* PETSC_CXX_COMPLEX_FIX */
9439829747SLisandro Dalcin 
95*108513bbSJunchao Zhang // In PETSc, a quad precision PetscComplex is a C type even with clanguage=cxx, therefore no C++ operator overloading needed for it.
96*108513bbSJunchao Zhang #if !defined(PETSC_USE_REAL___FLOAT128)
97*108513bbSJunchao Zhang 
98*108513bbSJunchao Zhang // Provide operator overloading for 'PetscComplex .op. (an integer type or a real type but not PetscReal)'.
99*108513bbSJunchao Zhang //
100*108513bbSJunchao Zhang // We enumerate all C/C++ POD (Plain Old Data) types to provide exact overload resolution, to keep the precision change
101*108513bbSJunchao Zhang // in the Type to PetscReal conversion intact, as intended by users performing these mixed precision operations.
102*108513bbSJunchao Zhang   #if !defined(PETSC_USE_REAL___FP16) && defined(PETSC_HAVE_REAL___FP16)
103*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(__fp16)
104*108513bbSJunchao Zhang   #endif
105*108513bbSJunchao Zhang 
106*108513bbSJunchao Zhang   #if !defined(PETSC_USE_REAL_SINGLE)
107*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(float)
108*108513bbSJunchao Zhang   #endif
109*108513bbSJunchao Zhang 
110*108513bbSJunchao Zhang   #if !defined(PETSC_USE_REAL_DOUBLE)
11139829747SLisandro Dalcin PETSC_CXX_COMPLEX_FIX(double)
112*108513bbSJunchao Zhang   #endif
113*108513bbSJunchao Zhang 
114*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(long double)
115*108513bbSJunchao Zhang 
116*108513bbSJunchao Zhang   #if defined(PETSC_HAVE_REAL___FLOAT128)
117*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(__float128)
118*108513bbSJunchao Zhang   #endif
119*108513bbSJunchao Zhang 
120*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(signed char)
121*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(short)
122*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(int)
123*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(long)
124*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(long long)
125*108513bbSJunchao Zhang 
126*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(unsigned char)
127*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(unsigned short)
128*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(unsigned int)
129*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(unsigned long)
130*108513bbSJunchao Zhang PETSC_CXX_COMPLEX_FIX(unsigned long long)
131*108513bbSJunchao Zhang 
132*108513bbSJunchao Zhang #endif
133