Boost logo

Boost Users :

Subject: Re: [Boost-users] [BGL] Searching for a convenient way to combine predicates for filtered_graph
From: Jeremiah Willcock (jewillco_at_[hidden])
Date: 2010-11-30 12:04:09


On Tue, 30 Nov 2010, Cedric Laczny wrote:

> On Tuesday, 30. November 2010 17:41:13 Jeremiah Willcock wrote:
>> On Tue, 30 Nov 2010, Cedric Laczny wrote:
>>> On Tuesday, 30. November 2010 16:57:17 Jeremiah Willcock wrote:
>>>> On Mon, 29 Nov 2010, Cedric Laczny wrote:
>>>>> Hi,
>>>>>
>>>>> I was wondering if there is a convenient (and to some extent intuitive)
>>>>> way to combine several predicates used in filtering a graph?
>>>>> The idea is to have some predicates defined and arbitrarily combine
>>>>> them so that the filtered_graph will check for compliance of each
>>>>> individual predicate and either make this vertex/edge visible or not.
>>>>> Of course, the predicates should be specific to vertices or edges,
>>>>> respectively, when being combined.
>>>>> When using std::vector or such, they would need to be all of the same
>>>>> type which does not seem very nice/feasible IMHO.
>>>>> Also defining a "big" predicate having a multitude of "smaller"
>>>>> predicates as members is not really an option as this is very
>>>>> restricted.
>>>>> Something like
>>>>> big_predicate = predicate1 || predicate2 || predicate3
>>>>> (syntax should just illustrate the idea) maybe?
>>>>
>>>> If you don't want to use Boost.Lambda, Boost.Bind also has some
>>>> operators overloaded
>>>> (<URL:http://www.boost.org/doc/libs/1_45_0/libs/bind/bind.html#operators
>>>>> ) to provide the syntax you wanted.
>>>
>>> Thanks for the hint. Unfortunately, I'm still hanging at the point where
>>> the type of the specified predicate(s) comes into play.
>>> Let's look at an example:
>>>
>>> struct VPred1{
>>>
>>> VPred1() {};
>>> // etc....
>>> template< V >
>>> bool operator( const V& v)
>>> {return true;}
>>>
>>> }
>>> struct Vpred2{
>>> // s. Vpred1 but operator() returns false
>>> }
>>>
>>> Vpred1 pred1;
>>> Vpred2 pred2;
>>> typedef adjacency_list<> Graph;
>>> Graph g;
>>> // fill graph g
>>> filtered_graph< Graph, keep_all, ??? > fg( g, keep_all(), ???);
>>>
>>> In the example above I would like to provide both vpred-structs to the
>>> filtered_graph like so:
>>> filtered_graph< Graph, keep_all, ??? > fg( g, keep_all(), pred1 &&
>>> pred2);
>>>
>>> This is not supposed to work out-of-the-box, it should just demonstrate
>>> the idea a bit more into detail.
>>>
>>> Concerning the "???" in the template-specification, I have no idea how
>>> this should be specifed. All the examples I have found so far, either
>>> for phoenix or bind, are direct applications and do not involve the
>>> specification of templates. Therefore I have nowhere to start learning
>>> how to do this.
>>
>> Yes, that's the hard part. If you have C++0x (or are willing to use
>> compiler extensions), you can use decltype/auto or typeof to infer the
>> return type of the operator. Another technique (that would make your code
>> messy) is to split the function after the construction of the predicate
>> into a separate function template; that template can then take the
>> predicate as a parameter and its type as a template parameter. You could
>> also try asking the bind developers if the return types of the operators
>> are documented, or if they would fix and document particular types for
>> them.
>>
>
> Ok, I will do that then.
> But let's say, the return types were known, am I right that a solution to
> combine the predicates would have to look like this?
>
> filtered_graph<> fg(g, keep_all(), bind<bool>(pred1, _1) && bind<bool>(pred2,
> _1));

Yes, probably, unless you made pred1 and pred2 look like bind-produced
predicates (I don't know how to do that; it might be in the bind manual
but I haven't checked).

-- Jeremiah Willcock


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