1 #pragma once
2 
3 #include <cstddef>
4 #include <vector>
5 
6 struct AtomInfoType;
7 struct ObjectMolecule;
8 
9 /*
10  * Ring finder subroutine
11  */
12 class AbstractRingFinder
13 {
14   ObjectMolecule* m_obj = nullptr;
15   std::vector<int> m_indices;
16 
17   void recursion(int atm, int depth);
18 
19 protected:
20   AbstractRingFinder() = delete;
AbstractRingFinder(unsigned maxringsize)21   AbstractRingFinder(unsigned maxringsize)
22       : m_indices(maxringsize)
23   {
24   }
25 
26   /**
27    * Optional object preparation. Note that `ObjectMoleculeUpdateNeighbors` is
28    * always called.
29    */
prepareObject(ObjectMolecule * obj)30   virtual void prepareObject(ObjectMolecule* obj) {}
31 
32   /**
33    * Optional atom filter.
34    * @return True to exclude an atom, false to include it.
35    */
atomIsExcluded(const AtomInfoType &)36   virtual bool atomIsExcluded(const AtomInfoType&) const { return false; }
37 
38   /**
39    * Is called when a ring is found.
40    *
41    * @param obj Molecule object
42    * @param indices Ring atom indices
43    * @param size Ring size
44    */
45   virtual void onRingFound(
46       ObjectMolecule* obj, const int* indices, size_t size) = 0;
47 
48 public:
49   /*
50    * Does a depth-first search for all paths of length in
51    * range [3, maxringsize], which lead back to `atm` and
52    * don't visit any atom twice.
53    */
54   void apply(ObjectMolecule* obj, int atm);
55 };
56