1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
<center><a href="https://gitlab.com/petsc/petsc/-/blob/2cd11c936b2c10bfd58f60105eda30ca65946a12/include/petsccxxcomplexfix.h">Actual source code: petsccxxcomplexfix.h</a></center><br>
<html>
<head>
<title></title>
<meta name="generator" content="c2html 0.9.6">
<meta name="date" content="2026-01-01T23:31:07+00:00">
</head>
<body bgcolor="#FFFFFF">
<pre width=80>
<a name="line1"> 1: </a><font color="#A020F0">#pragma once</font>
<a name="line3"> 3: </a><font color="#B22222">/* MANSEC = Sys */</font>
<a name="line5"> 5: </a><font color="#B22222">/*</font>
<a name="line6"> 6: </a><font color="#B22222"> The pragma below silence all compiler warnings coming from code in this header file.</font>
<a name="line7"> 7: </a><font color="#B22222"> In particular, it silences `-Wfloat-equal` warnings in `operator==()` and `operator!=` below.</font>
<a name="line8"> 8: </a><font color="#B22222"> Other compilers beyond GCC support this pragma.</font>
<a name="line9"> 9: </a><font color="#B22222">*/</font>
<a name="line10"> 10: </a><font color="#A020F0">#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__NEC__)</font>
<a name="line11"> 11: </a><font color="#A020F0"> #pragma GCC system_header</font>
<a name="line12"> 12: </a><font color="#A020F0">#endif</font>
<a name="line14"> 14: </a><font color="#B22222">/*</font>
<a name="line15"> 15: </a><font color="#B22222"> Defines additional operator overloading for the C++ complex class that are "missing" in the standard</font>
<a name="line16"> 16: </a><font color="#B22222"> include files. For example, the code fragment</font>
<a name="line18"> 18: </a><font color="#B22222"> std::complex<double> c = 22.0;</font>
<a name="line19"> 19: </a><font color="#B22222"> c = 11 + c;</font>
<a name="line21"> 21: </a><font color="#B22222"> will produce a compile time error such as</font>
<a name="line23"> 23: </a><font color="#B22222"> error: no match for 'operator+' (operand types are 'int' and 'std::complex<double>')</font>
<a name="line25"> 25: </a><font color="#B22222"> The code fragment</font>
<a name="line27"> 27: </a><font color="#B22222"> std::complex<float> c = 22.0;</font>
<a name="line28"> 28: </a><font color="#B22222"> c = 11.0 + c;</font>
<a name="line30"> 30: </a><font color="#B22222"> will produce a compile time error such as</font>
<a name="line32"> 32: </a><font color="#B22222"> error: no match for 'operator+' (operand types are 'double' and 'std::complex<float>')</font>
<a name="line34"> 34: </a><font color="#B22222"> This deficiency means one may need to write cumbersome code while working with the C++ complex classes.</font>
<a name="line36"> 36: </a><font color="#B22222"> This include file defines a few additional operator overload methods for the C++ complex classes to handle</font>
<a name="line37"> 37: </a><font color="#B22222"> these cases naturally within PETSc code.</font>
<a name="line39"> 39: </a><font color="#B22222"> This file is included in petscsystypes.h when feasible. In the small number of cases where these additional methods</font>
<a name="line40"> 40: </a><font color="#B22222"> may conflict with other code one may add '#define PETSC_SKIP_CXX_COMPLEX_FIX 1' before including any PETSc include</font>
<a name="line41"> 41: </a><font color="#B22222"> files to prevent these methods from being provided.</font>
<a name="line42"> 42: </a><font color="#B22222">*/</font>
<a name="line44"> 44: </a><font color="#B22222">// In PETSc, a quad precision <a href="../manualpages/Sys/PetscComplex.html">PetscComplex</a> is a C type even with clanguage=cxx, therefore no C++ operator overloading needed for it.</font>
<a name="line45"> 45: </a><font color="#A020F0">#if !defined(PETSC_USE_REAL___FLOAT128)</font>
<a name="line46"> 46: </a><font color="#A020F0"> #include <type_traits></font>
<a name="line47"> 47: </a><font color="#B22222">// For operations "Atype op Cmplex" or "Cmplex op Atype" with Cmplex being <a href="../manualpages/Sys/PetscComplex.html">PetscComplex</a>, the built-in support allows Atype to be <a href="../manualpages/Sys/PetscComplex.html">PetscComplex</a> or <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>.</font>
<a name="line48"> 48: </a><font color="#B22222">// We extend Atype to other C++ arithmetic types, and __fp16, __float128 if available.</font>
<a name="line49"> 49: </a><font color="#B22222">// We put Cmplex as a template parameter so that we can enforce Cmplex to be <a href="../manualpages/Sys/PetscComplex.html">PetscComplex</a> and forbid compilers to convert other types to <a href="../manualpages/Sys/PetscComplex.html">PetscComplex</a>.</font>
<a name="line50"> 50: </a><font color="#B22222">// This requires C++11 or later.</font>
<a name="line51"> 51: </a>template <typename Cmplex, typename Atype> <font color="#B22222">// operation on a complex and an arithmetic type</font>
<a name="line52"> 52: </a><font color="#4169E1"><a name="petsccomplex_extended_type"></a>struct petsccomplex_extended_type </font>:
<a name="line53"> 53: </a> std::integral_constant<bool, (std::is_same<Cmplex, <a href="../manualpages/Sys/PetscComplex.html">PetscComplex</a>>::value && std::is_arithmetic<Atype>::value && !std::is_same<Atype, <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>>::value)
<a name="line54"> 54: </a><font color="#A020F0"> #if defined(PETSC_HAVE_REAL___FP16) && !defined(PETSC_USE_REAL___FP16)</font>
<a name="line55"> 55: </a> || std::is_same<Atype, __fp16>::value
<a name="line56"> 56: </a><font color="#A020F0"> #endif</font>
<a name="line57"> 57: </a><font color="#A020F0"> #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FLOAT128)</font>
<a name="line58"> 58: </a> || std::is_same<Atype, __float128>::value
<a name="line59"> 59: </a><font color="#A020F0"> #endif</font>
<a name="line60"> 60: </a> > {
<a name="line61"> 61: </a>};
<a name="line63"> 63: </a>template <typename Cmplex, typename Atype>
<a name="line64"> 64: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, Cmplex>::type operator+(const Atype &lhs, const Cmplex &rhs)
<a name="line65"> 65: </a>{
<a name="line66"> 66: </a> <font color="#4169E1">return</font> <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(lhs) + rhs;
<a name="line67"> 67: </a>}
<a name="line69"> 69: </a>template <typename Cmplex, typename Atype>
<a name="line70"> 70: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, Cmplex>::type operator+(const Cmplex &lhs, const Atype &rhs)
<a name="line71"> 71: </a>{
<a name="line72"> 72: </a> <font color="#4169E1">return</font> lhs + <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(rhs);
<a name="line73"> 73: </a>}
<a name="line75"> 75: </a>template <typename Cmplex, typename Atype>
<a name="line76"> 76: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, Cmplex>::type operator-(const Atype &lhs, const Cmplex &rhs)
<a name="line77"> 77: </a>{
<a name="line78"> 78: </a> <font color="#4169E1">return</font> <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(lhs) - rhs;
<a name="line79"> 79: </a>}
<a name="line81"> 81: </a>template <typename Cmplex, typename Atype>
<a name="line82"> 82: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, Cmplex>::type operator-(const Cmplex &lhs, const Atype &rhs)
<a name="line83"> 83: </a>{
<a name="line84"> 84: </a> <font color="#4169E1">return</font> lhs - <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(rhs);
<a name="line85"> 85: </a>}
<a name="line87"> 87: </a>template <typename Cmplex, typename Atype>
<a name="line88"> 88: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, Cmplex>::type operator*(const Atype &lhs, const Cmplex &rhs)
<a name="line89"> 89: </a>{
<a name="line90"> 90: </a> <font color="#4169E1">return</font> <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(lhs) * rhs;
<a name="line91"> 91: </a>}
<a name="line93"> 93: </a>template <typename Cmplex, typename Atype>
<a name="line94"> 94: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, Cmplex>::type operator*(const Cmplex &lhs, const Atype &rhs)
<a name="line95"> 95: </a>{
<a name="line96"> 96: </a> <font color="#4169E1">return</font> lhs * <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(rhs);
<a name="line97"> 97: </a>}
<a name="line99"> 99: </a>template <typename Cmplex, typename Atype>
<a name="line100">100: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, Cmplex>::type operator/(const Atype &lhs, const Cmplex &rhs)
<a name="line101">101: </a>{
<a name="line102">102: </a> <font color="#4169E1">return</font> <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(lhs) / rhs;
<a name="line103">103: </a>}
<a name="line105">105: </a>template <typename Cmplex, typename Atype>
<a name="line106">106: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, Cmplex>::type operator/(const Cmplex &lhs, const Atype &rhs)
<a name="line107">107: </a>{
<a name="line108">108: </a> <font color="#4169E1">return</font> lhs / <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(rhs);
<a name="line109">109: </a>}
<a name="line111">111: </a>template <typename Cmplex, typename Atype>
<a name="line112">112: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, bool>::type operator==(const Atype &lhs, const Cmplex &rhs)
<a name="line113">113: </a>{
<a name="line114">114: </a> <font color="#4169E1">return</font> rhs.imag() == <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(0) && rhs.real() == <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(lhs);
<a name="line115">115: </a>}
<a name="line117">117: </a>template <typename Cmplex, typename Atype>
<a name="line118">118: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, bool>::type operator==(const Cmplex &lhs, const Atype &rhs)
<a name="line119">119: </a>{
<a name="line120">120: </a> <font color="#4169E1">return</font> lhs.imag() == <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(0) && lhs.real() == <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(rhs);
<a name="line121">121: </a>}
<a name="line123">123: </a>template <typename Cmplex, typename Atype>
<a name="line124">124: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, bool>::type operator!=(const Atype &lhs, const Cmplex &rhs)
<a name="line125">125: </a>{
<a name="line126">126: </a> <font color="#4169E1">return</font> rhs.imag() != <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(0) || rhs.real() != <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(lhs);
<a name="line127">127: </a>}
<a name="line129">129: </a>template <typename Cmplex, typename Atype>
<a name="line130">130: </a>inline typename std::enable_if<petsccomplex_extended_type<Cmplex, Atype>::value, bool>::type operator!=(const Cmplex &lhs, const Atype &rhs)
<a name="line131">131: </a>{
<a name="line132">132: </a> <font color="#4169E1">return</font> lhs.imag() != <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(0) || lhs.real() != <a href="../manualpages/Sys/PetscReal.html">PetscReal</a>(rhs);
<a name="line133">133: </a>}
<a name="line135">135: </a><font color="#A020F0">#endif</font>
</pre>
</body>
</html>
|