diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index dc3d9f37862..0157c74ab47 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -17,7 +17,7 @@ concurrency: jobs: build-linux: - runs-on: ubuntu-20.04 + runs-on: ${{ matrix.os || 'ubuntu-20.04' }} name: ${{ matrix.name }} strategy: fail-fast: false @@ -71,6 +71,18 @@ jobs: # Skip 2GiB artifact speeding up action. artifact: false + - name: Editor with C++20 (target=editor, tests=yes, dev_build=yes, cpp_standard=20) + cache-name: linux-editor-cpp20 + target: editor + tests: true + sconsflags: dev_build=yes cpp_standard=20 + bin: ./bin/godot.linuxbsd.editor.dev.x86_64 + build-mono: false + # Skip 2GiB artifact speeding up action. + artifact: false + # Ensure a later version of Ubuntu for full C++20 support. + os: ubuntu-24.04 + - name: Template w/ Mono (target=template_release, tests=yes) cache-name: linux-template-mono target: template_release diff --git a/SConstruct b/SConstruct index 63cff4fe167..c5fcb8b32fe 100644 --- a/SConstruct +++ b/SConstruct @@ -213,6 +213,7 @@ opts.Add(BoolVariable("debug_paths_relative", "Make file paths in debug symbols opts.Add(EnumVariable("lto", "Link-time optimization (production builds)", "none", ("none", "auto", "thin", "full"))) opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False)) opts.Add(BoolVariable("threads", "Enable threading support", True)) +opts.Add(EnumVariable("cpp_standard", "Set the C++ standard (Experimental)", "17", ("17", "20", "23"))) # Components opts.Add(BoolVariable("deprecated", "Enable compatibility code for deprecated and removed features", True)) @@ -643,14 +644,28 @@ cc_version = methods.get_compiler_version(env) cc_version_major = cc_version["major"] cc_version_minor = cc_version["minor"] cc_version_metadata1 = cc_version["metadata1"] +cpp_std = int(env["cpp_standard"]) if cc_version_major == -1: print_warning( "Couldn't detect compiler version, skipping version checks. " - "Build may fail if the compiler doesn't support C++17 fully." + f"Build may fail if the compiler doesn't support C++{cpp_std} fully." + ) +elif cpp_std == 23: + print_warning( + "Using an experimental C++ standard, skipping version checks. " + "Build may fail if the compiler doesn't support the latest C++ fully." ) elif methods.using_gcc(env): - if cc_version_major < 9: + if cpp_std == 20 and cc_version_major < 12: + print_error( + "Detected GCC version older than 12, which does not fully support " + "C++20. Supported versions are GCC 12 and later. Use a newer GCC " + 'version, or Clang 17 or later by passing "use_llvm=yes" to the ' + "SCons command line." + ) + Exit(255) + elif cpp_std == 17 and cc_version_major < 9: print_error( "Detected GCC version older than 9, which does not fully support " "C++17, or has bugs when compiling Godot. Supported versions are 9 " @@ -674,13 +689,27 @@ elif methods.using_clang(env): # in https://en.wikipedia.org/wiki/Xcode#Toolchain_versions if env["platform"] == "macos" or env["platform"] == "ios": vanilla = methods.is_vanilla_clang(env) - if vanilla and cc_version_major < 6: + if cpp_std == 20 and vanilla and cc_version_major < 17: + print_error( + "Detected Clang version older than 17, which does not fully support " + "C++20. Supported versions are Clang 17 and later." + ) + Exit(255) + # XCode started defaulting to c++20 in XCode 14, despite their equivalent Clang + # being 14. Assume 14 as the "minimum" version, but full support is uncertain. + elif cpp_std == 20 and not vanilla and cc_version_major < 14: + print_error( + "Detected Apple Clang version older than 14, which does not fully " + 'support C++20. "Supported" versions are Apple Clang 14 and later.' + ) + Exit(255) + elif cpp_std == 17 and vanilla and cc_version_major < 6: print_error( "Detected Clang version older than 6, which does not fully support " "C++17. Supported versions are Clang 6 and later." ) Exit(255) - elif not vanilla and cc_version_major < 10: + elif cpp_std == 17 and not vanilla and cc_version_major < 10: print_error( "Detected Apple Clang version older than 10, which does not fully " "support C++17. Supported versions are Apple Clang 10 and later." @@ -691,7 +720,13 @@ elif methods.using_clang(env): "Apple Clang < 12 doesn't support -ffile-prefix-map, disabling `debug_paths_relative` option." ) env["debug_paths_relative"] = False - elif cc_version_major < 6: + elif cpp_std == 20 and cc_version_major < 17: + print_error( + "Detected Clang version older than 17, which does not fully support " + "C++20. Supported versions are Clang 17 and later." + ) + Exit(255) + elif cpp_std == 17 and cc_version_major < 6: print_error( "Detected Clang version older than 6, which does not fully support " "C++17. Supported versions are Clang 6 and later." @@ -703,19 +738,25 @@ elif methods.using_clang(env): elif env.msvc: # Ensure latest minor builds of Visual Studio 2017/2019. # https://github.com/godotengine/godot/pull/94995#issuecomment-2336464574 - if cc_version_major == 16 and cc_version_minor < 11: + if cpp_std == 20 and cc_version_major < 16: + print_error( + "Detected Visual Studio version older than 2019, which does not fully " + "support C++20. Supported versions are Visual Studio 2019 and later." + ) + Exit(255) + elif cc_version_major == 16 and cc_version_minor < 11: print_error( "Detected Visual Studio 2019 version older than 16.11, which has bugs " "when compiling Godot. Use a newer VS2019 version, or VS2022." ) Exit(255) - if cc_version_major == 15 and cc_version_minor < 9: + elif cc_version_major == 15 and cc_version_minor < 9: print_error( "Detected Visual Studio 2017 version older than 15.9, which has bugs " "when compiling Godot. Use a newer VS2017 version, or VS2019/VS2022." ) Exit(255) - if cc_version_major < 15: + elif cc_version_major < 15: print_error( "Detected Visual Studio 2015 or earlier, which is unsupported in Godot. " "Supported versions are Visual Studio 2017 and later." @@ -801,11 +842,11 @@ if not env.msvc: # Specifying GNU extensions support explicitly, which are supported by # both GCC and Clang. Both currently default to gnu11 and gnu++17. env.Prepend(CFLAGS=["-std=gnu11"]) - env.Prepend(CXXFLAGS=["-std=gnu++17"]) + env.Prepend(CXXFLAGS=[f"-std=gnu++{cpp_std if cpp_std <= 20 else '2b'}"]) else: # MSVC started offering C standard support with Visual Studio 2019 16.8, which covers all # of our supported VS2019 & VS2022 versions; VS2017 will only pass the C++ standard. - env.Prepend(CXXFLAGS=["/std:c++17"]) + env.Prepend(CXXFLAGS=[f"/std:c++{cpp_std if cpp_std <= 20 else 'latest'}"]) if cc_version_major < 16: print_warning("Visual Studio 2017 cannot specify a C-Standard.") else: diff --git a/core/io/image.cpp b/core/io/image.cpp index aa391b77dd4..bb9cbb603af 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -873,7 +873,7 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict for (uint32_t i = 0; i < p_dst_height; i++) { // Add 0.5 in order to interpolate based on pixel center - uint32_t src_yofs_up_fp = (i + 0.5) * p_src_height * FRAC_LEN / p_dst_height; + uint32_t src_yofs_up_fp = (i + 0.5) * p_src_height * (int)FRAC_LEN / p_dst_height; // Calculate nearest src pixel center above current, and truncate to get y index uint32_t src_yofs_up = src_yofs_up_fp >= FRAC_HALF ? (src_yofs_up_fp - FRAC_HALF) >> FRAC_BITS : 0; uint32_t src_yofs_down = (src_yofs_up_fp + FRAC_HALF) >> FRAC_BITS; @@ -888,7 +888,7 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict uint32_t y_ofs_down = src_yofs_down * p_src_width * CC; for (uint32_t j = 0; j < p_dst_width; j++) { - uint32_t src_xofs_left_fp = (j + 0.5) * p_src_width * FRAC_LEN / p_dst_width; + uint32_t src_xofs_left_fp = (j + 0.5) * p_src_width * (int)FRAC_LEN / p_dst_width; uint32_t src_xofs_left = src_xofs_left_fp >= FRAC_HALF ? (src_xofs_left_fp - FRAC_HALF) >> FRAC_BITS : 0; uint32_t src_xofs_right = (src_xofs_left_fp + FRAC_HALF) >> FRAC_BITS; if (src_xofs_right >= p_src_width) { diff --git a/core/io/ip_address.h b/core/io/ip_address.h index da7b0f77db1..fb790dc5608 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -64,21 +64,10 @@ public: } return true; } + INEQUALITY_OPERATOR(const IPAddress &) - bool operator!=(const IPAddress &p_ip) const { - if (p_ip.valid != valid) { - return true; - } - if (!valid) { - return true; - } - for (int i = 0; i < 4; i++) { - if (field32[i] != p_ip.field32[i]) { - return true; - } - } - return false; - } + bool operator==(const String &p_ip) const { return operator==(IPAddress(p_ip)); } + INEQUALITY_OPERATOR(const String &) void clear(); bool is_wildcard() const { return wildcard; } diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp index 7d1d7c5648b..ee0e2b23d0d 100644 --- a/core/math/aabb.cpp +++ b/core/math/aabb.cpp @@ -41,10 +41,6 @@ bool AABB::operator==(const AABB &p_rval) const { return ((position == p_rval.position) && (size == p_rval.size)); } -bool AABB::operator!=(const AABB &p_rval) const { - return ((position != p_rval.position) || (size != p_rval.size)); -} - void AABB::merge_with(const AABB &p_aabb) { #ifdef MATH_CHECKS if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) { diff --git a/core/math/aabb.h b/core/math/aabb.h index 7a5581b5d45..409c1be24fd 100644 --- a/core/math/aabb.h +++ b/core/math/aabb.h @@ -60,7 +60,7 @@ struct [[nodiscard]] AABB { void set_size(const Vector3 &p_size) { size = p_size; } bool operator==(const AABB &p_rval) const; - bool operator!=(const AABB &p_rval) const; + INEQUALITY_OPERATOR(const AABB &) bool is_equal_approx(const AABB &p_aabb) const; bool is_finite() const; diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h index e205126cdf6..bd57fdc2c18 100644 --- a/core/math/audio_frame.h +++ b/core/math/audio_frame.h @@ -34,7 +34,7 @@ #include "core/math/vector2.h" #include "core/typedefs.h" -static inline float undenormalize(volatile float f) { +static inline float undenormalize(float f) { union { uint32_t i; float f; diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 34ed1c2d855..3660f9f6a7d 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -710,10 +710,6 @@ bool Basis::operator==(const Basis &p_matrix) const { return true; } -bool Basis::operator!=(const Basis &p_matrix) const { - return (!(*this == p_matrix)); -} - Basis::operator String() const { return "[X: " + get_column(0).operator String() + ", Y: " + get_column(1).operator String() + diff --git a/core/math/basis.h b/core/math/basis.h index 236d6661033..5f7ec12d33c 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -124,7 +124,7 @@ struct [[nodiscard]] Basis { bool is_finite() const; bool operator==(const Basis &p_matrix) const; - bool operator!=(const Basis &p_matrix) const; + INEQUALITY_OPERATOR(const Basis &) _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const; _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_vector) const; diff --git a/core/math/bvh_abb.h b/core/math/bvh_abb.h index 3d32c250c96..86888174d01 100644 --- a/core/math/bvh_abb.h +++ b/core/math/bvh_abb.h @@ -58,7 +58,7 @@ struct BVH_ABB { POINT neg_max; bool operator==(const BVH_ABB &o) const { return (min == o.min) && (neg_max == o.neg_max); } - bool operator!=(const BVH_ABB &o) const { return (*this == o) == false; } + INEQUALITY_OPERATOR(const BVH_ABB &) void set(const POINT &_min, const POINT &_max) { min = _min; diff --git a/core/math/bvh_tree.h b/core/math/bvh_tree.h index 0faa50555fb..dee1f9f8605 100644 --- a/core/math/bvh_tree.h +++ b/core/math/bvh_tree.h @@ -102,7 +102,7 @@ struct BVHHandle { void set_id(uint32_t p_id) { _data = p_id; } bool operator==(const BVHHandle &p_h) const { return _data == p_h._data; } - bool operator!=(const BVHHandle &p_h) const { return (*this == p_h) == false; } + INEQUALITY_OPERATOR(const BVHHandle &) }; // helper class to make iterative versions of recursive functions diff --git a/core/math/color.h b/core/math/color.h index 70fad78acbd..b091e2f7373 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -72,9 +72,7 @@ struct [[nodiscard]] Color { bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); } - bool operator!=(const Color &p_color) const { - return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); - } + INEQUALITY_OPERATOR(const Color &) Color operator+(const Color &p_color) const; void operator+=(const Color &p_color); diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp index 620a7541e45..717d86f3c54 100644 --- a/core/math/convex_hull.cpp +++ b/core/math/convex_hull.cpp @@ -40,6 +40,7 @@ * - adapted to Godot's code style * - replaced Bullet's types (e.g. vectors) with Godot's * - replaced custom Pool implementation with PagedAllocator + * - replaced Point32's inequality operator with macro */ /* @@ -139,9 +140,7 @@ public: return (x == b.x) && (y == b.y) && (z == b.z); } - bool operator!=(const Point32 &b) const { - return (x != b.x) || (y != b.y) || (z != b.z); - } + INEQUALITY_OPERATOR(const Point32 &) bool is_zero() { return (x == 0) && (y == 0) && (z == 0); diff --git a/core/math/plane.h b/core/math/plane.h index 6529fea60ac..984b5e41084 100644 --- a/core/math/plane.h +++ b/core/math/plane.h @@ -77,7 +77,7 @@ struct [[nodiscard]] Plane { bool is_finite() const; _FORCE_INLINE_ bool operator==(const Plane &p_plane) const; - _FORCE_INLINE_ bool operator!=(const Plane &p_plane) const; + INEQUALITY_OPERATOR(const Plane &) operator String() const; _FORCE_INLINE_ Plane() {} @@ -129,8 +129,4 @@ bool Plane::operator==(const Plane &p_plane) const { return normal == p_plane.normal && d == p_plane.d; } -bool Plane::operator!=(const Plane &p_plane) const { - return normal != p_plane.normal || d != p_plane.d; -} - #endif // PLANE_H diff --git a/core/math/projection.h b/core/math/projection.h index 5af43561c0c..74e62e645b0 100644 --- a/core/math/projection.h +++ b/core/math/projection.h @@ -143,10 +143,7 @@ struct [[nodiscard]] Projection { } return true; } - - bool operator!=(const Projection &p_cam) const { - return !(*this == p_cam); - } + INEQUALITY_OPERATOR(const Projection &) real_t get_lod_multiplier() const; diff --git a/core/math/quaternion.h b/core/math/quaternion.h index 655e55e0a20..0a1927d065f 100644 --- a/core/math/quaternion.h +++ b/core/math/quaternion.h @@ -111,7 +111,7 @@ struct [[nodiscard]] Quaternion { _FORCE_INLINE_ Quaternion operator/(real_t p_s) const; _FORCE_INLINE_ bool operator==(const Quaternion &p_quaternion) const; - _FORCE_INLINE_ bool operator!=(const Quaternion &p_quaternion) const; + INEQUALITY_OPERATOR(const Quaternion &) operator String() const; @@ -221,10 +221,6 @@ bool Quaternion::operator==(const Quaternion &p_quaternion) const { return x == p_quaternion.x && y == p_quaternion.y && z == p_quaternion.z && w == p_quaternion.w; } -bool Quaternion::operator!=(const Quaternion &p_quaternion) const { - return x != p_quaternion.x || y != p_quaternion.y || z != p_quaternion.z || w != p_quaternion.w; -} - _FORCE_INLINE_ Quaternion operator*(real_t p_real, const Quaternion &p_quaternion) { return p_quaternion * p_real; } diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp index c55226a57ec..412f0dd49ba 100644 --- a/core/math/rect2.cpp +++ b/core/math/rect2.cpp @@ -42,6 +42,10 @@ bool Rect2::is_finite() const { return position.is_finite() && size.is_finite(); } +bool Rect2::operator==(const Rect2i &p_rect) const { + return position == p_rect.get_position() && size == p_rect.get_position(); +} + bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const { #ifdef MATH_CHECKS if (unlikely(size.x < 0 || size.y < 0)) { diff --git a/core/math/rect2.h b/core/math/rect2.h index 817923c1348..97d796a112a 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -206,7 +206,9 @@ struct [[nodiscard]] Rect2 { bool is_finite() const; bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } - bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } + INEQUALITY_OPERATOR(const Rect2 &) + bool operator==(const Rect2i &p_rect) const; + INEQUALITY_OPERATOR(const Rect2i &) inline Rect2 grow(real_t p_amount) const { Rect2 g = *this; diff --git a/core/math/rect2i.h b/core/math/rect2i.h index 5f3a3d54f5d..96a3560e1da 100644 --- a/core/math/rect2i.h +++ b/core/math/rect2i.h @@ -145,7 +145,7 @@ struct [[nodiscard]] Rect2i { } bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; } - bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } + INEQUALITY_OPERATOR(const Rect2i &) Rect2i grow(int p_amount) const { Rect2i g = *this; diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index f6525fe5caf..5e8ed0f1cd8 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -201,16 +201,6 @@ bool Transform2D::operator==(const Transform2D &p_transform) const { return true; } -bool Transform2D::operator!=(const Transform2D &p_transform) const { - for (int i = 0; i < 3; i++) { - if (columns[i] != p_transform.columns[i]) { - return true; - } - } - - return false; -} - void Transform2D::operator*=(const Transform2D &p_transform) { columns[2] = xform(p_transform.columns[2]); diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 1ee7d3d84f7..6e2631bb0a7 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -106,7 +106,7 @@ struct [[nodiscard]] Transform2D { Transform2D looking_at(const Vector2 &p_target) const; bool operator==(const Transform2D &p_transform) const; - bool operator!=(const Transform2D &p_transform) const; + INEQUALITY_OPERATOR(const Transform2D &) void operator*=(const Transform2D &p_transform); Transform2D operator*(const Transform2D &p_transform) const; diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp index 2c91a7604b0..be7efdd9627 100644 --- a/core/math/transform_3d.cpp +++ b/core/math/transform_3d.cpp @@ -182,10 +182,6 @@ bool Transform3D::operator==(const Transform3D &p_transform) const { return (basis == p_transform.basis && origin == p_transform.origin); } -bool Transform3D::operator!=(const Transform3D &p_transform) const { - return (basis != p_transform.basis || origin != p_transform.origin); -} - void Transform3D::operator*=(const Transform3D &p_transform) { origin = xform(p_transform.origin); basis *= p_transform.basis; diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h index b1de233445e..560559f75a7 100644 --- a/core/math/transform_3d.h +++ b/core/math/transform_3d.h @@ -78,7 +78,7 @@ struct [[nodiscard]] Transform3D { bool is_finite() const; bool operator==(const Transform3D &p_transform) const; - bool operator!=(const Transform3D &p_transform) const; + INEQUALITY_OPERATOR(const Transform3D &) _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const; _FORCE_INLINE_ AABB xform(const AABB &p_aabb) const; diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index e86b97d6a80..d3b5e17cd6e 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -209,3 +209,7 @@ Vector2::operator String() const { Vector2::operator Vector2i() const { return Vector2i(x, y); } + +bool Vector2::operator==(const Vector2i &p_vec2) const { + return operator==((Vector2)p_vec2); +} diff --git a/core/math/vector2.h b/core/math/vector2.h index edb47db6fd3..bf5567b31b3 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -152,7 +152,9 @@ struct [[nodiscard]] Vector2 { Vector2 operator-() const; bool operator==(const Vector2 &p_vec2) const; - bool operator!=(const Vector2 &p_vec2) const; + INEQUALITY_OPERATOR(const Vector2 &) + bool operator==(const Vector2i &p_vec2) const; + INEQUALITY_OPERATOR(const Vector2i &) bool operator<(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y < p_vec2.y) : (x < p_vec2.x); } bool operator>(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y > p_vec2.y) : (x > p_vec2.x); } @@ -247,10 +249,6 @@ _FORCE_INLINE_ bool Vector2::operator==(const Vector2 &p_vec2) const { return x == p_vec2.x && y == p_vec2.y; } -_FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const { - return x != p_vec2.x || y != p_vec2.y; -} - Vector2 Vector2::lerp(const Vector2 &p_to, real_t p_weight) const { Vector2 res = *this; res.x = Math::lerp(res.x, p_to.x, p_weight); diff --git a/core/math/vector2i.cpp b/core/math/vector2i.cpp index 790f5647349..301cbac5380 100644 --- a/core/math/vector2i.cpp +++ b/core/math/vector2i.cpp @@ -130,10 +130,6 @@ bool Vector2i::operator==(const Vector2i &p_vec2) const { return x == p_vec2.x && y == p_vec2.y; } -bool Vector2i::operator!=(const Vector2i &p_vec2) const { - return x != p_vec2.x || y != p_vec2.y; -} - Vector2i::operator String() const { return "(" + itos(x) + ", " + itos(y) + ")"; } diff --git a/core/math/vector2i.h b/core/math/vector2i.h index fff9b0a658f..3c44079918f 100644 --- a/core/math/vector2i.h +++ b/core/math/vector2i.h @@ -126,7 +126,7 @@ struct [[nodiscard]] Vector2i { bool operator>=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); } bool operator==(const Vector2i &p_vec2) const; - bool operator!=(const Vector2i &p_vec2) const; + INEQUALITY_OPERATOR(const Vector2i &) int64_t length_squared() const; double length() const; diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 1e900026651..98ccc62711c 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -171,3 +171,7 @@ Vector3::operator String() const { Vector3::operator Vector3i() const { return Vector3i(x, y, z); } + +bool Vector3::operator==(const Vector3i &p_vec3) const { + return operator==((Vector3)p_vec3); +} diff --git a/core/math/vector3.h b/core/math/vector3.h index 14bc44c4e79..33666fd07bf 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -177,12 +177,15 @@ struct [[nodiscard]] Vector3 { _FORCE_INLINE_ Vector3 operator-() const; _FORCE_INLINE_ bool operator==(const Vector3 &p_v) const; - _FORCE_INLINE_ bool operator!=(const Vector3 &p_v) const; + INEQUALITY_OPERATOR(const Vector3 &) _FORCE_INLINE_ bool operator<(const Vector3 &p_v) const; _FORCE_INLINE_ bool operator<=(const Vector3 &p_v) const; _FORCE_INLINE_ bool operator>(const Vector3 &p_v) const; _FORCE_INLINE_ bool operator>=(const Vector3 &p_v) const; + bool operator==(const Vector3i &p_vec3) const; + INEQUALITY_OPERATOR(const Vector3i &) + operator String() const; operator Vector3i() const; @@ -421,10 +424,6 @@ bool Vector3::operator==(const Vector3 &p_v) const { return x == p_v.x && y == p_v.y && z == p_v.z; } -bool Vector3::operator!=(const Vector3 &p_v) const { - return x != p_v.x || y != p_v.y || z != p_v.z; -} - bool Vector3::operator<(const Vector3 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { diff --git a/core/math/vector3i.h b/core/math/vector3i.h index 40d0700bf73..96f2c595906 100644 --- a/core/math/vector3i.h +++ b/core/math/vector3i.h @@ -123,7 +123,7 @@ struct [[nodiscard]] Vector3i { _FORCE_INLINE_ Vector3i operator-() const; _FORCE_INLINE_ bool operator==(const Vector3i &p_v) const; - _FORCE_INLINE_ bool operator!=(const Vector3i &p_v) const; + INEQUALITY_OPERATOR(const Vector3i &) _FORCE_INLINE_ bool operator<(const Vector3i &p_v) const; _FORCE_INLINE_ bool operator<=(const Vector3i &p_v) const; _FORCE_INLINE_ bool operator>(const Vector3i &p_v) const; @@ -280,10 +280,6 @@ bool Vector3i::operator==(const Vector3i &p_v) const { return (x == p_v.x && y == p_v.y && z == p_v.z); } -bool Vector3i::operator!=(const Vector3i &p_v) const { - return (x != p_v.x || y != p_v.y || z != p_v.z); -} - bool Vector3i::operator<(const Vector3i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp index b6b914f36da..3c03324afad 100644 --- a/core/math/vector4.cpp +++ b/core/math/vector4.cpp @@ -221,3 +221,7 @@ static_assert(sizeof(Vector4) == 4 * sizeof(real_t)); Vector4::operator Vector4i() const { return Vector4i(x, y, z, w); } + +bool Vector4::operator==(const Vector4i &p_vec4) const { + return operator==((Vector4)p_vec4); +} diff --git a/core/math/vector4.h b/core/math/vector4.h index 9197e3587ab..dbb2faec245 100644 --- a/core/math/vector4.h +++ b/core/math/vector4.h @@ -135,12 +135,15 @@ struct [[nodiscard]] Vector4 { _FORCE_INLINE_ Vector4 operator/(real_t p_s) const; _FORCE_INLINE_ bool operator==(const Vector4 &p_vec4) const; - _FORCE_INLINE_ bool operator!=(const Vector4 &p_vec4) const; + INEQUALITY_OPERATOR(const Vector4 &) _FORCE_INLINE_ bool operator>(const Vector4 &p_vec4) const; _FORCE_INLINE_ bool operator<(const Vector4 &p_vec4) const; _FORCE_INLINE_ bool operator>=(const Vector4 &p_vec4) const; _FORCE_INLINE_ bool operator<=(const Vector4 &p_vec4) const; + bool operator==(const Vector4i &p_vec4) const; + INEQUALITY_OPERATOR(const Vector4i &) + operator String() const; operator Vector4i() const; @@ -231,10 +234,6 @@ bool Vector4::operator==(const Vector4 &p_vec4) const { return x == p_vec4.x && y == p_vec4.y && z == p_vec4.z && w == p_vec4.w; } -bool Vector4::operator!=(const Vector4 &p_vec4) const { - return x != p_vec4.x || y != p_vec4.y || z != p_vec4.z || w != p_vec4.w; -} - bool Vector4::operator<(const Vector4 &p_v) const { if (x == p_v.x) { if (y == p_v.y) { diff --git a/core/math/vector4i.h b/core/math/vector4i.h index a9036d684ab..dc15d2ff34e 100644 --- a/core/math/vector4i.h +++ b/core/math/vector4i.h @@ -125,7 +125,7 @@ struct [[nodiscard]] Vector4i { _FORCE_INLINE_ Vector4i operator-() const; _FORCE_INLINE_ bool operator==(const Vector4i &p_v) const; - _FORCE_INLINE_ bool operator!=(const Vector4i &p_v) const; + INEQUALITY_OPERATOR(const Vector4i &) _FORCE_INLINE_ bool operator<(const Vector4i &p_v) const; _FORCE_INLINE_ bool operator<=(const Vector4i &p_v) const; _FORCE_INLINE_ bool operator>(const Vector4i &p_v) const; @@ -292,10 +292,6 @@ bool Vector4i::operator==(const Vector4i &p_v) const { return (x == p_v.x && y == p_v.y && z == p_v.z && w == p_v.w); } -bool Vector4i::operator!=(const Vector4i &p_v) const { - return (x != p_v.x || y != p_v.y || z != p_v.z || w != p_v.w); -} - bool Vector4i::operator<(const Vector4i &p_v) const { if (x == p_v.x) { if (y == p_v.y) { diff --git a/core/object/object_id.h b/core/object/object_id.h index 7b677cb05b8..a6991754ebd 100644 --- a/core/object/object_id.h +++ b/core/object/object_id.h @@ -49,7 +49,7 @@ public: _ALWAYS_INLINE_ operator int64_t() const { return id; } _ALWAYS_INLINE_ bool operator==(const ObjectID &p_id) const { return id == p_id.id; } - _ALWAYS_INLINE_ bool operator!=(const ObjectID &p_id) const { return id != p_id.id; } + INEQUALITY_OPERATOR(const ObjectID &) _ALWAYS_INLINE_ bool operator<(const ObjectID &p_id) const { return id < p_id.id; } _ALWAYS_INLINE_ void operator=(int64_t p_int64) { id = p_int64; } diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h index f0706b4d08f..f8bec120324 100644 --- a/core/object/ref_counted.h +++ b/core/object/ref_counted.h @@ -83,9 +83,8 @@ public: _FORCE_INLINE_ bool operator==(const T *p_ptr) const { return reference == p_ptr; } - _FORCE_INLINE_ bool operator!=(const T *p_ptr) const { - return reference != p_ptr; - } + INEQUALITY_OPERATOR(const T *) + #ifdef STRICT_CHECKS // Delete these to prevent raw comparisons with `nullptr`. bool operator==(std::nullptr_t) const = delete; @@ -98,9 +97,18 @@ public: _FORCE_INLINE_ bool operator==(const Ref &p_r) const { return reference == p_r.reference; } - _FORCE_INLINE_ bool operator!=(const Ref &p_r) const { - return reference != p_r.reference; + INEQUALITY_OPERATOR(const Ref &) + + template + _FORCE_INLINE_ bool operator==(const Ref &p_r) const { + return reference == p_r.ptr(); } + INEQUALITY_OPERATOR_TEMPLATE(const Ref &, typename T_Other) + + _FORCE_INLINE_ bool operator==(const Variant &p_r) const { + return *this == Ref(p_r); + } + INEQUALITY_OPERATOR(const Variant &) _FORCE_INLINE_ T *operator*() const { return reference; diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp index fdc72bc8dcd..e63dbdc242f 100644 --- a/core/string/node_path.cpp +++ b/core/string/node_path.cpp @@ -153,10 +153,6 @@ bool NodePath::operator==(const NodePath &p_path) const { return true; } -bool NodePath::operator!=(const NodePath &p_path) const { - return (!(*this == p_path)); -} - void NodePath::operator=(const NodePath &p_path) { if (this == &p_path) { return; diff --git a/core/string/node_path.h b/core/string/node_path.h index 56799839d76..b5e54e34afe 100644 --- a/core/string/node_path.h +++ b/core/string/node_path.h @@ -83,9 +83,12 @@ public: bool is_empty() const; bool operator==(const NodePath &p_path) const; - bool operator!=(const NodePath &p_path) const; + INEQUALITY_OPERATOR(const NodePath &) void operator=(const NodePath &p_path); + bool operator==(const String &p_path) const { return operator==(NodePath(p_path)); } + INEQUALITY_OPERATOR(const String &) + void simplify(); NodePath simplified() const; diff --git a/core/string/string_name.cpp b/core/string/string_name.cpp index dff19b3a41a..fbb736a0add 100644 --- a/core/string/string_name.cpp +++ b/core/string/string_name.cpp @@ -47,10 +47,6 @@ bool StringName::_Data::operator==(const String &p_name) const { } } -bool StringName::_Data::operator!=(const String &p_name) const { - return !operator==(p_name); -} - bool StringName::_Data::operator==(const char *p_name) const { if (cname) { return strcmp(cname, p_name) == 0; @@ -59,10 +55,6 @@ bool StringName::_Data::operator==(const char *p_name) const { } } -bool StringName::_Data::operator!=(const char *p_name) const { - return !operator==(p_name); -} - StringName _scs_create(const char *p_chr, bool p_static) { return (p_chr[0] ? StringName(StaticCString::create(p_chr), p_static) : StringName()); } @@ -183,20 +175,6 @@ bool StringName::operator==(const char *p_name) const { return p_name[0] == 0; } -bool StringName::operator!=(const String &p_name) const { - return !(operator==(p_name)); -} - -bool StringName::operator!=(const char *p_name) const { - return !(operator==(p_name)); -} - -bool StringName::operator!=(const StringName &p_name) const { - // the real magic of all this mess happens here. - // this is why path comparisons are very fast - return _data != p_name._data; -} - char32_t StringName::operator[](int p_index) const { if (_data) { if (_data->cname) { @@ -541,17 +519,3 @@ StringName StringName::search(const String &p_name) { return StringName(); //does not exist } - -bool operator==(const String &p_name, const StringName &p_string_name) { - return p_string_name.operator==(p_name); -} -bool operator!=(const String &p_name, const StringName &p_string_name) { - return p_string_name.operator!=(p_name); -} - -bool operator==(const char *p_name, const StringName &p_string_name) { - return p_string_name.operator==(p_name); -} -bool operator!=(const char *p_name, const StringName &p_string_name) { - return p_string_name.operator!=(p_name); -} diff --git a/core/string/string_name.h b/core/string/string_name.h index d4b70d311dc..187d6263236 100644 --- a/core/string/string_name.h +++ b/core/string/string_name.h @@ -61,9 +61,9 @@ class StringName { #endif String get_name() const { return cname ? String(cname) : name; } bool operator==(const String &p_name) const; - bool operator!=(const String &p_name) const; + INEQUALITY_OPERATOR(const String &) bool operator==(const char *p_name) const; - bool operator!=(const char *p_name) const; + INEQUALITY_OPERATOR(const char *) int idx = 0; uint32_t hash = 0; @@ -102,8 +102,8 @@ public: bool operator==(const String &p_name) const; bool operator==(const char *p_name) const; - bool operator!=(const String &p_name) const; - bool operator!=(const char *p_name) const; + INEQUALITY_OPERATOR(const String &) + INEQUALITY_OPERATOR(const char *) char32_t operator[](int p_index) const; int length() const; @@ -146,7 +146,7 @@ public: _FORCE_INLINE_ const void *data_unique_pointer() const { return (void *)_data; } - bool operator!=(const StringName &p_name) const; + INEQUALITY_OPERATOR(const StringName &) _FORCE_INLINE_ operator String() const { if (_data) { @@ -204,10 +204,12 @@ public: #endif }; -bool operator==(const String &p_name, const StringName &p_string_name); -bool operator!=(const String &p_name, const StringName &p_string_name); -bool operator==(const char *p_name, const StringName &p_string_name); -bool operator!=(const char *p_name, const StringName &p_string_name); +#if __cplusplus < 202002L +_ALWAYS_INLINE_ bool operator==(const String &p_name, const StringName &p_string_name) { return p_string_name == p_name; } +_ALWAYS_INLINE_ bool operator==(const char *p_name, const StringName &p_string_name) { return p_string_name == p_name; } +INEQUALITY_OPERATOR_GLOBAL(const String &, const StringName &) +INEQUALITY_OPERATOR_GLOBAL(const char *, const StringName &) +#endif StringName _scs_create(const char *p_chr, bool p_static = false); diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 391a203d5b5..ecdcfe1e2af 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -724,50 +724,6 @@ bool String::operator==(const StrRange &p_str_range) const { return true; } -bool operator==(const char *p_chr, const String &p_str) { - return p_str == p_chr; -} - -bool operator==(const wchar_t *p_chr, const String &p_str) { -#ifdef WINDOWS_ENABLED - // wchar_t is 16-bit - return p_str == String::utf16((const char16_t *)p_chr); -#else - // wchar_t is 32-bi - return p_str == String((const char32_t *)p_chr); -#endif -} - -bool operator!=(const char *p_chr, const String &p_str) { - return !(p_str == p_chr); -} - -bool operator!=(const wchar_t *p_chr, const String &p_str) { -#ifdef WINDOWS_ENABLED - // wchar_t is 16-bit - return !(p_str == String::utf16((const char16_t *)p_chr)); -#else - // wchar_t is 32-bi - return !(p_str == String((const char32_t *)p_chr)); -#endif -} - -bool String::operator!=(const char *p_str) const { - return (!(*this == p_str)); -} - -bool String::operator!=(const wchar_t *p_str) const { - return (!(*this == p_str)); -} - -bool String::operator!=(const char32_t *p_str) const { - return (!(*this == p_str)); -} - -bool String::operator!=(const String &p_str) const { - return !((*this == p_str)); -} - bool String::operator<=(const String &p_str) const { return !(p_str < *this); } diff --git a/core/string/ustring.h b/core/string/ustring.h index 5d4b209c252..07330ba62e5 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -228,7 +228,7 @@ public: _FORCE_INLINE_ CharProxy operator[](int p_index) { return CharProxy(p_index, _cowdata); } bool operator==(const String &p_str) const; - bool operator!=(const String &p_str) const; + INEQUALITY_OPERATOR(const String &) String operator+(const String &p_str) const; String operator+(char32_t p_char) const; @@ -249,9 +249,10 @@ public: bool operator==(const char32_t *p_str) const; bool operator==(const StrRange &p_str_range) const; - bool operator!=(const char *p_str) const; - bool operator!=(const wchar_t *p_str) const; - bool operator!=(const char32_t *p_str) const; + INEQUALITY_OPERATOR(const char *) + INEQUALITY_OPERATOR(const wchar_t *) + INEQUALITY_OPERATOR(const char32_t *) + INEQUALITY_OPERATOR(const StrRange &) bool operator<(const char32_t *p_str) const; bool operator<(const char *p_str) const; @@ -498,10 +499,12 @@ public: String(const StrRange &p_range); }; -bool operator==(const char *p_chr, const String &p_str); -bool operator==(const wchar_t *p_chr, const String &p_str); -bool operator!=(const char *p_chr, const String &p_str); -bool operator!=(const wchar_t *p_chr, const String &p_str); +#if __cplusplus < 202002L +_ALWAYS_INLINE_ bool operator==(const char *p_cstr, const String &p_str) { return p_str == p_cstr; } +_ALWAYS_INLINE_ bool operator==(const wchar_t *p_cstr, const String &p_str) { return p_str == p_cstr; } +INEQUALITY_OPERATOR_GLOBAL(const char *, const String &) +INEQUALITY_OPERATOR_GLOBAL(const wchar_t *, const String &) +#endif String operator+(const char *p_chr, const String &p_str); String operator+(const wchar_t *p_chr, const String &p_str); diff --git a/core/templates/hash_map.h b/core/templates/hash_map.h index a3e8c2c788c..aaeb6f2d462 100644 --- a/core/templates/hash_map.h +++ b/core/templates/hash_map.h @@ -429,7 +429,7 @@ public: } _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return E == b.E; } - _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return E != b.E; } + INEQUALITY_OPERATOR(const ConstIterator &) _FORCE_INLINE_ explicit operator bool() const { return E != nullptr; @@ -465,7 +465,7 @@ public: } _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; } - _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; } + INEQUALITY_OPERATOR(const Iterator &) _FORCE_INLINE_ explicit operator bool() const { return E != nullptr; diff --git a/core/templates/hash_set.h b/core/templates/hash_set.h index 295b07e5e7c..5ba95042dbc 100644 --- a/core/templates/hash_set.h +++ b/core/templates/hash_set.h @@ -345,7 +345,7 @@ public: } _FORCE_INLINE_ bool operator==(const Iterator &b) const { return keys == b.keys && index == b.index; } - _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return keys != b.keys || index != b.index; } + INEQUALITY_OPERATOR(const Iterator &) _FORCE_INLINE_ explicit operator bool() const { return keys != nullptr; diff --git a/core/templates/list.h b/core/templates/list.h index 6663f06c309..17922902f41 100644 --- a/core/templates/list.h +++ b/core/templates/list.h @@ -154,7 +154,7 @@ public: } _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return E == b.E; } - _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return E != b.E; } + INEQUALITY_OPERATOR(const ConstIterator &) _FORCE_INLINE_ ConstIterator(const Element *p_E) { E = p_E; } _FORCE_INLINE_ ConstIterator() {} @@ -179,7 +179,7 @@ public: } _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; } - _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; } + INEQUALITY_OPERATOR(const Iterator &) Iterator(Element *p_E) { E = p_E; } Iterator() {} diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h index c281d70d928..e81db4764c5 100644 --- a/core/templates/local_vector.h +++ b/core/templates/local_vector.h @@ -193,7 +193,7 @@ public: } _FORCE_INLINE_ bool operator==(const Iterator &b) const { return elem_ptr == b.elem_ptr; } - _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return elem_ptr != b.elem_ptr; } + INEQUALITY_OPERATOR(const Iterator &) Iterator(T *p_ptr) { elem_ptr = p_ptr; } Iterator() {} @@ -218,7 +218,7 @@ public: } _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return elem_ptr == b.elem_ptr; } - _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return elem_ptr != b.elem_ptr; } + INEQUALITY_OPERATOR(const ConstIterator &) ConstIterator(const T *p_ptr) { elem_ptr = p_ptr; } ConstIterator() {} diff --git a/core/templates/pair.h b/core/templates/pair.h index fd774641c23..f76e58e9639 100644 --- a/core/templates/pair.h +++ b/core/templates/pair.h @@ -47,18 +47,13 @@ struct Pair { first(p_first), second(p_second) { } + + bool operator==(const Pair &other) const { + return (first == other.first) && (second == other.second); + } + INEQUALITY_OPERATOR(const Pair &) }; -template -bool operator==(const Pair &pair, const Pair &other) { - return (pair.first == other.first) && (pair.second == other.second); -} - -template -bool operator!=(const Pair &pair, const Pair &other) { - return (pair.first != other.first) || (pair.second != other.second); -} - template struct PairSort { bool operator()(const Pair &A, const Pair &B) const { @@ -92,18 +87,13 @@ struct KeyValue { key(p_key), value(p_value) { } + + bool operator==(const KeyValue &other) const { + return (key == other.key) && (value == other.value); + } + INEQUALITY_OPERATOR(const KeyValue &) }; -template -bool operator==(const KeyValue &pair, const KeyValue &other) { - return (pair.key == other.key) && (pair.value == other.value); -} - -template -bool operator!=(const KeyValue &pair, const KeyValue &other) { - return (pair.key != other.key) || (pair.value != other.value); -} - template struct KeyValueSort { bool operator()(const KeyValue &A, const KeyValue &B) const { diff --git a/core/templates/rb_map.h b/core/templates/rb_map.h index ef555e4a161..cfdbbefa34a 100644 --- a/core/templates/rb_map.h +++ b/core/templates/rb_map.h @@ -112,7 +112,7 @@ public: } _FORCE_INLINE_ bool operator==(const Iterator &p_it) const { return E == p_it.E; } - _FORCE_INLINE_ bool operator!=(const Iterator &p_it) const { return E != p_it.E; } + INEQUALITY_OPERATOR(const Iterator &) explicit operator bool() const { return E != nullptr; } @@ -144,7 +144,7 @@ public: } _FORCE_INLINE_ bool operator==(const ConstIterator &p_it) const { return E == p_it.E; } - _FORCE_INLINE_ bool operator!=(const ConstIterator &p_it) const { return E != p_it.E; } + INEQUALITY_OPERATOR(const ConstIterator &) explicit operator bool() const { return E != nullptr; } diff --git a/core/templates/rb_set.h b/core/templates/rb_set.h index ac7a8df36a3..867e81f6195 100644 --- a/core/templates/rb_set.h +++ b/core/templates/rb_set.h @@ -97,7 +97,7 @@ public: } _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; } - _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; } + INEQUALITY_OPERATOR(const Iterator &) explicit operator bool() const { return E != nullptr; } Iterator(Element *p_E) { E = p_E; } @@ -123,7 +123,7 @@ public: } _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return E == b.E; } - _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return E != b.E; } + INEQUALITY_OPERATOR(const ConstIterator &) _FORCE_INLINE_ ConstIterator(const Element *p_E) { E = p_E; } _FORCE_INLINE_ ConstIterator() {} diff --git a/core/templates/rid.h b/core/templates/rid.h index 3f6a62ff154..0d433010d91 100644 --- a/core/templates/rid.h +++ b/core/templates/rid.h @@ -55,9 +55,7 @@ public: _ALWAYS_INLINE_ bool operator>=(const RID &p_rid) const { return _id >= p_rid._id; } - _ALWAYS_INLINE_ bool operator!=(const RID &p_rid) const { - return _id != p_rid._id; - } + INEQUALITY_OPERATOR(const RID &) _ALWAYS_INLINE_ bool is_valid() const { return _id != 0; } _ALWAYS_INLINE_ bool is_null() const { return _id == 0; } diff --git a/core/templates/safe_list.h b/core/templates/safe_list.h index 60ccdd94234..81d5881646b 100644 --- a/core/templates/safe_list.h +++ b/core/templates/safe_list.h @@ -105,19 +105,13 @@ public: bool operator==(const void *p_other) const { return cursor == p_other; } - - bool operator!=(const void *p_other) const { - return cursor != p_other; - } + INEQUALITY_OPERATOR(const void *) // These two allow easy range-based for loops. bool operator==(const Iterator &p_other) const { return cursor == p_other.cursor; } - - bool operator!=(const Iterator &p_other) const { - return cursor != p_other.cursor; - } + INEQUALITY_OPERATOR(const Iterator &) }; public: diff --git a/core/templates/vector.h b/core/templates/vector.h index 52c10eea68f..2f14726684f 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -198,19 +198,7 @@ public: } return true; } - - bool operator!=(const Vector &p_arr) const { - Size s = size(); - if (s != p_arr.size()) { - return true; - } - for (Size i = 0; i < s; i++) { - if (operator[](i) != p_arr[i]) { - return true; - } - } - return false; - } + INEQUALITY_OPERATOR(const Vector &) struct Iterator { _FORCE_INLINE_ T &operator*() const { @@ -227,7 +215,7 @@ public: } _FORCE_INLINE_ bool operator==(const Iterator &b) const { return elem_ptr == b.elem_ptr; } - _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return elem_ptr != b.elem_ptr; } + INEQUALITY_OPERATOR(const Iterator &) Iterator(T *p_ptr) { elem_ptr = p_ptr; } Iterator() {} @@ -252,7 +240,7 @@ public: } _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return elem_ptr == b.elem_ptr; } - _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return elem_ptr != b.elem_ptr; } + INEQUALITY_OPERATOR(const ConstIterator &) ConstIterator(const T *p_ptr) { elem_ptr = p_ptr; } ConstIterator() {} diff --git a/core/typedefs.h b/core/typedefs.h index 35c4668581b..12dd503faf1 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -315,4 +315,19 @@ struct BuildIndexSequence<0, Is...> : IndexSequence {}; #define ___gd_is_defined(val) ____gd_is_defined(__GDARG_PLACEHOLDER_##val) #define GD_IS_DEFINED(x) ___gd_is_defined(x) +// Wrappers for secondary operators, omitted entirely from C++20 builds. +#if __cplusplus < 202002L +#define INEQUALITY_OPERATOR(m_type) \ + _ALWAYS_INLINE_ bool operator!=(m_type p_other) const { return !(*this == p_other); } +#define INEQUALITY_OPERATOR_TEMPLATE(m_type, ...) \ + template <__VA_ARGS__> \ + _ALWAYS_INLINE_ bool operator!=(m_type p_other) const { return !(*this == p_other); } +#define INEQUALITY_OPERATOR_GLOBAL(m_type1, m_type2) \ + _ALWAYS_INLINE_ bool operator!=(m_type1 p_left, m_type2 p_right) { return !(p_left == p_right); } +#else +#define INEQUALITY_OPERATOR(m_type) +#define INEQUALITY_OPERATOR_TEMPLATE(m_type, ...) +#define INEQUALITY_OPERATOR_GLOBAL(m_type1, m_type2) +#endif + #endif // TYPEDEFS_H diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 3e62d3dffa8..e32e90e3727 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -130,10 +130,6 @@ bool Array::operator==(const Array &p_array) const { return recursive_equal(p_array, 0); } -bool Array::operator!=(const Array &p_array) const { - return !recursive_equal(p_array, 0); -} - bool Array::recursive_equal(const Array &p_array, int recursion_count) const { // Cheap checks if (_p == p_array._p) { diff --git a/core/variant/array.h b/core/variant/array.h index 6c3bae6ccb3..752d31e6a5f 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -54,7 +54,7 @@ public: _FORCE_INLINE_ ConstIterator &operator--(); _FORCE_INLINE_ bool operator==(const ConstIterator &p_other) const { return element_ptr == p_other.element_ptr; } - _FORCE_INLINE_ bool operator!=(const ConstIterator &p_other) const { return element_ptr != p_other.element_ptr; } + INEQUALITY_OPERATOR(const ConstIterator &) _FORCE_INLINE_ ConstIterator(const Variant *p_element_ptr, Variant *p_read_only = nullptr) : element_ptr(p_element_ptr), read_only(p_read_only) {} @@ -81,7 +81,7 @@ public: _FORCE_INLINE_ Iterator &operator--(); _FORCE_INLINE_ bool operator==(const Iterator &p_other) const { return element_ptr == p_other.element_ptr; } - _FORCE_INLINE_ bool operator!=(const Iterator &p_other) const { return element_ptr != p_other.element_ptr; } + INEQUALITY_OPERATOR(const Iterator &) _FORCE_INLINE_ Iterator(Variant *p_element_ptr, Variant *p_read_only = nullptr) : element_ptr(p_element_ptr), read_only(p_read_only) {} @@ -123,7 +123,7 @@ public: void clear(); bool operator==(const Array &p_array) const; - bool operator!=(const Array &p_array) const; + INEQUALITY_OPERATOR(const Array &) bool recursive_equal(const Array &p_array, int recursion_count) const; uint32_t hash() const; diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index bb2d0313f66..4ca3d6f378c 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -280,10 +280,6 @@ bool Callable::operator==(const Callable &p_callable) const { } } -bool Callable::operator!=(const Callable &p_callable) const { - return !(*this == p_callable); -} - bool Callable::operator<(const Callable &p_callable) const { bool custom_a = is_custom(); bool custom_b = p_callable.is_custom(); @@ -490,10 +486,6 @@ bool Signal::operator==(const Signal &p_signal) const { return object == p_signal.object && name == p_signal.name; } -bool Signal::operator!=(const Signal &p_signal) const { - return object != p_signal.object || name != p_signal.name; -} - bool Signal::operator<(const Signal &p_signal) const { if (object == p_signal.object) { return name < p_signal.name; diff --git a/core/variant/callable.h b/core/variant/callable.h index e3c940a0e59..385c5228a34 100644 --- a/core/variant/callable.h +++ b/core/variant/callable.h @@ -119,7 +119,7 @@ public: const Callable *get_base_comparator() const; //used for bind/unbind to do less precise comparisons (ignoring binds) in signal connect/disconnect bool operator==(const Callable &p_callable) const; - bool operator!=(const Callable &p_callable) const; + INEQUALITY_OPERATOR(const Callable &) bool operator<(const Callable &p_callable) const; void operator=(const Callable &p_callable); @@ -183,7 +183,7 @@ public: StringName get_name() const; bool operator==(const Signal &p_signal) const; - bool operator!=(const Signal &p_signal) const; + INEQUALITY_OPERATOR(const Signal &) bool operator<(const Signal &p_signal) const; operator String() const; diff --git a/core/variant/container_type_validate.h b/core/variant/container_type_validate.h index 0a23c69cb4b..2da1b86346b 100644 --- a/core/variant/container_type_validate.h +++ b/core/variant/container_type_validate.h @@ -69,9 +69,7 @@ struct ContainerTypeValidate { _FORCE_INLINE_ bool operator==(const ContainerTypeValidate &p_type) const { return type == p_type.type && class_name == p_type.class_name && script == p_type.script; } - _FORCE_INLINE_ bool operator!=(const ContainerTypeValidate &p_type) const { - return type != p_type.type || class_name != p_type.class_name || script != p_type.script; - } + INEQUALITY_OPERATOR(const ContainerTypeValidate &) // Coerces String and StringName into each other and int into float when needed. _FORCE_INLINE_ bool validate(Variant &inout_variant, const char *p_operation = "use") const { diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp index 2db754438ff..3a8370a38f0 100644 --- a/core/variant/dictionary.cpp +++ b/core/variant/dictionary.cpp @@ -244,10 +244,6 @@ bool Dictionary::operator==(const Dictionary &p_dictionary) const { return recursive_equal(p_dictionary, 0); } -bool Dictionary::operator!=(const Dictionary &p_dictionary) const { - return !recursive_equal(p_dictionary, 0); -} - bool Dictionary::recursive_equal(const Dictionary &p_dictionary, int recursion_count) const { // Cheap checks if (_p == p_dictionary._p) { diff --git a/core/variant/dictionary.h b/core/variant/dictionary.h index 5f3ce40219b..536a6f75b69 100644 --- a/core/variant/dictionary.h +++ b/core/variant/dictionary.h @@ -74,7 +74,7 @@ public: bool erase(const Variant &p_key); bool operator==(const Dictionary &p_dictionary) const; - bool operator!=(const Dictionary &p_dictionary) const; + INEQUALITY_OPERATOR(const Dictionary &) bool recursive_equal(const Dictionary &p_dictionary, int recursion_count) const; uint32_t hash() const; diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 186643b024a..030f15f2e32 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -855,17 +855,6 @@ bool Variant::operator==(const Variant &p_variant) const { return hash_compare(p_variant); } -bool Variant::operator!=(const Variant &p_variant) const { - // Don't use `!hash_compare(p_variant)` given it makes use of OP_EQUAL - if (type != p_variant.type) { //evaluation of operator== needs to be more strict - return true; - } - bool v; - Variant r; - evaluate(OP_NOT_EQUAL, *this, p_variant, r, v); - return r; -} - bool Variant::operator<(const Variant &p_variant) const { if (type != p_variant.type) { //if types differ, then order by type first return type < p_variant.type; diff --git a/core/variant/variant.h b/core/variant/variant.h index d4e4b330cdc..c92508358ef 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -507,6 +507,73 @@ public: #undef VARIANT_ENUM_CLASS_CONSTRUCTOR +#define VARIANT_OPERATOR_CONSTRUCTOR(m_type) \ + _FORCE_INLINE_ bool operator==(m_type p_other) const { return *this == Variant(p_other); } \ + INEQUALITY_OPERATOR(m_type) +#define VARIANT_OPERATOR_CONSTRUCTOR_TEMPLATE(m_type, ...) \ + template <__VA_ARGS__> \ + _FORCE_INLINE_ bool operator==(m_type p_other) const { return *this == Variant(p_other); } \ + INEQUALITY_OPERATOR_TEMPLATE(m_type, __VA_ARGS__) + + VARIANT_OPERATOR_CONSTRUCTOR(bool) + VARIANT_OPERATOR_CONSTRUCTOR(int64_t) + VARIANT_OPERATOR_CONSTRUCTOR(int32_t) + VARIANT_OPERATOR_CONSTRUCTOR(int16_t) + VARIANT_OPERATOR_CONSTRUCTOR(int8_t) + VARIANT_OPERATOR_CONSTRUCTOR(uint64_t) + VARIANT_OPERATOR_CONSTRUCTOR(uint32_t) + VARIANT_OPERATOR_CONSTRUCTOR(uint16_t) + VARIANT_OPERATOR_CONSTRUCTOR(uint8_t) + VARIANT_OPERATOR_CONSTRUCTOR(double) + VARIANT_OPERATOR_CONSTRUCTOR(float) + VARIANT_OPERATOR_CONSTRUCTOR(const String &) + VARIANT_OPERATOR_CONSTRUCTOR(const char *) + VARIANT_OPERATOR_CONSTRUCTOR(char32_t) + VARIANT_OPERATOR_CONSTRUCTOR(const Vector2 &) + VARIANT_OPERATOR_CONSTRUCTOR(const Vector2i &) + VARIANT_OPERATOR_CONSTRUCTOR(const Rect2 &) + VARIANT_OPERATOR_CONSTRUCTOR(const Rect2i &) + VARIANT_OPERATOR_CONSTRUCTOR(const Vector3 &) + VARIANT_OPERATOR_CONSTRUCTOR(const Vector3i &) + VARIANT_OPERATOR_CONSTRUCTOR(const Transform2D &) + VARIANT_OPERATOR_CONSTRUCTOR(const Vector4 &) + VARIANT_OPERATOR_CONSTRUCTOR(const Vector4i &) + VARIANT_OPERATOR_CONSTRUCTOR(const Plane &) + VARIANT_OPERATOR_CONSTRUCTOR(const Quaternion &) + VARIANT_OPERATOR_CONSTRUCTOR(const ::AABB &) + VARIANT_OPERATOR_CONSTRUCTOR(const Basis &) + VARIANT_OPERATOR_CONSTRUCTOR(const Transform3D &) + VARIANT_OPERATOR_CONSTRUCTOR(const Projection &) + VARIANT_OPERATOR_CONSTRUCTOR(const Color &) + VARIANT_OPERATOR_CONSTRUCTOR(const StringName &) + VARIANT_OPERATOR_CONSTRUCTOR(const NodePath &) + VARIANT_OPERATOR_CONSTRUCTOR(const ::RID &) + VARIANT_OPERATOR_CONSTRUCTOR_TEMPLATE(const T *, typename T, std::enable_if_t, int> = 0) + VARIANT_OPERATOR_CONSTRUCTOR(const ObjectID &) + VARIANT_OPERATOR_CONSTRUCTOR(const Callable &) + VARIANT_OPERATOR_CONSTRUCTOR(const Signal &) + VARIANT_OPERATOR_CONSTRUCTOR(const Dictionary &) + VARIANT_OPERATOR_CONSTRUCTOR(const Array &) + VARIANT_OPERATOR_CONSTRUCTOR(const PackedByteArray &) + VARIANT_OPERATOR_CONSTRUCTOR(const PackedInt32Array &) + VARIANT_OPERATOR_CONSTRUCTOR(const PackedInt64Array &) + VARIANT_OPERATOR_CONSTRUCTOR(const PackedFloat32Array &) + VARIANT_OPERATOR_CONSTRUCTOR(const PackedFloat64Array &) + VARIANT_OPERATOR_CONSTRUCTOR(const PackedStringArray &) + VARIANT_OPERATOR_CONSTRUCTOR(const PackedVector2Array &) + VARIANT_OPERATOR_CONSTRUCTOR(const PackedVector3Array &) + VARIANT_OPERATOR_CONSTRUCTOR(const PackedColorArray &) + VARIANT_OPERATOR_CONSTRUCTOR(const PackedVector4Array &) + VARIANT_OPERATOR_CONSTRUCTOR(const Vector<::RID> &) + VARIANT_OPERATOR_CONSTRUCTOR(const Vector &) + VARIANT_OPERATOR_CONSTRUCTOR(const Vector &) + VARIANT_OPERATOR_CONSTRUCTOR(const Vector &) + VARIANT_OPERATOR_CONSTRUCTOR(const Vector &) + VARIANT_OPERATOR_CONSTRUCTOR(const IPAddress &) + +#undef VARIANT_OPERATOR_CONSTRUCTOR +#undef VARIANT_OPERATOR_CONSTRUCTOR_TEMPLATE + // If this changes the table in variant_op must be updated enum Operator { //comparison @@ -762,7 +829,7 @@ public: //argsVariant call() bool operator==(const Variant &p_variant) const; - bool operator!=(const Variant &p_variant) const; + INEQUALITY_OPERATOR(const Variant &) bool operator<(const Variant &p_variant) const; uint32_t hash() const; uint32_t recursive_hash(int recursion_count) const; diff --git a/editor/import/resource_importer_dynamic_font.cpp b/editor/import/resource_importer_dynamic_font.cpp index fa222b27902..543ab46c9a4 100644 --- a/editor/import/resource_importer_dynamic_font.cpp +++ b/editor/import/resource_importer_dynamic_font.cpp @@ -191,7 +191,7 @@ Error ResourceImporterDynamicFont::import(const String &p_source_file, const Str for (int i = 0; i < contours.size(); i++) { for (int j = prev_start; j <= contours[i]; j++) { int next_point = (j < contours[i]) ? (j + 1) : prev_start; - if ((points[j].z != TextServer::CONTOUR_CURVE_TAG_ON) || (!Math::is_equal_approx(points[j].x, points[next_point].x) && !Math::is_equal_approx(points[j].y, points[next_point].y))) { + if (((int)points[j].z != TextServer::CONTOUR_CURVE_TAG_ON) || (!Math::is_equal_approx(points[j].x, points[next_point].x) && !Math::is_equal_approx(points[j].y, points[next_point].y))) { is_pixel = false; break; } diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 804f9c607e7..931b9533332 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -46,10 +46,6 @@ bool AbstractPolygon2DEditor::Vertex::operator==(const AbstractPolygon2DEditor:: return polygon == p_vertex.polygon && vertex == p_vertex.vertex; } -bool AbstractPolygon2DEditor::Vertex::operator!=(const AbstractPolygon2DEditor::Vertex &p_vertex) const { - return !(*this == p_vertex); -} - bool AbstractPolygon2DEditor::Vertex::valid() const { return vertex >= 0; } diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h index 66d4e1b7ef0..791243b13fe 100644 --- a/editor/plugins/abstract_polygon_2d_editor.h +++ b/editor/plugins/abstract_polygon_2d_editor.h @@ -55,7 +55,7 @@ class AbstractPolygon2DEditor : public HBoxContainer { vertex(p_vertex) {} bool operator==(const Vertex &p_vertex) const; - bool operator!=(const Vertex &p_vertex) const; + INEQUALITY_OPERATOR(const Vertex &) bool valid() const; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index e9a796dae72..4849e383975 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3338,7 +3338,7 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) { Vector2 line_starts[4]; Vector2 line_ends[4]; for (int i = 0; i < 4; i++) { - real_t anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i]; + real_t anchor_val = (i >= 2) ? (int)ANCHOR_END - anchors_values[i] : anchors_values[i]; line_starts[i] = corners_pos[i].lerp(corners_pos[(i + 1) % 4], anchor_val); line_ends[i] = corners_pos[(i + 3) % 4].lerp(corners_pos[(i + 2) % 4], anchor_val); bool anchor_snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0; @@ -3356,11 +3356,11 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) { _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 3) % 4]) / 2, (Side)(dragged_anchor)); percent_val = anchors_values[(dragged_anchor + 1) % 4]; - percent_val = ((dragged_anchor + 1) % 4 >= 2) ? ANCHOR_END - percent_val : percent_val; + percent_val = ((dragged_anchor + 1) % 4 >= 2) ? (int)ANCHOR_END - percent_val : percent_val; _draw_percentage_at_position(percent_val, (line_starts[dragged_anchor] + anchors_pos[dragged_anchor]) / 2, (Side)(dragged_anchor)); percent_val = anchors_values[dragged_anchor]; - percent_val = (dragged_anchor >= 2) ? ANCHOR_END - percent_val : percent_val; + percent_val = (dragged_anchor >= 2) ? (int)ANCHOR_END - percent_val : percent_val; _draw_percentage_at_position(percent_val, (line_ends[(dragged_anchor + 1) % 4] + anchors_pos[dragged_anchor]) / 2, (Side)((dragged_anchor + 1) % 4)); } diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index dc86acd884d..d559af066e9 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -3019,7 +3019,7 @@ void Node3DEditorViewport::_notification(int p_what) { for (int i = 0; i < FRAME_TIME_HISTORY; i++) { cpu_time += cpu_time_history[i]; } - cpu_time /= FRAME_TIME_HISTORY; + cpu_time /= (int)FRAME_TIME_HISTORY; // Prevent unrealistically low values. cpu_time = MAX(0.01, cpu_time); @@ -3029,7 +3029,7 @@ void Node3DEditorViewport::_notification(int p_what) { for (int i = 0; i < FRAME_TIME_HISTORY; i++) { gpu_time += gpu_time_history[i]; } - gpu_time /= FRAME_TIME_HISTORY; + gpu_time /= (int)FRAME_TIME_HISTORY; // Prevent division by zero for the FPS counter (and unrealistically low values). // This limits the reported FPS to 100000. gpu_time = MAX(0.01, gpu_time); diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 7f64ae902b0..c3f395378ae 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -223,10 +223,7 @@ public: return false; } - - bool operator!=(const DataType &p_other) const { - return !(*this == p_other); - } + INEQUALITY_OPERATOR(const DataType &) void operator=(const DataType &p_other) { kind = p_other.kind; diff --git a/modules/gdscript/gdscript_tokenizer_buffer.cpp b/modules/gdscript/gdscript_tokenizer_buffer.cpp index 2046480f0eb..3510fe62572 100644 --- a/modules/gdscript/gdscript_tokenizer_buffer.cpp +++ b/modules/gdscript/gdscript_tokenizer_buffer.cpp @@ -38,7 +38,7 @@ int GDScriptTokenizerBuffer::_token_to_binary(const Token &p_token, Vector &r_buffer, int p_start, HashMap &r_identifiers_map, HashMap &r_constants_map) { int pos = p_start; - int token_type = p_token.type & TOKEN_MASK; + int token_type = p_token.type & (int)TOKEN_MASK; switch (p_token.type) { case GDScriptTokenizer::Token::ANNOTATION: diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index 4c11565c512..4f5d8e96b30 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -1028,13 +1028,13 @@ void GridMapEditor::_draw_grids(const Vector3 &cell_size) { for (int j = -GRID_CURSOR_SIZE; j <= GRID_CURSOR_SIZE; j++) { for (int k = -GRID_CURSOR_SIZE; k <= GRID_CURSOR_SIZE; k++) { Vector3 p = axis_n1 * j + axis_n2 * k; - float trans = Math::pow(MAX(0, 1.0 - (Vector2(j, k).length() / GRID_CURSOR_SIZE)), 2); + float trans = Math::pow(MAX(0, 1.0 - (Vector2(j, k).length() / (int)GRID_CURSOR_SIZE)), 2); Vector3 pj = axis_n1 * (j + 1) + axis_n2 * k; - float transj = Math::pow(MAX(0, 1.0 - (Vector2(j + 1, k).length() / GRID_CURSOR_SIZE)), 2); + float transj = Math::pow(MAX(0, 1.0 - (Vector2(j + 1, k).length() / (int)GRID_CURSOR_SIZE)), 2); Vector3 pk = axis_n1 * j + axis_n2 * (k + 1); - float transk = Math::pow(MAX(0, 1.0 - (Vector2(j, k + 1).length() / GRID_CURSOR_SIZE)), 2); + float transk = Math::pow(MAX(0, 1.0 - (Vector2(j, k + 1).length() / (int)GRID_CURSOR_SIZE)), 2); grid_points[i].push_back(p); grid_points[i].push_back(pk); diff --git a/modules/mono/editor/semver.h b/modules/mono/editor/semver.h index 2f65e99ef5b..cf49a0a2c8b 100644 --- a/modules/mono/editor/semver.h +++ b/modules/mono/editor/semver.h @@ -60,10 +60,7 @@ public: bool operator==(const SemVer &b) const { return cmp(*this, b) == 0; } - - bool operator!=(const SemVer &b) const { - return !operator==(b); - } + INEQUALITY_OPERATOR(const SemVer &) bool operator<(const SemVer &b) const { return cmp(*this, b) < 0; diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h index ff6c68727d7..c823dfa38e1 100644 --- a/modules/mono/mono_gc_handle.h +++ b/modules/mono/mono_gc_handle.h @@ -46,10 +46,14 @@ extern "C" { struct GCHandleIntPtr { void *value; - _FORCE_INLINE_ bool operator==(const GCHandleIntPtr &p_other) { return value == p_other.value; } - _FORCE_INLINE_ bool operator!=(const GCHandleIntPtr &p_other) { return value != p_other.value; } + _FORCE_INLINE_ bool operator==(const GCHandleIntPtr &p_other) const { return value == p_other.value; } + INEQUALITY_OPERATOR(const GCHandleIntPtr &) + // FIXME: C++20 doesn't allow aggregate initializers to bypass deleted constructors. + // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1008r1.pdf +#if __cplusplus < 202002L GCHandleIntPtr() = delete; +#endif }; } diff --git a/modules/navigation/nav_utils.h b/modules/navigation/nav_utils.h index ba4c44b748f..ce6839b85de 100644 --- a/modules/navigation/nav_utils.h +++ b/modules/navigation/nav_utils.h @@ -142,9 +142,7 @@ struct NavigationPoly { return poly == p_other.poly; } - bool operator!=(const NavigationPoly &p_other) const { - return !(*this == p_other); - } + INEQUALITY_OPERATOR(const NavigationPoly &) }; struct NavPolyTravelCostGreaterThan { diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index a5f1629cf03..67c122d644b 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -486,15 +486,15 @@ float JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool return p_trigger ? -1.0f : 0.0f; } if (!p_xinput) { - return (float)p_val / MAX_JOY_AXIS; + return (float)p_val / (int)MAX_JOY_AXIS; } if (p_trigger) { // Convert to a value between -1.0f and 1.0f. - return 2.0f * p_val / MAX_TRIGGER - 1.0f; + return 2.0f * p_val / (int)MAX_TRIGGER - 1.0f; } float value; if (p_val < 0) { - value = (float)p_val / MAX_JOY_AXIS; + value = (float)p_val / (int)MAX_JOY_AXIS; } else { value = (float)p_val / (MAX_JOY_AXIS - 1); } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index c1d197ea9b2..95fa0f823db 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1008,56 +1008,56 @@ int Control::_get_anchors_layout_preset() const { float top = get_anchor(SIDE_TOP); float bottom = get_anchor(SIDE_BOTTOM); - if (left == ANCHOR_BEGIN && right == ANCHOR_BEGIN && top == ANCHOR_BEGIN && bottom == ANCHOR_BEGIN) { + if (left == (int)ANCHOR_BEGIN && right == (int)ANCHOR_BEGIN && top == (int)ANCHOR_BEGIN && bottom == (int)ANCHOR_BEGIN) { return (int)LayoutPreset::PRESET_TOP_LEFT; } - if (left == ANCHOR_END && right == ANCHOR_END && top == ANCHOR_BEGIN && bottom == ANCHOR_BEGIN) { + if (left == (int)ANCHOR_END && right == (int)ANCHOR_END && top == (int)ANCHOR_BEGIN && bottom == (int)ANCHOR_BEGIN) { return (int)LayoutPreset::PRESET_TOP_RIGHT; } - if (left == ANCHOR_BEGIN && right == ANCHOR_BEGIN && top == ANCHOR_END && bottom == ANCHOR_END) { + if (left == (int)ANCHOR_BEGIN && right == (int)ANCHOR_BEGIN && top == (int)ANCHOR_END && bottom == (int)ANCHOR_END) { return (int)LayoutPreset::PRESET_BOTTOM_LEFT; } - if (left == ANCHOR_END && right == ANCHOR_END && top == ANCHOR_END && bottom == ANCHOR_END) { + if (left == (int)ANCHOR_END && right == (int)ANCHOR_END && top == (int)ANCHOR_END && bottom == (int)ANCHOR_END) { return (int)LayoutPreset::PRESET_BOTTOM_RIGHT; } - if (left == ANCHOR_BEGIN && right == ANCHOR_BEGIN && top == 0.5 && bottom == 0.5) { + if (left == (int)ANCHOR_BEGIN && right == (int)ANCHOR_BEGIN && top == 0.5 && bottom == 0.5) { return (int)LayoutPreset::PRESET_CENTER_LEFT; } - if (left == ANCHOR_END && right == ANCHOR_END && top == 0.5 && bottom == 0.5) { + if (left == (int)ANCHOR_END && right == (int)ANCHOR_END && top == 0.5 && bottom == 0.5) { return (int)LayoutPreset::PRESET_CENTER_RIGHT; } - if (left == 0.5 && right == 0.5 && top == ANCHOR_BEGIN && bottom == ANCHOR_BEGIN) { + if (left == 0.5 && right == 0.5 && top == (int)ANCHOR_BEGIN && bottom == (int)ANCHOR_BEGIN) { return (int)LayoutPreset::PRESET_CENTER_TOP; } - if (left == 0.5 && right == 0.5 && top == ANCHOR_END && bottom == ANCHOR_END) { + if (left == 0.5 && right == 0.5 && top == (int)ANCHOR_END && bottom == (int)ANCHOR_END) { return (int)LayoutPreset::PRESET_CENTER_BOTTOM; } if (left == 0.5 && right == 0.5 && top == 0.5 && bottom == 0.5) { return (int)LayoutPreset::PRESET_CENTER; } - if (left == ANCHOR_BEGIN && right == ANCHOR_BEGIN && top == ANCHOR_BEGIN && bottom == ANCHOR_END) { + if (left == (int)ANCHOR_BEGIN && right == (int)ANCHOR_BEGIN && top == (int)ANCHOR_BEGIN && bottom == (int)ANCHOR_END) { return (int)LayoutPreset::PRESET_LEFT_WIDE; } - if (left == ANCHOR_END && right == ANCHOR_END && top == ANCHOR_BEGIN && bottom == ANCHOR_END) { + if (left == (int)ANCHOR_END && right == (int)ANCHOR_END && top == (int)ANCHOR_BEGIN && bottom == (int)ANCHOR_END) { return (int)LayoutPreset::PRESET_RIGHT_WIDE; } - if (left == ANCHOR_BEGIN && right == ANCHOR_END && top == ANCHOR_BEGIN && bottom == ANCHOR_BEGIN) { + if (left == (int)ANCHOR_BEGIN && right == (int)ANCHOR_END && top == (int)ANCHOR_BEGIN && bottom == (int)ANCHOR_BEGIN) { return (int)LayoutPreset::PRESET_TOP_WIDE; } - if (left == ANCHOR_BEGIN && right == ANCHOR_END && top == ANCHOR_END && bottom == ANCHOR_END) { + if (left == (int)ANCHOR_BEGIN && right == (int)ANCHOR_END && top == (int)ANCHOR_END && bottom == (int)ANCHOR_END) { return (int)LayoutPreset::PRESET_BOTTOM_WIDE; } - if (left == 0.5 && right == 0.5 && top == ANCHOR_BEGIN && bottom == ANCHOR_END) { + if (left == 0.5 && right == 0.5 && top == (int)ANCHOR_BEGIN && bottom == (int)ANCHOR_END) { return (int)LayoutPreset::PRESET_VCENTER_WIDE; } - if (left == ANCHOR_BEGIN && right == ANCHOR_END && top == 0.5 && bottom == 0.5) { + if (left == (int)ANCHOR_BEGIN && right == (int)ANCHOR_END && top == 0.5 && bottom == 0.5) { return (int)LayoutPreset::PRESET_HCENTER_WIDE; } - if (left == ANCHOR_BEGIN && right == ANCHOR_END && top == ANCHOR_BEGIN && bottom == ANCHOR_END) { + if (left == (int)ANCHOR_BEGIN && right == (int)ANCHOR_END && top == (int)ANCHOR_BEGIN && bottom == (int)ANCHOR_END) { return (int)LayoutPreset::PRESET_FULL_RECT; } diff --git a/scene/resources/2d/tile_set.h b/scene/resources/2d/tile_set.h index 15e1a16359e..3db826f7554 100644 --- a/scene/resources/2d/tile_set.h +++ b/scene/resources/2d/tile_set.h @@ -103,12 +103,10 @@ union TileMapCell { } } - bool operator!=(const TileMapCell &p_other) const { - return !(source_id == p_other.source_id && coord_x == p_other.coord_x && coord_y == p_other.coord_y && alternative_tile == p_other.alternative_tile); - } bool operator==(const TileMapCell &p_other) const { return source_id == p_other.source_id && coord_x == p_other.coord_x && coord_y == p_other.coord_y && alternative_tile == p_other.alternative_tile; } + INEQUALITY_OPERATOR(const TileMapCell &) }; class TileMapPattern : public Resource { @@ -276,9 +274,7 @@ public: bool operator<(const TerrainsPattern &p_terrains_pattern) const; bool operator==(const TerrainsPattern &p_terrains_pattern) const; - bool operator!=(const TerrainsPattern &p_terrains_pattern) const { - return !operator==(p_terrains_pattern); - }; + INEQUALITY_OPERATOR(const TerrainsPattern &) void set_terrain(int p_terrain); int get_terrain() const; diff --git a/scene/resources/3d/primitive_meshes.cpp b/scene/resources/3d/primitive_meshes.cpp index ceeb73d0ef2..104ec41b7be 100644 --- a/scene/resources/3d/primitive_meshes.cpp +++ b/scene/resources/3d/primitive_meshes.cpp @@ -2754,11 +2754,11 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph Vector polygon; for (int32_t j = start; j <= end; j++) { - if (points[j].z == TextServer::CONTOUR_CURVE_TAG_ON) { + if (points[j].z == (int)TextServer::CONTOUR_CURVE_TAG_ON) { // Point on the curve. Vector2 p = Vector2(points[j].x, points[j].y) * pixel_size; polygon.push_back(ContourPoint(p, true)); - } else if (points[j].z == TextServer::CONTOUR_CURVE_TAG_OFF_CONIC) { + } else if (points[j].z == (int)TextServer::CONTOUR_CURVE_TAG_OFF_CONIC) { // Conic Bezier arc. int32_t next = (j == end) ? start : (j + 1); int32_t prev = (j == start) ? end : (j - 1); @@ -2767,16 +2767,16 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph Vector2 p2; // For successive conic OFF points add a virtual ON point in the middle. - if (points[prev].z == TextServer::CONTOUR_CURVE_TAG_OFF_CONIC) { + if (points[prev].z == (int)TextServer::CONTOUR_CURVE_TAG_OFF_CONIC) { p0 = (Vector2(points[prev].x, points[prev].y) + Vector2(points[j].x, points[j].y)) / 2.0; - } else if (points[prev].z == TextServer::CONTOUR_CURVE_TAG_ON) { + } else if (points[prev].z == (int)TextServer::CONTOUR_CURVE_TAG_ON) { p0 = Vector2(points[prev].x, points[prev].y); } else { ERR_FAIL_MSG(vformat("Invalid conic arc point sequence at %d:%d", i, j)); } - if (points[next].z == TextServer::CONTOUR_CURVE_TAG_OFF_CONIC) { + if (points[next].z == (int)TextServer::CONTOUR_CURVE_TAG_OFF_CONIC) { p2 = (Vector2(points[j].x, points[j].y) + Vector2(points[next].x, points[next].y)) / 2.0; - } else if (points[next].z == TextServer::CONTOUR_CURVE_TAG_ON) { + } else if (points[next].z == (int)TextServer::CONTOUR_CURVE_TAG_ON) { p2 = Vector2(points[next].x, points[next].y); } else { ERR_FAIL_MSG(vformat("Invalid conic arc point sequence at %d:%d", i, j)); @@ -2794,7 +2794,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph polygon.push_back(ContourPoint(p, false)); t += step; } - } else if (points[j].z == TextServer::CONTOUR_CURVE_TAG_OFF_CUBIC) { + } else if (points[j].z == (int)TextServer::CONTOUR_CURVE_TAG_OFF_CUBIC) { // Cubic Bezier arc. int32_t cur = j; int32_t next1 = (j == end) ? start : (j + 1); @@ -2802,7 +2802,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph int32_t prev = (j == start) ? end : (j - 1); // There must be exactly two OFF points and two ON points for each cubic arc. - if (points[prev].z != TextServer::CONTOUR_CURVE_TAG_ON) { + if (points[prev].z != (int)TextServer::CONTOUR_CURVE_TAG_ON) { cur = (cur == 0) ? end : cur - 1; next1 = (next1 == 0) ? end : next1 - 1; next2 = (next2 == 0) ? end : next2 - 1; @@ -2810,10 +2810,10 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph } else { j++; } - ERR_FAIL_COND_MSG(points[prev].z != TextServer::CONTOUR_CURVE_TAG_ON, vformat("Invalid cubic arc point sequence at %d:%d", i, prev)); - ERR_FAIL_COND_MSG(points[cur].z != TextServer::CONTOUR_CURVE_TAG_OFF_CUBIC, vformat("Invalid cubic arc point sequence at %d:%d", i, cur)); - ERR_FAIL_COND_MSG(points[next1].z != TextServer::CONTOUR_CURVE_TAG_OFF_CUBIC, vformat("Invalid cubic arc point sequence at %d:%d", i, next1)); - ERR_FAIL_COND_MSG(points[next2].z != TextServer::CONTOUR_CURVE_TAG_ON, vformat("Invalid cubic arc point sequence at %d:%d", i, next2)); + ERR_FAIL_COND_MSG(points[prev].z != (int)TextServer::CONTOUR_CURVE_TAG_ON, vformat("Invalid cubic arc point sequence at %d:%d", i, prev)); + ERR_FAIL_COND_MSG(points[cur].z != (int)TextServer::CONTOUR_CURVE_TAG_OFF_CUBIC, vformat("Invalid cubic arc point sequence at %d:%d", i, cur)); + ERR_FAIL_COND_MSG(points[next1].z != (int)TextServer::CONTOUR_CURVE_TAG_OFF_CUBIC, vformat("Invalid cubic arc point sequence at %d:%d", i, next1)); + ERR_FAIL_COND_MSG(points[next2].z != (int)TextServer::CONTOUR_CURVE_TAG_ON, vformat("Invalid cubic arc point sequence at %d:%d", i, next2)); Vector2 p0 = Vector2(points[prev].x, points[prev].y); Vector2 p1 = Vector2(points[cur].x, points[cur].y); diff --git a/scene/resources/audio_stream_wav.cpp b/scene/resources/audio_stream_wav.cpp index f9787dde2e6..fca66826d43 100644 --- a/scene/resources/audio_stream_wav.cpp +++ b/scene/resources/audio_stream_wav.cpp @@ -311,7 +311,7 @@ int AudioStreamPlaybackWAV::mix(AudioFrame *p_buffer, float p_rate_scale, int p_ srate *= p_rate_scale; float playback_speed_scale = AudioServer::get_singleton()->get_playback_speed_scale(); float fincrement = (srate * playback_speed_scale) / base_rate; - int32_t increment = int32_t(MAX(fincrement * MIX_FRAC_LEN, 1)); + int32_t increment = int32_t(MAX(fincrement * (int)MIX_FRAC_LEN, 1)); increment *= sign; //looping diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 4d1d733f8b8..321b48da445 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -976,15 +976,15 @@ enum OldArrayFormat { OLD_ARRAY_FORMAT_INDEX = 1 << OLD_ARRAY_INDEX, OLD_ARRAY_COMPRESS_BASE = (OLD_ARRAY_INDEX + 1), - OLD_ARRAY_COMPRESS_VERTEX = 1 << (OLD_ARRAY_VERTEX + OLD_ARRAY_COMPRESS_BASE), // mandatory - OLD_ARRAY_COMPRESS_NORMAL = 1 << (OLD_ARRAY_NORMAL + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_TANGENT = 1 << (OLD_ARRAY_TANGENT + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_COLOR = 1 << (OLD_ARRAY_COLOR + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_TEX_UV = 1 << (OLD_ARRAY_TEX_UV + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_TEX_UV2 = 1 << (OLD_ARRAY_TEX_UV2 + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_BONES = 1 << (OLD_ARRAY_BONES + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_WEIGHTS = 1 << (OLD_ARRAY_WEIGHTS + OLD_ARRAY_COMPRESS_BASE), - OLD_ARRAY_COMPRESS_INDEX = 1 << (OLD_ARRAY_INDEX + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_VERTEX = 1 << (OLD_ARRAY_VERTEX + (int)OLD_ARRAY_COMPRESS_BASE), // mandatory + OLD_ARRAY_COMPRESS_NORMAL = 1 << (OLD_ARRAY_NORMAL + (int)OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TANGENT = 1 << (OLD_ARRAY_TANGENT + (int)OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_COLOR = 1 << (OLD_ARRAY_COLOR + (int)OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TEX_UV = 1 << (OLD_ARRAY_TEX_UV + (int)OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TEX_UV2 = 1 << (OLD_ARRAY_TEX_UV2 + (int)OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_BONES = 1 << (OLD_ARRAY_BONES + (int)OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_WEIGHTS = 1 << (OLD_ARRAY_WEIGHTS + (int)OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_INDEX = 1 << (OLD_ARRAY_INDEX + (int)OLD_ARRAY_COMPRESS_BASE), OLD_ARRAY_FLAG_USE_2D_VERTICES = OLD_ARRAY_COMPRESS_INDEX << 1, OLD_ARRAY_FLAG_USE_16_BIT_BONES = OLD_ARRAY_COMPRESS_INDEX << 2, diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp index 16f42aea9eb..60f5fefb263 100644 --- a/servers/audio/effects/audio_effect_chorus.cpp +++ b/servers/audio/effects/audio_effect_chorus.cpp @@ -88,7 +88,7 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A float c1 = 1.0 - auxlp; float c2 = auxlp; AudioFrame h = filter_h[vc]; - if (v.cutoff >= AudioEffectChorus::MS_CUTOFF_MAX) { + if (v.cutoff >= (int)AudioEffectChorus::MS_CUTOFF_MAX) { c1 = 1.0; c2 = 0.0; } diff --git a/servers/rendering/rendering_device_commons.h b/servers/rendering/rendering_device_commons.h index d72265958cb..008d80b8cb2 100644 --- a/servers/rendering/rendering_device_commons.h +++ b/servers/rendering/rendering_device_commons.h @@ -926,9 +926,10 @@ public: BitField stages; uint32_t length = 0; // Size of arrays (in total elements), or ubos (in bytes * total elements). - bool operator!=(const ShaderUniform &p_other) const { - return binding != p_other.binding || type != p_other.type || writable != p_other.writable || stages != p_other.stages || length != p_other.length; + bool operator==(const ShaderUniform &p_other) const { + return binding == p_other.binding && type == p_other.type && writable == p_other.writable && stages == p_other.stages && length == p_other.length; } + INEQUALITY_OPERATOR(const ShaderUniform &) bool operator<(const ShaderUniform &p_other) const { if (binding != p_other.binding) { diff --git a/servers/rendering/rendering_device_driver.h b/servers/rendering/rendering_device_driver.h index 97c84c9d05f..5aeab53851d 100644 --- a/servers/rendering/rendering_device_driver.h +++ b/servers/rendering/rendering_device_driver.h @@ -135,7 +135,7 @@ public: } \ _ALWAYS_INLINE_ bool operator<(const m_name##ID &p_other) const { return id < p_other.id; } \ _ALWAYS_INLINE_ bool operator==(const m_name##ID &p_other) const { return id == p_other.id; } \ - _ALWAYS_INLINE_ bool operator!=(const m_name##ID &p_other) const { return id != p_other.id; } \ + INEQUALITY_OPERATOR(const m_name##ID &) \ _ALWAYS_INLINE_ m_name##ID(const m_name##ID &p_other) : ID(p_other.id) {} \ _ALWAYS_INLINE_ explicit m_name##ID(uint64_t p_int) : ID(p_int) {} \ _ALWAYS_INLINE_ explicit m_name##ID(void *p_ptr) : ID((size_t)p_ptr) {} \ diff --git a/servers/text_server.cpp b/servers/text_server.cpp index d2cf4674ae0..063ca27b0c0 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -155,10 +155,6 @@ bool Glyph::operator==(const Glyph &p_a) const { return (p_a.index == index) && (p_a.font_rid == font_rid) && (p_a.font_size == font_size) && (p_a.start == start); } -bool Glyph::operator!=(const Glyph &p_a) const { - return (p_a.index != index) || (p_a.font_rid != font_rid) || (p_a.font_size != font_size) || (p_a.start != start); -} - bool Glyph::operator<(const Glyph &p_a) const { if (p_a.start == start) { if (p_a.count == count) { diff --git a/servers/text_server.h b/servers/text_server.h index ba3fdaa35e9..02ccb70a33e 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -582,7 +582,7 @@ struct Glyph { int32_t index = 0; // Glyph index (font specific) or UTF-32 codepoint (for the invalid glyphs). bool operator==(const Glyph &p_a) const; - bool operator!=(const Glyph &p_a) const; + INEQUALITY_OPERATOR(const Glyph &) bool operator<(const Glyph &p_a) const; bool operator>(const Glyph &p_a) const; diff --git a/thirdparty/misc/r128.h b/thirdparty/misc/r128.h index ff05569ea78..eaba3e52787 100644 --- a/thirdparty/misc/r128.h +++ b/thirdparty/misc/r128.h @@ -302,8 +302,10 @@ struct numeric_limits static const bool has_infinity = false; static const bool has_quiet_NaN = false; static const bool has_signaling_NaN = false; +#if !(__cplusplus > 202002L || (defined(_MSVC_LANG) && _MSVC_LANG > 202002L)) static const float_denorm_style has_denorm = denorm_absent; static const bool has_denorm_loss = false; +#endif static R128 infinity() throw() { return R128_zero; } static R128 quiet_NaN() throw() { return R128_zero; }