Common Structures

Iterators

Iterators provide a container-independent way to access elements in an aggregate structure without exposing or requiring any underlying structure. This vital implementation intends to provide an easy way to create an input iterator via a value reference generation function, similar to how iterators in the python language function.

Each iterator class descends from a common base-class due to a wealth of shared functionality. This base class has protected constructors in order to prevent direct use.

It is currently undefined behavior when dereferencing an iterator after source data has been released (e.g. if the next_value_func is iterating over a vector of values and the source vector is released in the middle of iteration).

Generation Function

The value reference generation function’s purpose is to return the reference to the next value of type T in a sequence every time it is called. When the end of a specific is reached, an exception is raised to signal the end of iteration.`

Upon incrementing this iterator, this next function is called and the reference it returns is retained in order to yield the value or reference when the * or -> operator is invoked on this iterator.

Generator function caveat: Since the next-value generator function is to return references, the function should ideally return unique references every time it is called. If this is not the case, the prefix-increment operator does not function correctly since the returned iterator copy and old, incremented iterator share the same reference and thus share the same value yielded.

Providing a function

Next value functions can be provided in various ways from existing functions to functions created on the fly. Usually, inline structure definitions or lambda functions are used to provide the next-value functionality.

For example, the following shows how to use a lambda function to satisfy the next_value_func parameter for a vital::iterator of type int:

int a[] = { 0, 1, 2, 3 };
using iterator_t = vital::iterator< int >;
iterator_t it( []() ->iterator_t::reference {
  static size_t i = 0;
  if( i == 4 ) throw vital::stop_iteration_exception();
  return a[i++];
} );

Similarly an inline structure that overloads operator() can be provided if more state needs to be tracked:

using iterator_t = vital::iterator< int >;
struct next_int_generator
{
  int *a;
  size_t len;
  size_t idx;

  next_int_generator(int *a, size_t len )
   : a( a )
   , len( len )
   , idx( 0 )
  {}

  iterator_t::reference operator()()
  {
    if( idx == len ) throw vital::stop_iteration_exception();
    return a[idx++];
  }
};
int a[] = {0, 1, 2, 3};
iterator_t it( next_int_generator(a, 4) );
template<typename T, typename Tb>
class base_iterator

Internal base class for vital iterator types, fulfilling the input-iterator concept.

Template Parameters
  • T: Value type being iterated over. This should not be const.
  • Tb: Base type for references and pointers. This will will be the same as T for a non-const iterator and the const version of T for a const iterator.

Public Functions

virtual ~base_iterator()

Default destructor.

virtual base_iterator<T, Tb> &operator=(base_iterator<T, Tb> const &rhs)

Assignment operator overload

Assigning another iterator to this iterator copies the other iterator’s next value function, current value pointer and past-end state flag. Remember that copying the other iterator’s next-value function does not copy that function’s state and iterations by the other iterator now affect iteration returns of this iterator.

Return
Reference to this iterator instance.
Parameters
  • rhs: Other iterator instance to assign to this iterator instance.

virtual base_iterator<T, Tb> &operator++()

Prefix increment operator overload (e.g. ++i)

This requests and stores the reference to the next value provided by the generation function.

Return
Reference to this iterator instance.

virtual base_iterator<T, Tb> operator++(int)

Postfix increment operator overload (e.g. i++).

Return
A copy of this iterator before requesting the next value reference. If the next value function does not return sequentially unique references, then the returned iterator’s reference will point to the same value as this iterator.

virtual value_type operator*() const

Dereference operator overload

Return
A copy of the current iteration reference.

virtual pointer operator->() const

Arrow operator overload

Return
Pointer to the current iteration reference.

Friends

bool operator==(base_iterator<T, Tb> const &lhs, base_iterator<T, Tb> const &rhs)

Equality operator overload

Two iterators are considered equal if their current iteration references are equal in value or both iterators in a past-end state. If one iterator is in a past-end state and the other is not, they two iterators will never be equal.

Return
If the two iterators are equal to each other.

bool operator!=(base_iterator<T, Tb> const &lhs, base_iterator<T, Tb> const &rhs)

Inequality operator overload

Return
If the two iterators is NOT equal to each other.

void swap(base_iterator<T, Tb> const &lhs, base_iterator<T, Tb> const &rhs)

Override of swap function between two same-type iterators.

Swaps function reference, current value pointer and past-end state boolean.

template<typename T>
class iterator : public kwiver::vital::base_iterator<T, T>

Vital templated non-const iterator class.

Template Parameters
  • T: Value type being iterated over.

Public Functions

iterator()

Construct default iterator.

A default constructed iterator is set to be a past-end iterator and is equal to any iterator past its end.

iterator(next_value_func_t const &next_value_func)

Construct iterator with a function to yield the next iteration value reference or raise a stop_iteration_exception.

Parameters
  • next_value_func: Function that returns the reference to the next value in a sequence until the end of that sequence, then raising the stop_iteration_exception.

iterator(iterator<T> const &other)

Copy Constructor (shallow)

Shallow copy iteration state from another iterator. This is shallow because the next-value function’s state is not fully copied, but now shared between the original and copied iterator. Thus, as one iterator is moved, the generation function state is changed, affecting subsequent generator function returns in the other iterator.

Parameters
  • other: Other iterator to copy from.

Friends

friend kwiver::vital::iterator::const_iterator< T >

Allow const_iterator to access protected members when copy-constructing from a non-const iterator instance.

template<typename T>
class const_iterator : public kwiver::vital::base_iterator<T, T const>

Vital templated const iterator class.

This class is similar to the vital::iterator except that returned references and pointers from dereferencing and arrow operators are const.

This subclass provides additional overloaded implementations of `friend bool operator== and friend bool operator!= for the different combinations of const and non-const iterator equality checks.

Template Parameters
  • T: Value type being iterated over.

Public Functions

const_iterator()

Construct default iterator.

A default constructed iterator is set to be a past-end iterator and is equal to any iterator past its end.

const_iterator(next_value_func_t const &next_value_func)

Construct iterator with a function to yield the next iteration value reference or raise a stop_iteration_exception.

Parameters
  • next_value_func: Function that returns the reference to the next value in a sequence until the end of that sequence, then raising the stop_iteration_exception.

const_iterator(const_iterator<T> const &other)

Copy Constructor (shallow)

Shallow copy iteration state from another iterator. This is shallow because the next-value function’s state is not fully copied, but now shared between the original and copied iterator. Thus, as one iterator is moved, the generation function state is changed, affecting subsequent generator function returns in the other iterator.

Parameters
  • other: Other iterator to copy from.

const_iterator(iterator<T> const &other)

Copy Constructor (shallow) from non-const iterator

Shallow copy iteration state from another iterator. This is shallow because the next-value function’s state is not fully copied, but now shared between the original and copied iterator. Thus, as one iterator is moved, the generation function state is changed, affecting subsequent generator function returns in the other iterator.

Parameters
  • other: Other iterator to copy from.

Friends

bool operator==(iterator<T> const &it, const_iterator<T> const &cit)

Friend operator== overload for testing [non-const, const] equality.

bool operator==(const_iterator<T> const &cit, iterator<T> const &it)

Friend operator== overload for testing [const, non-const] equality.

bool operator!=(iterator<T> const &it, const_iterator<T> const &cit)

Friend operator!= overload for testing [non-const, const] non-equality.

bool operator!=(const_iterator<T> const &cit, iterator<T> const &it)

Friend operator!= overload for testing [const, non-const] non-equality.

References

In creating this structure, the following were referenced for what composes input iterators as well as how this fits into C++ class and function definitions: