Here are presented full listings of program examples used in
article
«iterator_pair - A Simple and Useful Iterator Adapter»
published by
ACCU Overload 126 (April, 2015). See
www.accu.org
You may leave your comments to the article in this thread.
Listing 1.
#include <iostream>
#include <algorithm>
#include <iterator>
#include <cstdlib>
#include <ctime>
int main()
{
const size_t N = 20;
int a[N], b[N], c[N];
std::srand( ( unsigned int )std::time( nullptr ) );
std::generate( std::begin( a ), std::end( a ),
[] { return ( std::rand() % ( N / 2 ) ); } );
std::cout << "A: ";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::generate( std::begin( b ), std::end( b ),
[] { return ( std::rand() % ( N / 2 ) ); } );
std::cout << "B: ";
for ( int x : b ) std::cout << x << ' ';
std::cout << std::endl;
std::transform( std::begin( a ), std::end( a ),
std::begin( b ),
std::begin( c ),
[] ( int x, int y )
{
return ( std::min( x, y ) );
} );
std::cout << "C: ";
for ( int x : c ) std::cout << x << ' ';
std::cout << std::endl;
}
The program might have the following output:
A: 2 0 3 7 2 4 0 4 2 2 6 5 3 6 7 0 6 9 0 2
B: 6 2 1 4 0 5 5 4 6 0 2 8 2 7 7 7 1 7 3 5
C: 2 0 1 4 0 4 0 4 2 0 2 5 2 6 7 0 1 7 0 2
Listing 2.
/* iterator_pair - iterator adapter for a pair of iterators
*
* (C) Copyright Vladimir N. Grigoriev 2013, 2014, 2015.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#ifndef ITERATOR_PAIR_H
#define ITERATOR_PAIR_H
#include <iterator>
#include <utility>
namespace usr
{
using namespace std;
template <class Iterator1, class Iterator2>
class iterator_pair
: public iterator<output_iterator_tag,
pair<typename iterator_traits<Iterator1>::value_type,
typename iterator_traits<Iterator2>::value_type>,
void,
void,
void>
{
public:
typedef pair<Iterator1, Iterator2> iterator_type;
iterator_pair( Iterator1, Iterator2 );
explicit iterator_pair( const pair<Iterator1, Iterator2> & );
explicit iterator_pair( pair<Iterator1, Iterator2> && );
iterator_type base() const;
iterator_pair<Iterator1, Iterator2> &
operator =( const pair<typename iterator_traits<Iterator1>::value_type,
typename iterator_traits<Iterator2>::value_type> & );
iterator_pair<Iterator1, Iterator2> &
operator =( pair<typename iterator_traits<Iterator1>::value_type,
typename iterator_traits<Iterator2>::value_type> && );
iterator_pair<Iterator1, Iterator2> & operator *();
iterator_pair<Iterator1, Iterator2> & operator ++();
iterator_pair<Iterator1, Iterator2> operator ++( int );
protected:
iterator_type it;
};
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
make_iterator_pair( Iterator1, Iterator2 );
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
make_iterator_pair( const pair<Iterator1, Iterator2> & );
}
namespace usr
{
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>::iterator_pair
( Iterator1 it1, Iterator2 it2 )
: it( it1, it2 ) {}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>::iterator_pair
( const pair<Iterator1, Iterator2> &it_pair )
: it( it_pair ) {}
template <class Iterator1, class Iterator2>
typename iterator_pair<Iterator1, Iterator2>::iterator_type
iterator_pair<Iterator1, Iterator2>::base() const
{
return ( it );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2> &
iterator_pair<Iterator1, Iterator2>::operator =
( const pair<typename iterator_traits<Iterator1>::value_type,
typename iterator_traits<Iterator2>::value_type> &value )
{
*( it.first ) = value.first;
*( it.second ) = value.second;
return ( *this );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2> &
iterator_pair<Iterator1, Iterator2>::operator =
( pair<typename iterator_traits<Iterator1>::value_type,
typename iterator_traits<Iterator2>::value_type> &&value )
{
*( it.first ) = value.first;
*( it.second ) = value.second;
return ( *this );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2> &
iterator_pair<Iterator1, Iterator2>::operator *()
{
return ( *this );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2> &
iterator_pair<Iterator1, Iterator2>::operator ++()
{
++it.first;
++it.second;
return ( *this );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
iterator_pair<Iterator1, Iterator2>::operator ++( int )
{
iterator_pair<Iterator1, Iterator2> tmp( it );
it.first++;
it.second++;
return ( tmp );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
make_iterator_pair( pair<Iterator1, Iterator2> &&it_pair )
{
return ( iterator_pair<Iterator1, Iterator2>( it_pair ) );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
make_iterator_pair( Iterator1 it1, Iterator2 it2 )
{
return ( iterator_pair<Iterator1, Iterator2>( it1, it2 ) );
}
template <class Iterator1, class Iterator2>
iterator_pair<Iterator1, Iterator2>
make_iterator_pair( const pair<Iterator1, Iterator2> &it_pair )
{
return ( iterator_pair<Iterator1, Iterator2>( it_pair ) );
}
}
#endif // ITERATOR_PAIR_H
Listing 3.
#include <iostream>
#include <algorithm>
#include <iterator>
#include <cstdlib>
#include <ctime>
#include "iterator_pair.h"
int main()
{
const size_t N = 20;
int a[N], b[N], c[N], d[N];
std::srand( ( unsigned int )std::time( nullptr ) );
std::generate( std::begin( a ), std::end( a ),
[] { return ( std::rand() % ( N / 2 ) ); } );
std::cout << "A: ";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::generate( std::begin( b ), std::end( b ),
[] { return ( std::rand() % ( N / 2 ) ); } );
std::cout << "B: ";
for ( int x : b ) std::cout << x << ' ';
std::cout << std::endl;
std::transform( std::begin( a ), std::end( a ),
std::begin( b ),
usr::make_iterator_pair( std::begin( c ), std::begin( d ) ),
[] ( int x, int y )
{
return ( std::minmax( x, y ) );
} );
std::cout << "C: ";
for ( int x : c ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "D: ";
for ( int x : d ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << std::endl;
std::cout << "A: ";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "B: ";
for ( int x : b ) std::cout << x << ' ';
std::cout << std::endl;
std::transform( std::begin( a ), std::end( a ),
std::begin( b ),
usr::make_iterator_pair( std::begin( a ), std::begin( b ) ),
[] ( int x, int y )
{
return ( std::minmax( x, y ) );
} );
std::cout << "A: ";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "B: ";
for ( int x : b ) std::cout << x << ' ';
std::cout << std::endl;
}
The program might have the following output:
A: 3 1 2 2 9 3 4 9 8 8 2 5 7 2 3 5 3 0 8 4
B: 6 8 7 2 5 7 5 2 1 2 4 7 3 7 1 2 2 5 3 2
C: 3 1 2 2 5 3 4 2 1 2 2 5 3 2 1 2 2 0 3 2
D: 6 8 7 2 9 7 5 9 8 8 4 7 7 7 3 5 3 5 8 4
A: 3 1 2 2 9 3 4 9 8 8 2 5 7 2 3 5 3 0 8 4
B: 6 8 7 2 5 7 5 2 1 2 4 7 3 7 1 2 2 5 3 2
A: 3 1 2 2 5 3 4 2 1 2 2 5 3 2 1 2 2 0 3 2
B: 6 8 7 2 9 7 5 9 8 8 4 7 7 7 3 5 3 5 8 4
Listing 4.
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <forward_list>
#include <algorithm>
#include <iterator>
#include <sstream>
#include "iterator_pair.h"
int main()
{
std::map<int, std::string> m;
std::istringstream is( "Hello new iterator adapter iterator_pair!" );
int i = 0;
std::transform( std::istream_iterator<std::string>( is ),
std::istream_iterator<std::string>(),
std::inserter( m, m.begin() ),
[&i]( const std::string &s )
{
return ( std::make_pair( i++, s ) );
} );
std::vector<int> v( m.size() );
std::forward_list<std::string> l( m.size() );
std::copy( m.begin(), m.end(),
usr::make_iterator_pair( v.begin(), l.begin() ) );
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
for ( const std::string &s : l ) std::cout << s << ' ';
std::cout << std::endl;
}
The program has the following output:
0 1 2 3 4
Hello new iterator adapter iterator_pair!
Listing 5.
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <forward_list>
#include <algorithm>
#include <iterator>
#include <sstream>
#include "iterator_pair.h"
int main()
{
std::map<int, std::string> m;
std::istringstream is( "Hello new iterator adapter iterator_pair!" );
int i = 0;
std::transform( std::istream_iterator<std::string>( is ),
std::istream_iterator<std::string>(),
std::inserter( m, m.begin() ),
[&i]( const std::string &s )
{
return ( std::make_pair( i++, s ) );
} );
std::vector<int> v;
v.reserve( m.size() );
std::forward_list<std::string> l;
std::copy( m.begin(), m.end(),
usr::make_iterator_pair( std::back_inserter( v ),
std::front_inserter( l ) ) );
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
for ( const std::string &s : l ) std::cout << s << ' ';
std::cout << std::endl;
}
The program won't compile.
Listings 6 - 9 are skipped because they are not complete programs.
Listing 10.
#include <iostream>
#include <iomanip>
#include <numeric>
#include <algorithm>
#include <iterator>
#include <limits>
#include <ctime>
#include <cstdlib>
#include <cstdint>
int * partial_sum( const std::uint8_t a[], size_t n, int b[] )
{
if ( n )
{
auto acc = int( *a++ );
*b++ = acc;
while ( --n )
{
acc = acc + *a++;
*b++ = acc;
}
}
return b;
}
int main()
{
const size_t N = 10;
std::uint8_t a[N];
int b[N];
std::srand( ( unsigned int )std::time( nullptr ) );
std::generate( std::begin( a ), std::end( a ),
[] ()
{
return std::rand() % std::numeric_limits<std::uint8_t>::max();
} );
for ( int x : a ) std::cout << std::setw( 4 ) << x << ' ';
std::cout << std::endl << std::endl;
::partial_sum( a, N, b );
for ( int x : b ) std::cout << std::setw( 4 ) << x << ' ';
std::cout << std::endl;
std::partial_sum( std::begin( a ), std::end( a ), std::begin( b ) );
for ( int x : b ) std::cout << std::setw( 4 ) << x << ' ';
std::cout << std::endl;
}
The program output might look like
110 152 109 192 160 180 82 212 74 6
110 262 371 563 723 903 985 1197 1271 1277
110 6 115 51 211 135 217 173 247 253
Listing 11.
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <iterator>
#include <limits>
#include <ctime>
#include <cstdlib>
#include <cstdint>
int * partial_sum( const std::uint8_t a[], size_t n, int b[] )
{
if ( n )
{
auto acc = int( *a++ );
*b++ = acc;
while ( --n )
{
acc = acc + *a++;
*b++ = acc;
}
}
return b;
}
namespace usr
{
template <class InputIterator, class OutputIterator>
OutputIterator partial_sum( InputIterator first,
InputIterator last,
OutputIterator result )
{
if ( first != last )
{
typename std::iterator_traits<OutputIterator>::value_type acc = *first++;
*result++ = acc;
for ( ; first != last; ++first, ++result )
{
acc = acc + *first;
*result = acc;
}
}
return result;
}
} // end of namespace usr
int main()
{
const size_t N = 10;
std::uint8_t a[N];
int b[N];
std::srand( ( unsigned int )std::time( nullptr ) );
std::generate( std::begin( a ), std::end( a ),
[] ()
{
return std::rand() % std::numeric_limits<std::uint8_t>::max();
} );
for ( int x : a ) std::cout << std::setw( 4 ) << x << ' ';
std::cout << std::endl << std::endl;
::partial_sum( a, N, b );
for ( int x : b ) std::cout << std::setw( 4 ) << x << ' ';
std::cout << std::endl;
usr::partial_sum( std::begin( a ), std::end( a ), std::begin( b ) );
for ( int x : b ) std::cout << std::setw( 4 ) << x << ' ';
std::cout << std::endl;
}
The outputs of partial sums:
140 138 70 20 134 191 181 45 56 37
140 278 348 368 502 693 874 919 975 1012
140 278 348 368 502 693 874 919 975 1012
Listing 12.
#include <iostream>
#include <string>
#include <numeric>
#include <iterator>
namespace usr
{
template <class InputIterator, class OutputIterator>
OutputIterator partial_sum( InputIterator first,
InputIterator last,
OutputIterator result )
{
if ( first != last )
{
typename std::iterator_traits<OutputIterator>::value_type acc = *first++;
*result++ = acc;
for ( ; first != last; ++first, ++result )
{
acc = acc + *first;
*result = acc;
}
}
return result;
}
} // end of namespace usr
int main()
{
const char * s[] =
{
"Hello ", "new ", "iterator ", "adapter ", "iterator_pair!"
};
usr::partial_sum( std::begin( s ), std::end( s ),
std::ostream_iterator<std::string>( std::cout, "\n" ) );
}
The output will be:
Hello
Hello new
Hello new iterator
Hello new iterator adapter
Hello new iterator adapter iterator_pair!