1 // Copyright (c) 2015, Novartis Institutes for BioMedical Research Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following
12 // disclaimer in the documentation and/or other materials provided
13 // with the distribution.
14 // * Neither the name of Novartis Institutes for BioMedical Research Inc.
15 // nor the names of its contributors may be used to endorse or promote
16 // products derived from this software without specific prior written
17 // permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 //
31
32 #include <RDGeneral/export.h>
33 #ifndef __RD_FILTER_MATCHER_H__
34 #define __RD_FILTER_MATCHER_H__
35 #include <GraphMol/RDKitBase.h>
36 #include <GraphMol/Substruct/SubstructMatch.h>
37 #include "FilterMatcherBase.h"
38 #include <GraphMol/MolPickler.h>
39
40 namespace RDKit {
41
42 namespace {
getArgName(const boost::shared_ptr<FilterMatcherBase> & arg)43 std::string getArgName(const boost::shared_ptr<FilterMatcherBase> &arg) {
44 if (arg.get()) return arg->getName();
45 return "<nullmatcher>";
46 }
47 } // namespace
48
49 namespace FilterMatchOps {
50 class RDKIT_FILTERCATALOG_EXPORT And : public FilterMatcherBase {
51 boost::shared_ptr<FilterMatcherBase> arg1;
52 boost::shared_ptr<FilterMatcherBase> arg2;
53
54 public:
55 // !Default Constructor for serialization
And()56 And() : FilterMatcherBase("And"), arg1(), arg2() {}
57
58 //! Constructs an Ander
59 //! True if arg1 and arg2 FilterMatchers are true
60
And(const FilterMatcherBase & arg1,const FilterMatcherBase & arg2)61 And(const FilterMatcherBase &arg1, const FilterMatcherBase &arg2)
62 : FilterMatcherBase("And"), arg1(arg1.copy()), arg2(arg2.copy()) {}
63
And(const boost::shared_ptr<FilterMatcherBase> & arg1,const boost::shared_ptr<FilterMatcherBase> & arg2)64 And(const boost::shared_ptr<FilterMatcherBase> &arg1,
65 const boost::shared_ptr<FilterMatcherBase> &arg2)
66 : FilterMatcherBase("And"), arg1(arg1), arg2(arg2) {}
67
And(const And & rhs)68 And(const And &rhs)
69 : FilterMatcherBase(rhs), arg1(rhs.arg1), arg2(rhs.arg2) {}
70
getName()71 virtual std::string getName() const {
72 return "(" + getArgName(arg1) + " " + FilterMatcherBase::getName() + " " +
73 getArgName(arg2) + ")";
74 }
75
isValid()76 bool isValid() const {
77 return arg1.get() && arg2.get() && arg1->isValid() && arg2->isValid();
78 }
79
hasMatch(const ROMol & mol)80 bool hasMatch(const ROMol &mol) const {
81 PRECONDITION(isValid(),
82 "FilterMatchOps::And is not valid, null arg1 or arg2");
83 return arg1->hasMatch(mol) && arg2->hasMatch(mol);
84 }
85
getMatches(const ROMol & mol,std::vector<FilterMatch> & matchVect)86 bool getMatches(const ROMol &mol, std::vector<FilterMatch> &matchVect) const {
87 PRECONDITION(isValid(),
88 "FilterMatchOps::And is not valid, null arg1 or arg2");
89 std::vector<FilterMatch> matches;
90 if (arg1->getMatches(mol, matches) && arg2->getMatches(mol, matches)) {
91 matchVect = matches;
92 return true;
93 }
94 return false;
95 }
96
copy()97 boost::shared_ptr<FilterMatcherBase> copy() const {
98 return boost::shared_ptr<FilterMatcherBase>(new And(*this));
99 }
100
101 private:
102 #ifdef RDK_USE_BOOST_SERIALIZATION
103 friend class boost::serialization::access;
104 template <class Archive>
serialize(Archive & ar,const unsigned int version)105 void serialize(Archive &ar, const unsigned int version) {
106 RDUNUSED_PARAM(version);
107 ar &boost::serialization::base_object<FilterMatcherBase>(*this);
108
109 ar &arg1;
110 ar &arg2;
111 }
112 #endif
113 };
114
115 class RDKIT_FILTERCATALOG_EXPORT Or : public FilterMatcherBase {
116 boost::shared_ptr<FilterMatcherBase> arg1;
117 boost::shared_ptr<FilterMatcherBase> arg2;
118
119 public:
120 // !Default Constructor for serialization
Or()121 Or() : FilterMatcherBase("Or"), arg1(), arg2() {}
122
123 //! Constructs or Ander
124 //! true if arg1 or arg2 are true
Or(const FilterMatcherBase & arg1,const FilterMatcherBase & arg2)125 Or(const FilterMatcherBase &arg1, const FilterMatcherBase &arg2)
126 : FilterMatcherBase("Or"), arg1(arg1.copy()), arg2(arg2.copy()) {}
127
Or(const boost::shared_ptr<FilterMatcherBase> & arg1,const boost::shared_ptr<FilterMatcherBase> & arg2)128 Or(const boost::shared_ptr<FilterMatcherBase> &arg1,
129 const boost::shared_ptr<FilterMatcherBase> &arg2)
130 : FilterMatcherBase("Or"), arg1(arg1), arg2(arg2) {}
131
Or(const Or & rhs)132 Or(const Or &rhs) : FilterMatcherBase(rhs), arg1(rhs.arg1), arg2(rhs.arg2) {}
133
getName()134 virtual std::string getName() const {
135 return "(" + getArgName(arg1) + " " + FilterMatcherBase::getName() + " " +
136 getArgName(arg2) + ")";
137 }
138
isValid()139 bool isValid() const {
140 return arg1.get() && arg2.get() && arg1->isValid() && arg2->isValid();
141 }
142
hasMatch(const ROMol & mol)143 bool hasMatch(const ROMol &mol) const {
144 PRECONDITION(isValid(), "Or is not valid, null arg1 or arg2");
145 return arg1->hasMatch(mol) || arg2->hasMatch(mol);
146 }
147
getMatches(const ROMol & mol,std::vector<FilterMatch> & matchVect)148 bool getMatches(const ROMol &mol, std::vector<FilterMatch> &matchVect) const {
149 PRECONDITION(isValid(),
150 "FilterMatchOps::Or is not valid, null arg1 or arg2");
151 // we want both matches to run in order to accumulate all matches
152 // into matchVect, otherwise the or can be arbitrary...
153 bool res1 = arg1->getMatches(mol, matchVect);
154 bool res2 = arg2->getMatches(mol, matchVect);
155 return res1 || res2;
156 }
157
copy()158 boost::shared_ptr<FilterMatcherBase> copy() const {
159 return boost::shared_ptr<FilterMatcherBase>(new Or(*this));
160 }
161
162 #ifdef RDK_USE_BOOST_SERIALIZATION
163 friend class boost::serialization::access;
164 template <class Archive>
serialize(Archive & ar,const unsigned int version)165 void serialize(Archive &ar, const unsigned int version) {
166 RDUNUSED_PARAM(version);
167 ar &boost::serialization::base_object<FilterMatcherBase>(*this);
168 ar &arg1;
169 ar &arg2;
170 }
171 #endif
172 };
173
174 class RDKIT_FILTERCATALOG_EXPORT Not : public FilterMatcherBase {
175 boost::shared_ptr<FilterMatcherBase> arg1;
176
177 public:
178 // !Default Constructor for serialization
Not()179 Not() : FilterMatcherBase("Not"), arg1() {}
180
181 //! Constructs a Noter
182 //! true if arg1 is false (note, never returns matches
183 // from getMatches since a false internal match matches
184 // nothing!
Not(const FilterMatcherBase & arg1)185 Not(const FilterMatcherBase &arg1)
186 : FilterMatcherBase("Not"), arg1(arg1.copy()) {}
187
Not(const boost::shared_ptr<FilterMatcherBase> & arg1)188 Not(const boost::shared_ptr<FilterMatcherBase> &arg1)
189 : FilterMatcherBase("Not"), arg1(arg1) {}
190
Not(const Not & rhs)191 Not(const Not &rhs) : FilterMatcherBase(rhs), arg1(rhs.arg1) {}
192
getName()193 virtual std::string getName() const {
194 return "(" + FilterMatcherBase::getName() + " " + getArgName(arg1) + ")";
195 }
196
isValid()197 bool isValid() const { return arg1.get() && arg1->isValid(); }
198
hasMatch(const ROMol & mol)199 bool hasMatch(const ROMol &mol) const {
200 PRECONDITION(isValid(), "FilterMatchOps::Not: arg1 is null");
201 return !arg1->hasMatch(mol);
202 }
203
getMatches(const ROMol & mol,std::vector<FilterMatch> &)204 bool getMatches(const ROMol &mol, std::vector<FilterMatch> &) const {
205 PRECONDITION(isValid(), "FilterMatchOps::Not: arg1 is null");
206 // If we are a not, we really can't hold the match for
207 // this query since by definition it won't exist!
208 std::vector<FilterMatch> matchVect;
209 return !arg1->getMatches(mol, matchVect);
210 }
211
copy()212 boost::shared_ptr<FilterMatcherBase> copy() const {
213 return boost::shared_ptr<FilterMatcherBase>(new Not(*this));
214 }
215
216 private:
217 #ifdef RDK_USE_BOOST_SERIALIZATION
218 friend class boost::serialization::access;
219 template <class Archive>
serialize(Archive & ar,const unsigned int version)220 void serialize(Archive &ar, const unsigned int version) {
221 RDUNUSED_PARAM(version);
222 ar &boost::serialization::base_object<FilterMatcherBase>(*this);
223 ar &arg1;
224 }
225 #endif
226 };
227 } // namespace FilterMatchOps
228
229 RDKIT_FILTERCATALOG_EXPORT extern const char *SMARTS_MATCH_NAME_DEFAULT;
230 class RDKIT_FILTERCATALOG_EXPORT SmartsMatcher : public FilterMatcherBase {
231 ROMOL_SPTR d_pattern;
232 unsigned int d_min_count{0};
233 unsigned int d_max_count;
234
235 public:
236 //! Construct a SmartsMatcher
237 SmartsMatcher(const std::string &name = SMARTS_MATCH_NAME_DEFAULT)
FilterMatcherBase(name)238 : FilterMatcherBase(name),
239 d_pattern(),
240
241 d_max_count(UINT_MAX) {}
242
243 //! Construct a SmartsMatcher from a query molecule
244 /*
245 \param pattern query molecule used as the substructure search
246 \param unsigned int minCount minimum number of times the pattern needs to
247 appear
248 \param maxCount the maximum number of times the pattern should appear
249 a value of UINT_MAX indicates the pattern can exist any number of times.
250 [default UINT_MAX]
251
252 */
253 SmartsMatcher(const ROMol &pattern, unsigned int minCount = 1,
254 unsigned int maxCount = UINT_MAX);
255
256 //! Construct a SmartsMatcher
257 /*
258 \param name name for the smarts pattern
259 \param pattern query molecule used as the substructure search
260 \param unsigned int minCount minimum number of times the pattern needs to
261 appear
262 \param maxCount the maximum number of times the pattern should appear
263 a value of UINT_MAX indicates the pattern can exist any number of times.
264 [default UINT_MAX]
265
266 */
267
268 SmartsMatcher(const std::string &name, const ROMol &pattern,
269 unsigned int minCount = 1, unsigned int maxCount = UINT_MAX);
270
271 //! Construct a SmartsMatcher from a smarts pattern
272 /*
273 \param name name for the smarts pattern
274 \param smarts smarts pattern to use for the filter
275 \param unsigned int minCount minimum number of times the pattern needs to
276 appear
277 \param maxCount the maximum number of times the pattern should appear
278 a value of UINT_MAX indicates the pattern can exist any number of times.
279 [default UINT_MAX]
280 */
281
282 SmartsMatcher(const std::string &name, const std::string &smarts,
283 unsigned int minCount = 1, unsigned int maxCount = UINT_MAX);
284
285 //! Construct a SmartsMatcher from a shared_ptr
286 /*
287 \param name name for the smarts pattern
288 \param pattern shared_ptr query molecule used as the substructure search
289 \param unsigned int minCount minimum number of times the pattern needs to
290 appear
291 \param maxCount the maximum number of times the pattern should appear
292 a value of UINT_MAX indicates the pattern can exist any number of times.
293 [default UINT_MAX]
294 */
295
296 SmartsMatcher(const std::string &name, ROMOL_SPTR onPattern,
297 unsigned int minCount = 1, unsigned int maxCount = UINT_MAX);
298
299 SmartsMatcher(const SmartsMatcher &rhs);
300
301 //! Returns True if the Smarts pattern is valid
isValid()302 bool isValid() const { return d_pattern.get(); }
303
304 //! Return the shared_ptr to the underlying query molecule
getPattern()305 const ROMOL_SPTR &getPattern() const { return d_pattern; }
306 //! Set the smarts pattern for the matcher
307 void setPattern(const std::string &smarts);
308 //! Set the query molecule for the matcher
309 void setPattern(const ROMol &mol);
310 //! Set the shared query molecule for the matcher
setPattern(const ROMOL_SPTR & pat)311 void setPattern(const ROMOL_SPTR &pat) { d_pattern = pat; }
312
313 //! Get the minimum match count for the pattern to be true
getMinCount()314 unsigned int getMinCount() const { return d_min_count; }
315 //! Set the minimum match count for the pattern to be true
setMinCount(unsigned int val)316 void setMinCount(unsigned int val) { d_min_count = val; }
317 //! Get the maximum match count for the pattern to be true
getMaxCount()318 unsigned int getMaxCount() const { return d_max_count; }
319 //! Set the maximum match count for the pattern to be true
setMaxCount(unsigned int val)320 void setMaxCount(unsigned int val) { d_max_count = val; }
321
322 virtual bool getMatches(const ROMol &mol,
323 std::vector<FilterMatch> &matchVect) const;
324 virtual bool hasMatch(const ROMol &mol) const;
copy()325 virtual boost::shared_ptr<FilterMatcherBase> copy() const {
326 return boost::shared_ptr<FilterMatcherBase>(new SmartsMatcher(*this));
327 }
328
329 private:
330 #ifdef RDK_USE_BOOST_SERIALIZATION
331 friend class boost::serialization::access;
332 template <class Archive>
save(Archive & ar,const unsigned int version)333 void save(Archive &ar, const unsigned int version) const {
334 RDUNUSED_PARAM(version);
335 ar &boost::serialization::base_object<FilterMatcherBase>(*this);
336 std::string res;
337 MolPickler::pickleMol(*d_pattern.get(), res);
338 ar &res;
339 ar &d_min_count;
340 ar &d_max_count;
341 }
342 template <class Archive>
load(Archive & ar,const unsigned int version)343 void load(Archive &ar, const unsigned int version) {
344 ar &boost::serialization::base_object<FilterMatcherBase>(*this);
345 {
346 RDUNUSED_PARAM(version);
347 std::string res;
348 ar &res;
349 d_pattern = boost::shared_ptr<ROMol>(new ROMol(res));
350 }
351 ar &d_min_count;
352 ar &d_max_count;
353 }
354 BOOST_SERIALIZATION_SPLIT_MEMBER();
355 #endif
356 };
357
358 // ------------------------------------------------------------------
359 // Syntactic sugar for the following style patterns
360 // Add exclusion patterns
361 // using FilterMatchOps;
362 // And(new SmartsMatcher(pat1),
363 // new Not(SmartsMatcher(pat2)))
364 // The exclusion match never adds any FilterMatches when getMatches
365 // is called, the main intent is for it to be used with an
366 // And construct, such as:
367 // And(SmartsMatcher(..), ExclusionList(...))
368 //
369 // which will return the SmartsMatcher FilterMatch only if no patterns
370 // in the exclusion list are found.
371 class RDKIT_FILTERCATALOG_EXPORT ExclusionList : public FilterMatcherBase {
372 std::vector<boost::shared_ptr<FilterMatcherBase>> d_offPatterns;
373
374 public:
ExclusionList()375 ExclusionList() : FilterMatcherBase("Not any of"), d_offPatterns() {}
376
377 //! Constructs an ExclusionList
378 //! true if non of the FilterMatcherBases are true
379 //! Syntactic sugar for
380 //! using FilterMatchOps;
381 //! And(Not(SmartsMatcher(pat1),
382 //! And(Not(SmartsMatcher(pat2)),
383 //! And(Not(Single...
384
ExclusionList(const std::vector<boost::shared_ptr<FilterMatcherBase>> & offPatterns)385 ExclusionList(
386 const std::vector<boost::shared_ptr<FilterMatcherBase>> &offPatterns)
387 : FilterMatcherBase("Not any of"), d_offPatterns(offPatterns) {}
388
getName()389 virtual std::string getName() const {
390 std::string res;
391 res = "(" + FilterMatcherBase::getName();
392 for (size_t i = 0; i < d_offPatterns.size(); ++i) {
393 res += " " + d_offPatterns[i]->getName();
394 }
395 res += ")";
396 return res;
397 }
398
isValid()399 bool isValid() const {
400 for (size_t i = 0; i < d_offPatterns.size(); ++i)
401 if (!d_offPatterns[i]->isValid()) return false;
402 return true;
403 }
404
addPattern(const FilterMatcherBase & base)405 void addPattern(const FilterMatcherBase &base) {
406 PRECONDITION(base.isValid(), "Invalid FilterMatcherBase");
407 d_offPatterns.push_back(base.copy());
408 }
409
setExclusionPatterns(const std::vector<boost::shared_ptr<FilterMatcherBase>> & offPatterns)410 void setExclusionPatterns(
411 const std::vector<boost::shared_ptr<FilterMatcherBase>> &offPatterns) {
412 d_offPatterns = offPatterns;
413 }
414
getMatches(const ROMol & mol,std::vector<FilterMatch> &)415 virtual bool getMatches(const ROMol &mol, std::vector<FilterMatch> &) const {
416 PRECONDITION(isValid(),
417 "ExclusionList: one of the exclusion pattens is invalid");
418 bool result = true;
419 for (size_t i = 0; i < d_offPatterns.size() && result; ++i) {
420 result &= !d_offPatterns[i]->hasMatch(mol);
421 }
422
423 return result;
424 }
425
hasMatch(const ROMol & mol)426 virtual bool hasMatch(const ROMol &mol) const {
427 PRECONDITION(isValid(),
428 "ExclusionList: one of the exclusion pattens is invalid");
429 bool result = true;
430 for (size_t i = 0; i < d_offPatterns.size() && result; ++i) {
431 result &= !d_offPatterns[i]->hasMatch(mol);
432 }
433
434 return result;
435 }
436
copy()437 virtual boost::shared_ptr<FilterMatcherBase> copy() const {
438 return boost::shared_ptr<FilterMatcherBase>(new ExclusionList(*this));
439 }
440
441 private:
442 #ifdef RDK_USE_BOOST_SERIALIZATION
443 friend class boost::serialization::access;
444 template <class Archive>
serialize(Archive & ar,const unsigned int version)445 void serialize(Archive &ar, const unsigned int version) {
446 RDUNUSED_PARAM(version);
447 ar &boost::serialization::base_object<FilterMatcherBase>(*this);
448 ar &d_offPatterns;
449 }
450 #endif
451 };
452
453 class RDKIT_FILTERCATALOG_EXPORT FilterHierarchyMatcher
454 : public FilterMatcherBase {
455 std::vector<boost::shared_ptr<FilterHierarchyMatcher>> d_children;
456 boost::shared_ptr<FilterMatcherBase> d_matcher;
457
458 public:
459 // !Default Constructor for serialization
FilterHierarchyMatcher()460 FilterHierarchyMatcher() : FilterMatcherBase(), d_matcher() {}
461 //! Constructs a FilterHierarchyMatcher from a FilterMatchBase
462 //! A FilterHierarchyMatcher is a tree hierarchy where to
463 //! match a child node, one needs to match the parent first.
464 //! For each branch, the lowest nodes are returned when
465 //! getting the filter matches.
466 /*
467 \param matcher FilterMatcherBase to match this node against
468 */
FilterHierarchyMatcher(const FilterMatcherBase & matcher)469 FilterHierarchyMatcher(const FilterMatcherBase &matcher)
470 : FilterMatcherBase(), d_matcher(matcher.copy()) {}
471
472 //! Return the name for this node (from the underlying FilterMatcherBase)
getName()473 virtual std::string getName() const {
474 if (d_matcher.get()) {
475 return d_matcher->getName();
476 }
477 return "FilterMatcherHierarchy root";
478 }
479
480 //! returns true if this node has a valid matcher
isValid()481 bool isValid() const { return d_matcher->isValid(); }
482
483 //! Set a new FilterMatcherBase for this node
484 /*
485 \param matcher The new FilterMatcherBase
486 */
setPattern(const FilterMatcherBase & matcher)487 void setPattern(const FilterMatcherBase &matcher) {
488 PRECONDITION(matcher.isValid(), "Adding invalid patterns is not allowed.");
489 d_matcher = matcher.copy();
490 PRECONDITION(getName() == d_matcher->getName(), "Opps");
491 }
492
493 //! add a FilterHierarchy as a child.
494 //! returns the FilterHierarchy pointer used in the tree (this is a
495 //! shallow copy of the original)
496 /*
497 \param hierarchy The new FilterHierarchyMatcher child for this node
498 */
addChild(const FilterHierarchyMatcher & hierarchy)499 boost::shared_ptr<FilterHierarchyMatcher> addChild(
500 const FilterHierarchyMatcher &hierarchy) {
501 PRECONDITION(hierarchy.d_matcher.get() && hierarchy.d_matcher->isValid(),
502 "Only one root node is allowed in a FilterHierarchyMatcher");
503
504 d_children.push_back(boost::shared_ptr<FilterHierarchyMatcher>(
505 new FilterHierarchyMatcher(hierarchy)));
506 return d_children.back();
507 }
508
509 //! returns the FilterMatches against the given molecule
510 /*
511 \param mol The molecule to match against
512 \param matches The vector of FilterMatch objects that match
513 */
514 virtual bool getMatches(const ROMol &mol,
515 std::vector<FilterMatch> &matches) const;
516
517 //! Does this node match the molecule
518 /*
519 \param mol The molecule to match against
520 */
hasMatch(const ROMol & mol)521 virtual bool hasMatch(const ROMol &mol) const {
522 std::vector<FilterMatch> temp;
523 return getMatches(mol, temp);
524 }
525
526 //! copys the FilterHierarchyMatcher into a FilterMatcherBase
copy()527 virtual boost::shared_ptr<FilterMatcherBase> copy() const {
528 return boost::shared_ptr<FilterMatcherBase>(
529 new FilterHierarchyMatcher(*this));
530 }
531
532 private:
533 #ifdef RDK_USE_BOOST_SERIALIZATION
534 friend class boost::serialization::access;
535 template <class Archive>
serialize(Archive & ar,const unsigned int version)536 void serialize(Archive &ar, const unsigned int version) {
537 RDUNUSED_PARAM(version);
538 ar &boost::serialization::base_object<FilterMatcherBase>(*this);
539 ar &d_children;
540 ar &d_matcher;
541 }
542 #endif
543 };
544
545 #ifdef RDK_USE_BOOST_SERIALIZATION
546 // Register all known filter matcher types for serialization
547 template <class Archive>
registerFilterMatcherTypes(Archive & ar)548 void registerFilterMatcherTypes(Archive &ar) {
549 ar.register_type(static_cast<FilterMatchOps::And *>(nullptr));
550 ar.register_type(static_cast<FilterMatchOps::Or *>(nullptr));
551 ar.register_type(static_cast<FilterMatchOps::Not *>(nullptr));
552 ar.register_type(static_cast<SmartsMatcher *>(nullptr));
553 ar.register_type(static_cast<ExclusionList *>(nullptr));
554 ar.register_type(static_cast<FilterHierarchyMatcher *>(nullptr));
555 }
556 #endif
557 } // namespace RDKit
558
559 #ifdef RDK_USE_BOOST_SERIALIZATION
560 BOOST_CLASS_VERSION(RDKit::SmartsMatcher, 1)
561 BOOST_CLASS_VERSION(RDKit::ExclusionList, 1)
562 BOOST_CLASS_VERSION(RDKit::FilterHierarchyMatcher, 1)
563 #endif
564
565 #endif
566