@@ -194,6 +194,18 @@ class TclList {
194
194
return this ->_obj ;
195
195
}
196
196
197
+ Tcl_Obj* operator *(size_t idx) {
198
+ int count;
199
+ Tcl_Obj* objp;
200
+
201
+ Tcl_ListObjLength (this ->_interp , this ->_obj , &count);
202
+ if (idx >= count)
203
+ return nullptr ;
204
+ Tcl_ListObjIndex (this ->_interp , this ->_obj , idx, &objp);
205
+
206
+ return tcl_obj_getptr<T>(objp);
207
+ }
208
+
197
209
/* *
198
210
* @brief Iterator
199
211
* Dereferencing it yields a pointer to a C++ object
@@ -203,11 +215,10 @@ class TclList {
203
215
* return `TclList<T>` for `TclList<TclList<T>>::Iterator::operaotr*()`.
204
216
* Primitive TCL types might also need a specialized handling.
205
217
*/
206
- template <class dummy >
207
218
class Iterator {
208
219
public:
209
220
Iterator& operator =(const Iterator& other) {
210
- this ->_idx = other-> _idx ;
221
+ this ->_idx = other. _idx ;
211
222
return *this ;
212
223
}
213
224
@@ -237,14 +248,14 @@ class TclList {
237
248
Tcl_Obj* _obj; /* Underlying Tcl_Obj representing the list */
238
249
};
239
250
240
- Iterator< void > begin () {
241
- return Iterator< void > (this ->_interp , this ->_obj , 0 );
251
+ Iterator begin () {
252
+ return Iterator (this ->_interp , this ->_obj , 0 );
242
253
}
243
254
244
- Iterator< void > end () {
255
+ Iterator end () {
245
256
int count;
246
257
Tcl_ListObjLength (this ->_interp , this ->_obj , &count);
247
- return Iterator< void > (this ->_interp , this ->_obj , count);
258
+ return Iterator (this ->_interp , this ->_obj , count);
248
259
}
249
260
250
261
/* *
@@ -261,7 +272,113 @@ class TclList {
261
272
Tcl_Obj* _obj; /* Underlying Tcl_Obj representing the list */
262
273
};
263
274
275
+ class TclDynList {
276
+ public:
277
+ /* *
278
+ * @brief Create empty TCL list
279
+ */
280
+ inline TclDynList (Tcl_Interp* interp)
281
+ : _interp(interp)
282
+ , _obj(Tcl_NewListObj(0 , nullptr )) {}
283
+
284
+ /* *
285
+ * @brief Import a TCL list from Tcl_Obj of list type, or create one-element list from
286
+ * object of any other type.
287
+ */
288
+ TclDynList (Tcl_Interp* interp, Tcl_Obj* obj);
289
+
290
+ /* *
291
+ * @brief Get the raw TCL_Obj representing the list.
292
+ */
293
+ inline Tcl_Obj* tcl_obj () {
294
+ return this ->_obj ;
295
+ }
296
+
297
+ Tcl_Obj* operator [](size_t idx);
298
+
299
+ template <typename T>
300
+ Tcl_Obj* at (size_t idx) {
301
+ Tcl_Obj* obj = (*this )[idx];
302
+ if (obj == nullptr )
303
+ return nullptr ;
304
+ return tcl_obj_getptr<T>(obj);
305
+ }
306
+
307
+ /* *
308
+ * @brief Iterator
309
+ * Dereferencing it yields a pointer to a C++ object
310
+ *
311
+ * TODO: If we ever need to handle a TCL list of TCL lists this won't work. It might be possible to use
312
+ * template spcializations to derive a class with alternative implementation of `operator*()` that would
313
+ * return `TclList<T>` for `TclList<TclList<T>>::Iterator::operaotr*()`.
314
+ * Primitive TCL types might also need a specialized handling.
315
+ */
316
+ class Iterator {
317
+ public:
318
+ inline Iterator& operator =(const Iterator& other) {
319
+ this ->_idx = other._idx ;
320
+ return *this ;
321
+ }
322
+
323
+ inline Iterator& operator ++() {
324
+ this ->_idx ++;
325
+ return *this ;
326
+ }
327
+
328
+ inline bool operator !=(const Iterator& other) {
329
+ return (this ->_interp != other._interp ) || (this ->_obj != other._obj ) || (this ->_idx != other._idx );
330
+ }
331
+
332
+ inline Tcl_Obj* operator *() const {
333
+ Tcl_Obj* objp;
334
+ Tcl_ListObjIndex (this ->_interp , this ->_obj , this ->_idx , &objp);
335
+ return objp;
336
+ }
337
+
338
+ template <typename T>
339
+ inline T* at () const {
340
+ return tcl_obj_getptr<T>(**this );
341
+ }
342
+
343
+ inline Iterator (Tcl_Interp* interp, Tcl_Obj* obj, int idx)
344
+ : _interp(interp)
345
+ , _obj(obj)
346
+ , _idx(idx) {}
347
+
348
+ protected:
349
+ Tcl_Interp* _interp;
350
+ int _idx; /* Currently visited index on the list */
351
+ Tcl_Obj* _obj; /* Underlying Tcl_Obj representing the list */
352
+ };
353
+
354
+ inline Iterator begin () {
355
+ return Iterator (this ->_interp , this ->_obj , 0 );
356
+ }
357
+
358
+ inline Iterator end () {
359
+ int count;
360
+ Tcl_ListObjLength (this ->_interp , this ->_obj , &count);
361
+ return Iterator (this ->_interp , this ->_obj , count);
362
+ }
363
+
364
+ /* *
365
+ * @brief Get number of elements on the list.
366
+ */
367
+ inline size_t size () const {
368
+ int len;
369
+ Tcl_ListObjLength (this ->_interp , this ->_obj , &len);
370
+ return size_t (len);
371
+ }
372
+
373
+ protected:
374
+ Tcl_Interp* _interp;
375
+ Tcl_Obj* _obj; /* Underlying Tcl_Obj representing the list */
376
+ };
377
+
264
378
class TclCtx ;
379
+ class TclClient ;
380
+
381
+ TclDynList tcl_obj_getdynlist (TclClient* client, Tcl_Obj* obj);
265
382
266
383
/* *
267
384
* @brief Provide a C++ state with TCL interface.
@@ -380,6 +497,7 @@ class TclClient {
380
497
friend class TclCtx ;
381
498
template <typename T>
382
499
friend TclList<T> tcl_obj_getlist (TclClient* client, Tcl_Obj* obj);
500
+ friend TclDynList tcl_obj_getdynlist (TclClient* client, Tcl_Obj* obj);
383
501
384
502
Tcl_Interp* _interp;
385
503
};
0 commit comments