Actual source code: petsccxxcomplexfix.h

      1: #pragma once

      3: /*
      4:     The pragma below silence all compiler warnings coming from code in this header file.
      5:     In particular, it silences `-Wfloat-equal` warnings in `operator==()` and `operator!=` below.
      6:     Other compilers beyond GCC support this pragma.
      7: */
      8: #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__NEC__)
      9:   #pragma GCC system_header
     10: #endif

     12: /*
     13:      Defines additional operator overloading for the C++ complex class that are "missing" in the standard
     14:      include files. For example, the code fragment

     16:      std::complex<double> c = 22.0;
     17:      c = 11 + c;

     19:      will produce a compile time error such as

     21:      error: no match for 'operator+' (operand types are 'int' and 'std::complex<double>')

     23:      The code fragment

     25:      std::complex<float> c = 22.0;
     26:      c = 11.0 + c;

     28:      will produce a compile time error such as

     30:      error: no match for 'operator+' (operand types are 'double' and 'std::complex<float>')

     32:      This deficiency means one may need to write cumbersome code while working with the C++ complex classes.

     34:      This include file defines a few additional operator overload methods for the C++ complex classes to handle
     35:      these cases naturally within PETSc code.

     37:      This file is included in petscsystypes.h when feasible. In the small number of cases where these additional methods
     38:      may conflict with other code one may add '#define PETSC_SKIP_CXX_COMPLEX_FIX 1' before including any PETSc include
     39:      files to prevent these methods from being provided.
     40: */

     42: #define PETSC_CXX_COMPLEX_FIX(Type) \
     43:   static inline PetscComplex operator+(const PetscComplex &lhs, const Type &rhs) \
     44:   { \
     45:     return const_cast<PetscComplex &>(lhs) + PetscReal(rhs); \
     46:   } \
     47:   static inline PetscComplex operator+(const Type &lhs, const PetscComplex &rhs) \
     48:   { \
     49:     return PetscReal(lhs) + const_cast<PetscComplex &>(rhs); \
     50:   } \
     51:   static inline PetscComplex operator-(const PetscComplex &lhs, const Type &rhs) \
     52:   { \
     53:     return const_cast<PetscComplex &>(lhs) - PetscReal(rhs); \
     54:   } \
     55:   static inline PetscComplex operator-(const Type &lhs, const PetscComplex &rhs) \
     56:   { \
     57:     return PetscReal(lhs) - const_cast<PetscComplex &>(rhs); \
     58:   } \
     59:   static inline PetscComplex operator*(const PetscComplex &lhs, const Type &rhs) \
     60:   { \
     61:     return const_cast<PetscComplex &>(lhs) * PetscReal(rhs); \
     62:   } \
     63:   static inline PetscComplex operator*(const Type &lhs, const PetscComplex &rhs) \
     64:   { \
     65:     return PetscReal(lhs) * const_cast<PetscComplex &>(rhs); \
     66:   } \
     67:   static inline PetscComplex operator/(const PetscComplex &lhs, const Type &rhs) \
     68:   { \
     69:     return const_cast<PetscComplex &>(lhs) / PetscReal(rhs); \
     70:   } \
     71:   static inline PetscComplex operator/(const Type &lhs, const PetscComplex &rhs) \
     72:   { \
     73:     return PetscReal(lhs) / const_cast<PetscComplex &>(rhs); \
     74:   } \
     75:   static inline bool operator==(const PetscComplex &lhs, const Type &rhs) \
     76:   { \
     77:     return const_cast<PetscComplex &>(lhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(lhs).real() == PetscReal(rhs); \
     78:   } \
     79:   static inline bool operator==(const Type &lhs, const PetscComplex &rhs) \
     80:   { \
     81:     return const_cast<PetscComplex &>(rhs).imag() == PetscReal(0) && const_cast<PetscComplex &>(rhs).real() == PetscReal(lhs); \
     82:   } \
     83:   static inline bool operator!=(const PetscComplex &lhs, const Type &rhs) \
     84:   { \
     85:     return const_cast<PetscComplex &>(lhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(lhs).real() != PetscReal(rhs); \
     86:   } \
     87:   static inline bool operator!=(const Type &lhs, const PetscComplex &rhs) \
     88:   { \
     89:     return const_cast<PetscComplex &>(rhs).imag() != PetscReal(0) || const_cast<PetscComplex &>(rhs).real() != PetscReal(lhs); \
     90:   } \
     91: /* PETSC_CXX_COMPLEX_FIX */

     93: /*
     94:     Due to the C++ automatic promotion rules for floating point and integer values only the two cases below
     95:     need to be handled.
     96: */
     97: #if defined(PETSC_USE_REAL_SINGLE)
     98: PETSC_CXX_COMPLEX_FIX(double)
     99: #elif defined(PETSC_USE_REAL_DOUBLE)
    100: PETSC_CXX_COMPLEX_FIX(PetscInt)
    101: #endif /* PETSC_USE_REAL_* */