24 #ifndef TVM_RUNTIME_CONTAINER_ARRAY_H_ 25 #define TVM_RUNTIME_CONTAINER_ARRAY_H_ 29 #include <type_traits> 43 size_t size()
const {
return this->size_; }
59 void clear() { ShrinkBy(size_); }
75 int64_t
size = from->size_;
76 ICHECK_GE(cap, size) <<
"ValueError: not enough capacity";
81 for (int64_t& i = p->size_ = 0; i < size; ++i) {
94 int64_t
size = from->size_;
95 ICHECK_GE(cap, size) <<
"ValueError: not enough capacity";
100 for (int64_t& i = p->size_ = 0; i < size; ++i) {
101 new (write++)
ObjectRef(std::move(*read++));
116 for (int64_t& i = p->size_ = 0; i < n; ++i) {
128 size_t GetSize()
const {
return this->size_; }
136 ObjectRef* MutableEnd()
const {
return MutableBegin() + size_; }
159 template <
typename IterType>
160 ArrayNode* InitRange(int64_t idx, IterType first, IterType last) {
162 for (; first != last; ++first) {
176 ArrayNode* MoveElementsLeft(int64_t dst, int64_t src_begin, int64_t src_end) {
177 ObjectRef* from = MutableBegin() + src_begin;
179 while (src_begin++ != src_end) {
180 *to++ = std::move(*from++);
192 ArrayNode* MoveElementsRight(int64_t dst, int64_t src_begin, int64_t src_end) {
193 ObjectRef* from = MutableBegin() + src_end;
194 ObjectRef* to = MutableBegin() + (src_end - src_begin + dst);
195 while (src_begin++ != src_end) {
196 *--to = std::move(*--from);
209 while (delta-- > 0) {
223 while (delta-- > 0) {
237 static constexpr int64_t kInitSize = 4;
240 static constexpr int64_t kIncFactor = 2;
246 template <
typename,
typename>
259 template <
typename T,
typename IterType>
261 : std::bool_constant<std::is_base_of_v<
262 T, std::remove_cv_t<std::remove_reference_t<decltype(*std::declval<IterType>())>>>> {};
264 template <
typename T,
typename IterType>
267 template <
typename T,
typename IterType>
287 template <
typename T,
288 typename =
typename std::enable_if<std::is_base_of<ObjectRef, T>::value>::type>
296 Array() { data_ = ArrayNode::Empty(); }
303 data_ = std::move(other.data_);
326 template <
typename IterType>
327 Array(IterType first, IterType last) {
335 Array(std::initializer_list<T> init) {
336 Assign(init.begin(), init.end());
344 Assign(init.begin(), init.end());
360 data_ = std::move(other.data_);
411 ICHECK(p !=
nullptr) <<
"ValueError: cannot index a null array";
412 ICHECK(0 <= i && i < p->size_)
413 <<
"IndexError: indexing " << i <<
" on an array of size " << p->size_;
414 return DowncastNoCheck<T>(*(p->
begin() + i));
420 return p ==
nullptr ? 0 : GetArrayNode()->size_;
426 return p ==
nullptr ? 0 : GetArrayNode()->capacity_;
435 ICHECK(p !=
nullptr) <<
"ValueError: cannot index a null array";
436 ICHECK_GT(p->size_, 0) <<
"IndexError: cannot index an empty array";
437 return DowncastNoCheck<T>(*(p->
begin()));
443 ICHECK(p !=
nullptr) <<
"ValueError: cannot index a null array";
444 ICHECK_GT(p->size_, 0) <<
"IndexError: cannot index an empty array";
445 return DowncastNoCheck<T>(*(p->
end() - 1));
466 ICHECK(data_ !=
nullptr) <<
"ValueError: cannot insert a null array";
467 int64_t idx = std::distance(
begin(), position);
468 int64_t
size = GetArrayNode()->size_;
469 auto addr = CopyOnWrite(1)
471 ->MoveElementsRight(idx + 1, idx, size)
482 template <
typename IterType>
487 ICHECK(data_ !=
nullptr) <<
"ValueError: cannot insert a null array";
488 int64_t idx = std::distance(
begin(), position);
489 int64_t
size = GetArrayNode()->size_;
490 int64_t numel = std::distance(first, last);
493 ->MoveElementsRight(idx + numel, idx, size)
494 ->InitRange(idx, first, last);
499 ICHECK(data_ !=
nullptr) <<
"ValueError: cannot pop_back because array is null";
500 int64_t
size = GetArrayNode()->size_;
501 ICHECK_GT(size, 0) <<
"ValueError: cannot pop_back because array is empty";
502 CopyOnWrite()->ShrinkBy(1);
510 ICHECK(data_ !=
nullptr) <<
"ValueError: cannot erase a null array";
511 int64_t st = std::distance(
begin(), position);
512 int64_t
size = GetArrayNode()->size_;
513 ICHECK(0 <= st && st < size) <<
"ValueError: cannot erase at index " << st
514 <<
", because Array size is " <<
size;
516 ->MoveElementsLeft(st, st + 1, size)
529 ICHECK(data_ !=
nullptr) <<
"ValueError: cannot erase a null array";
530 int64_t
size = GetArrayNode()->size_;
531 int64_t st = std::distance(
begin(), first);
532 int64_t ed = std::distance(
begin(), last);
533 ICHECK_LT(st, ed) <<
"ValueError: cannot erase array in range [" << st <<
", " << ed <<
")";
534 ICHECK(0 <= st && st <= size && 0 <= ed && ed <= size)
535 <<
"ValueError: cannot erase array in range [" << st <<
", " << ed <<
")" 536 <<
", because array size is " <<
size;
538 ->MoveElementsLeft(st, ed, size)
547 ICHECK_GE(n, 0) <<
"ValueError: cannot resize an Array to negative size";
548 if (data_ ==
nullptr) {
552 int64_t
size = GetArrayNode()->size_;
554 CopyOnWrite(n - size)->EnlargeBy(n - size);
555 }
else if (size > n) {
556 CopyOnWrite()->ShrinkBy(size - n);
565 if (data_ ==
nullptr || n > GetArrayNode()->capacity_) {
572 if (data_ !=
nullptr) {
586 void Set(int64_t i, T value) {
588 ICHECK(0 <= i && i < p->size_)
589 <<
"IndexError: indexing " << i <<
" on an array of size " << p->size_;
590 *(p->MutableBegin() + i) = std::move(value);
615 template <
typename F,
typename U = std::invoke_result_t<F, T>>
617 return Array<U>(MapHelper(data_, fmap));
626 template <
typename F,
typename = std::enable_if_t<std::is_same_v<T, std::invoke_result_t<F, T>>>>
628 data_ = MapHelper(std::move(data_), fmutate);
637 template <
typename IterType>
638 void Assign(IterType first, IterType last) {
639 int64_t cap = std::distance(first, last);
640 ICHECK_GE(cap, 0) <<
"ValueError: cannot construct an Array of negative size";
642 if (p !=
nullptr && data_.
unique() && p->capacity_ >= cap) {
647 data_ = ArrayNode::Empty(cap);
652 for (int64_t& i = p->size_ = 0; i < cap; ++i, ++first, ++itr) {
666 if (data_ ==
nullptr) {
667 return SwitchContainer(ArrayNode::kInitSize);
669 if (!data_.unique()) {
670 return SwitchContainer(capacity());
672 return static_cast<ArrayNode*
>(data_.get());
684 ArrayNode* CopyOnWrite(int64_t reserve_extra) {
688 const int64_t kInitSize = ArrayNode::kInitSize;
689 return SwitchContainer(
std::max(kInitSize, reserve_extra));
691 if (p->capacity_ >= p->size_ + reserve_extra) {
692 return CopyOnWrite();
694 int64_t cap = p->capacity_ * ArrayNode::kIncFactor;
695 cap =
std::max(cap, p->size_ + reserve_extra);
696 return SwitchContainer(cap);
703 ArrayNode* SwitchContainer(int64_t capacity) {
704 if (data_ ==
nullptr) {
705 data_ = ArrayNode::Empty(capacity);
706 }
else if (data_.unique()) {
711 return static_cast<ArrayNode*
>(data_.get());
736 template <
typename F,
typename U = std::invoke_result_t<F, T>>
738 if (data ==
nullptr) {
744 constexpr
bool is_same_output_type = std::is_same_v<T, U>;
746 if constexpr (is_same_output_type) {
752 for (
auto it = arr->MutableBegin(); it != arr->MutableEnd(); it++) {
753 T mapped = fmap(DowncastNoCheck<T>(std::move(*it)));
754 *it = std::move(mapped);
760 constexpr
bool compatible_types = is_valid_iterator_v<T, U*> || is_valid_iterator_v<U, T*>;
765 auto it = arr->
begin();
766 if constexpr (compatible_types) {
773 bool all_identical =
true;
774 for (; it != arr->end(); it++) {
775 U mapped = fmap(DowncastNoCheck<T>(*it));
776 if (!mapped.same_as(*it)) {
782 all_identical =
false;
784 output->InitRange(0, arr->begin(), it);
785 output->SetItem(it - arr->begin(), std::move(mapped));
818 for (; it != arr->end(); it++) {
819 U mapped = fmap(DowncastNoCheck<T>(*it));
820 output->SetItem(it - arr->begin(), std::move(mapped));
833 template <
typename T,
834 typename =
typename std::enable_if<std::is_base_of<ObjectRef, T>::value>::type>
836 for (
const auto& x : rhs) {
839 return std::move(lhs);
845 return ArrayNode::Empty();
855 #endif // TVM_RUNTIME_CONTAINER_ARRAY_H_ void reserve(int64_t n)
Make sure the list has the capacity of at least n.
Definition: array.h:564
static constexpr const uint32_t _type_index
Definition: array.h:122
array node content in array
Definition: array.h:40
const T operator[](int64_t i) const
Immutably read i-th element from array.
Definition: array.h:409
Managed reference to IterSplitExprNode.
Definition: iter_affine_map.h:187
A custom smart pointer for Object.
Definition: object.h:358
Runtime Optional container types.
void insert(iterator position, IterType first, IterType last)
Insert a range of elements into the given position.
Definition: array.h:483
Array(Array< T > &&other)
move constructor
Definition: array.h:302
TVM_DECLARE_FINAL_OBJECT_INFO(ArrayNode, Object)
T ResultType
Definition: array.h:377
void SetItem(int64_t i, ObjectRef item)
Set i-th element of the array in-place.
Definition: array.h:66
const T back() const
Definition: array.h:441
runtime implementation for LibTorch/TorchScript.
Definition: analyzer.h:36
static ObjectPtr< ArrayNode > CopyFrom(int64_t cap, ArrayNode *from)
Constructs a container and copy from another.
Definition: array.h:74
bool empty() const
Definition: array.h:430
iterator adapter that adapts TIter to return another type.
Definition: base.h:241
void resize(int64_t n)
Resize the array.
Definition: array.h:546
size_t size() const
Definition: array.h:43
Base utilities for common POD(plain old data) container types.
const ObjectRef * end() const
Definition: array.h:56
Array(const size_t n, const T &val)
Constructs a container with n elements. Each element is a copy of val.
Definition: array.h:352
friend ObjectPtr< ArrayNode > make_object()
Definition: array.h:844
ArrayNode * GetArrayNode() const
Definition: array.h:594
base class of all object containers.
Definition: object.h:167
Array()
default constructor
Definition: array.h:296
void Set(int64_t i, T value)
set i-th element of the array.
Definition: array.h:586
Array< T > & operator=(const Array< T > &other)
copy assign operator
Definition: array.h:369
void push_back(const T &item)
push a new item to the back of the list
Definition: array.h:455
Base template for classes with array like memory layout.
Definition: base.h:100
const ObjectRef * begin() const
Definition: array.h:53
void insert(iterator position, const T &val)
Insert an element into the given position.
Definition: array.h:465
size_t size() const
Definition: array.h:418
const T front() const
Definition: array.h:433
void erase(iterator position)
Erase an element on the given position.
Definition: array.h:509
Array, container representing a contiguous sequence of ObjectRefs.
Definition: array.h:289
bool unique() const
Definition: object.h:862
ObjectPtr< Object > data_
Internal pointer that backs the reference.
Definition: object.h:574
Array(const Array< T > &other)
copy constructor
Definition: array.h:310
void erase(iterator first, iterator last)
Erase a given range of elements.
Definition: array.h:525
PrimExpr max(PrimExpr a, PrimExpr b, Span span=Span())
take maximum of two values
void clear()
Release reference to all the elements.
Definition: array.h:59
reverse_iterator rbegin() const
Definition: array.h:391
void * AddressOf(size_t idx) const
Return the raw pointer to the element at idx.
Definition: base.h:169
Array(IterType first, IterType last)
Constructor from iterator.
Definition: array.h:327
iterator end() const
Definition: array.h:388
Base class of all object reference.
Definition: object.h:511
Array(const std::vector< T > &init)
constructor from vector
Definition: array.h:343
iterator begin() const
Definition: array.h:385
T * get() const
Definition: object.h:411
ArrayNode * CopyOnWrite()
Copy on write semantics Do nothing if current handle is the unique copy of the array. Otherwise make a new copy of the array to ensure the current handle hold a unique copy.
Definition: array.h:665
Array< T > & operator=(Array< T > &&other)
move assign operator
Definition: array.h:359
iterator adapter that adapts TIter to return another type.
Definition: base.h:188
bool unique() const
Definition: object.h:458
static constexpr const char * _type_key
Definition: array.h:123
Helper struct for type-checking.
Definition: array.h:260
void MutateByApply(F fmutate)
Helper function to apply fmutate to mutate an array.
Definition: array.h:627
runtime::Array.
Definition: object.h:68
const ObjectRef at(int64_t i) const
Read i-th element from array.
Definition: array.h:50
size_t capacity() const
Definition: array.h:424
const ObjectRef & operator[](size_t idx) const
Access element at index.
Definition: base.h:107
Optional container that to represent to a Nullable variant of T.
Definition: optional.h:51
void pop_back()
Remove the last item of the list.
Definition: array.h:498
reverse_iterator rend() const
Definition: array.h:397
void Assign(IterType first, IterType last)
reset the array to content from iterator.
Definition: array.h:638
static T convert(const ObjectRef &n)
Definition: array.h:378
constexpr bool is_valid_iterator_v
Definition: array.h:268
Array(std::initializer_list< T > init)
constructor from initializer list
Definition: array.h:335
void EmplaceInit(size_t idx, Args &&... args)
Construct a value in place with the arguments.
Definition: base.h:149
Array< U > Map(F fmap) const
Helper function to apply a map function onto the array.
Definition: array.h:616
static ObjectPtr< ArrayNode > CreateRepeated(int64_t n, const ObjectRef &val)
Constructs a container with n elements. Each element is a copy of val.
Definition: array.h:113
Array(ObjectPtr< Object > n)
constructor from pointer
Definition: array.h:318
Array< T > Concat(Array< T > lhs, const Array< T > &rhs)
Concat two Arrays.
Definition: array.h:835
void clear()
Release reference to all the elements.
Definition: array.h:571
static ObjectPtr< ArrayNode > MoveFrom(int64_t cap, ArrayNode *from)
Constructs a container and move from another.
Definition: array.h:93