@@ -23,25 +23,7 @@ using namespace runtime;
2323 * @param number The NSNumber instance whose scalar type is to be deduced.
2424 * @return The corresponding ScalarType.
2525 */
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);
4527
4628/* *
4729 * Converts the value held in the NSNumber to the specified C++ type T.
@@ -51,8 +33,8 @@ static inline ScalarType deduceType(NSNumber *number) {
5133 * @return The value converted to type T.
5234 */
5335template <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)) &&
5638 isIntegralType (CppTypeToScalarType<T>::value, true )),
5739 " Cannot convert floating point to integral type" );
5840 T value;
@@ -93,6 +75,49 @@ static inline T extractValue(NSNumber *number) {
9375 return value;
9476}
9577
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+
96121} // namespace executorch::extension::utils
97122
98123#endif // __cplusplus
0 commit comments