Boost logo

Boost Users :

Subject: Re: [Boost-users] [Tuple] Help getting started with Tuple-based meta-programming
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2009-03-20 16:01:24


AMDG

Dominique Devienne wrote:
> // Context: retrieving all the rows (result set) from a given SQL query.
> // pseudo code of boilerplate code I keep repeating right now
> struct { int id; std::string name; } Row;
> void doit() {
> ResultSet rset = sql_exec("select id, name from t");
> std::vector<Row> rows;
> while (rset.hasMoreRows()) {
> Row row;
> row.id = rset.get<int>(0);
> row.name = rset.get<const char*>(1);
> rows.push_back(row);
> }
> // process rows
> }
>
> // Code I'd like to write instead
> void doit() {
> typedef boost::tuple<int, std::string> Row;
> std::vector<Row> rows;
> sql_get_rows("select id, name from t", rows); // optional arg to
> get only first N elements
> // process rows
> }
>
> PS: returning the vector would be better, but because of the copy
> involved I guess I must pass it as a non-const ref instead, to fill it
> up. Will the new move semantic from the upcoming standard allow a
> function to return the vector without the copy? Just curious

In this case, I think Boost.Fusion can help (warning untested).

#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/include/boost_tuple.hpp>

struct get_t {
    ResultSet& r;
    int& n;
    template<class T>
    void operator()(T& t) const {
        t = r.get<T>(n++);
    }
};

template<Row>
void get_rows(const char* query, std::vector<Row>& out) {
    ResultSet rset = sql_exec(query);
    while(rset.hasMoreRows()) {
        Row row;
        int n = 0;
        get_t getter = { rset, n };
        boost::fusion::for_each(row, getter);
        out.push_back(row);
    }
}

In Christ,
Steven Watanabe


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