@@ -42,8 +42,18 @@ namespace tvm {
4242namespace ffi {
4343
4444/* ! \brief array node content in array */
45- class ArrayObj : public Object , public details ::InplaceArrayBase<ArrayObj, Any > {
45+ class ArrayObj : public Object , public details ::InplaceArrayBase<ArrayObj, TVMFFIAny > {
4646 public:
47+ ~ArrayObj () {
48+ Any* begin = MutableBegin ();
49+ for (int64_t i = 0 ; i < size_; ++i) {
50+ (begin + i)->Any ::~Any ();
51+ }
52+ if (data_deleter_ != nullptr ) {
53+ data_deleter_ (data_);
54+ }
55+ }
56+
4757 /* ! \return The size of the array */
4858 size_t size () const { return this ->size_ ; }
4959
@@ -52,10 +62,22 @@ class ArrayObj : public Object, public details::InplaceArrayBase<ArrayObj, Any>
5262 * \param i The index
5363 * \return the i-th element.
5464 */
55- const Any at (int64_t i) const { return this ->operator [](i); }
65+ const Any& at (int64_t i) const { return this ->operator [](i); }
66+
67+ /* !
68+ * \brief Read i-th element from array.
69+ * \param i The index
70+ * \return the i-th element.
71+ */
72+ const Any& operator [](int64_t i) const {
73+ if (i >= size_) {
74+ TVM_FFI_THROW (IndexError) << " Index " << i << " out of bounds " << size_;
75+ }
76+ return static_cast <Any*>(data_)[i];
77+ }
5678
5779 /* ! \return begin constant iterator */
58- const Any* begin () const { return static_cast <Any*>(InplaceArrayBase::AddressOf ( 0 ) ); }
80+ const Any* begin () const { return static_cast <Any*>(data_ ); }
5981
6082 /* ! \return end constant iterator */
6183 const Any* end () const { return begin () + size_; }
@@ -68,7 +90,12 @@ class ArrayObj : public Object, public details::InplaceArrayBase<ArrayObj, Any>
6890 * \param i The index
6991 * \param item The value to be set
7092 */
71- void SetItem (int64_t i, Any item) { this ->operator [](i) = std::move (item); }
93+ void SetItem (int64_t i, Any item) {
94+ if (i >= size_) {
95+ TVM_FFI_THROW (IndexError) << " Index " << i << " out of bounds " << size_;
96+ }
97+ static_cast <Any*>(data_)[i] = std::move (item);
98+ }
7299
73100 /* !
74101 * \brief Constructs a container and copy from another
@@ -138,21 +165,31 @@ class ArrayObj : public Object, public details::InplaceArrayBase<ArrayObj, Any>
138165 size_t GetSize () const { return this ->size_ ; }
139166
140167 /* ! \return begin mutable iterator */
141- Any* MutableBegin () const { return static_cast <Any*>(InplaceArrayBase::AddressOf ( 0 ) ); }
168+ Any* MutableBegin () const { return static_cast <Any*>(this -> data_ ); }
142169
143170 /* ! \return end mutable iterator */
144171 Any* MutableEnd () const { return MutableBegin () + size_; }
145172
173+ /* !
174+ * \brief Emplace a new element at the back of the array
175+ * \param args The arguments to construct the new element
176+ */
177+ template <typename ... Args>
178+ void EmplaceInit (size_t idx, Args&&... args) {
179+ Any* itr = MutableBegin () + idx;
180+ new (itr) Any (std::forward<Args>(args)...);
181+ }
182+
146183 /* !
147184 * \brief Create an ArrayObj with the given capacity.
148185 * \param n Required capacity
149186 * \return Ref-counted ArrayObj requested
150187 */
151188 static ObjectPtr<ArrayObj> Empty (int64_t n = kInitSize ) {
152- TVM_FFI_ICHECK_GE (n, 0 );
153189 ObjectPtr<ArrayObj> p = make_inplace_array_object<ArrayObj, Any>(n);
154190 p->capacity_ = n;
155191 p->size_ = 0 ;
192+ p->data_ = p->AddressOf (0 );
156193 return p;
157194 }
158195
@@ -235,11 +272,17 @@ class ArrayObj : public Object, public details::InplaceArrayBase<ArrayObj, Any>
235272 return this ;
236273 }
237274
275+ /* ! \brief Data pointer to the first element of the array */
276+ void * data_;
238277 /* ! \brief Number of elements used */
239278 int64_t size_;
240-
241279 /* ! \brief Number of elements allocated */
242280 int64_t capacity_;
281+ /* !
282+ * \brief Optional data deleter when data is allocated separately
283+ * and its deletion is not managed by ArrayObj::deleter_.
284+ */
285+ void (*data_deleter_)(void *) = nullptr ;
243286
244287 /* ! \brief Initial size of ArrayObj */
245288 static constexpr int64_t kInitSize = 4 ;
@@ -472,6 +515,12 @@ class Array : public ObjectRef {
472515 p->EmplaceInit (p->size_ ++, item);
473516 }
474517
518+ template <typename ... Args>
519+ void emplace_back (Args&&... args) {
520+ ArrayObj* p = CopyOnWrite (1 );
521+ p->EmplaceInit (p->size_ ++, std::forward<Args>(args)...);
522+ }
523+
475524 /* !
476525 * \brief Insert an element into the given position
477526 * \param position An iterator pointing to the insertion point
0 commit comments