Books & articles: discussions & supplemental materials Program listings for article "iterator_pair - A Simple and Useful Iterator Adapter" (Overload 126)

Program listings for article "iterator_pair - A Simple and Useful Iterator Adapter" (Overload 126)

: 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. [pre2] #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; } [/pre2] The program might have the following output: [pre2] 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 [/pre2] Listing 2. [pre2] /* 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 [/pre2] Listing 3. [pre2] #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; } [/pre2] The program might have the following output: [pre2] 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 [/pre2] Listing 4. [pre2] #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; } [/pre2] The program has the following output: [pre2] 0 1 2 3 4 Hello new iterator adapter iterator_pair! [/pre2] Listing 5. [pre2] #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; } [/pre2] The program won't compile. Listings 6 - 9 are skipped because they are not complete programs. Listing 10. [pre2] #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; } [/pre2] The program output might look like [pre2] 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 [/pre2] Listing 11. [pre2] #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; } [/pre2] The outputs of partial sums: [pre2] 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 [/pre2] Listing 12. [pre2] #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" ) ); } [/pre2] The output will be: [pre2] Hello Hello new Hello new iterator Hello new iterator adapter Hello new iterator adapter iterator_pair! [/pre2]

- 1

vavs: super