Occasionally, one may want to use a logical operator to join two or more
functors. While it is certainly possible to write a quick functor which
wraps two or more functors, with the "magic" of templates this is not
necessary. The functors OEAnd
, OEOr
and OENot
are
already defined. The each have constructors which take the appropriate
number of predicates as arguments and generate a single unary predicate.
Often these functors can be constructed inline.
The following example demonstrates use of the OEAnd
and OENot
composition predicates with two of the predefined atom predicates
#include "oechem.h" #include "oesystem.h" #include <iostream> using namespace OESystem; using namespace OEChem; using namespace std; unsigned int Count(const OEUnaryPredicate<OEAtomBase> &fcn, const OEMolBase &mol) { unsigned int count = 0; OEIter<OEAtomBase> atom; for(atom = mol.GetAtoms();atom;++atom) if(fcn(*atom)) ++count; return count; } int main() { OEGraphMol mol; OEParseSmiles(mol, "c1c(O)c(O)c(Cl)cc1CCCBr"); cerr << "Number of Aromatic Oxygens = " << Count(OEAnd<OEAtomBase>(OEIsOxygen(),OEIsAromaticAtom()),mol) << endl; cerr << "Number of Non-Carbons = " << Count(OENot<OEAtomBase>(OEHasAtomicNum(6)),mol) << endl; return 0; }
The example above is an extension of listing 18.2 above. It shows the use of OEChem's composition functors to build expressions from OEChem's predefined atom predicates. Thought the explicit template type instantiation isn't strictly necessary, in practice it is required to help several parsers make it through the expression.
As a convenience to programmers, three related template free functions have
been defined. These are operator &&
, operator ||
and
operator !
which take one or more OEUnaryPredicates as arguments and
return the appropriate composition predicate. Not only do these make code much
easier to read, but in our experience, they also make the code easier for C++
parsers to parse.
The following example is identical to the previous composition listing except that the composition predicates have been replaced by the operator free-functions.
#include "oechem.h" #include "oesystem.h" #include <iostream> using namespace OESystem; using namespace OEChem; using namespace std; unsigned int Count(const OEUnaryPredicate<OEAtomBase> &fcn, const OEMolBase &mol) { unsigned int count = 0; OEIter<OEAtomBase> atom; for(atom = mol.GetAtoms();atom;++atom) if(fcn(*atom)) ++count; return count; } int main() { OEGraphMol mol; OEParseSmiles(mol, "c1c(O)c(O)c(Cl)cc1CCCBr"); cerr << "Number of Aromatic Oxygens = " << Count(OEIsOxygen() && OEIsAromaticAtom(),mol) << endl; cerr << "Number of Non-Carbons = " << Count(!OEHasAtomicNum(6),mol) << endl; return 0; }