Skip to content

Commit 2e36fa9

Browse files
Add STL forward iterators to DLL container.
1 parent b85d9fd commit 2e36fa9

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed

include/tscore/List.h

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,94 @@ template <class C, class L = typename C::Link_link> struct DLL {
256256
}
257257

258258
DLL() : head(nullptr) {}
259+
260+
/// STL compliant iterator.
261+
class iterator : public std::forward_iterator_tag
262+
{
263+
friend DLL;
264+
using self_type = iterator; ///< Self reference type.
265+
C *_spot = nullptr; ///< Current location in the list.
266+
public:
267+
/// STL compliance type definitions.
268+
/// @{
269+
using size_type = size_t;
270+
using value_type = C;
271+
using pointer = C *;
272+
using reference = C &;
273+
/// @}
274+
275+
iterator() = default; ///< Construct empty iteratgor.
276+
277+
/// Dereference operator.
278+
C &operator*();
279+
280+
/// Indirection operator.
281+
C *operator->();
282+
283+
/// Pre-increment.
284+
self_type &operator++();
285+
286+
/// Post-increment.
287+
self_type operator++(int);
288+
289+
/// Equality.
290+
bool operator==(self_type const &that);
291+
292+
/// Inequality.
293+
bool operator!=(self_type const &that);
294+
295+
protected:
296+
/// Construct for a specific element.
297+
iterator(C *spot) : _spot(spot) {}
298+
};
299+
300+
iterator begin();
301+
iterator end();
302+
303+
class const_iterator : public std::forward_iterator_tag
304+
{
305+
friend DLL;
306+
using self_type = iterator;
307+
C *_spot = nullptr; ///< Current location in the list.
308+
public:
309+
/// STL compliance type definitions.
310+
/// @{
311+
using size_type = size_t;
312+
using value_type = C const;
313+
using pointer = C const *;
314+
using reference = C const &;
315+
/// @}
316+
317+
const_iterator() = default; ///< Construct empty iterator.
318+
/// Convert from iterator to constant iterator.
319+
const_iterator(iterator spot) : _spot(spot._spot) {}
320+
321+
/// Dereference operator.
322+
C const &operator*();
323+
324+
/// Indirection operator.
325+
C const *operator->();
326+
327+
/// Pre-increment.
328+
self_type &operator++();
329+
330+
/// Post-increment.
331+
self_type operator++(int);
332+
333+
/// Equality.
334+
bool operator==(self_type const &that);
335+
336+
/// Inequality.
337+
bool operator!=(self_type const &that);
338+
339+
protected:
340+
const_iterator(C *spot) : _spot(spot) {}
341+
};
342+
343+
const_iterator begin() const;
344+
const_iterator end() const;
259345
};
346+
260347
#define DList(_c, _f) DLL<_c, _c::Link##_##_f>
261348
#define DListM(_c, _m, _ml, _l) DLL<_c, _c::Link##_##_ml##_##_l>
262349

@@ -316,6 +403,124 @@ DLL<C, L>::insert(C *e, C *after)
316403
prev(next(e)) = e;
317404
}
318405

406+
template <class C, class L>
407+
auto
408+
DLL<C, L>::begin() -> iterator
409+
{
410+
return iterator{head};
411+
}
412+
413+
template <class C, class L>
414+
auto
415+
DLL<C, L>::end() -> iterator
416+
{
417+
return iterator{};
418+
}
419+
420+
template <class C, class L>
421+
auto
422+
DLL<C, L>::begin() const -> const_iterator
423+
{
424+
return const_iterator{head};
425+
}
426+
template <class C, class L>
427+
428+
auto
429+
DLL<C, L>::end() const -> const_iterator
430+
{
431+
return const_iterator{};
432+
}
433+
434+
template <class C, class L>
435+
C &
436+
DLL<C, L>::iterator::operator*()
437+
{
438+
return *_spot;
439+
}
440+
441+
template <class C, class L>
442+
C *
443+
DLL<C, L>::iterator::operator->()
444+
{
445+
return _spot;
446+
}
447+
448+
template <class C, class L>
449+
auto
450+
DLL<C, L>::iterator::operator++() -> self_type &
451+
{
452+
_spot = next(_spot);
453+
return *this;
454+
}
455+
456+
template <class C, class L>
457+
auto
458+
DLL<C, L>::iterator::operator++(int) -> self_type
459+
{
460+
self_type zret{*this};
461+
++*this;
462+
return zret;
463+
}
464+
465+
template <class C, class L>
466+
bool
467+
DLL<C, L>::iterator::operator==(DLL::iterator::self_type const &that)
468+
{
469+
return _spot == that._spot;
470+
}
471+
472+
template <class C, class L>
473+
bool
474+
DLL<C, L>::iterator::operator!=(DLL::iterator::self_type const &that)
475+
{
476+
return _spot != that._spot;
477+
}
478+
479+
template <class C, class L>
480+
C const &
481+
DLL<C, L>::const_iterator::operator*()
482+
{
483+
return *_spot;
484+
}
485+
486+
template <class C, class L>
487+
C const *
488+
DLL<C, L>::const_iterator::operator->()
489+
{
490+
return _spot;
491+
}
492+
493+
template <class C, class L>
494+
auto
495+
DLL<C, L>::const_iterator::operator++() -> self_type &
496+
{
497+
_spot = next(_spot);
498+
return *this;
499+
}
500+
501+
template <class C, class L>
502+
auto
503+
DLL<C, L>::const_iterator::operator++(int) -> self_type
504+
{
505+
self_type zret{*this};
506+
++*this;
507+
return zret;
508+
}
509+
510+
template <class C, class L>
511+
bool
512+
DLL<C, L>::const_iterator::operator==(DLL::const_iterator::self_type const &that)
513+
{
514+
return _spot == that._spot;
515+
}
516+
517+
template <class C, class L>
518+
bool
519+
DLL<C, L>::const_iterator::operator!=(DLL::const_iterator::self_type const &that)
520+
{
521+
return _spot != that._spot;
522+
}
523+
319524
//
320525
// List descriptor for queue of objects of type C.
321526
//

0 commit comments

Comments
 (0)