Sign in to follow this  
paulbird

C++ database extension

Recommended Posts

What I would like to do is to extend C++ to do something like this:
class A{
  public:
  float x;
  float y;
  int z;
};
A a[1000];

A2 = Select(A).Where(x>3 && y<5 || z==10);
Which creates a new array from the old array where each member satisfies a[n].x>3 && a[n].y<5. So we introduce new commands such as "Where" which treat an array of classes like a database. Do you think it is possible to make such a command as this in C++? Could anyone suggest an example?

Share this post


Link to post
Share on other sites
You're not likely going to modify C++' syntax - in that case, why not design a programming/scripting language of your own? :)

Anyway, you could write a function that takes an array of A's and an expression and returns a new array. Now I think the parameter part is going to be the hardest to pull off here, giving minimum and maximum values for each member variabele might be sufficient but it means you'll need to write a different function for every other class you want this functionality for. You could write the function to accept a string containing the expression, but that solution is more complex, and still class-specific.
In other words, as far as I know, it's possible to write such functionality, but not in a templatized way - every new class requires a new version of the function to be written.

However, I'd like to know: why would you want this? For what situations do you intend to use this and what's the ultimate goal?
The reason I ask these questions is that there might be another, simpler or more effective, way to achieve what you need... :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Captain P
You're not likely going to modify C++' syntax - in that case, why not design a programming/scripting language of your own? :)

No need. Select can return a Query object that will have a Where method that will accept a lambda function (see boost.lambda, as the AP suggested).

Quote:
Original post by Captain P
However, I'd like to know: why would you want this? For what situations do you intend to use this and what's the ultimate goal?
The reason I ask these questions is that there might be another, simpler or more effective, way to achieve what you need... :)

Obviously, the goal is to have a simple embedded C++ query system. I actually think that this is a very good idea from a design point of view - and it can be quite effective. Now, I also happen to find code such as the OP's code incredibly easy to read (if the reader knows some tidy bits about lambda functions of course [smile]).

@paulbird: if you need more help to understand the concept of lambda functions, just ask to the boards - we'll be happy to help. Your idea is quite good.

Regards,

Share this post


Link to post
Share on other sites
The reasons are the same reasons you would use a database language such as SQL. But instead you would apply this to arrays of classes in C++.

For example if I had an array of objects

class OBJECT{
public:
Color color;
float height;
float width;
} objects[1000];

And I want to get an array of objects which are red and whose height is greater than 3. It would be useful to be able to simply write:

newobjects = Select(objects).where(color==Red && height>3)

or

newobjects = Select(objects).where(element.color==Red && element.height>3)

Then I want to double the widths of all thoses objects:

Select(newobjects).width*=2;

or

Select(newobjects).set(width=width*2);

for example.

PS

Yes it would be useful if someone could give an example of how do do something like this in Lambda functions, it might be interesting for other people too!

Share this post


Link to post
Share on other sites
What you're after is basically what's called "filter" in functional languages. Maybe C++ implements it as part of its standard library?

Anyway, it's easy enough to implement, but I haven't done C++ in years, so consider this a naive example.


#include <list>
#include <iostream>
#include <iterator>
#include <boost/lambda/lambda.hpp>

using namespace boost::lambda;

// This is your "where".
template<typename Container, typename Predicate>
void filter(Container const& orig, Container& result, Predicate p) {
typename Container::const_iterator it;
for(it = orig.begin(); it != orig.end(); ++it) {
if (p(*it)) {
result.push_back(*it);
}
}
}

int main() {
std::list<int> l1;
std::list<int> l2;

for(int i = 0; i < 10; ++i) {
l1.push_back(i);
}

// Filter (keep) items whose value is greater than 5.
// _1 > 5 is the lambda function.
filter(l1, l2, _1 > 5);

std::copy(l2.begin(), l2.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}



Hope this helps.

Share this post


Link to post
Share on other sites
C++, even with boost::lambda, isn't terribly well suited for this kind of thing. If you need this kind of behavior, another language might be more appropriate.

The same thing in Ruby with comments for the non-rubyist:

class A
attr_accessor :x,:y,:z # allows non-class access to these variables
def initialize(x,y,z)
@x,@y,@z = x,y,z # @variable is used for member variables.
end
def to_s
"#{@x},#{@y},#{@z}" # describe how we want this to be printed out and whatnot.
end
end


a1 = [ A.new(1,2,3) , A.new(4,4,4) , A.new(5,6,7) , A.new(8,9,10) ]
# original example array


a2 = a1.find_all { |a| (a.x > 3 && a.y < 5) || (a.z == 10) }
# pretty self explanitory - returns a new array for which the block expression is true.


a2.each { |a| puts a }
# prints "4,4,4" and "8,9,10" on seperate lines


EDIT: Replaced that collect stuff with a simple .find_all, making it even easier :P

Of note: find_all is fairly mundane - it looks something like this:

class Array
def find_all( & block )
results = Array.new()
for i in 0..@length
if block(data[i])
results.push( data[i] )
end
end
end
end

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this