@@ -23,25 +23,7 @@ using namespace runtime;
23
23
* @param number The NSNumber instance whose scalar type is to be deduced.
24
24
* @return The corresponding ScalarType.
25
25
*/
26
- static inline ScalarType deduceType (NSNumber *number) {
27
- auto type = [number objCType ][0 ];
28
- type = (type >= ' A' && type <= ' Z' ) ? type + (' a' - ' A' ) : type;
29
- if (type == ' c' ) {
30
- return ScalarType::Byte;
31
- } else if (type == ' s' ) {
32
- return ScalarType::Short;
33
- } else if (type == ' i' ) {
34
- return ScalarType::Int;
35
- } else if (type == ' q' || type == ' l' ) {
36
- return ScalarType::Long;
37
- } else if (type == ' f' ) {
38
- return ScalarType::Float;
39
- } else if (type == ' d' ) {
40
- return ScalarType::Double;
41
- }
42
- ET_CHECK_MSG (false , " Unsupported type: %c " , type);
43
- return ScalarType::Undefined;
44
- }
26
+ ScalarType deduceType (NSNumber *number);
45
27
46
28
/* *
47
29
* Converts the value held in the NSNumber to the specified C++ type T.
@@ -51,8 +33,8 @@ static inline ScalarType deduceType(NSNumber *number) {
51
33
* @return The value converted to type T.
52
34
*/
53
35
template <typename T>
54
- static inline T extractValue (NSNumber *number) {
55
- ET_CHECK_MSG (!(isFloatingType (deduceScalarType (number)) &&
36
+ T extractValue (NSNumber *number) {
37
+ ET_CHECK_MSG (!(isFloatingType (deduceType (number)) &&
56
38
isIntegralType (CppTypeToScalarType<T>::value, true )),
57
39
" Cannot convert floating point to integral type" );
58
40
T value;
@@ -93,6 +75,49 @@ static inline T extractValue(NSNumber *number) {
93
75
return value;
94
76
}
95
77
78
+ /* *
79
+ * Converts an NSArray of NSNumber objects to a std::vector of type T.
80
+ *
81
+ * @tparam T The target C++ numeric type.
82
+ * @param array The NSArray containing NSNumber objects.
83
+ * @return A std::vector with the values extracted as type T.
84
+ */
85
+ template <typename T>
86
+ std::vector<T> toVector (NSArray <NSNumber *> *array) {
87
+ std::vector<T> vector;
88
+ vector.reserve (array.count );
89
+ for (NSNumber *number in array) {
90
+ vector.push_back (extractValue<T>(number));
91
+ }
92
+ return vector;
93
+ }
94
+
95
+ // Trait for types that can be wrapped into an NSNumber.
96
+ template <typename T>
97
+ constexpr bool isNSNumberWrapable =
98
+ std::is_arithmetic_v<T> ||
99
+ std::is_same_v<T, BOOL > ||
100
+ std::is_same_v<T, BFloat16> ||
101
+ std::is_same_v<T, Half>;
102
+
103
+ /* *
104
+ * Converts a generic container of numeric values to an NSArray of NSNumber objects.
105
+ *
106
+ * @tparam Container The container type holding numeric values.
107
+ * @param container The container whose items are to be converted.
108
+ * @return An NSArray populated with NSNumber objects representing the container's items.
109
+ */
110
+ template <typename Container>
111
+ NSArray <NSNumber *> *toNSArray (const Container &container) {
112
+ static_assert (isNSNumberWrapable<typename Container::value_type>, " Invalid container value type" );
113
+ const NSUInteger count = std::distance (std::begin (container), std::end (container));
114
+ NSMutableArray <NSNumber *> *array = [NSMutableArray arrayWithCapacity: count];
115
+ for (const auto &item : container) {
116
+ [array addObject: @(item)];
117
+ }
118
+ return array;
119
+ }
120
+
96
121
} // namespace executorch::extension::utils
97
122
98
123
#endif // __cplusplus
0 commit comments