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