| 72 | } |
| 73 | |
| 74 | af_err af_set_union(af_array* out, const af_array first, const af_array second, |
| 75 | const bool is_unique) { |
| 76 | try { |
| 77 | const ArrayInfo& first_info = getInfo(first); |
| 78 | const ArrayInfo& second_info = getInfo(second); |
| 79 | |
| 80 | af_array res; |
| 81 | if (first_info.isEmpty()) { return af_retain_array(out, second); } |
| 82 | |
| 83 | if (second_info.isEmpty()) { return af_retain_array(out, first); } |
| 84 | |
| 85 | ARG_ASSERT(1, (first_info.isVector() || first_info.isScalar())); |
| 86 | ARG_ASSERT(1, (second_info.isVector() || second_info.isScalar())); |
| 87 | |
| 88 | af_dtype first_type = first_info.getType(); |
| 89 | af_dtype second_type = second_info.getType(); |
| 90 | |
| 91 | ARG_ASSERT(1, first_type == second_type); |
| 92 | |
| 93 | switch (first_type) { |
| 94 | case f32: res = setUnion<float>(first, second, is_unique); break; |
| 95 | case f64: res = setUnion<double>(first, second, is_unique); break; |
| 96 | case s32: res = setUnion<int>(first, second, is_unique); break; |
| 97 | case u32: res = setUnion<uint>(first, second, is_unique); break; |
| 98 | case s16: res = setUnion<short>(first, second, is_unique); break; |
| 99 | case u16: res = setUnion<ushort>(first, second, is_unique); break; |
| 100 | case s64: res = setUnion<intl>(first, second, is_unique); break; |
| 101 | case u64: res = setUnion<uintl>(first, second, is_unique); break; |
| 102 | case b8: res = setUnion<char>(first, second, is_unique); break; |
| 103 | case s8: res = setUnion<schar>(first, second, is_unique); break; |
| 104 | case u8: res = setUnion<uchar>(first, second, is_unique); break; |
| 105 | default: TYPE_ERROR(1, first_type); |
| 106 | } |
| 107 | |
| 108 | std::swap(*out, res); |
| 109 | } |
| 110 | CATCHALL; |
| 111 | |
| 112 | return AF_SUCCESS; |
| 113 | } |
| 114 | |
| 115 | template<typename T> |
| 116 | static inline af_array setIntersect(const af_array first, const af_array second, |