[tuple] or [fusion::tuple]: feature request

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. 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. Best regards, Oleg Abrosimov.

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

Thank you for quick response, it solves my problem. about my second request (wide char support in manipulators) - I've realized that there are three preprocessor branches in fusion source, and I've seen one that is intended for buggy compilers, so, fusion supports wide chars, sorry for noise. Best regards, Oleg Abrosimov. Joel de Guzman:
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,

Hello! I have one more need about tuples. I need two functions: one for general case and one for tuples returned by make_tuple function. It is equal to the following functionality provided by boost::variant library: "// general cases template <typename T> void some_func(const T &); template <typename T> class some_class; // function template overload template <BOOST_VARIANT_ENUM_PARAMS(typename T)> void some_func(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &); // explicit partial specialization template <BOOST_VARIANT_ENUM_PARAMS(typename T)> class some_class< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >;" Best, Oleg Abrosimov.

Oleg Abrosimov wrote:
Hello! I have one more need about tuples. I need two functions: one for general case and one for tuples returned by make_tuple function. It is equal to the following functionality provided by boost::variant library:
"// general cases template <typename T> void some_func(const T &); template <typename T> class some_class;
// function template overload template <BOOST_VARIANT_ENUM_PARAMS(typename T)> void some_func(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> &);
// explicit partial specialization template <BOOST_VARIANT_ENUM_PARAMS(typename T)> class some_class< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >;"
For fusion, you can use enable_if and fusion::is_sequence. HTH. Cheers, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
participants (2)
-
Joel de Guzman
-
Oleg Abrosimov