$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Markus Werle (numerical.simulation_at_[hidden])
Date: 2008-08-20 10:35:40
> [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