Quantcast
Viewing all articles
Browse latest Browse all 10

A better output_iterator

I was using the [std::stream_iterator](http://www.cplusplus.com/reference/std/iterator/ostream_iterator/), for example:

[cc lang="cpp"]
std::vector vals;
vals.push_back (12);
vals.push_back (22);
vals.push_back (5);
vals.push_back (30);

// The std::ostream_iterator appends the “,”
std::ostringstream str3;
std::copy (vals.begin(), vals.end(), std::ostream_iterator (str3, “,”));
CPPUNIT_ASSERT_EQUAL (std::string (“12,22,5,30,”), str3.str());
[/cc]

It has the “,” after the last item.

So here’s an implementation that doesn’t append the seperator after the last one:

[cc lang="cpp"]
#ifndef INCLUDED_OUTITER_H
#define INCLUDED_OUTITER_H

#include

/**
* A replacement for std::ostream_iterator that doesn’t put the
* seperator after the last item.
*/
template typename Traits = std::char_traits >
class outiter : public std::iterator
{
public:
typedef CharType char_type;
typedef Traits traits_type;
typedef std::basic_ostream ostream_type;

/// Initialize from a stream
outiter (ostream_type &stream)
: m_stream (&stream),
m_string (0),
m_started (false)
{}

/// Copy constructor
outiter (const outiter &copy)
: m_stream (copy.m_stream),
m_string (copy.m_string),
m_started (copy.m_started)
{}

/// Initialize from a stream and the seperator
outiter (ostream_type &stream, const CharType *str)
: m_stream (&stream),
m_string (str),
m_started (false)
{}

/// Assignment actually does the output
outiter &
operator=(const Type &value)
{
if (!m_started)
{
m_started = true;
}
else if (m_string)
{
(*m_stream) << m_string;
}

(*m_stream) << value;
return *this;
}

/// Just return a reference to this
outiter &
operator*()
{
return *this;
}

/// Just return a reference to this
outiter &
operator++()
{
return *this;
}

/// Just return a reference to this
outiter &
operator++(int)
{
return *this;
}
private:
/// The stream to write to
ostream_type * m_stream;
/// The seperator (may be NULL)
const char_type * m_string;
/// Flag to indicate if we've output anything
bool m_started;
};
#endif /* INCLUDED_OUTITER_H */
[/cc]

And here's the corresponding code to use it:

[cc lang="cpp"]
std::ostringstream str;
std::copy (vals.begin(), vals.end(), outiter (str, “,”));
CPPUNIT_ASSERT_EQUAL (std::string (“12,22,5,30″), str.str());
[/cc]


Viewing all articles
Browse latest Browse all 10

Trending Articles