Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Iterator.h File Reference
#include "Stroika/Foundation/StroikaPreComp.h"
#include <compare>
#include <iterator>
#include <memory>
#include <optional>
#include <string>
#include "Stroika/Foundation/Common/Common.h"
#include "Stroika/Foundation/Memory/SharedByValue.h"
#include "Iterator.inl"

Go to the source code of this file.

Classes

struct  Stroika::Foundation::Traversal::DefaultIteratorTraits< CATEGORY, T, DIFF, POINTER, REFERENCE >
 
class  Stroika::Foundation::Traversal::Iterator< T, ITERATOR_TRAITS >
 An Iterator<T> is a copyable object which allows traversing the contents of some container. It is like an std::const_iterator. More...
 
class  Stroika::Foundation::Traversal::Iterator< T, ITERATOR_TRAITS >::IRep
 Implementation detail for iterator implementors. More...
 

Namespaces

namespace  Stroika::Foundation
 

Concepts

concept  Stroika::Foundation::Traversal::IInputIterator
 

Functions

template<typename ITERATOR >
constexpr iterator_traits< ITERATOR >::pointer Stroika::Foundation::Traversal::Iterator2Pointer (ITERATOR i)
 More clear way of writing '&*' - convert iterator to pointer.
 

Detailed Description

TODO

THIS IS BAD AND MUST BE REWRITEN - NOT WAHT WE WANT - TOO STRONG A PROMISE.

    The Major Design limitation of this approach to iterators is that it requires a non-inlinable
    function call per iteration (roughly). Basically - if you pass a callback into an iterator rep
    then to APPLY that function on each iteration requires a non-inlinable (indirect through pointer)
    function call, or if you do the reverse, and directly use the iterator so no you can inline
    apply the function, you must call a virtual function for each iteration to bump the next pointer.

    Fundamentally - you have multiple polymorphism (on representation of container and thing to apply
    at each iteration).

    Two tricks:
    (1)     Paging.
            Read a bunch at a time. This is tricky to implement and doesn't affect overall computational
            complexity (because it reduces number of virtual calls by a constant factor). But if that
            constant factor is big enough - 10-100-1000? - that still could be relevant pragmatically.

            The biggest challenge is preserving the existing safety and patch semantics generically,
            in light of update during iteration, and making sure for uses where that doesn't help its
            not allowed to hurt.

    (2)     special case common combinations. For example - at the point in the code where you have:
            Iterator<T> i;
            for (; i != e.end (); ++i) {
                do_this();
            }

            One could put in special purpose code for the Iterator<T>::operator++ that said:
            if (dynamic_cast<Sequence_Array::_IRep*> (myIRep) != nullptr) {
                then peek and cheat...
            }
            Maybe when the iterator is constructed - it checks for a couple important types
            and sets a flag, so the only cost when this doesn't work is checking that bool flag.
            And the benefit in the more common case is you avoid the virtual function call! so the it++ can be
            inlined (a big win often times).

Definition in file Iterator.h.

Function Documentation

◆ Iterator2Pointer()

template<typename ITERATOR >
constexpr iterator_traits< ITERATOR >::pointer Stroika::Foundation::Traversal::Iterator2Pointer ( ITERATOR  i)
constexpr

More clear way of writing '&*' - convert iterator to pointer.

Sometimes (especially when interacting with low level code) its handy to convert an iterator to a pointer. This is always legal for a short period (

But the idiom is somewhat queer, and wrapping in this method makes it a bit more clear.

Note
This returns a const pointer for a const_iterator, and a pointer for a regular (non-cost) iterator.

Definition at line 258 of file Iterator.inl.