
[ignore this gmane cheater line]
Hi! Looks like migration from boost::tuple to std::tr1:.tuple is a lot more pain than I thought. I have some compile time magic class that makes use of the default template args of boost::tuple: template < typename T0 = boost::tuples::null_type, typename T1 = boost::tuples::null_type, typename T2 = boost::tuples::null_type, typename T3 = boost::tuples::null_type, typename T4 = boost::tuples::null_type, typename T5 = boost::tuples::null_type, typename T6 = boost::tuples::null_type, typename T7 = boost::tuples::null_type, typename T8 = boost::tuples::null_type, typename T9 = boost::tuples::null_type> struct string_to_tuple { // ... }; Now from the docs I see: namespace std { namespace tr1 { // [6.1.3] Class template tuple template <class T1 = unspecified , class T2 = unspecified , ..., class TM = unspecified > class tuple; which leaves me lost without typeof(std::tr1::ignore) at hand. Any idea how to get around this? Btw.: Why does the standard leave this type unspecified? To be more specific: rewrite this code based on std::tr1::tuple ;-) --- snip --- // Usage: // int main() // { // try // { // { // typedef boost::tuple<int, int> tuple_t; // // std::list<tuple_t> test = // string_to_tuple<int, int>::apply(" ( 1, 2 ) ( 3, 4)(5,6)"); // // std::copy(test.begin(), test.end(), // std::ostream_iterator<tuple_t> (std::cout, "\n")); // } // // { // typedef boost::tuple<unsigned int, int, double> tuple_t; // // std::list<tuple_t> test = // string_to_tuple<unsigned int, int, double>::apply // (" ( 1, -2 , 5.123) ( 3, 4,7.9)(5,6,8.6789)"); // // std::copy(test.begin(), test.end(), // std::ostream_iterator<tuple_t> (std::cout, "\n")); // } // // } // catch (std::exception const & e) // { // std::cerr << e.what() << std::endl; // } // } #ifndef BOOSTTUPLESFROMSTRING_H #define BOOSTTUPLESFROMSTRING_H // #define BOOST_SPIRIT_DEBUG_OUT std::cerr // #define BOOST_SPIRIT_DEBUG #include "Enforce.h" #ifndef PHOENIX_LIMIT #define PHOENIX_LIMIT 11 #else #if (PHOENIX_LIMIT < 11) #define ERROR_MESSAGE LOCATION ": " \ "PHOENIX_LIMIT must be a at least 11, but is " \ STRINGIZE(PHOENIX_LIMIT) #pragma message (ERROR_MESSAGE) #error Check the output for details #endif #endif #include <boost/config.hpp> // for BOOST_STATIC_CONSTANT #include <boost/spirit/core.hpp> #include <boost/spirit/attribute.hpp> #include <boost/spirit/core/non_terminal/rule.hpp> #include <boost/spirit/utility/lists.hpp> #include <boost/spirit/utility/loops.hpp> #include <boost/spirit/utility/confix.hpp> #include <boost/spirit/actor/push_back_actor.hpp> #include <boost/spirit/actor/assign_actor.hpp> #include <boost/spirit/phoenix/primitives.hpp> #include <boost/spirit/phoenix/functions.hpp> #include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple_io.hpp> #include <list> #include <iterator> #include <algorithm> #include <string> namespace boost { namespace spirit { struct no_action { template< typename T, typename ValueT > void act(T& ref_, ValueT const& value_) const { // do nothing } template< typename T, typename IteratorT > void act( T& ref_, IteratorT const& first_, IteratorT const& last_ ) const { // do nothing } }; static inline boost::spirit::ref_value_actor<boost::tuples::null_type, no_action> assign_a(boost::tuples::null_type & nt) { boost::spirit::ref_value_actor<boost::tuples::null_type, no_action> na (nt); return na; } } // namespace boost } // namespace spirit namespace { struct append_tuple_to_container_impl { template <typename Container, typename String> struct result { typedef void type; }; template <typename Container, typename String> void operator()(Container& c, String const & s) const { typedef typename Container::value_type tuple_t; tuple_t t; std::istringstream ss(s); ss >> boost::tuples::set_open('(') >> boost::tuples::set_close(')') >> boost::tuples::set_delimiter(',') >> t; c.push_back(t); } }; phoenix::function<append_tuple_to_container_impl> const append_tuple_to_container = append_tuple_to_container_impl(); struct insert_as_tuple_impl { template <typename Container, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> struct result { typedef void type; }; template <typename Container, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> void operator()(Container & c, T0 const & t0, T1 const & t1, T2 const & t2, T3 const & t3, T4 const & t4, T5 const & t5, T6 const & t6, T7 const & t7, T8 const & t8, T9 const & t9) { c.push_back(boost::make_tuple(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9)); } }; phoenix::function<insert_as_tuple_impl> const insert_as_tuple = insert_as_tuple_impl(); template < typename T0 = boost::tuples::null_type, typename T1 = boost::tuples::null_type, typename T2 = boost::tuples::null_type, typename T3 = boost::tuples::null_type, typename T4 = boost::tuples::null_type, typename T5 = boost::tuples::null_type, typename T6 = boost::tuples::null_type, typename T7 = boost::tuples::null_type, typename T8 = boost::tuples::null_type, typename T9 = boost::tuples::null_type> struct string_to_tuple { //////////////////////////////////////////////////////////////////////// //// // type to boost::spirit parser mapping template <typename T, int Dummy = 0> struct parser; template <int Dummy> struct parser<boost::tuples::null_type, Dummy> { static inline boost::spirit::epsilon_parser p() { boost::spirit::epsilon_parser result; return result; }; static inline boost::spirit::epsilon_parser comma() { boost::spirit::epsilon_parser result; return result; } }; #define PARSER_TRAITS(TYPE, PARSER_T) \ template <int Dummy> struct parser<TYPE, Dummy> \ { \ static inline \ PARSER_T p() \ { \ PARSER_T result; \ return result; \ } \ \ static inline \ boost::spirit::strlit<char const *> comma() \ { \ boost::spirit::strlit<char const *> str_p(","); \ return str_p; \ } \ } PARSER_TRAITS(int, boost::spirit::int_parser<int>); PARSER_TRAITS(unsigned int, boost::spirit::uint_parser<unsigned>); typedef boost::spirit::real_parser <double, boost::spirit::ureal_parser_policies<double> > real_parser_t; PARSER_TRAITS(float, real_parser_t); PARSER_TRAITS(double, real_parser_t); template <int Dummy> struct parser<std::string, Dummy> { typedef boost::spirit::contiguous <boost::spirit::confix_parser <boost::spirit::strlit<const char*>, boost::spirit::kleene_star <boost::spirit::anychar_parser>, boost::spirit::strlit<const char*>, boost::spirit::unary_parser_category, boost::spirit::non_nested, boost::spirit::non_lexeme> > parser_t; static inline parser_t p() { using namespace boost::spirit; using namespace phoenix; parser_t result = lexeme_d[confix_p("\"" , (*anychar_p) , "\"")]; return result; } static inline boost::spirit::strlit<char const *> comma() { boost::spirit::strlit<char const *> str_p(","); return str_p; } }; // PARSER_TRAITS(std::string, quoted_string_grammar); //////////////////////////////////////////////////////////////////////// //// // typedefs and integral constants typedef typename boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_t; BOOST_STATIC_CONSTANT(int, tuple_len = boost::tuples::length<tuple_t>::value); //////////////////////////////////////////////////////////////////////// //// // static inline std::list<tuple_t> apply(std::string const & s) { using namespace boost::spirit; using namespace phoenix; std::list<tuple_t> result; T0 t0; T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; typedef rule<phrase_scanner_t> rule_t; rule_t rule_tuple_rep = (str_p("(") >> parser<T0>::p()[assign_a(t0)] >> parser<T1>::comma() >> parser<T1>::p()[assign_a(t1)] >> parser<T2>::comma() >> parser<T2>::p()[assign_a(t2)] >> parser<T3>::comma() >> parser<T3>::p()[assign_a(t3)] >> parser<T4>::comma() >> parser<T4>::p()[assign_a(t4)] >> parser<T5>::comma() >> parser<T5>::p()[assign_a(t5)] >> parser<T6>::comma() >> parser<T6>::p()[assign_a(t6)] >> parser<T7>::comma() >> parser<T7>::p()[assign_a(t7)] >> parser<T8>::comma() >> parser<T8>::p()[assign_a(t8)] >> parser<T9>::comma() >> parser<T9>::p()[assign_a(t9)] >> ")")[insert_as_tuple(var(result), var (t0), var(t1), var(t2), var (t3), var(t4), var(t5), var (t6), var(t7), var(t8), var (t9))] ; rule_t rule_tuple_list = *(rule_tuple_rep) >> end_p // for trailing whitespace ; BOOST_SPIRIT_DEBUG_RULE(rule_tuple_rep); BOOST_SPIRIT_DEBUG_RULE(rule_tuple_list); parse_info<> info; try { info = parse(s.c_str(), rule_tuple_list, space_p); } catch (std::exception const & e) { std::cerr << e.what() << std::endl; } ENFORCE(info.full) ("Failed to generate a list of tuples from ") ("string representation\n'") (s)("'\n"); return result; } }; } // namespace #endif // BOOSTTUPLESFROMSTRING_H