Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qjsnumbercoercion.h
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QJSNUMBERCOERCION_H
5#define QJSNUMBERCOERCION_H
6
7#include <QtCore/qglobal.h>
8#include <cstring>
9
11
13{
14public:
15
16 static constexpr bool isInteger(double d)
17 {
18 // Comparing d with itself checks for NaN and comparing d with the min and max values
19 // for int also covers infinities.
20 if (!equals(d, d) || d < (std::numeric_limits<int>::min)()
21 || d > (std::numeric_limits<int>::max)()) {
22 return false;
23 }
24
25 return equals(static_cast<int>(d), d);
26 }
27
28 static constexpr bool isArrayIndex(double d)
29 {
30 return d >= 0
31 && equals(d, d)
32 && d <= (std::numeric_limits<uint>::max)()
33 && equals(static_cast<uint>(d), d);
34 }
35
36 static constexpr bool isArrayIndex(qint64 i)
37 {
38 return i >= 0 && i <= (std::numeric_limits<uint>::max)();
39 }
40
41 static constexpr bool isArrayIndex(quint64 i)
42 {
43 return i <= (std::numeric_limits<uint>::max)();
44 }
45
46 static constexpr int toInteger(double d) {
47 // Check for NaN
48 if (!equals(d, d))
49 return 0;
50
51 if (d >= (std::numeric_limits<int>::min)() && d <= (std::numeric_limits<int>::max)()) {
52 const int i = static_cast<int>(d);
53 if (equals(i, d))
54 return i;
55 }
56
58 }
59
60 static constexpr bool equals(double lhs, double rhs)
61 {
64 return lhs == rhs;
66 }
67
68private:
69 constexpr QJSNumberCoercion(double dbl)
70 {
71 // the dbl == 0 path is guaranteed constexpr. The other one may or may not be, depending
72 // on whether and how the compiler inlines the memcpy.
73 // In order to declare the ctor constexpr we need one guaranteed constexpr path.
74 if (!equals(dbl, 0))
75 memcpy(&d, &dbl, sizeof(double));
76 }
77
78 constexpr int sign() const
79 {
80 return (d >> 63) ? -1 : 1;
81 }
82
83 constexpr bool isDenormal() const
84 {
85 return static_cast<int>((d << 1) >> 53) == 0;
86 }
87
88 constexpr int exponent() const
89 {
90 return static_cast<int>((d << 1) >> 53) - 1023;
91 }
92
93 constexpr quint64 significant() const
94 {
95 quint64 m = (d << 12) >> 12;
96 if (!isDenormal())
97 m |= (static_cast<quint64>(1) << 52);
98 return m;
99 }
100
101 constexpr int toInteger()
102 {
103 int e = exponent() - 52;
104 if (e < 0) {
105 if (e <= -53)
106 return 0;
107 return sign() * static_cast<int>(significant() >> -e);
108 } else {
109 if (e > 31)
110 return 0;
111 return sign() * (static_cast<int>(significant()) << e);
112 }
113 }
114
115 quint64 d = 0;
116};
117
119
120#endif // QJSNUMBERCOERCION_H
Implements the JavaScript double-to-int coercion.
static constexpr bool isArrayIndex(qint64 i)
static constexpr bool equals(double lhs, double rhs)
static constexpr bool isArrayIndex(double d)
static constexpr int toInteger(double d)
static constexpr bool isInteger(double d)
static constexpr bool isArrayIndex(quint64 i)
Combined button and popup list for selecting options.
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_FLOAT_COMPARE
#define QT_WARNING_PUSH
const GLfloat * m
GLint * exponent
unsigned long long quint64
Definition qtypes.h:61
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60