MCPcopy Create free account
hub / github.com/apache/tvm-ffi / MapHelper

Method MapHelper

include/tvm/ffi/container/array.h:746–846  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

744 */
745 template <typename F, typename U = std::invoke_result_t<F, T>>
746 static ObjectPtr<Object> MapHelper(ObjectPtr<Object> data, F fmap) {
747 if (data == nullptr) {
748 return nullptr;
749 }
750
751 TVM_FFI_ICHECK(data->IsInstance<ArrayObj>());
752
753 constexpr bool is_same_output_type = std::is_same_v<T, U>;
754
755 if constexpr (is_same_output_type) {
756 if (data.unique()) {
757 // Mutate-in-place path. Only allowed if the output type U is
758 // the same as type T, we have a mutable this*, and there are
759 // no other shared copies of the array.
760 auto arr = static_cast<ArrayObj*>(data.get());
761 for (auto it = arr->MutableBegin(); it != arr->MutableEnd(); it++) {
762 T value = details::AnyUnsafe::CopyFromAnyViewAfterCheck<T>(*it);
763 // reset the original value to nullptr, to ensure unique ownership
764 it->reset();
765 T mapped = fmap(std::move(value));
766 *it = std::move(mapped);
767 }
768 return data;
769 }
770 }
771
772 constexpr bool compatible_types = is_valid_iterator_v<T, U*> || is_valid_iterator_v<U, T*>;
773
774 ObjectPtr<ArrayObj> output = nullptr;
775 auto arr = static_cast<ArrayObj*>(data.get());
776
777 auto it = arr->begin();
778 if constexpr (compatible_types) {
779 // Copy-on-write path, if the output Array<U> might be
780 // represented by the same underlying array as the existing
781 // Array<T>. Typically, this is for functions that map `T` to
782 // `T`, but can also apply to functions that map `T` to
783 // `Optional<T>`, or that map `T` to a subclass or superclass of
784 // `T`.
785 bool all_identical = true;
786 for (; it != arr->end(); it++) {
787 U mapped = fmap(details::AnyUnsafe::CopyFromAnyViewAfterCheck<T>(*it));
788 if (!(*it).same_as(mapped)) {
789 // At least one mapped element is different than the
790 // original. Therefore, prepare the output array,
791 // consisting of any previous elements that had mapped to
792 // themselves (if any), and the element that didn't map to
793 // itself.
794 //
795 // We cannot use `U()` as the default object, as `U` may be
796 // a non-nullable type. Since the default `Any()`
797 // will be overwritten before returning, all objects will be
798 // of type `U` for the calling scope.
799 all_identical = false;
800 output = ArrayObj::CreateRepeated(static_cast<int64_t>(arr->size()), Any());
801 output->InitRange(0, arr->begin(), it);
802 output->SetItem(it - arr->begin(), std::move(mapped));
803 it++;

Callers

nothing calls this directly

Calls 12

MutableBeginMethod · 0.80
MutableEndMethod · 0.80
InitRangeMethod · 0.80
SetItemMethod · 0.80
AnyClass · 0.50
uniqueMethod · 0.45
getMethod · 0.45
resetMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
same_asMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected