3

There are operator classes in STL like less, equal_to, greater_equal etc. How to easily combine them to use with for example remove_if function?

For example I want to remove in vector elements which are greater than 0 AND less than 3 AND not equal to 2, then it would be something like:

remove_if (v.begin(), v.end(), bind2nd(greater<int>(),0) + bind2nd(less<int>(),3) + not1(bind2nd(equal_to<int>(), 2)));

User during running of program can specify filtering options for example he can write: remove if x > 0 && x < 3 && x != 2, or he can write: remove if x > 5 || x == 3. Then command is parsed and appropriate operators with their arguments are combined together to one predicate.

scdmb
  • 15,091
  • 21
  • 85
  • 128
  • possible duplicate of [Combining Predicates](http://stackoverflow.com/questions/545394/combining-predicates) – Björn Pollex Oct 07 '11 at 10:54
  • there is rather talk about static combining of parameters, but I mean dynamic combinining of predicates, like I can choose that I want greater+less+equal or greater_equal+less or only less etc. – scdmb Oct 07 '11 at 11:01
  • if I were you I would implement my own comparison function with overloaded plus operator – Andrey Atapin Oct 07 '11 at 11:14
  • please explain "dynamic combining". In your example the predicate is already known at compile-time. That's the opposite of "dynamic" – sellibitze Oct 07 '11 at 11:23
  • user during running of program can specify filtering options for example he can write: remove if x > 0 && x < 3 && x != 2, or he can write: remove if x > 5 || x == 3. Then command is parsed and appropriate operators with their arguments are combined together to one predicate. – scdmb Oct 07 '11 at 11:28
  • 1
    You should add this requirement to the question. This makes it a totally different question. – sellibitze Oct 07 '11 at 11:37

2 Answers2

3

This is rather simple in your case, actually.

You first need to parse the statement the user gave, and turn it into an AST (Abstract Syntax Tree). It turns out that this AST is nearly already suitable.

x > 0 && x < 3 && x != 2

Can be expressed as a tree:

      AND
     /   \
    >     AND
   / \   /    \
  x  0   <    !=
        / \   / \
       x   3 x   2

All nodes should inherit from a common base class, and you should implement a Visitor to evaluate the x parameter for a given value.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • "rather simple" is a bit of understatement in terms of complexity. – sellibitze Oct 08 '11 at 14:09
  • @sellibitze: rather simple assumes he already has something working for the parsing part. If he doesn't then it's slightly more complicated obviously as generating the AST is the true obstacle. – Matthieu M. Oct 08 '11 at 15:07
0

I guess by "dynamic combining" you refer to the ability to "compose" the predicate "in-line". In your example, the predicate is known at compile-time, so, "dynamic" is not the right term for that.

Consider "Boost.Bind". It offers operator overloading for composition.

bind(greater<int>(),_1,0) && bind(less<int>(),_1,3) && !bind(equal_to<int>(), _1, 2)

Edit: Cosidering your explanation of "dynamic composition", the above code is not what you want. You need an expression parser and evaluator. But this has little to do with your actual code example. There is no easy solution to this. You could try to check out some expression parser libraries and see if / which of them are suitable for your problem.

sellibitze
  • 27,611
  • 3
  • 75
  • 95
  • let's say that one time there are 3 predicates and another time there is only 1 predicate, so what's then? – scdmb Oct 07 '11 at 11:30
  • It's not clear what exactly it is that you are asking for. My current impression is that you are interested in converting an expression string (std::string with runtime-dependent value) into some predicate. Consider updating your question with more details. – sellibitze Oct 07 '11 at 11:43