3838#include < list>
3939#include < vector>
4040
41- namespace tiledb ::sm {
42- class MemoryTracker ;
43- }
44-
4541namespace tiledb ::common {
4642
43+ namespace detail {
44+ template <typename T>
45+ class WhiteboxIndexedList ;
46+ }
47+
4748/* *
4849 * Container class for data that cannot be moved but that we want to access by
4950 * an index.
@@ -52,7 +53,136 @@ namespace tiledb::common {
5253 */
5354template <class T >
5455class IndexedList {
56+ using Self = IndexedList<T>;
57+ using Elements = tdb::pmr::list<T>;
58+ using Indexes = std::vector<T*>;
59+
60+ friend class detail ::WhiteboxIndexedList<T>;
61+
5562 public:
63+ /* *
64+ * Iterator handle to a mutable element of an `IndexedList`.
65+ */
66+ class iterator {
67+ Elements::iterator elt_;
68+ Indexes::iterator idx_;
69+
70+ friend class IndexedList <T>;
71+
72+ iterator (Elements::iterator elt, Indexes::iterator idx)
73+ : elt_(elt)
74+ , idx_(idx) {
75+ }
76+
77+ public:
78+ using difference_type = int64_t ;
79+ using value_type = T;
80+
81+ T& operator *() const {
82+ return *elt_;
83+ }
84+
85+ T* operator ->() const {
86+ return &*elt_;
87+ }
88+
89+ iterator& operator ++() {
90+ ++elt_;
91+ ++idx_;
92+ return *this ;
93+ }
94+
95+ iterator& operator ++(int ) {
96+ elt_++;
97+ idx_++;
98+ return *this ;
99+ }
100+
101+ iterator& operator --() {
102+ --elt_;
103+ --idx_;
104+ return *this ;
105+ }
106+
107+ iterator& operator --(int ) {
108+ elt_--;
109+ idx_--;
110+ return *this ;
111+ }
112+
113+ bool operator ==(const iterator& other) const {
114+ return elt_ == other.elt_ ;
115+ }
116+
117+ bool operator !=(const iterator& other) const {
118+ return !(*this == other);
119+ }
120+ };
121+
122+ /* *
123+ * Iterator handle to an immutable element of an `IndexedList`.
124+ */
125+ class const_iterator {
126+ Elements::const_iterator elt_;
127+ Indexes::const_iterator idx_;
128+
129+ friend class IndexedList <T>;
130+
131+ const_iterator (Elements::const_iterator elt, Indexes::const_iterator idx)
132+ : elt_(elt)
133+ , idx_(idx) {
134+ }
135+
136+ public:
137+ using difference_type = int64_t ;
138+ using value_type = T;
139+
140+ const_iterator (IndexedList<T>::iterator ii)
141+ : elt_(ii.elt_)
142+ , idx_(ii.idx_) {
143+ }
144+
145+ const T& operator *() const {
146+ return *elt_;
147+ }
148+
149+ const T* operator ->() const {
150+ return &*elt_;
151+ }
152+
153+ const_iterator& operator ++() {
154+ ++elt_;
155+ ++idx_;
156+ return *this ;
157+ }
158+
159+ const_iterator& operator ++(int ) {
160+ elt_++;
161+ idx_++;
162+ return *this ;
163+ }
164+
165+ const_iterator& operator --() {
166+ --elt_;
167+ --idx_;
168+ return *this ;
169+ }
170+
171+ const_iterator& operator --(int ) {
172+ elt_--;
173+ idx_--;
174+ return *this ;
175+ }
176+
177+ bool operator ==(const const_iterator& other) const {
178+ return elt_ == other.elt_ ;
179+ }
180+
181+ bool operator !=(const const_iterator& other) const {
182+ return !(*this == other);
183+ }
184+ };
185+
56186 /* ********************************* */
57187 /* CONSTRUCTORS & DESTRUCTORS */
58188 /* ********************************* */
@@ -65,7 +195,9 @@ class IndexedList {
65195 *
66196 * @param memory_tracker The memory tracker for the underlying containers.
67197 */
68- explicit IndexedList (shared_ptr<sm::MemoryTracker> memory_tracker);
198+ explicit IndexedList (pmr::memory_resource* resource)
199+ : list_(resource) {
200+ }
69201
70202 DISABLE_COPY_AND_COPY_ASSIGN (IndexedList);
71203 DISABLE_MOVE_AND_MOVE_ASSIGN (IndexedList);
@@ -92,24 +224,20 @@ class IndexedList {
92224 return list_.get_allocator ();
93225 }
94226
95- /* * Returns an iterator to the beginning of the items. */
96- typename std::list<T>::iterator begin () {
97- return list_.begin ();
227+ iterator begin () {
228+ return iterator (list_.begin (), vec_.begin ());
98229 }
99230
100- /* * Returns an iterator to the beginning of the items. */
101- typename std::list<T>::const_iterator begin () const {
102- return list_.begin ();
231+ const_iterator begin () const {
232+ return const_iterator (list_.begin (), vec_.begin ());
103233 }
104234
105- /* * Returns an iterator to the end of the items. */
106- typename std::list<T>::iterator end () {
107- return list_.end ();
235+ iterator end () {
236+ return iterator (list_.end (), vec_.end ());
108237 }
109238
110- /* * Returns an iterator to the end of the items. */
111- typename std::list<T>::const_iterator end () const {
112- return list_.end ();
239+ const_iterator end () const {
240+ return const_iterator (list_.end (), vec_.end ());
113241 }
114242
115243 /* * Returns wether the container is empty or not. */
@@ -144,15 +272,21 @@ class IndexedList {
144272 *
145273 * @param num Number of items to add.
146274 */
147- void resize (size_t num) {
275+ template <std::copyable... Args>
276+ void resize (size_t num, Args... args) {
148277 if (list_.size () != 0 || vec_.size () != 0 ) {
149278 throw std::logic_error (
150279 " Resize should only be called on empty container." );
151280 }
152281
153282 vec_.reserve (num);
154283 for (uint64_t n = 0 ; n < num; n++) {
155- emplace_back (memory_tracker_);
284+ std::tuple<std::decay_t <Args>...> copied_args (args...);
285+ std::apply (
286+ [this ](auto &&... copied_arg) {
287+ this ->emplace_back <Args...>(std::move (copied_arg)...);
288+ },
289+ copied_args);
156290 }
157291 }
158292
@@ -204,15 +338,48 @@ class IndexedList {
204338 return *(vec_.at (index));
205339 }
206340
207- private:
208- /* * The memory tracker for the underlying list. */
209- shared_ptr<sm::MemoryTracker> memory_tracker_;
341+ /* *
342+ * @return a pointer to the last element of the list
343+ */
344+ T* back () {
345+ if (empty ()) {
346+ return nullptr ;
347+ } else {
348+ return vec_.back ();
349+ }
350+ }
210351
352+ /* *
353+ * @return a pointer to the last element of the list
354+ */
355+ const T* back () const {
356+ if (empty ()) {
357+ return nullptr ;
358+ } else {
359+ return vec_.back ();
360+ }
361+ }
362+
363+ /* *
364+ * Transfers the elements from `other` between its positions `first` and
365+ * `last` to `*this`. The elements are inserted at `pos`.
366+ */
367+ void splice (
368+ const_iterator pos,
369+ Self& other,
370+ const_iterator first,
371+ const_iterator last) {
372+ list_.splice (pos.elt_ , other.list_ , first.elt_ , last.elt_ );
373+ vec_.insert (pos.idx_ , first.idx_ , last.idx_ );
374+ other.vec_ .erase (first.idx_ , last.idx_ );
375+ }
376+
377+ private:
211378 /* * List that contains all the elements. */
212- tdb::pmr::list<T> list_;
379+ Elements list_;
213380
214381 /* * Vector that contains a pointer to the elements allowing indexed access. */
215- std::vector<T*> vec_;
382+ Indexes vec_;
216383};
217384
218385} // namespace tiledb::common
0 commit comments