|
Boost Users : |
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
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net