Skip to content

Commit f690fb3

Browse files
committed
Fix up CSSValueVariant
1 parent e7eda39 commit f690fb3

File tree

1 file changed

+59
-75
lines changed
  • packages/react-native-reanimated/Common/cpp/reanimated/CSS/common/values

1 file changed

+59
-75
lines changed

packages/react-native-reanimated/Common/cpp/reanimated/CSS/common/values/CSSValueVariant.h

Lines changed: 59 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,42 @@ class CSSValueVariant final : public CSSValue {
7171
CSSValueVariant() = default;
7272

7373
/**
74-
* Construct from any TValue that is or can construct one of the AllowedTypes
74+
* Construct from any value that is or can construct one of the AllowedTypes
7575
* (chooses the first one that matches)
7676
*/
77-
template <typename TValue>
78-
explicit CSSValueVariant(TValue &&value)
79-
requires((std::is_constructible_v<AllowedTypes, TValue> || ...))
77+
explicit CSSValueVariant(auto &&value)
78+
requires((std::is_constructible_v<AllowedTypes, decltype(value)> || ...))
8079
{ // NOLINT(whitespace/braces)
81-
// If TValue exactly matches one of AllowedTypes, store it directly:
80+
using ValueType = decltype(value);
81+
82+
// If value type exactly matches one of AllowedTypes, store it directly:
8283
if constexpr ((std::is_same_v<
83-
std::remove_reference_t<TValue>,
84+
std::remove_reference_t<ValueType>,
8485
AllowedTypes> ||
8586
...)) {
86-
storage_ = std::forward<TValue>(value);
87+
storage_ = std::forward<ValueType>(value);
8788
} else {
88-
// Otherwise, try each type in turn
89-
if (!tryConstruct(std::forward<TValue>(value))) {
89+
// Otherwise, try to construct the CSSValue from each type in turn
90+
auto tryOne = [&]<typename TCSSValue>() -> bool {
91+
if constexpr (std::is_constructible_v<TCSSValue, ValueType>) {
92+
if constexpr (ValueConstructibleCSSValue<TCSSValue, ValueType>) {
93+
// For construction from a non-jsi::Value, we perform a runtime
94+
// canConstruct check only if the type has a canConstruct method.
95+
// (this is needed e.g. when different CSS value types can be
96+
// constructed from the same value type, like CSSLength and
97+
// CSSKeyword)
98+
if (!TCSSValue::canConstruct(std::forward<ValueType>(value))) {
99+
return false;
100+
}
101+
}
102+
storage_ = TCSSValue(std::forward<ValueType>(value));
103+
return true;
104+
}
105+
return false;
106+
};
107+
108+
// Try constructing with each allowed type until one succeeds
109+
if (!(tryOne.template operator()<AllowedTypes>() || ...)) {
90110
throw std::runtime_error(
91111
"[Reanimated] No compatible type found for construction");
92112
}
@@ -98,15 +118,43 @@ class CSSValueVariant final : public CSSValue {
98118
* (chooses the first one that matches)
99119
*/
100120
CSSValueVariant(jsi::Runtime &rt, const jsi::Value &jsiValue) {
101-
if (!tryConstruct(rt, jsiValue)) {
121+
auto tryOne = [&]<typename TCSSValue>() -> bool {
122+
// We have to check in a runtime if the type can be constructed from the
123+
// provided jsi::Value. The first match will be used to construct the
124+
// CSS value.
125+
if (!TCSSValue::canConstruct(rt, jsiValue)) {
126+
return false;
127+
}
128+
storage_ = TCSSValue(rt, jsiValue);
129+
return true;
130+
};
131+
132+
// Try constructing with each allowed type until one succeeds
133+
if (!(tryOne.template operator()<AllowedTypes>() || ...)) {
102134
throw std::runtime_error(
103135
"[Reanimated] No compatible type found for construction from: " +
104136
stringifyJSIValue(rt, jsiValue));
105137
}
106138
}
107139

140+
/**
141+
* Construct from folly::dynamic if it matches any AllowedType's constructor
142+
* (chooses the first one that matches)
143+
*/
108144
explicit CSSValueVariant(const folly::dynamic &value) {
109-
if (!tryConstruct(value)) {
145+
auto tryOne = [&]<typename TCSSValue>() -> bool {
146+
// We have to check in a runtime if the type can be constructed from the
147+
// provided folly::dynamic. The first match will be used to construct the
148+
// CSS value.
149+
if (!TCSSValue::canConstruct(value)) {
150+
return false;
151+
}
152+
storage_ = TCSSValue(value);
153+
return true;
154+
};
155+
156+
// Try constructing with each allowed type until one succeeds
157+
if (!(tryOne.template operator()<AllowedTypes>() || ...)) {
110158
throw std::runtime_error(
111159
"[Reanimated] No compatible type found for construction from: " +
112160
folly::toJson(value));
@@ -212,70 +260,6 @@ class CSSValueVariant final : public CSSValue {
212260
const double fallbackInterpolateThreshold) const {
213261
return (progress < fallbackInterpolateThreshold) ? *this : to;
214262
}
215-
216-
/**
217-
* Tries to construct type from a given value
218-
*/
219-
template <typename TValue>
220-
bool tryConstruct(TValue &&value) {
221-
auto tryOne = [&]<typename TCSSValue>() -> bool {
222-
if constexpr (std::is_constructible_v<TCSSValue, TValue>) {
223-
if constexpr (ValueConstructibleCSSValue<TCSSValue, TValue>) {
224-
// For construction from a non-jsi::Value, we perform a runtime
225-
// canConstruct check only if the type has a canConstruct method.
226-
// (this is needed e.g. when different CSS value types can be
227-
// constructed from the same value type, like CSSLength and
228-
// CSSKeyword)
229-
if (!TCSSValue::canConstruct(std::forward<TValue>(value))) {
230-
return false;
231-
}
232-
}
233-
storage_ = TCSSValue(std::forward<TValue>(value));
234-
return true;
235-
}
236-
return false;
237-
};
238-
239-
// Try constructing with each allowed type until one succeeds
240-
return (tryOne.template operator()<AllowedTypes>() || ...);
241-
}
242-
243-
/**
244-
* Tries to construct type from a given jsi::Value
245-
*/
246-
bool tryConstruct(jsi::Runtime &rt, const jsi::Value &jsiValue) {
247-
auto tryOne = [&]<typename TCSSValue>() -> bool {
248-
// We have to check in a runtime if the type can be constructed from the
249-
// provided jsi::Value. The first match will be used to construct the
250-
// CSS value.
251-
if (!TCSSValue::canConstruct(rt, jsiValue)) {
252-
return false;
253-
}
254-
storage_ = TCSSValue(rt, jsiValue);
255-
return true;
256-
};
257-
258-
// Try constructing with each allowed type until one succeeds
259-
return (tryOne.template operator()<AllowedTypes>() || ...);
260-
}
261-
262-
/**
263-
* Tries to construct type from a given folly::dynamic
264-
*/
265-
bool tryConstruct(const folly::dynamic &value) {
266-
auto tryOne = [&]<typename TCSSValue>() -> bool {
267-
// We have to check in a runtime if the type can be constructed from the
268-
// provided folly::dynamic. The first match will be used to construct the
269-
// CSS value.
270-
if (!TCSSValue::canConstruct(value)) {
271-
return false;
272-
}
273-
storage_ = TCSSValue(value);
274-
return true;
275-
};
276-
// Try constructing with each allowed type until one succeeds
277-
return (tryOne.template operator()<AllowedTypes>() || ...);
278-
}
279263
};
280264

281265
} // namespace reanimated::css

0 commit comments

Comments
 (0)