A library for working with phylogenetic data.
v0.25.0
TransformIterator< TransformFunctor, BaseIterator > Class Template Reference

#include <genesis/utils/containers/transform_iterator.hpp>

Detailed Description

template<typename TransformFunctor, typename BaseIterator>
class genesis::utils::TransformIterator< TransformFunctor, BaseIterator >

Iterator class that allows to transform an underlying iterator by applying a function to each element before dereferencing.

The constructor is used to set the transformation function. See also make_transform_iterator() and make_transform_range() for helper functions to easily create an instance.

This iterator takes the argument and return types of the TransformFunctor into account:

  • If the TransformFunctor returns by value, we copy that value into an internal cache. This way, in cases where the iterator is dereferenced multiple times at the same iteration position, we do not need to apply the TransformFunctor each time.
  • However, if the TransformFunctor returns by reference (const or non-const, but see also below), making a copy would be wasteful. Hence, in that case, we simply forward that reference here as well. This kind of transforming iterator is for example useful to efficiently select an entry from the underlying BaseIterator, e.g., an iterator over a std::pair<> could be transformed for selecting the first entry, without the need to copy that. If the TransformIterator is used that way, the underlying type does not even need to be copyable.
  • Lastly, if the TransformFunctor returns by non-const reference, the underlying element can also be modified!

When using lambda functions for the TransformFunctor, a bit of extra care is necessary to handle references correctly. In these cases, the return type has to be specified explicitly. For example, to select a particular entry, the following can be used:

// Some vector of vectors, e.g, a table of sorts.
std::vector<std::vector<LargeClass>> data;

// Fixed index of the element (i.e., the column when `data` is interpreted as a table)
// that we want to get from each of the rows of the above data.
size_t index = 2;

// Iterate the rows of data, and select a particular column index in each step.
// Have the lambda return those values per reference in order to avoid copies.
auto column_range = make_transform_range(
    [index]( std::vector<LargeClass> const& values ) -> LargeClass const& {
        assert( index < values.size() )
        return values[index];
    },
    data
);

// Print the resulting values.
for( auto const& value : column_range ) {
    std::cout << value << "\n";
}

