
Oleg Abrosimov wrote:
Hello dear authors of boost tuple libraries!
I've a need to implement a function that gets a tuple of manipulators and applies them to stream:
template <typename T, typename Tuple> std::string string_from(T const& t, Tuple const& manip) { std::stringstream ss; ss << manip << t; return ss.str(); }
usage of this function would be:
std::string s = string_from(1.2, boost::make_tuple(std::setprecision(2), std::scientific));
The problem is: how I can efficiently suppress output of left/right/delimiter strings? Of cause, with fusion::tuple I can do the following (manipulator names are taken from boost::tuple docs, though):
template <typename T, typename Tuple> std::string string_from(T const& t, Tuple const& manip) { std::stringstream ss; ss << set_open("") << set_close("") << set_delimiter("") << manip << t; return ss.str(); }
but it has a lot of overhead in tuple's output iterator that should be avoided for me.
I feel that the best solution would be to have a function "print_tuple(stream, tuple)" in tuples library that just do what I want.
With Fusion, this is easy. Using lambda/phoenix: fusion::for_each(tup, std::cout << _1); If you want it to be a function (using plain-ole functors): namespace detail { template <class Out> struct my_printer { printer(Out& out) : out(out) {} template <class T> void operator()(T const& val) const { out << val; } Out& out; }; } template <class Out, class Tuple> Out& print_tuple(Out& out, Tuple const& tup) { fusion::for_each(tup, detail::my_printer<Out>(out)); }
One more issue with fusion::tuple manipulators as they are in boost 1.33.1 (unofficially): I've discovered that only narrow strings and characters are supported. am I right? If so, I believe that wide versions should be added too.
Hmmm... Have you tried? Those are templated on Char type AFICT. I have to admit not testing that though. The Fusion I/O tests are simply those from Boost.Tuples. Added in my TODO list. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net