Sharing a generic sollution (lots of boost)

N

Noah Roberts

A while back I posted a question either here or to the boost user list
about how to iterate through a vector of strings and perform a lexical
cast on them into elements of a tuple. I was working with sqlite3 and
found myself repeatedly writing code like so:

t.get<0>() = boost::lexical_cast<double>(vect[0]);
t.get<1>() = boost::lexical_cast<int>(vect[1]);
....

For each query I would invent. Certainly there seemed there should be a
way to use metaprogramming to approach this problem. I could get here:

t.get said:
>(vect[N]);

However, I couldn't figure how to insert that into a metaprogram. I
figured it would have something to do with for_each but couldn't figure
it out. When I approached whatever list I posted my question to I was
sent to some library...I forget which one but it wasn't the answer.
Well, last night a light in my brain turned on. It's actually very
simple once it dawns on one how to do it:

template < typename TUPLE >
struct tuple_assign
{
TUPLE & t;
std::vector< std::string > const& data;

tuple_assign(TUPLE & to, std::vector<std::string> const& from) :
t(to), data(from) {}

template < typename T>
void operator() (T) // T must be an mpl::int_
{
boost::tuples::get<T::value>(t) =
boost::lexical_cast< boost::tuples::element<T::value,
TUPLE>::type>(data[T::value]);
}
};

Your calling code looks like so:

boost::tuple<double, int, std::string> t;
std::vector<std::string> d;
d += "5.2","42","HELLO!";

boost::mpl::for_each< boost::mpl::range<0,3> >(tuple_assign<
boost::tuple<double,int,std::string> >(t,d));

The range can also be derived through the template system like so:

boost::mpl::range< 0,
boost::tuples::length<boost::tuple<double,int,std::string> >

Much safety can be placed on this system. I haven't done so here. This
problem solved though, there's nothing stopping a generic query
interface that could be used something like so:

tie(x, y, z) = query.run();

as well as an iterative interface that provides a similar tuple interface.
 
N

Noah Roberts

Noah said:
template < typename T>
void operator() (T) // T must be an mpl::int_
{
boost::tuples::get<T::value>(t) =
boost::lexical_cast< boost::tuples::element<T::value,
TUPLE>::type>(data[T::value]);
}

In my shortcut writing I neglected "typename". The above call to the
element metafunction must be preceded by "typename".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top