Boost logo

Boost :

From: John Torjo (john.lists_at_[hidden])
Date: 2003-12-01 21:38:24


Dear boosters,

I browsed the sandbox, but could not find a simpler ostream_iterator.
The thing is that I don't like the fact that when writing using an
ostream_iterator I have to provide the value_type I'm writing.
This is both tedios and error prone.

Example:

std::copy( vs.begin(), vs.end(),
   std::ostream_iterator<std::string>(std::cout, " "));
                         ^^^ tedious and error prone.

This should not be necessary since it can be deduced at the time of writing.

I wrote a small helper. Any interest in adding it to boost?
Best,
John

-----------------------

#include <boost/iterator.hpp>
#include <iterator>

namespace boost {
     namespace detail {
         template<class char_type, class traits_type>
         struct ostream_write_helper {
             typedef ::std::basic_ostream<char_type,traits_type> ostream_type;
             typedef ostream_write_helper<char_type,traits_type> self_type;
             ostream_write_helper( ostream_type * out, const char_type * delim)
                 : m_out( out), m_delim( delim) {}

             template< class T> self_type& operator=( const T & val) {
                 *m_out << val;
                 if ( m_delim)
                     *m_out << m_delim;
                 return *this;
             }
         private:
             ostream_type *m_out;
             const char_type * m_delim;
         };
     }

template< class char_type, class traits_type>
class ostream_iterator_t
: public ::boost::iterator< ::std::output_iterator_tag,
::boost::detail::ostream_write_helper<char_type,traits_type> > {
         typedef ::std::basic_ostream<char_type,traits_type> ostream_type;
         typedef ::boost::detail::ostream_write_helper<char_type,traits_type>
write_helper;
         typedef ostream_iterator_t<char_type,traits_type> self_type;
public:

        ostream_iterator_t(ostream_type& out, const char_type * delim)
         : m_out( &out), m_delim( delim) {}

        write_helper operator*() {
         return write_helper( m_out, m_delim);
     }
        self_type& operator++() {return *this; }
        self_type operator++(int) {return *this; }
private:
     ostream_type *m_out;
     const char_type * m_delim;
};

template< class c, class t>
inline ostream_iterator_t<c,t> ostream_iterator( ::std::basic_ostream<c,t> &
out, const c * delim = 0) {
     return ostream_iterator_t<c,t>( out, delim);
}

}

///////////////////////////////
// Test

#include <vector>
#include <iostream>
#include <string>

int main(int argc, char* argv[])
{
     std::vector<std::string> vs;
     std::vector<int> vi;
     vs.push_back( "this");
     vs.push_back( "is");
     vs.push_back( "a");
     vs.push_back( "test");
     vi.push_back( 1);
     vi.push_back( 10);
     vi.push_back( 11);
     vi.push_back( 20);
     vi.push_back( 21);
     std::copy( vs.begin(), vs.end(),
         // as opposed to
         // std::ostream_iterator<std::string>(std::cout, " "));
         boost::ostream_iterator(std::cout, " "));
     std::copy( vi.begin(), vi.end(),
         // as opposed to
         // std::ostream_iterator<int>(std::cout, " "));
         boost::ostream_iterator(std::cout, "\n ") );
        return 0;
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk