Skip to content

Commit 72f879c

Browse files
authored
Utility helper to extract a value from NSNumber. (#9595)
Summary: . Reviewed By: bsoyluoglu Differential Revision: D71752749
1 parent fd75d05 commit 72f879c

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

extension/apple/ExecuTorch/Internal/ExecuTorchUtils.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
#ifdef __cplusplus
1212

1313
#import <executorch/runtime/core/exec_aten/exec_aten.h>
14+
#import <executorch/runtime/core/exec_aten/util/scalar_type_util.h>
1415

1516
namespace executorch::extension::utils {
1617
using namespace aten;
18+
using namespace runtime;
1719

1820
/**
1921
* Deduces the scalar type for a given NSNumber based on its type encoding.
@@ -41,6 +43,56 @@ static inline ScalarType deduceScalarType(NSNumber *number) {
4143
return ScalarType::Undefined;
4244
}
4345

46+
/**
47+
* Converts the value held in the NSNumber to the specified C++ type T.
48+
*
49+
* @tparam T The target C++ numeric type.
50+
* @param number The NSNumber instance to extract the value from.
51+
* @return The value converted to type T.
52+
*/
53+
template <typename T>
54+
static inline T extractValue(NSNumber *number) {
55+
ET_CHECK_MSG(!(isFloatingType(deduceScalarType(number)) &&
56+
isIntegralType(CppTypeToScalarType<T>::value, true)),
57+
"Cannot convert floating point to integral type");
58+
T value;
59+
if constexpr (std::is_same_v<T, uint8_t>) {
60+
value = number.unsignedCharValue;
61+
} else if constexpr (std::is_same_v<T, int8_t>) {
62+
value = number.charValue;
63+
} else if constexpr (std::is_same_v<T, int16_t>) {
64+
value = number.shortValue;
65+
} else if constexpr (std::is_same_v<T, int32_t>) {
66+
value = number.intValue;
67+
} else if constexpr (std::is_same_v<T, int64_t>) {
68+
value = number.longLongValue;
69+
} else if constexpr (std::is_same_v<T, float>) {
70+
value = number.floatValue;
71+
} else if constexpr (std::is_same_v<T, double>) {
72+
value = number.doubleValue;
73+
} else if constexpr (std::is_same_v<T, BOOL>) {
74+
value = number.boolValue;
75+
} else if constexpr (std::is_same_v<T, uint16_t>) {
76+
value = number.unsignedShortValue;
77+
} else if constexpr (std::is_same_v<T, uint32_t>) {
78+
value = number.unsignedIntValue;
79+
} else if constexpr (std::is_same_v<T, uint64_t>) {
80+
value = number.unsignedLongLongValue;
81+
} else if constexpr (std::is_same_v<T, NSInteger>) {
82+
value = number.integerValue;
83+
} else if constexpr (std::is_same_v<T, NSUInteger>) {
84+
value = number.unsignedIntegerValue;
85+
} else if constexpr (std::is_same_v<T, BFloat16> ||
86+
std::is_same_v<T, Half>) {
87+
value = T(number.floatValue);
88+
} else {
89+
static_assert(sizeof(T) == 0, "Unsupported type");
90+
}
91+
ET_DCHECK_MSG(std::numeric_limits<T>::lowest() <= value && value <= std::numeric_limits<T>::max(),
92+
"Value out of range");
93+
return value;
94+
}
95+
4496
} // namespace executorch::extension::utils
4597

4698
#endif // __cplusplus

0 commit comments

Comments
 (0)