By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,409 Members | 1,043 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,409 IT Pros & Developers. It's quick & easy.

vectorstream analogous to std::stringstream

P: n/a
Is there a vectorstream class that implements the functionality similar to
std::stringstream but with std::vector, not std::string?

cheers,
Marcin
Feb 7 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a

"Marcin Kalicinski" <ka****@poczta.onet.pl> wrote in message
news:0g*******************@newsfe7-gui.ntli.net...
Is there a vectorstream class that implements the functionality similar to
std::stringstream but with std::vector, not std::string?


What would you want it to do that stringstream doesn't?

-Mike
Feb 7 '06 #2

P: n/a
In article <0g*******************@newsfe7-gui.ntli.net>,
"Marcin Kalicinski" <ka****@poczta.onet.pl> wrote:
Is there a vectorstream class that implements the functionality similar to
std::stringstream but with std::vector, not std::string?


A vector of what? Such a beast doesn't exist, but it is easy to copy the
contents to a vector...

void copy_to_vec( iostream& ios, vector<char>& vec )
{
vec.clear();
ios << noskipws; // optional
copy( istream_iterator<char>( ios ), istream_iterator<char>(),
back_inserter( vec ) );
}

Why do you want to do this? There is probably a better way to do what
you want.

--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Feb 7 '06 #3

P: n/a

"Marcin Kalicinski" <ka****@poczta.onet.pl> wrote in message
news:0g*******************@newsfe7-gui.ntli.net...
| Is there a vectorstream class that implements the functionality
similar to
| std::stringstream but with std::vector, not std::string?
|
| cheers,
| Marcin
|

No, since a std::string is a predefined entity while a vector could be a
vector of anything.

However, encapsulating a templated vector and overloading a global
operator<< and operator>> to stream a vector's contents is a trivial
exercise with great benefits.

_____
// Container.h

#include <vector>
#include <algorithm>
#include <iterator>

template< class T >
class Container
{
std::vector< T > vt;
public:
Container() : vt() { }
Container(const Container& copy_)
{
vt = copy_.vt; // or std::swap
}
~Container() { }
/* member functions */
void push_back(T t)
{
vt.push_back(t);
}
/* friends */
friend std::ostream& operator<<(std::ostream&, const Container&);
}; // class Container

template< class T >
std::ostream& operator<<(std::ostream& os, const Container< T >& cont)
{
std::copy( cont.vt.begin(),
cont.vt.end(),
std::ostream_iterator< T >(os, " ") );
return os;
}
__________
// test.cpp

#include <iostream>
#include <ostream>
#include "Container.h"

int main()
{
Container<int> container;
for (int i = 0; i < 10; ++i)
{
container.push_back(i);
}
std::cout << container << std::endl;

Container<int> c2(container); // copy
std::cout << c2 << std::endl;

return 0;
}

/*
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
*/

And that Container can be a container of anything, including a container
of a complex user-type with itself having an appropriate operator<<
overload.

To give you a perspective of the power and flexibility involved, lets
have the container display its size and then its contents. Thats a
simple modification.

template< class T >
std::ostream& operator<<(std::ostream& os, const Container< T >& cont)
{
os << "container size = " << cont.vt.size() << "\n"; // mod
std::copy( cont.vt.begin(),
cont.vt.end(),
std::ostream_iterator< T >(os, " ") );
return os;
}

/*
container size = 10
0 1 2 3 4 5 6 7 8 9
container size = 10
0 1 2 3 4 5 6 7 8 9
*/

Do you see why no std::vectorstream was ever included with the standard?
What if i wanted a comma between the elements? What if i wanted no
spaces?

While some languages limit you to a finite number of tools and
possibilities: standard C++ begs, pleads and becons you to create,
fashion and expand what is available with relatively little effort.

Feb 7 '06 #4

P: n/a
>> Is there a vectorstream class that implements the functionality similar
to std::stringstream but with std::vector, not std::string?


What would you want it to do that stringstream doesn't?


I'm using boost::serialization, and I want it to serialize my data into raw
memory. Using stringstream it would look like that:

std::stringstream stream;
binary_oarchive oa(stream);
oa << some_object;
std::string buffer = stream.str(); // #1
char *raw = buffer.data(); // #2

#1 - redundant string copy operation
#2 - data() is potentially costly because string does not guarantee that its
contents are continuous in the memory

Because of that I'd like to use std::vector instead of std::string.

cheers,
Marcin
Feb 7 '06 #5

P: n/a
Marcin Kalicinski wrote:
Is there a vectorstream class that implements the functionality similar to
std::stringstream but with std::vector, not std::string?


There is none in the standard C++ library but it is actually pretty
easy to create streams which read or write from a 'std::vector<char>'.
The class for reading from an 'std::vector<char>' would look
something like this:

class vectorinbuf:
public std::streambuf
{
public:
vectorinbuf(std::vector<char>& vec) {
this->setg(&vec[0], &vec[0], &vec[0] + vec.size());
}
};
class ivectorstream:
private virtual vectorinbuf,
public std::istream
{
public:
ivectorstream(std::vector<char>& vec):
vectorinbuf(vec),
std::istream(this)
{
}
};

The class for writing to a vector is a little bit more complex but
not much:

class vectoroutbuf:
public std::streambuf
{
public:
vectoroutbuf(std::vector<char>& vec):
m_vector(vec)
{
}
int overflow(int c)
{
if (c != std::char_traits<char>::eof())
m_vector.push_back(c);
return std::char_traits<char>::not_eof(c);
}
private:
std::vector<char> m_vector;
};
class ovectorstream:
private virtual vectoroutbuf,
public std::ostream
{
public:
ovectorstream(std::vector<char>& vec):
vectoroutbuf(vec),
std::ostream(this)
{
}
};

The behavior of the output stream is not tuned for performance,
though: writing of each individual character goes through a
virtual function call. This can be improved by some form of
buffering and synchronization. For example, the class could use
the initial size of the 'std::vector<char>' as a buffer instead
of appending to the vector. In this case, it would be necessary
to have a suitable call which adjusts the size of the vector to
the actual number of characters written.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence
Feb 8 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.