| 87 | } |
| 88 | |
| 89 | af_err af_sort_index(af_array *out, af_array *indices, const af_array in, |
| 90 | const unsigned dim, const bool isAscending) { |
| 91 | try { |
| 92 | const ArrayInfo &info = getInfo(in); |
| 93 | af_dtype type = info.getType(); |
| 94 | |
| 95 | if (info.elements() <= 0) { |
| 96 | AF_CHECK(af_create_handle(out, 0, nullptr, type)); |
| 97 | AF_CHECK(af_create_handle(indices, 0, nullptr, type)); |
| 98 | return AF_SUCCESS; |
| 99 | } |
| 100 | |
| 101 | af_array val; |
| 102 | af_array idx; |
| 103 | |
| 104 | switch (type) { |
| 105 | case f32: |
| 106 | sort_index<float>(&val, &idx, in, dim, isAscending); |
| 107 | break; |
| 108 | case f64: |
| 109 | sort_index<double>(&val, &idx, in, dim, isAscending); |
| 110 | break; |
| 111 | case s32: sort_index<int>(&val, &idx, in, dim, isAscending); break; |
| 112 | case u32: sort_index<uint>(&val, &idx, in, dim, isAscending); break; |
| 113 | case s16: |
| 114 | sort_index<short>(&val, &idx, in, dim, isAscending); |
| 115 | break; |
| 116 | case u16: |
| 117 | sort_index<ushort>(&val, &idx, in, dim, isAscending); |
| 118 | break; |
| 119 | case s64: sort_index<intl>(&val, &idx, in, dim, isAscending); break; |
| 120 | case u64: |
| 121 | sort_index<uintl>(&val, &idx, in, dim, isAscending); |
| 122 | break; |
| 123 | case s8: sort_index<schar>(&val, &idx, in, dim, isAscending); break; |
| 124 | case u8: sort_index<uchar>(&val, &idx, in, dim, isAscending); break; |
| 125 | case b8: sort_index<char>(&val, &idx, in, dim, isAscending); break; |
| 126 | default: TYPE_ERROR(1, type); |
| 127 | } |
| 128 | std::swap(*out, val); |
| 129 | std::swap(*indices, idx); |
| 130 | } |
| 131 | CATCHALL; |
| 132 | |
| 133 | return AF_SUCCESS; |
| 134 | } |
| 135 | |
| 136 | template<typename Tk, typename Tv> |
| 137 | static inline void sort_by_key(af_array *okey, af_array *oval, |