From ade44a5a6b5bdf41a928a11c0311eeec54cf911a Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Wed, 13 Sep 2023 20:42:05 -0700 Subject: [PATCH] Breaking: Use C++ 20 Summary: X-link: https://github.com/facebook/react-native/pull/39437 Have been running into places where C++ 20 makes life easier for use like `std::bit_cast` (that one is easy to polyfill), in-class member initializer support for bitfields, designated initializers, defaulted comparison operator, concepts instead of SFINAE, and probably more. Our other infra is in the process of making this jump, or already has. This tests it out everywhere, across the various reference builds, to see if we have any issues. This is a bit more aggressive than I had previously, but n - 1 is going to be a better long term place than n - 2. I think it is likely everything will be buildable for a while under Clang 10 (released 3.5 years ago), GCC 10 (releaseed 3.5 years ago), and VS 16.11 (released 2 years ago). Differential Revision: D49261607 --- Package.swift | 2 +- README.md | 2 +- Yoga.podspec | 2 +- cmake/project-defaults.cmake | 2 +- java/jni/YGJNIVanilla.cpp | 15 ++++++++------- javascript/CMakeLists.txt | 2 +- yoga/bits/BitCast.h | 29 ----------------------------- yoga/style/CompactValue.h | 11 +++++------ 8 files changed, 18 insertions(+), 47 deletions(-) delete mode 100644 yoga/bits/BitCast.h diff --git a/Package.swift b/Package.swift index 4c8d846fa9..15f94268cb 100644 --- a/Package.swift +++ b/Package.swift @@ -28,5 +28,5 @@ let package = Package( ] ) ], - cxxLanguageStandard: CXXLanguageStandard(rawValue: "c++17") + cxxLanguageStandard: CXXLanguageStandard(rawValue: "c++20") ) diff --git a/README.md b/README.md index 3fc4aeee61..00972de2c7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Yoga is an embeddable and performant flexbox layout engine with bindings for mul ## Building -Yoga's main implementation targets C++ 17 with accompanying build logic in CMake. A wrapper is provided to build the main library and run unit tests. +Yoga's main implementation targets C++ 20 with accompanying build logic in CMake. A wrapper is provided to build the main library and run unit tests. ```sh ./unit_tests diff --git a/Yoga.podspec b/Yoga.podspec index 847b37735f..d2e48494ad 100644 --- a/Yoga.podspec +++ b/Yoga.podspec @@ -33,7 +33,7 @@ Pod::Spec.new do |spec| '-Werror', '-Wextra', '-Wconversion', - '-std=c++17', + '-std=c++20', '-fPIC' ] diff --git a/cmake/project-defaults.cmake b/cmake/project-defaults.cmake index 8868ce93d9..08f50a4ece 100644 --- a/cmake/project-defaults.cmake +++ b/cmake/project-defaults.cmake @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/java/jni/YGJNIVanilla.cpp b/java/jni/YGJNIVanilla.cpp index 9e69b7b70a..37f5b191b8 100644 --- a/java/jni/YGJNIVanilla.cpp +++ b/java/jni/YGJNIVanilla.cpp @@ -5,19 +5,20 @@ * LICENSE file in the root directory of this source tree. */ -#include "YGJNIVanilla.h" +#include #include #include #include + +#include +#include + #include "LayoutContext.h" #include "YGJNI.h" +#include "YGJNIVanilla.h" #include "YGJTypesVanilla.h" #include "YogaJniException.h" #include "common.h" -#include "jni.h" - -#include -#include using namespace facebook; using namespace facebook::yoga; @@ -645,8 +646,8 @@ static YGSize YGJNIMeasureFunc( uint32_t wBits = 0xFFFFFFFF & (measureResult >> 32); uint32_t hBits = 0xFFFFFFFF & measureResult; - const float measuredWidth = yoga::bit_cast(wBits); - const float measuredHeight = yoga::bit_cast(hBits); + const float measuredWidth = std::bit_cast(wBits); + const float measuredHeight = std::bit_cast(hBits); return YGSize{measuredWidth, measuredHeight}; } else { diff --git a/javascript/CMakeLists.txt b/javascript/CMakeLists.txt index 96400b701b..44cbfcebe5 100644 --- a/javascript/CMakeLists.txt +++ b/javascript/CMakeLists.txt @@ -14,7 +14,7 @@ file(GLOB SOURCES CONFIGURE_DEPENDS include_directories(..) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) add_compile_definitions( EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0) diff --git a/yoga/bits/BitCast.h b/yoga/bits/BitCast.h deleted file mode 100644 index eaca348c8c..0000000000 --- a/yoga/bits/BitCast.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include - -namespace facebook::yoga { - -// Polyfill for std::bit_cast() from C++20, to allow safe type punning -// https://en.cppreference.com/w/cpp/numeric/bit_cast -template -std::enable_if_t< - sizeof(To) == sizeof(From) && std::is_trivially_copyable_v && - std::is_trivially_copyable_v && - std::is_trivially_constructible_v, - To> -bit_cast(const From& src) noexcept { - To dst; - std::memcpy(&dst, &src, sizeof(To)); - return dst; -} - -} // namespace facebook::yoga diff --git a/yoga/style/CompactValue.h b/yoga/style/CompactValue.h index 8fa0892cf4..f2c4e6bdbd 100644 --- a/yoga/style/CompactValue.h +++ b/yoga/style/CompactValue.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -14,8 +15,6 @@ #include #include -#include - static_assert( std::numeric_limits::is_iec559, "facebook::yoga::detail::CompactValue only works with IEEE754 floats"); @@ -64,7 +63,7 @@ class YG_EXPORT CompactValue { } uint32_t unitBit = Unit == YGUnitPercent ? PERCENT_BIT : 0; - auto data = yoga::bit_cast(value); + auto data = std::bit_cast(value); data -= BIAS; data |= unitBit; return {data}; @@ -117,7 +116,7 @@ class YG_EXPORT CompactValue { return YGValue{0.0f, YGUnitPercent}; } - if (std::isnan(yoga::bit_cast(repr_))) { + if (std::isnan(std::bit_cast(repr_))) { return YGValueUndefined; } @@ -126,14 +125,14 @@ class YG_EXPORT CompactValue { data += BIAS; return YGValue{ - yoga::bit_cast(data), + std::bit_cast(data), repr_ & 0x40000000 ? YGUnitPercent : YGUnitPoint}; } bool isUndefined() const noexcept { return ( repr_ != AUTO_BITS && repr_ != ZERO_BITS_POINT && - repr_ != ZERO_BITS_PERCENT && std::isnan(yoga::bit_cast(repr_))); + repr_ != ZERO_BITS_PERCENT && std::isnan(std::bit_cast(repr_))); } bool isAuto() const noexcept {