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 ) { VITAL_THROW( vital::stop_iteration_exception, "container-name" ); }
  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 ) { VITAL_THROW( vital::stop_iteration_exception, "container-name" ); }
    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

Default destructor.

inline 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.

Parameters:

rhs – Other iterator instance to assign to this iterator instance.

Returns:

Reference to this iterator instance.

inline 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.

Returns:

Reference to this iterator instance.

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

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

Returns:

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.

inline virtual value_type operator*() const

Dereference operator overload

Returns:

A copy of the current iteration reference.

inline virtual pointer operator->() const

Arrow operator overload

Returns:

Pointer to the current iteration reference.

Friends

inline friend 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.

Returns:

If the two iterators are equal to each other.

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

Inequality operator overload

Returns:

If the two iterators is NOT equal to each other.

inline friend 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() = default

Construct default iterator.

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

inline 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.

inline 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 class const_iterator< T >
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() = default

Construct default iterator.

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

inline 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.

inline 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.

inline 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

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

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

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

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

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

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

inline friend 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:

Iterable Mixin

This mixin is intended to allow containers implemented in Vital to expose an iteration interface via the C++ standard begin and end methods.

template<typename T>
class iterable

Pure-virtual mixin class to add iteration support to a class.

Template Parameters:

Type – to iterate over.

Subclassed by kwiver::vital::set< descriptor_sptr >, kwiver::vital::set< image_container_sptr >, kwiver::vital::set< detected_object_sptr >, kwiver::vital::set< T >

Iterator Accessors

Accessors for const and non-const iterators

Get the non-const iterator to the beginning of the collection.

return:

An iterator over the objects in this collection.

inline virtual iterator end()

Get the non-const iterator past the end of the collection

Returns:

An iterator base the end of this collection.

inline virtual const_iterator cbegin() const

Get the const iterator to the beginning of the collection.

Returns:

An iterator over the objects in this collection.

inline virtual const_iterator cend() const

Get the const iterator past the end of the collection

Returns:

An iterator base the end of this collection.

Public Functions

iterable() = default

Constructor.

virtual ~iterable() = default

Destructor.