Please take note of the updates at the end of this post.
Update: I have created a public project on GitHub for this library!
Here is a working library, presented as a complete working program, that I just hacked together:
#include
#include
#include
#include
// Default delimiters
template struct Delims { static const char *delim[3]; };
template const char *Delims::delim[3]={"[", ", ", "]"};
// Special delimiters for sets.
template struct Delims< std::set > { static const char *delim[3]; };
template const char *Delims< std::set >::delim[3]={"{", ", ", "}"};
template struct IsContainer { enum { value = false }; };
template struct IsContainer< std::vector > { enum { value = true }; };
template struct IsContainer< std::set > { enum { value = true }; };
template
typename boost::enable_if, std::ostream&>::type
operator<<(std::ostream & o, const C & x)
{
o << Delims::delim[0];
for (typename C::const_iterator i = x.begin(); i != x.end(); ++i)
{
if (i != x.begin()) o << Delims::delim[1];
o << *i;
}
o << Delims::delim[2];
return o;
}
template struct IsChar { enum { value = false }; };
template <> struct IsChar { enum { value = true }; };
template
typename boost::disable_if, std::ostream&>::type
operator<<(std::ostream & o, const T (&x)[N])
{
o << "[";
for (int i = 0; i != N; ++i)
{
if (i) o << ",";
o << x[i];
}
o << "]";
return o;
}
int main()
{
std::vector i;
i.push_back(23);
i.push_back(34);
std::set j;
j.insert("hello");
j.insert("world");
double k[] = { 1.1, 2.2, M_PI, -1.0/123.0 };
std::cout << i << "\n" << j << "\n" << k << "\n";
}
It currently only works with vector
and set
, but can be made to work with most containers, just by expanding on the IsContainer
specializations. I haven't thought much about whether this code is minimal, but I can't immediately think of anything I could strip out as redundant.
EDIT: Just for kicks, I included a version that handles arrays. I had to exclude char arrays to avoid further ambiguities; it might still get into trouble with wchar_t[]
.