Boost logo

Boost Users :

Subject: [Boost-users] C# LINQ is cool. What about boost.qlang?
From: Germán Diago (germandiago_at_[hidden])
Date: 2009-10-13 10:43:49


Hello. I've been reading a bit about C#'s linq and it's very cool in my opinion.
I would like to see something similar in c++, and boost is the ideal
place I think.
As I would like to see something similar, I started a prototype adapted to c++.

For now I've been playing with the basics:

-from, where and select operators.
-it just can be used (for now) with from, where and select, all in a
row, but this will change.
-it should work with any range: containers, boost.range, etc.
-it's just a c++0x version. It works great with lambdas (gcc svn has lambdas).
-Can use any boost.fusion sequence as the object type to query.
(Although the plan is to be able to give data providers to
use to query any type of source.

The prototype works in the following way. For example (C++0x) :

vector<int> numbers = {1, 2, 3, 4, 8, 5, 9 , 24, 19, 15, 12 }

auto query = from(numbers).where([](int i) { return i < 15 && i > 10}).
                      select(fields::full_object);

This will construct an object with the query (without evaluating it).
The original Range CANNOT be modified.
If you want to modify , copy the result to a new container (in the
future call query.to_vector(), query.to_list() to return a list or
vector of objects.

This will evaluate everything:

for (auto it = query.begin(); it != query.end(); ++it)
    cout << *it << endl;

You can traverse the range as many times as you like, and
 If you have, for example:

struct Doctor {
  string name_;
  string surname_;
  string specializedin_;
};

BOOST_FUSION_ADAPT_STRUCT(Doctor...)

you can do, for example:

vector<Doctor> doctors = {....};

auto query = from(doctors).where([](const Doctor & d) { return
d.surname_ == "Smith"; }).
                      select(fields::_1);

The plan to improve readability is to use fusion associative sequence to do:

auto query = from(doctors).where([](const Doctor & d) { return
d.surname_ == "Smith"; }).
                      select(Doctorfields::name, Doctorfields::specializedin);

The query will return a tuple<string, string> in this case (the one
before this would return tuple<string>.
Queries with multiple fields don't work for now.

A first implementation with the ability to select the full object or a
field number (not several, but planned) is attached. Test it if you
want
and tell me what you think.
The plan would be the same as the .NET platform: to be able to query
XML, text files, objects, databases... giving
extension points to add data providers.
Another thing that doesn't work right now is to nest a query inside
another query, but I'll work on it.

Feedback is welcome.





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