Skip to content

Commit

Permalink
<bit> and <concepts> (facebook#41822)
Browse files Browse the repository at this point in the history
Summary:

X-link: facebook/yoga#1497

The lowest common denominator build encountered for Yoga internally has been Clang 12 + MSVC 2017 stdlib. This has allowed Yoga to use C++ 20 language features, but not library features. React Native for mobile has not been bound to this restriction.

Builds using that toolchain are being updated to latest MSVC 2019 stdlib (which has good C++ 20 library support), along with Clang 17 (or maybe a stop at 15) pending projects using `-fcoroutines-ts` being migrated to C++ 20.

This tests out some C++ 20 standard library usages against the current Clang 12 + MSVC 2019 stdlib toolchain, and adds a couple concepts for better constraints/compiler error messages if misused.

Yoga OSS CI tests as far back as Clang/libc++ 14 along with a similar era GCC/libstdc++ as part of tests against Ubuntu 22.04 LTS stock toolchain. Once this internal toolchain is updated, that will be the least common denominator (compared to mobile builds or any internal builds).

Changelog: [Internal]

Differential Revision: D51604487
  • Loading branch information
NickGerleman authored and facebook-github-bot committed Dec 7, 2023
1 parent eb661df commit 0174789
Show file tree
Hide file tree
Showing 20 changed files with 37 additions and 123 deletions.
30 changes: 0 additions & 30 deletions packages/react-native/ReactCommon/yoga/yoga/bits/BitCast.h

This file was deleted.

5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/Align.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ constexpr inline int32_t ordinalCount<Align>() {
return 9;
}

template <>
constexpr inline int32_t bitCount<Align>() {
return 4;
}

constexpr inline Align scopedEnum(YGAlign unscoped) {
return static_cast<Align>(unscoped);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/Dimension.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ constexpr inline int32_t ordinalCount<Dimension>() {
return 2;
}

template <>
constexpr inline int32_t bitCount<Dimension>() {
return 1;
}

constexpr inline Dimension scopedEnum(YGDimension unscoped) {
return static_cast<Dimension>(unscoped);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/Direction.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ constexpr inline int32_t ordinalCount<Direction>() {
return 3;
}

template <>
constexpr inline int32_t bitCount<Direction>() {
return 2;
}

constexpr inline Direction scopedEnum(YGDirection unscoped) {
return static_cast<Direction>(unscoped);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/Display.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ constexpr inline int32_t ordinalCount<Display>() {
return 2;
}

template <>
constexpr inline int32_t bitCount<Display>() {
return 1;
}

constexpr inline Display scopedEnum(YGDisplay unscoped) {
return static_cast<Display>(unscoped);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/Edge.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ constexpr inline int32_t ordinalCount<Edge>() {
return 9;
}

template <>
constexpr inline int32_t bitCount<Edge>() {
return 4;
}

constexpr inline Edge scopedEnum(YGEdge unscoped) {
return static_cast<Edge>(unscoped);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ constexpr inline int32_t ordinalCount<ExperimentalFeature>() {
return 2;
}

template <>
constexpr inline int32_t bitCount<ExperimentalFeature>() {
return 1;
}

constexpr inline ExperimentalFeature scopedEnum(YGExperimentalFeature unscoped) {
return static_cast<ExperimentalFeature>(unscoped);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ constexpr inline int32_t ordinalCount<FlexDirection>() {
return 4;
}

template <>
constexpr inline int32_t bitCount<FlexDirection>() {
return 2;
}

constexpr inline FlexDirection scopedEnum(YGFlexDirection unscoped) {
return static_cast<FlexDirection>(unscoped);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/Gutter.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ constexpr inline int32_t ordinalCount<Gutter>() {
return 3;
}

template <>
constexpr inline int32_t bitCount<Gutter>() {
return 2;
}

constexpr inline Gutter scopedEnum(YGGutter unscoped) {
return static_cast<Gutter>(unscoped);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/Justify.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ constexpr inline int32_t ordinalCount<Justify>() {
return 6;
}

template <>
constexpr inline int32_t bitCount<Justify>() {
return 3;
}

constexpr inline Justify scopedEnum(YGJustify unscoped) {
return static_cast<Justify>(unscoped);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/LogLevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ constexpr inline int32_t ordinalCount<LogLevel>() {
return 6;
}

template <>
constexpr inline int32_t bitCount<LogLevel>() {
return 3;
}

constexpr inline LogLevel scopedEnum(YGLogLevel unscoped) {
return static_cast<LogLevel>(unscoped);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ constexpr inline int32_t ordinalCount<MeasureMode>() {
return 3;
}

template <>
constexpr inline int32_t bitCount<MeasureMode>() {
return 2;
}

constexpr inline MeasureMode scopedEnum(YGMeasureMode unscoped) {
return static_cast<MeasureMode>(unscoped);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/NodeType.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ constexpr inline int32_t ordinalCount<NodeType>() {
return 2;
}

template <>
constexpr inline int32_t bitCount<NodeType>() {
return 1;
}

constexpr inline NodeType scopedEnum(YGNodeType unscoped) {
return static_cast<NodeType>(unscoped);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/Overflow.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ constexpr inline int32_t ordinalCount<Overflow>() {
return 3;
}

template <>
constexpr inline int32_t bitCount<Overflow>() {
return 2;
}

constexpr inline Overflow scopedEnum(YGOverflow unscoped) {
return static_cast<Overflow>(unscoped);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ constexpr inline int32_t ordinalCount<PositionType>() {
return 3;
}

template <>
constexpr inline int32_t bitCount<PositionType>() {
return 2;
}

constexpr inline PositionType scopedEnum(YGPositionType unscoped) {
return static_cast<PositionType>(unscoped);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/Unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ constexpr inline int32_t ordinalCount<Unit>() {
return 4;
}

template <>
constexpr inline int32_t bitCount<Unit>() {
return 2;
}

constexpr inline Unit scopedEnum(YGUnit unscoped) {
return static_cast<Unit>(unscoped);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/enums/Wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ constexpr inline int32_t ordinalCount<Wrap>() {
return 3;
}

template <>
constexpr inline int32_t bitCount<Wrap>() {
return 2;
}

constexpr inline Wrap scopedEnum(YGWrap unscoped) {
return static_cast<Wrap>(unscoped);
}
Expand Down
27 changes: 23 additions & 4 deletions packages/react-native/ReactCommon/yoga/yoga/enums/YogaEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,52 @@

#pragma once

#include <bit>
#include <iterator>
#include <type_traits>

namespace facebook::yoga {

/**
* Concept for any enum/enum class
*/
template <typename EnumT>
concept Enumeration = std::is_enum_v<EnumT>;

/**
* Count of ordinals in a Yoga enum which is sequential
*/
template <Enumeration EnumT>
constexpr inline int32_t ordinalCount();

/**
* Count of bits needed to represent every ordinal
* Concept for a yoga enum which is sequential
*/
template <typename EnumT>
constexpr inline int32_t bitCount();
concept HasOrdinality = (ordinalCount<EnumT>() > 0);

/**
* Count of bits needed to represent every ordinal
*/
template <HasOrdinality EnumT>
constexpr inline int32_t bitCount() {
return std::bit_width(
static_cast<std::underlying_type_t<EnumT>>(ordinalCount<EnumT>() - 1));
}

/**
* Polyfill of C++ 23 to_underlying()
* https://en.cppreference.com/w/cpp/utility/to_underlying
*/
constexpr auto to_underlying(auto e) noexcept {
constexpr auto to_underlying(Enumeration auto e) noexcept {
return static_cast<std::underlying_type_t<decltype(e)>>(e);
}

/**
* Convenience function to iterate through every value in a Yoga enum as part of
* a range-based for loop.
*/
template <typename EnumT>
template <HasOrdinality EnumT>
auto ordinals() {
struct Iterator {
EnumT e{};
Expand Down
13 changes: 9 additions & 4 deletions packages/react-native/ReactCommon/yoga/yoga/numeric/Comparison.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,32 @@
#include <algorithm>
#include <array>
#include <cmath>
#include <concepts>

#include <yoga/Yoga.h>

namespace facebook::yoga {

constexpr bool isUndefined(auto value) {
constexpr bool isUndefined(std::floating_point auto value) {
return value != value;
}

constexpr bool isDefined(auto value) {
constexpr bool isDefined(std::floating_point auto value) {
return !isUndefined(value);
}

constexpr auto maxOrDefined(auto a, auto b) {
constexpr auto maxOrDefined(
std::floating_point auto a,
std::floating_point auto b) {
if (yoga::isDefined(a) && yoga::isDefined(b)) {
return std::max(a, b);
}
return yoga::isUndefined(a) ? b : a;
}

constexpr auto minOrDefined(auto a, auto b) {
constexpr auto minOrDefined(
std::floating_point auto a,
std::floating_point auto b) {
if (yoga::isDefined(a) && yoga::isDefined(b)) {
return std::min(a, b);
}
Expand Down
10 changes: 5 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/style/CompactValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

#pragma once

#include <bit>
#include <cmath>
#include <cstdint>
#include <limits>

#include <yoga/YGMacros.h>
#include <yoga/YGValue.h>

#include <yoga/bits/BitCast.h>
#include <yoga/numeric/Comparison.h>

static_assert(
Expand Down Expand Up @@ -69,7 +69,7 @@ class YG_EXPORT CompactValue {
}

uint32_t unitBit = Unit == YGUnitPercent ? PERCENT_BIT : 0;
auto data = yoga::bit_cast<uint32_t>(value);
auto data = std::bit_cast<uint32_t>(value);
data -= BIAS;
data |= unitBit;
return {data};
Expand Down Expand Up @@ -112,7 +112,7 @@ class YG_EXPORT CompactValue {
return YGValue{0.0f, YGUnitPercent};
}

if (std::isnan(yoga::bit_cast<float>(repr_))) {
if (std::isnan(std::bit_cast<float>(repr_))) {
return YGValueUndefined;
}

Expand All @@ -121,14 +121,14 @@ class YG_EXPORT CompactValue {
data += BIAS;

return YGValue{
yoga::bit_cast<float>(data),
std::bit_cast<float>(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<float>(repr_)));
repr_ != ZERO_BITS_PERCENT && std::isnan(std::bit_cast<float>(repr_)));
}

bool isDefined() const noexcept {
Expand Down

0 comments on commit 0174789

Please sign in to comment.