1 /*
2  * DQt - D bindings for the Qt Toolkit
3  *
4  * GNU Lesser General Public License Usage
5  * This file may be used under the terms of the GNU Lesser
6  * General Public License version 3 as published by the Free Software
7  * Foundation and appearing in the file LICENSE.LGPL3 included in the
8  * packaging of this file. Please review the following information to
9  * ensure the GNU Lesser General Public License version 3 requirements
10  * will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
11  */
12 module qt.core.math;
13 extern(C++):
14 
15 version(Windows) {} else
16     version = NotWindowsOrCygwin;
17 version(Cygwin)
18     version = NotWindowsOrCygwin;
19 
20 import qt.config;
21 import qt.core.global;
22 import qt.helpers;
23 
24 /+ #if 0
25 #pragma qt_class(QtMath)
26 #endif
27 
28 #if __has_include(<bit>) && __cplusplus > 201703L
29 #endif
30 
31 #ifndef _USE_MATH_DEFINES
32 #  define _USE_MATH_DEFINES
33 #  define undef_USE_MATH_DEFINES
34 #endif
35 
36 #ifdef undef_USE_MATH_DEFINES
37 #  undef _USE_MATH_DEFINES
38 #  undef undef_USE_MATH_DEFINES
39 #endif +/
40 
41 
42 /+ #define QT_SINE_TABLE_SIZE 256 +/
43 enum QT_SINE_TABLE_SIZE = 256;
44 
45 /+ Q_CORE_EXPORT +/ extern __gshared const(qreal)[ QT_SINE_TABLE_SIZE] qt_sine_table;
46 
47 int qCeil(T)(T v)
48 {
49     version(Cygwin){}else
50     version(Windows)
51         import libc.math;
52     version(NotWindowsOrCygwin)
53         import libc.mathcalls;
54 
55     /+ using std::ceil; +/
56     return cast(int)(ceil(v));
57 }
58 
59 int qFloor(T)(T v)
60 {
61     version(Cygwin){}else
62     version(Windows)
63         import libc.math;
64     version(NotWindowsOrCygwin)
65         import libc.mathcalls;
66 
67     /+ using std::floor; +/
68     return cast(int)(floor(v));
69 }
70 
71 auto qFabs(T)(T v)
72 {
73     version(Cygwin){}else
74     version(Windows)
75         import libc.math;
76     version(NotWindowsOrCygwin)
77         import libc.mathcalls;
78 
79     /+ using std::fabs; +/
80     return fabs(v);
81 }
82 
83 auto qSin(T)(T v)
84 {
85     version(Cygwin){}else
86     version(Windows)
87         import libc.math;
88     version(NotWindowsOrCygwin)
89         import libc.mathcalls;
90 
91     /+ using std::sin; +/
92     return sin(v);
93 }
94 
95 auto qCos(T)(T v)
96 {
97     version(Cygwin){}else
98     version(Windows)
99         import libc.math;
100     version(NotWindowsOrCygwin)
101         import libc.mathcalls;
102 
103     /+ using std::cos; +/
104     return cos(v);
105 }
106 
107 auto qTan(T)(T v)
108 {
109     version(Cygwin){}else
110     version(Windows)
111         import libc.math;
112     version(NotWindowsOrCygwin)
113         import libc.mathcalls;
114 
115     /+ using std::tan; +/
116     return tan(v);
117 }
118 
119 auto qAcos(T)(T v)
120 {
121     version(Cygwin){}else
122     version(Windows)
123         import libc.math;
124     version(NotWindowsOrCygwin)
125         import libc.mathcalls;
126 
127     /+ using std::acos; +/
128     return acos(v);
129 }
130 
131 auto qAsin(T)(T v)
132 {
133     version(Cygwin){}else
134     version(Windows)
135         import libc.math;
136     version(NotWindowsOrCygwin)
137         import libc.mathcalls;
138 
139     /+ using std::asin; +/
140     return asin(v);
141 }
142 
143 auto qAtan(T)(T v)
144 {
145     version(Cygwin){}else
146     version(Windows)
147         import libc.math;
148     version(NotWindowsOrCygwin)
149         import libc.mathcalls;
150 
151     /+ using std::atan; +/
152     return atan(v);
153 }
154 
155 auto qAtan2(T1, T2)(T1 y, T2 x)
156 {
157     version(Cygwin){}else
158     version(Windows)
159         import libc.math;
160     version(NotWindowsOrCygwin)
161         import libc.mathcalls;
162 
163     /+ using std::atan2; +/
164     return atan2(y, x);
165 }
166 
167 auto qSqrt(T)(T v)
168 {
169     version(Cygwin){}else
170     version(Windows)
171         import libc.math;
172     version(NotWindowsOrCygwin)
173         import libc.mathcalls;
174 
175     /+ using std::sqrt; +/
176     return sqrt(v);
177 }
178 
179 /+ namespace QtPrivate {
180 template <typename R, typename F> // For qfloat16 to specialize
181 struct QHypotType { using type = decltype(std::hypot(R(1), F(1))); };
182 
183 // Implements hypot() without limiting number of arguments:
184 template <typename T>
185 class QHypotHelper
186 {
187     T scale, total;
188     template <typename F> friend class QHypotHelper;
189     QHypotHelper(T first, T prior) : scale(first), total(prior) {}
190 public:
191     QHypotHelper(T first) : scale(qAbs(first)), total(1) {}
192     T result() const
193     { return qIsFinite(scale) ? scale > 0 ? scale * T(std::sqrt(total)) : T(0) : scale; }
194 
195     template<typename F, typename ...Fs>
196     auto add(F first, Fs... rest) const
197     { return add(first).add(rest...); }
198 
199     template<typename F, typename R = typename QHypotType<T, F>::type>
200     QHypotHelper<R> add(F next) const
201     {
202         if (qIsInf(scale) || (qIsNaN(scale) && !qIsInf(next)))
203             return QHypotHelper<R>(scale, R(1));
204         if (qIsNaN(next))
205             return QHypotHelper<R>(next, R(1));
206         const R val = qAbs(next);
207         if (!(scale > 0) || qIsInf(next))
208             return QHypotHelper<R>(val, R(1));
209         if (!(val > 0))
210             return QHypotHelper<R>(scale, total);
211         if (val > scale) {
212             const R ratio = scale / next;
213             return QHypotHelper<R>(val, total * ratio * ratio + 1);
214         }
215         const R ratio = next / scale;
216         return QHypotHelper<R>(scale, total + ratio * ratio);
217     }
218 };
219 } // QtPrivate
220 
221 template<typename F, typename ...Fs>
222 auto qHypot(F first, Fs... rest)
223 {
224     return QtPrivate::QHypotHelper<F>(first).add(rest...).result();
225 }
226 
227 // However, where possible, use the standard library implementations:
228 template <typename Tx, typename Ty>
229 auto qHypot(Tx x, Ty y)
230 {
231     // C99 has hypot(), hence C++11 has std::hypot()
232     using std::hypot;
233     return hypot(x, y);
234 }
235 
236 #if __cpp_lib_hypot >= 201603L // Expected to be true
237 template <typename Tx, typename Ty, typename Tz>
238 auto qHypot(Tx x, Ty y, Tz z)
239 {
240     using std::hypot;
241     return hypot(x, y, z);
242 }
243 #endif +/ // else: no need to over-ride the arbitrarily-many-arg form
244 
245 auto qLn(T)(T v)
246 {
247     import core.stdc.math;
248 
249     /+ using std::log; +/
250     return log(v);
251 }
252 
253 auto qExp(T)(T v)
254 {
255     import core.stdc.math;
256 
257     /+ using std::exp; +/
258     return exp(v);
259 }
260 
261 auto qPow(T1, T2)(T1 x, T2 y)
262 {
263     version(Cygwin){}else
264     version(Windows)
265         import libc.math;
266     version(NotWindowsOrCygwin)
267         import libc.mathcalls;
268 
269     /+ using std::pow; +/
270     return pow(x, y);
271 }
272 
273 // TODO: use template variables (e.g. Qt::pi<type>) for these once we have C++14 support:
274 
275 /+ #ifndef M_E
276 #define M_E (2.7182818284590452354)
277 #endif
278 
279 #ifndef M_LOG2E
280 #define M_LOG2E (1.4426950408889634074)
281 #endif
282 
283 #ifndef M_LOG10E
284 #define M_LOG10E (0.43429448190325182765)
285 #endif
286 
287 #ifndef M_LN2
288 #define M_LN2 (0.69314718055994530942)
289 #endif
290 
291 #ifndef M_LN10
292 #define M_LN10 (2.30258509299404568402)
293 #endif +/
294 
295 static if(versionIsSet!("Windows") && !defined!"M_PI" && !defined!"_BSD_SOURCE" && !defined!"_GNU_SOURCE" && !defined!"_POSIX_C_SOURCE" && !defined!"_POSIX_SOURCE" && !defined!"_USE_MATH_DEFINES" && !defined!"_XOPEN_SOURCE" && !versionIsSet!("Cygwin") && defined!"__STRICT_ANSI__")
296 {
297 /+ #define M_PI (3.14159265358979323846) +/
298 enum M_PI = (3.14159265358979323846);
299 }
300 
301 /+ #ifndef M_PI_2
302 #define M_PI_2 (1.57079632679489661923)
303 #endif
304 
305 #ifndef M_PI_4
306 #define M_PI_4 (0.78539816339744830962)
307 #endif
308 
309 #ifndef M_1_PI
310 #define M_1_PI (0.31830988618379067154)
311 #endif
312 
313 #ifndef M_2_PI
314 #define M_2_PI (0.63661977236758134308)
315 #endif
316 
317 #ifndef M_2_SQRTPI
318 #define M_2_SQRTPI (1.12837916709551257390)
319 #endif
320 
321 #ifndef M_SQRT2
322 #define M_SQRT2 (1.41421356237309504880)
323 #endif
324 
325 #ifndef M_SQRT1_2
326 #define M_SQRT1_2 (0.70710678118654752440)
327 #endif +/
328 
329 /+pragma(inline, true) qreal qFastSin(qreal x)
330 {
331     int si = cast(int)(x * (0.5 * QT_SINE_TABLE_SIZE / mixin(((versionIsSet!("Windows") && !versionIsSet!("Cygwin") && (defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || !defined!"__STRICT_ANSI__"))) ? q{
332             M_PI
333         } : ((!versionIsSet!("Windows") || versionIsSet!("Cygwin"))) ? q{
334         M_PI
335         } : ((versionIsSet!("Windows") && !defined!"M_PI" && !defined!"_BSD_SOURCE" && !defined!"_GNU_SOURCE" && !defined!"_POSIX_C_SOURCE" && !defined!"_POSIX_SOURCE" && !defined!"_USE_MATH_DEFINES" && !defined!"_XOPEN_SOURCE" && !versionIsSet!("Cygwin") && defined!"__STRICT_ANSI__")) ? q{
336         M_PI
337         } : q{
338         M_PI
339         }))); // Would be more accurate with qRound, but slower.
340     qreal d = x - si * (2.0 * mixin(((versionIsSet!("Windows") && !versionIsSet!("Cygwin") && (defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || !defined!"__STRICT_ANSI__"))) ? q{
341             M_PI
342         } : ((!versionIsSet!("Windows") || versionIsSet!("Cygwin"))) ? q{
343         M_PI
344         } : ((versionIsSet!("Windows") && !defined!"M_PI" && !defined!"_BSD_SOURCE" && !defined!"_GNU_SOURCE" && !defined!"_POSIX_C_SOURCE" && !defined!"_POSIX_SOURCE" && !defined!"_USE_MATH_DEFINES" && !defined!"_XOPEN_SOURCE" && !versionIsSet!("Cygwin") && defined!"__STRICT_ANSI__")) ? q{
345         M_PI
346         } : q{
347         M_PI
348         }) / QT_SINE_TABLE_SIZE);
349     int ci = si + QT_SINE_TABLE_SIZE / 4;
350     si &= QT_SINE_TABLE_SIZE - 1;
351     ci &= QT_SINE_TABLE_SIZE - 1;
352     return qt_sine_table[si] + (qt_sine_table[ci] - 0.5 * qt_sine_table[si] * d) * d;
353 }+/
354 
355 /+pragma(inline, true) qreal qFastCos(qreal x)
356 {
357     int ci = cast(int)(x * (0.5 * QT_SINE_TABLE_SIZE / mixin(((versionIsSet!("Windows") && !versionIsSet!("Cygwin") && (defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || !defined!"__STRICT_ANSI__"))) ? q{
358             M_PI
359         } : ((!versionIsSet!("Windows") || versionIsSet!("Cygwin"))) ? q{
360         M_PI
361         } : ((versionIsSet!("Windows") && !defined!"M_PI" && !defined!"_BSD_SOURCE" && !defined!"_GNU_SOURCE" && !defined!"_POSIX_C_SOURCE" && !defined!"_POSIX_SOURCE" && !defined!"_USE_MATH_DEFINES" && !defined!"_XOPEN_SOURCE" && !versionIsSet!("Cygwin") && defined!"__STRICT_ANSI__")) ? q{
362         M_PI
363         } : q{
364         M_PI
365         }))); // Would be more accurate with qRound, but slower.
366     qreal d = x - ci * (2.0 * mixin(((versionIsSet!("Windows") && !versionIsSet!("Cygwin") && (defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || !defined!"__STRICT_ANSI__"))) ? q{
367             M_PI
368         } : ((!versionIsSet!("Windows") || versionIsSet!("Cygwin"))) ? q{
369         M_PI
370         } : ((versionIsSet!("Windows") && !defined!"M_PI" && !defined!"_BSD_SOURCE" && !defined!"_GNU_SOURCE" && !defined!"_POSIX_C_SOURCE" && !defined!"_POSIX_SOURCE" && !defined!"_USE_MATH_DEFINES" && !defined!"_XOPEN_SOURCE" && !versionIsSet!("Cygwin") && defined!"__STRICT_ANSI__")) ? q{
371         M_PI
372         } : q{
373         M_PI
374         }) / QT_SINE_TABLE_SIZE);
375     int si = ci + QT_SINE_TABLE_SIZE / 4;
376     si &= QT_SINE_TABLE_SIZE - 1;
377     ci &= QT_SINE_TABLE_SIZE - 1;
378     return qt_sine_table[si] - (qt_sine_table[ci] + 0.5 * qt_sine_table[si] * d) * d;
379 }+/
380 
381 /+pragma(inline, true) float qDegreesToRadians(float degrees)
382 {
383     static if(!versionIsSet!("Windows") || defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || versionIsSet!("Cygwin") || !defined!"__STRICT_ANSI__")
384         import libc.math;
385 
386     return degrees * float( mixin(((versionIsSet!("Windows") && !versionIsSet!("Cygwin") && (defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || !defined!"__STRICT_ANSI__"))) ? q{
387             M_PI
388         } : ((!versionIsSet!("Windows") || versionIsSet!("Cygwin"))) ? q{
389         M_PI
390         } : ((versionIsSet!("Windows") && !defined!"M_PI" && !defined!"_BSD_SOURCE" && !defined!"_GNU_SOURCE" && !defined!"_POSIX_C_SOURCE" && !defined!"_POSIX_SOURCE" && !defined!"_USE_MATH_DEFINES" && !defined!"_XOPEN_SOURCE" && !versionIsSet!("Cygwin") && defined!"__STRICT_ANSI__")) ? q{
391         M_PI
392         } : q{
393         M_PI
394         }) / 180);
395 }
396 
397 pragma(inline, true) double qDegreesToRadians(double degrees)
398 {
399     static if(!versionIsSet!("Windows") || defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || versionIsSet!("Cygwin") || !defined!"__STRICT_ANSI__")
400         import libc.math;
401 
402     return degrees * ( mixin(((versionIsSet!("Windows") && !versionIsSet!("Cygwin") && (defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || !defined!"__STRICT_ANSI__"))) ? q{
403             M_PI
404         } : ((!versionIsSet!("Windows") || versionIsSet!("Cygwin"))) ? q{
405         M_PI
406         } : ((versionIsSet!("Windows") && !defined!"M_PI" && !defined!"_BSD_SOURCE" && !defined!"_GNU_SOURCE" && !defined!"_POSIX_C_SOURCE" && !defined!"_POSIX_SOURCE" && !defined!"_USE_MATH_DEFINES" && !defined!"_XOPEN_SOURCE" && !versionIsSet!("Cygwin") && defined!"__STRICT_ANSI__")) ? q{
407         M_PI
408         } : q{
409         M_PI
410         }) / 180);
411 }
412 
413 pragma(inline, true) real  qDegreesToRadians(real  degrees)
414 {
415     static if(!versionIsSet!("Windows") || defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || versionIsSet!("Cygwin") || !defined!"__STRICT_ANSI__")
416         import libc.math;
417 
418     return degrees * ( mixin(((versionIsSet!("Windows") && !versionIsSet!("Cygwin") && (defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || !defined!"__STRICT_ANSI__"))) ? q{
419             M_PI
420         } : ((!versionIsSet!("Windows") || versionIsSet!("Cygwin"))) ? q{
421         M_PI
422         } : ((versionIsSet!("Windows") && !defined!"M_PI" && !defined!"_BSD_SOURCE" && !defined!"_GNU_SOURCE" && !defined!"_POSIX_C_SOURCE" && !defined!"_POSIX_SOURCE" && !defined!"_USE_MATH_DEFINES" && !defined!"_XOPEN_SOURCE" && !versionIsSet!("Cygwin") && defined!"__STRICT_ANSI__")) ? q{
423         M_PI
424         } : q{
425         M_PI
426         }) / 180);
427 }
428 
429 pragma(inline, true) double qDegreesToRadians(T, /+ std::enable_if_t<std::is_integral_v<T>, bool> +/ /+ = true +/)(T degrees)
430 {
431     return qDegreesToRadians(static_cast!(double)(degrees));
432 }
433 
434 pragma(inline, true) float qRadiansToDegrees(float radians)
435 {
436     static if(!versionIsSet!("Windows") || defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || versionIsSet!("Cygwin") || !defined!"__STRICT_ANSI__")
437         import libc.math;
438 
439     return radians * float(180 / mixin(((versionIsSet!("Windows") && !versionIsSet!("Cygwin") && (defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || !defined!"__STRICT_ANSI__"))) ? q{
440             M_PI
441         } : ((!versionIsSet!("Windows") || versionIsSet!("Cygwin"))) ? q{
442         M_PI
443         } : ((versionIsSet!("Windows") && !defined!"M_PI" && !defined!"_BSD_SOURCE" && !defined!"_GNU_SOURCE" && !defined!"_POSIX_C_SOURCE" && !defined!"_POSIX_SOURCE" && !defined!"_USE_MATH_DEFINES" && !defined!"_XOPEN_SOURCE" && !versionIsSet!("Cygwin") && defined!"__STRICT_ANSI__")) ? q{
444         M_PI
445         } : q{
446         M_PI
447         }));
448 }
449 
450 pragma(inline, true) double qRadiansToDegrees(double radians)
451 {
452     static if(!versionIsSet!("Windows") || defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || versionIsSet!("Cygwin") || !defined!"__STRICT_ANSI__")
453         import libc.math;
454 
455     return radians * (180 / mixin(((versionIsSet!("Windows") && !versionIsSet!("Cygwin") && (defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || !defined!"__STRICT_ANSI__"))) ? q{
456             M_PI
457         } : ((!versionIsSet!("Windows") || versionIsSet!("Cygwin"))) ? q{
458         M_PI
459         } : ((versionIsSet!("Windows") && !defined!"M_PI" && !defined!"_BSD_SOURCE" && !defined!"_GNU_SOURCE" && !defined!"_POSIX_C_SOURCE" && !defined!"_POSIX_SOURCE" && !defined!"_USE_MATH_DEFINES" && !defined!"_XOPEN_SOURCE" && !versionIsSet!("Cygwin") && defined!"__STRICT_ANSI__")) ? q{
460         M_PI
461         } : q{
462         M_PI
463         }));
464 }
465 
466 pragma(inline, true) real  qRadiansToDegrees(real  radians)
467 {
468     static if(!versionIsSet!("Windows") || defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || versionIsSet!("Cygwin") || !defined!"__STRICT_ANSI__")
469         import libc.math;
470 
471     return radians * (180 / mixin(((versionIsSet!("Windows") && !versionIsSet!("Cygwin") && (defined!"_BSD_SOURCE" || defined!"_GNU_SOURCE" || defined!"_POSIX_C_SOURCE" || defined!"_POSIX_SOURCE" || defined!"_USE_MATH_DEFINES" || defined!"_XOPEN_SOURCE" || !defined!"__STRICT_ANSI__"))) ? q{
472             M_PI
473         } : ((!versionIsSet!("Windows") || versionIsSet!("Cygwin"))) ? q{
474         M_PI
475         } : ((versionIsSet!("Windows") && !defined!"M_PI" && !defined!"_BSD_SOURCE" && !defined!"_GNU_SOURCE" && !defined!"_POSIX_C_SOURCE" && !defined!"_POSIX_SOURCE" && !defined!"_USE_MATH_DEFINES" && !defined!"_XOPEN_SOURCE" && !versionIsSet!("Cygwin") && defined!"__STRICT_ANSI__")) ? q{
476         M_PI
477         } : q{
478         M_PI
479         }));
480 }+/
481 
482 // A qRadiansToDegrees(Integral) overload isn't here; it's extremely
483 // questionable that someone is manipulating quantities in radians
484 // using integral datatypes...
485 
486 extern(C++, "QtPrivate") {
487 pragma(inline, true) quint32 qConstexprNextPowerOfTwo(quint32 v)
488 {
489     v |= v >> 1;
490     v |= v >> 2;
491     v |= v >> 4;
492     v |= v >> 8;
493     v |= v >> 16;
494     ++v;
495     return v;
496 }
497 
498 pragma(inline, true) quint64 qConstexprNextPowerOfTwo(quint64 v)
499 {
500     v |= v >> 1;
501     v |= v >> 2;
502     v |= v >> 4;
503     v |= v >> 8;
504     v |= v >> 16;
505     v |= v >> 32;
506     ++v;
507     return v;
508 }
509 
510 pragma(inline, true) quint32 qConstexprNextPowerOfTwo(qint32 v)
511 {
512     return qConstexprNextPowerOfTwo(quint32(v));
513 }
514 
515 pragma(inline, true) quint64 qConstexprNextPowerOfTwo(qint64 v)
516 {
517     return qConstexprNextPowerOfTwo(quint64(v));
518 }
519 } // namespace QtPrivate
520 
521 /+pragma(inline, true) quint32 qNextPowerOfTwo(quint32 v)
522 {
523 /+ #if defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L +/
524     static if((configValue!"__cpp_lib_int_pow2" >= 202002 && defined!"__cpp_lib_int_pow2"))
525     {
526         return /+ std:: +/bit_ceil(v + 1);
527     }
528     else
529     {
530     /+ #elif defined(QT_HAS_BUILTIN_CLZ) +/
531         if (v == 0)
532             return 1;
533         return 2U << (31 ^ /+ QAlgorithmsPrivate:: +/qt_builtin_clz(v));
534     }
535 /+ #else
536     return QtPrivate::qConstexprNextPowerOfTwo(v);
537 #endif +/
538 }+/
539 
540 /+pragma(inline, true) quint64 qNextPowerOfTwo(quint64 v)
541 {
542 /+ #if defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L +/
543     static if((configValue!"__cpp_lib_int_pow2" >= 202002 && defined!"__cpp_lib_int_pow2"))
544     {
545         return /+ std:: +/bit_ceil(v + 1);
546     }
547     else
548     {
549     /+ #elif defined(QT_HAS_BUILTIN_CLZLL) +/
550         if (v == 0)
551             return 1;
552         return 2uL << (63 ^ /+ QAlgorithmsPrivate:: +/qt_builtin_clzll(v));
553     }
554 /+ #else
555     return QtPrivate::qConstexprNextPowerOfTwo(v);
556 #endif +/
557 }+/
558 
559 pragma(inline, true) quint32 qNextPowerOfTwo(qint32 v)
560 {
561     return qNextPowerOfTwo(quint32(v));
562 }
563 
564 pragma(inline, true) quint64 qNextPowerOfTwo(qint64 v)
565 {
566     return qNextPowerOfTwo(quint64(v));
567 }
568