7
7
8
8
namespace std
9
9
{
10
- std::complex<double > operator +(std::complex<double > self, long other)
10
+ template <class T >
11
+ std::complex<T> operator +(std::complex<T> self, long other)
11
12
{
12
- return self + double (other);
13
+ return self + T (other);
13
14
}
14
15
15
- std::complex<double > operator +(long self, std::complex<double > other)
16
+ template <class T >
17
+ std::complex<T> operator +(long self, std::complex<T> other)
16
18
{
17
- return double (self) + other;
19
+ return T (self) + other;
18
20
}
19
21
20
- std::complex<double > operator -(std::complex<double > self, long other)
22
+ template <class T >
23
+ std::complex<T> operator -(std::complex<T> self, long other)
21
24
{
22
- return self - double (other);
25
+ return self - T (other);
23
26
}
24
27
25
- std::complex<double > operator -(long self, std::complex<double > other)
28
+ template <class T >
29
+ std::complex<T> operator -(long self, std::complex<T> other)
26
30
{
27
- return double (self) - other;
31
+ return T (self) - other;
28
32
}
29
33
30
- std::complex<double > operator *(std::complex<double > self, long other)
34
+ template <class T >
35
+ std::complex<T> operator *(std::complex<T> self, long other)
31
36
{
32
- return self * double (other);
37
+ return self * T (other);
33
38
}
34
39
35
- std::complex<double > operator *(long self, std::complex<double > other)
40
+ template <class T >
41
+ std::complex<T> operator *(long self, std::complex<T> other)
36
42
{
37
- return double (self) * other;
43
+ return T (self) * other;
38
44
}
39
45
40
- std::complex<double > operator /(std::complex<double > self, long other)
46
+ template <class T >
47
+ std::complex<T> operator /(std::complex<T> self, long other)
41
48
{
42
- return self / double (other);
49
+ return self / T (other);
43
50
}
44
51
45
- std::complex<double > operator /(long self, std::complex<double > other)
52
+ template <class T >
53
+ std::complex<T> operator /(long self, std::complex<T> other)
46
54
{
47
- return double (self) / other;
55
+ return T (self) / other;
48
56
}
49
57
50
- bool operator ==(std::complex<double > self, long other)
58
+ template <class T >
59
+ bool operator ==(std::complex<T> self, long other)
51
60
{
52
- return self == double (other);
61
+ return self == T (other);
53
62
}
54
63
55
- bool operator ==(long self, std::complex<double > other)
64
+ template <class T >
65
+ bool operator ==(long self, std::complex<T> other)
56
66
{
57
- return double (self) == other;
67
+ return T (self) == other;
58
68
}
59
69
60
- bool operator !=(std::complex<double > self, long other)
70
+ template <class T >
71
+ bool operator !=(std::complex<T> self, long other)
61
72
{
62
- return self != double (other);
73
+ return self != T (other);
63
74
}
64
75
65
- bool operator !=(long self, std::complex<double > other)
76
+ template <class T >
77
+ bool operator !=(long self, std::complex<T> other)
66
78
{
67
- return double (self) != other;
79
+ return T (self) != other;
68
80
}
69
81
70
82
template <class T >
@@ -111,15 +123,20 @@ namespace std
111
123
{
112
124
return !self.real () && !self.imag ();
113
125
}
126
+ template <class T >
127
+ size_t hash<std::complex<T>>::operator ()(std::complex<T> const &x) const
128
+ {
129
+ return std::hash<T>{}(x.real ()) ^ std::hash<T>{}(x.imag ());
130
+ };
114
131
}
115
132
116
133
PYTHONIC_NS_BEGIN
117
134
118
135
namespace __builtin__
119
136
{
120
137
121
- template <size_t AttributeID>
122
- double getattr (std::complex<double > const &self)
138
+ template <size_t AttributeID, class T >
139
+ T getattr (std::complex<T > const &self)
123
140
{
124
141
return AttributeID == pythonic::types::attr::REAL ? std::real (self)
125
142
: std::imag (self);
@@ -142,36 +159,57 @@ PyObject *to_python<std::complex<long double>>::convert(
142
159
PyArray_DescrFromType (NPY_CLONGDOUBLE), nullptr );
143
160
}
144
161
145
- template <class T >
146
- PyObject *to_python<std::complex<T>>::convert(std::complex<T> const &c)
162
+ template <>
163
+ PyObject *
164
+ to_python<std::complex<double >>::convert(std::complex<double > const &c)
147
165
{
148
166
return PyComplex_FromDoubles (c.real (), c.imag ());
149
167
}
150
168
169
+ template <>
170
+ PyObject *to_python<std::complex<float >>::convert(std::complex<float > const &c)
171
+ {
172
+ return PyArray_Scalar (const_cast <std::complex<float > *>(&c),
173
+ PyArray_DescrFromType (NPY_CFLOAT), nullptr );
174
+ }
175
+
151
176
template <>
152
177
bool from_python<std::complex<long double >>::is_convertible(PyObject *obj)
153
178
{
154
- return PyComplex_Check (obj) || PyArray_IsScalar (obj, CLongDouble);
179
+ return PyArray_IsScalar (obj, CLongDouble);
155
180
}
156
181
157
- template <class T >
158
- bool from_python<std::complex<T >>::is_convertible(PyObject *obj)
182
+ template <>
183
+ bool from_python<std::complex<double >>::is_convertible(PyObject *obj)
159
184
{
160
185
return PyComplex_Check (obj);
161
186
}
162
- template <class T >
163
- std::complex<T> from_python<std::complex<T>>::convert(PyObject *obj)
187
+
188
+ template <>
189
+ bool from_python<std::complex<float >>::is_convertible(PyObject *obj)
190
+ {
191
+ return PyArray_IsScalar (obj, CFloat);
192
+ }
193
+
194
+ template <>
195
+ std::complex<long double >
196
+ from_python<std::complex<long double >>::convert(PyObject *obj)
197
+ {
198
+ auto val = PyArrayScalar_VAL (obj, CLongDouble);
199
+ return {val.real , val.imag };
200
+ }
201
+
202
+ template <>
203
+ std::complex<double > from_python<std::complex<double >>::convert(PyObject *obj)
204
+ {
205
+ return {PyComplex_RealAsDouble (obj), PyComplex_ImagAsDouble (obj)};
206
+ }
207
+
208
+ template <>
209
+ std::complex<float > from_python<std::complex<float >>::convert(PyObject *obj)
164
210
{
165
- if (PyArray_IsScalar (obj, CLongDouble)) {
166
- auto val = PyArrayScalar_VAL (obj, CLongDouble);
167
- return {static_cast <T>(val.real ), static_cast <T>(val.imag )};
168
- }
169
- if (PyComplex_Check (obj))
170
- return {PyComplex_RealAsDouble (obj), PyComplex_ImagAsDouble (obj)};
171
- else if (PyFloat_Check (obj))
172
- return {PyFloat_AsDouble (obj), 0 .};
173
- else
174
- return {(double )PyInt_AsLong (obj), 0 .};
211
+ auto val = PyArrayScalar_VAL (obj, CFloat);
212
+ return {val.real , val.imag };
175
213
}
176
214
PYTHONIC_NS_END
177
215
#endif
0 commit comments