Inspired by the Boost Transform Iterator (https://www.boost.org/doc/libs/1_66_0/libs/iterator/doc/html/iterator/specialized/transform.html) and the Intel TBB Transform Iterator (https://software.intel.com/content/www/us/en/develop/documentation/onetbb-documentation/top/intel-174-oneapi-threading-building-blocks-onetbb-developer-reference/iterators/transform-iterator.html). See also https://www.fluentcpp.com/2019/02/12/the-terrible-problem-of-incrementing-a-smart-iterator/ for a discussuion on the issue of calling the transform functor multiple times with caching. We went a bit above and beyond that, as explained above.

Definition at line 104 of file transform_iterator.hpp.

Public Member Functions

 TransformIterator (TransformFunctor unary_func, BaseIterator iterator)
 Construct a transforming iterator, given the underlying base iterator and the transformation function. More...
 
 TransformIterator (TransformIterator &&)=default
 
 TransformIterator (TransformIterator const &)=default
 
 ~TransformIterator ()=default
 
BaseIterator base () const
 
bool operator!= (TransformIterator const &it) const
 
return_typeoperator* () const
 
TransformIterator operator+ (difference_type n) const
 
TransformIteratoroperator++ ()
 
TransformIterator operator++ (int)
 
TransformIteratoroperator+= (difference_type n)
 
TransformIterator operator- (difference_type n) const
 
difference_type operator- (TransformIterator const &it) const
 
TransformIteratoroperator-- ()
 
TransformIterator operator-- (int)
 
TransformIteratoroperator-= (difference_type n)
 
return_typeoperator-> () const
 
bool operator< (TransformIterator const &it) const
 
bool operator<= (TransformIterator const &it) const
 
TransformIteratoroperator= (TransformIterator &&)=default
 
TransformIteratoroperator= (TransformIterator const &)=default
 
bool operator== (TransformIterator const &it) const
 
bool operator> (TransformIterator const &it) const
 
bool operator>= (TransformIterator const &it) const
 
return_typeoperator[] (difference_type i) const
 

Public Types

using cache_type = typename std::conditional< std::is_reference< result_type >::value, bool, result_type >::type
 
using difference_type = typename std::iterator_traits< BaseIterator >::difference_type
 
using iterator_category = typename std::iterator_traits< BaseIterator >::iterator_category
 
using pointer = return_type *
 
using reference = return_type &
 
using result_type = typename std::result_of< TransformFunctor(typename std::iterator_traits< BaseIterator >::reference) >::type
 
using return_type = typename std::remove_reference< result_type >::type
 
using value_type = return_type
 

Friends

TransformIterator operator+ (difference_type n, TransformIterator const &it)
 

Constructor & Destructor Documentation

◆ TransformIterator() [1/3]

TransformIterator ( TransformFunctor  unary_func,
BaseIterator  iterator 
)
inline

Construct a transforming iterator, given the underlying base iterator and the transformation function.

This constructor needs to be used for both the begin and end of the range that one wants to iterate, using the same transformation function both times. See also make_transform_iterator() and make_transform_range() for helper functions to easily create an instance.

Definition at line 167 of file transform_iterator.hpp.

◆ ~TransformIterator()

~TransformIterator ( )
default

◆ TransformIterator() [2/3]

TransformIterator ( TransformIterator< TransformFunctor, BaseIterator > const &  )
default

◆ TransformIterator() [3/3]

TransformIterator ( TransformIterator< TransformFunctor, BaseIterator > &&  )
default

Member Function Documentation

◆ base()

BaseIterator base ( ) const
inline

Definition at line 222 of file transform_iterator.hpp.

◆ operator!=()

bool operator!= ( TransformIterator< TransformFunctor, BaseIterator > const &  it) const
inline

Definition at line 306 of file transform_iterator.hpp.

◆ operator*()

return_type& operator* ( ) const
inline

Definition at line 207 of file transform_iterator.hpp.

◆ operator+()

TransformIterator operator+ ( difference_type  n) const
inline

Definition at line 259 of file transform_iterator.hpp.

◆ operator++() [1/2]

TransformIterator& operator++ ( )
inline

Definition at line 231 of file transform_iterator.hpp.

◆ operator++() [2/2]

TransformIterator operator++ ( int  )
inline

Definition at line 245 of file transform_iterator.hpp.

◆ operator+=()

TransformIterator& operator+= ( difference_type  n)
inline

Definition at line 269 of file transform_iterator.hpp.

◆ operator-() [1/2]

TransformIterator operator- ( difference_type  n) const
inline

Definition at line 264 of file transform_iterator.hpp.

◆ operator-() [2/2]

difference_type operator- ( TransformIterator< TransformFunctor, BaseIterator > const &  it) const
inline

Definition at line 292 of file transform_iterator.hpp.

◆ operator--() [1/2]

TransformIterator& operator-- ( )
inline

Definition at line 238 of file transform_iterator.hpp.

◆ operator--() [2/2]

TransformIterator operator-- ( int  )
inline

Definition at line 252 of file transform_iterator.hpp.

◆ operator-=()

TransformIterator& operator-= ( difference_type  n)
inline

Definition at line 276 of file transform_iterator.hpp.

◆ operator->()

return_type* operator-> ( ) const
inline

Definition at line 212 of file transform_iterator.hpp.

◆ operator<()

bool operator< ( TransformIterator< TransformFunctor, BaseIterator > const &  it) const
inline

Definition at line 311 of file transform_iterator.hpp.

◆ operator<=()

bool operator<= ( TransformIterator< TransformFunctor, BaseIterator > const &  it) const
inline

Definition at line 321 of file transform_iterator.hpp.

◆ operator=() [1/2]

TransformIterator& operator= ( TransformIterator< TransformFunctor, BaseIterator > &&  )
default

◆ operator=() [2/2]

TransformIterator& operator= ( TransformIterator< TransformFunctor, BaseIterator > const &  )
default

◆ operator==()

bool operator== ( TransformIterator< TransformFunctor, BaseIterator > const &  it) const
inline

Definition at line 301 of file transform_iterator.hpp.

◆ operator>()

bool operator> ( TransformIterator< TransformFunctor, BaseIterator > const &  it) const
inline

Definition at line 316 of file transform_iterator.hpp.

◆ operator>=()

bool operator>= ( TransformIterator< TransformFunctor, BaseIterator > const &  it) const
inline

Definition at line 326 of file transform_iterator.hpp.

◆ operator[]()

return_type& operator[] ( difference_type  i) const
inline

Definition at line 217 of file transform_iterator.hpp.

Friends And Related Function Documentation

◆ operator+

TransformIterator operator+ ( difference_type  n,
TransformIterator< TransformFunctor, BaseIterator > const &  it 
)
friend

Definition at line 287 of file transform_iterator.hpp.

Member Typedef Documentation

◆ cache_type

using cache_type = typename std::conditional< std::is_reference<result_type>::value, bool, result_type >::type

Definition at line 127 of file transform_iterator.hpp.

◆ difference_type

using difference_type = typename std::iterator_traits<BaseIterator>::difference_type

Definition at line 153 of file transform_iterator.hpp.

◆ iterator_category

using iterator_category = typename std::iterator_traits<BaseIterator>::iterator_category

Definition at line 152 of file transform_iterator.hpp.

◆ pointer

using pointer = return_type*

Definition at line 144 of file transform_iterator.hpp.

◆ reference

Definition at line 145 of file transform_iterator.hpp.

◆ result_type

using result_type = typename std::result_of< TransformFunctor( typename std::iterator_traits<BaseIterator>::reference ) >::type

Definition at line 115 of file transform_iterator.hpp.

◆ return_type

using return_type = typename std::remove_reference<result_type>::type

Definition at line 134 of file transform_iterator.hpp.

◆ value_type

Definition at line 143 of file transform_iterator.hpp.


The documentation for this class was generated from the following file: