Coverage Report

Created: 2026-06-23 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rdkit/Code/RDGeneral/hanoiSort.h
Line
Count
Source
1
//
2
//  Copyright (C) 2014-2025 Greg Landrum and other RDKit contributors
3
//  Adapted from pseudo-code from Roger Sayle
4
//
5
//   @@ All Rights Reserved @@
6
//  This file is part of the RDKit.
7
//  The contents are covered by the terms of the BSD license
8
//  which is included in the file license.txt, found at the root
9
//  of the RDKit source tree.
10
//
11
12
#include <RDGeneral/export.h>
13
#ifndef HANOISORT_H
14
#define HANOISORT_H
15
16
#include <cstring>
17
#include <cassert>
18
#include <cstdlib>
19
#include <vector>
20
#include <span>
21
22
#if defined(_MSC_VER)
23
#pragma warning(push, 1)
24
#pragma warning(disable : 4800)
25
#endif
26
namespace RDKit {
27
namespace detail {
28
template <typename CompareFunc>
29
bool hanoi(int *base, int nel, int *temp, int *count, int *changed,
30
423M
           CompareFunc compar) {
31
423M
  assert(base);
32
423M
  assert(temp);
33
423M
  assert(count);
34
423M
  assert(changed);
35
  // std::cerr<<"  hanoi: "<<nel<< " start " << (*base)+1 << std::endl;
36
423M
  int *b1, *b2;
37
423M
  int *t1, *t2;
38
423M
  int *s1, *s2;
39
423M
  int n1, n2;
40
423M
  int result;
41
423M
  int *ptr;
42
43
423M
  if (nel == 1) {
44
60.8M
    count[base[0]] = 1;
45
60.8M
    return false;
46
363M
  } else if (nel == 2) {
47
152M
    n1 = base[0];
48
152M
    n2 = base[1];
49
152M
    int stat =
50
152M
        (/*!changed || */ changed[n1] || changed[n2]) ? compar(n1, n2) : 0;
51
152M
    if (stat == 0) {
52
147M
      count[n1] = 2;
53
147M
      count[n2] = 0;
54
147M
      return false;
55
147M
    } else if (stat < 0) {
56
3.00M
      count[n1] = 1;
57
3.00M
      count[n2] = 1;
58
3.00M
      return false;
59
3.00M
    } else /* stat > 0 */ {
60
1.91M
      count[n1] = 1;
61
1.91M
      count[n2] = 1;
62
1.91M
      base[0] = n2; /* temp[0] = n2; */
63
1.91M
      base[1] = n1; /* temp[1] = n1; */
64
1.91M
      return false; /* return True;  */
65
1.91M
    }
66
152M
  }
67
68
210M
  n1 = nel / 2;
69
210M
  n2 = nel - n1;
70
210M
  b1 = base;
71
210M
  t1 = temp;
72
210M
  b2 = base + n1;
73
210M
  t2 = temp + n1;
74
75
210M
  if (hanoi(b1, n1, t1, count, changed, compar)) {
76
64.3M
    if (hanoi(b2, n2, t2, count, changed, compar)) {
77
60.1M
      s2 = t2;
78
60.1M
    } else {
79
4.20M
      s2 = b2;
80
4.20M
    }
81
64.3M
    result = false;
82
64.3M
    ptr = base;
83
64.3M
    s1 = t1;
84
146M
  } else {
85
146M
    if (hanoi(b2, n2, t2, count, changed, compar)) {
86
20.3M
      s2 = t2;
87
125M
    } else {
88
125M
      s2 = b2;
89
125M
    }
90
146M
    result = true;
91
146M
    ptr = temp;
92
146M
    s1 = b1;
93
146M
  }
94
95
225M
  while (true) {
96
225M
    assert(*s1 != *s2);
97
225M
    int stat =
98
225M
        (/*!changed || */ changed[*s1] || changed[*s2]) ? compar(*s1, *s2) : 0;
99
225M
    int len1 = count[*s1];
100
225M
    int len2 = count[*s2];
101
225M
    assert(len1 > 0);
102
225M
    assert(len2 > 0);
103
225M
    if (stat == 0) {
104
211M
      count[*s1] = len1 + len2;
105
211M
      count[*s2] = 0;
106
211M
      memmove(ptr, s1, len1 * sizeof(int));
107
211M
      ptr += len1;
108
211M
      n1 -= len1;
109
211M
      if (n1 == 0) {
110
206M
        if (ptr != s2) {
111
182M
          memmove(ptr, s2, n2 * sizeof(int));
112
182M
        }
113
206M
        return result;
114
206M
      }
115
5.53M
      s1 += len1;
116
117
      // std::cerr<<"  cpy: "<<*s1<<" "<<*s2<<" "<<len2<<std::endl;
118
5.53M
      memmove(ptr, s2, len2 * sizeof(int));
119
5.53M
      ptr += len2;
120
5.53M
      n2 -= len2;
121
5.53M
      if (n2 == 0) {
122
1.62M
        memmove(ptr, s1, n1 * sizeof(int));
123
1.62M
        return result;
124
1.62M
      }
125
3.90M
      s2 += len2;
126
13.7M
    } else if (stat < 0 && len1 > 0) {
127
6.11M
      memmove(ptr, s1, len1 * sizeof(int));
128
6.11M
      ptr += len1;
129
6.11M
      n1 -= len1;
130
6.11M
      if (n1 == 0) {
131
1.34M
        if (ptr != s2) {
132
1.21M
          memmove(ptr, s2, n2 * sizeof(int));
133
1.21M
        }
134
1.34M
        return result;
135
1.34M
      }
136
4.76M
      s1 += len1;
137
7.59M
    } else if (stat > 0 && len2 > 0) /* stat > 0 */ {
138
7.59M
      memmove(ptr, s2, len2 * sizeof(int));
139
7.59M
      ptr += len2;
140
7.59M
      n2 -= len2;
141
7.59M
      if (n2 == 0) {
142
1.08M
        memmove(ptr, s1, n1 * sizeof(int));
143
1.08M
        return result;
144
1.08M
      }
145
6.51M
      s2 += len2;
146
6.51M
    } else {
147
0
      assert(0);
148
0
    }
149
225M
  }
150
210M
}
bool RDKit::detail::hanoi<RDKit::Canon::AtomCompareFunctor>(int*, int, int*, int*, int*, RDKit::Canon::AtomCompareFunctor)
Line
Count
Source
30
418M
           CompareFunc compar) {
31
418M
  assert(base);
32
418M
  assert(temp);
33
418M
  assert(count);
34
418M
  assert(changed);
35
  // std::cerr<<"  hanoi: "<<nel<< " start " << (*base)+1 << std::endl;
36
418M
  int *b1, *b2;
37
418M
  int *t1, *t2;
38
418M
  int *s1, *s2;
39
418M
  int n1, n2;
40
418M
  int result;
41
418M
  int *ptr;
42
43
418M
  if (nel == 1) {
44
59.9M
    count[base[0]] = 1;
45
59.9M
    return false;
46
358M
  } else if (nel == 2) {
47
150M
    n1 = base[0];
48
150M
    n2 = base[1];
49
150M
    int stat =
50
150M
        (/*!changed || */ changed[n1] || changed[n2]) ? compar(n1, n2) : 0;
51
150M
    if (stat == 0) {
52
145M
      count[n1] = 2;
53
145M
      count[n2] = 0;
54
145M
      return false;
55
145M
    } else if (stat < 0) {
56
3.00M
      count[n1] = 1;
57
3.00M
      count[n2] = 1;
58
3.00M
      return false;
59
3.00M
    } else /* stat > 0 */ {
60
1.91M
      count[n1] = 1;
61
1.91M
      count[n2] = 1;
62
1.91M
      base[0] = n2; /* temp[0] = n2; */
63
1.91M
      base[1] = n1; /* temp[1] = n1; */
64
1.91M
      return false; /* return True;  */
65
1.91M
    }
66
150M
  }
67
68
208M
  n1 = nel / 2;
69
208M
  n2 = nel - n1;
70
208M
  b1 = base;
71
208M
  t1 = temp;
72
208M
  b2 = base + n1;
73
208M
  t2 = temp + n1;
74
75
208M
  if (hanoi(b1, n1, t1, count, changed, compar)) {
76
63.6M
    if (hanoi(b2, n2, t2, count, changed, compar)) {
77
59.4M
      s2 = t2;
78
59.4M
    } else {
79
4.15M
      s2 = b2;
80
4.15M
    }
81
63.6M
    result = false;
82
63.6M
    ptr = base;
83
63.6M
    s1 = t1;
84
144M
  } else {
85
144M
    if (hanoi(b2, n2, t2, count, changed, compar)) {
86
20.2M
      s2 = t2;
87
124M
    } else {
88
124M
      s2 = b2;
89
124M
    }
90
144M
    result = true;
91
144M
    ptr = temp;
92
144M
    s1 = b1;
93
144M
  }
94
95
223M
  while (true) {
96
223M
    assert(*s1 != *s2);
97
223M
    int stat =
98
223M
        (/*!changed || */ changed[*s1] || changed[*s2]) ? compar(*s1, *s2) : 0;
99
223M
    int len1 = count[*s1];
100
223M
    int len2 = count[*s2];
101
223M
    assert(len1 > 0);
102
223M
    assert(len2 > 0);
103
223M
    if (stat == 0) {
104
209M
      count[*s1] = len1 + len2;
105
209M
      count[*s2] = 0;
106
209M
      memmove(ptr, s1, len1 * sizeof(int));
107
209M
      ptr += len1;
108
209M
      n1 -= len1;
109
209M
      if (n1 == 0) {
110
203M
        if (ptr != s2) {
111
179M
          memmove(ptr, s2, n2 * sizeof(int));
112
179M
        }
113
203M
        return result;
114
203M
      }
115
5.52M
      s1 += len1;
116
117
      // std::cerr<<"  cpy: "<<*s1<<" "<<*s2<<" "<<len2<<std::endl;
118
5.52M
      memmove(ptr, s2, len2 * sizeof(int));
119
5.52M
      ptr += len2;
120
5.52M
      n2 -= len2;
121
5.52M
      if (n2 == 0) {
122
1.62M
        memmove(ptr, s1, n1 * sizeof(int));
123
1.62M
        return result;
124
1.62M
      }
125
3.90M
      s2 += len2;
126
13.7M
    } else if (stat < 0 && len1 > 0) {
127
6.11M
      memmove(ptr, s1, len1 * sizeof(int));
128
6.11M
      ptr += len1;
129
6.11M
      n1 -= len1;
130
6.11M
      if (n1 == 0) {
131
1.34M
        if (ptr != s2) {
132
1.21M
          memmove(ptr, s2, n2 * sizeof(int));
133
1.21M
        }
134
1.34M
        return result;
135
1.34M
      }
136
4.76M
      s1 += len1;
137
7.59M
    } else if (stat > 0 && len2 > 0) /* stat > 0 */ {
138
7.59M
      memmove(ptr, s2, len2 * sizeof(int));
139
7.59M
      ptr += len2;
140
7.59M
      n2 -= len2;
141
7.59M
      if (n2 == 0) {
142
1.08M
        memmove(ptr, s1, n1 * sizeof(int));
143
1.08M
        return result;
144
1.08M
      }
145
6.51M
      s2 += len2;
146
6.51M
    } else {
147
      assert(0);
148
0
    }
149
223M
  }
150
208M
}
bool RDKit::detail::hanoi<RDKit::Canon::SpecialChiralityAtomCompareFunctor>(int*, int, int*, int*, int*, RDKit::Canon::SpecialChiralityAtomCompareFunctor)
Line
Count
Source
30
4.63M
           CompareFunc compar) {
31
4.63M
  assert(base);
32
4.63M
  assert(temp);
33
4.63M
  assert(count);
34
4.63M
  assert(changed);
35
  // std::cerr<<"  hanoi: "<<nel<< " start " << (*base)+1 << std::endl;
36
4.63M
  int *b1, *b2;
37
4.63M
  int *t1, *t2;
38
4.63M
  int *s1, *s2;
39
4.63M
  int n1, n2;
40
4.63M
  int result;
41
4.63M
  int *ptr;
42
43
4.63M
  if (nel == 1) {
44
745k
    count[base[0]] = 1;
45
745k
    return false;
46
3.89M
  } else if (nel == 2) {
47
1.67M
    n1 = base[0];
48
1.67M
    n2 = base[1];
49
1.67M
    int stat =
50
1.67M
        (/*!changed || */ changed[n1] || changed[n2]) ? compar(n1, n2) : 0;
51
1.67M
    if (stat == 0) {
52
1.67M
      count[n1] = 2;
53
1.67M
      count[n2] = 0;
54
1.67M
      return false;
55
1.67M
    } else if (stat < 0) {
56
385
      count[n1] = 1;
57
385
      count[n2] = 1;
58
385
      return false;
59
545
    } else /* stat > 0 */ {
60
545
      count[n1] = 1;
61
545
      count[n2] = 1;
62
545
      base[0] = n2; /* temp[0] = n2; */
63
545
      base[1] = n1; /* temp[1] = n1; */
64
545
      return false; /* return True;  */
65
545
    }
66
1.67M
  }
67
68
2.21M
  n1 = nel / 2;
69
2.21M
  n2 = nel - n1;
70
2.21M
  b1 = base;
71
2.21M
  t1 = temp;
72
2.21M
  b2 = base + n1;
73
2.21M
  t2 = temp + n1;
74
75
2.21M
  if (hanoi(b1, n1, t1, count, changed, compar)) {
76
674k
    if (hanoi(b2, n2, t2, count, changed, compar)) {
77
628k
      s2 = t2;
78
628k
    } else {
79
45.6k
      s2 = b2;
80
45.6k
    }
81
674k
    result = false;
82
674k
    ptr = base;
83
674k
    s1 = t1;
84
1.54M
  } else {
85
1.54M
    if (hanoi(b2, n2, t2, count, changed, compar)) {
86
171k
      s2 = t2;
87
1.37M
    } else {
88
1.37M
      s2 = b2;
89
1.37M
    }
90
1.54M
    result = true;
91
1.54M
    ptr = temp;
92
1.54M
    s1 = b1;
93
1.54M
  }
94
95
2.21M
  while (true) {
96
2.21M
    assert(*s1 != *s2);
97
2.21M
    int stat =
98
2.21M
        (/*!changed || */ changed[*s1] || changed[*s2]) ? compar(*s1, *s2) : 0;
99
2.21M
    int len1 = count[*s1];
100
2.21M
    int len2 = count[*s2];
101
2.21M
    assert(len1 > 0);
102
2.21M
    assert(len2 > 0);
103
2.21M
    if (stat == 0) {
104
2.21M
      count[*s1] = len1 + len2;
105
2.21M
      count[*s2] = 0;
106
2.21M
      memmove(ptr, s1, len1 * sizeof(int));
107
2.21M
      ptr += len1;
108
2.21M
      n1 -= len1;
109
2.21M
      if (n1 == 0) {
110
2.21M
        if (ptr != s2) {
111
2.00M
          memmove(ptr, s2, n2 * sizeof(int));
112
2.00M
        }
113
2.21M
        return result;
114
2.21M
      }
115
274
      s1 += len1;
116
117
      // std::cerr<<"  cpy: "<<*s1<<" "<<*s2<<" "<<len2<<std::endl;
118
274
      memmove(ptr, s2, len2 * sizeof(int));
119
274
      ptr += len2;
120
274
      n2 -= len2;
121
274
      if (n2 == 0) {
122
0
        memmove(ptr, s1, n1 * sizeof(int));
123
0
        return result;
124
0
      }
125
274
      s2 += len2;
126
274
    } else if (stat < 0 && len1 > 0) {
127
1
      memmove(ptr, s1, len1 * sizeof(int));
128
1
      ptr += len1;
129
1
      n1 -= len1;
130
1
      if (n1 == 0) {
131
1
        if (ptr != s2) {
132
1
          memmove(ptr, s2, n2 * sizeof(int));
133
1
        }
134
1
        return result;
135
1
      }
136
0
      s1 += len1;
137
81
    } else if (stat > 0 && len2 > 0) /* stat > 0 */ {
138
81
      memmove(ptr, s2, len2 * sizeof(int));
139
81
      ptr += len2;
140
81
      n2 -= len2;
141
81
      if (n2 == 0) {
142
0
        memmove(ptr, s1, n1 * sizeof(int));
143
0
        return result;
144
0
      }
145
81
      s2 += len2;
146
81
    } else {
147
      assert(0);
148
0
    }
149
2.21M
  }
150
2.21M
}
bool RDKit::detail::hanoi<RDKit::Canon::SpecialSymmetryAtomCompareFunctor>(int*, int, int*, int*, int*, RDKit::Canon::SpecialSymmetryAtomCompareFunctor)
Line
Count
Source
30
461k
           CompareFunc compar) {
31
461k
  assert(base);
32
461k
  assert(temp);
33
461k
  assert(count);
34
461k
  assert(changed);
35
  // std::cerr<<"  hanoi: "<<nel<< " start " << (*base)+1 << std::endl;
36
461k
  int *b1, *b2;
37
461k
  int *t1, *t2;
38
461k
  int *s1, *s2;
39
461k
  int n1, n2;
40
461k
  int result;
41
461k
  int *ptr;
42
43
461k
  if (nel == 1) {
44
70.2k
    count[base[0]] = 1;
45
70.2k
    return false;
46
391k
  } else if (nel == 2) {
47
194k
    n1 = base[0];
48
194k
    n2 = base[1];
49
194k
    int stat =
50
194k
        (/*!changed || */ changed[n1] || changed[n2]) ? compar(n1, n2) : 0;
51
194k
    if (stat == 0) {
52
193k
      count[n1] = 2;
53
193k
      count[n2] = 0;
54
193k
      return false;
55
193k
    } else if (stat < 0) {
56
306
      count[n1] = 1;
57
306
      count[n2] = 1;
58
306
      return false;
59
351
    } else /* stat > 0 */ {
60
351
      count[n1] = 1;
61
351
      count[n2] = 1;
62
351
      base[0] = n2; /* temp[0] = n2; */
63
351
      base[1] = n1; /* temp[1] = n1; */
64
351
      return false; /* return True;  */
65
351
    }
66
194k
  }
67
68
196k
  n1 = nel / 2;
69
196k
  n2 = nel - n1;
70
196k
  b1 = base;
71
196k
  t1 = temp;
72
196k
  b2 = base + n1;
73
196k
  t2 = temp + n1;
74
75
196k
  if (hanoi(b1, n1, t1, count, changed, compar)) {
76
50.5k
    if (hanoi(b2, n2, t2, count, changed, compar)) {
77
47.0k
      s2 = t2;
78
47.0k
    } else {
79
3.50k
      s2 = b2;
80
3.50k
    }
81
50.5k
    result = false;
82
50.5k
    ptr = base;
83
50.5k
    s1 = t1;
84
146k
  } else {
85
146k
    if (hanoi(b2, n2, t2, count, changed, compar)) {
86
19.1k
      s2 = t2;
87
127k
    } else {
88
127k
      s2 = b2;
89
127k
    }
90
146k
    result = true;
91
146k
    ptr = temp;
92
146k
    s1 = b1;
93
146k
  }
94
95
199k
  while (true) {
96
199k
    assert(*s1 != *s2);
97
199k
    int stat =
98
199k
        (/*!changed || */ changed[*s1] || changed[*s2]) ? compar(*s1, *s2) : 0;
99
199k
    int len1 = count[*s1];
100
199k
    int len2 = count[*s2];
101
199k
    assert(len1 > 0);
102
199k
    assert(len2 > 0);
103
199k
    if (stat == 0) {
104
196k
      count[*s1] = len1 + len2;
105
196k
      count[*s2] = 0;
106
196k
      memmove(ptr, s1, len1 * sizeof(int));
107
196k
      ptr += len1;
108
196k
      n1 -= len1;
109
196k
      if (n1 == 0) {
110
195k
        if (ptr != s2) {
111
173k
          memmove(ptr, s2, n2 * sizeof(int));
112
173k
        }
113
195k
        return result;
114
195k
      }
115
1.09k
      s1 += len1;
116
117
      // std::cerr<<"  cpy: "<<*s1<<" "<<*s2<<" "<<len2<<std::endl;
118
1.09k
      memmove(ptr, s2, len2 * sizeof(int));
119
1.09k
      ptr += len2;
120
1.09k
      n2 -= len2;
121
1.09k
      if (n2 == 0) {
122
171
        memmove(ptr, s1, n1 * sizeof(int));
123
171
        return result;
124
171
      }
125
924
      s2 += len2;
126
2.02k
    } else if (stat < 0 && len1 > 0) {
127
922
      memmove(ptr, s1, len1 * sizeof(int));
128
922
      ptr += len1;
129
922
      n1 -= len1;
130
922
      if (n1 == 0) {
131
552
        if (ptr != s2) {
132
505
          memmove(ptr, s2, n2 * sizeof(int));
133
505
        }
134
552
        return result;
135
552
      }
136
370
      s1 += len1;
137
1.10k
    } else if (stat > 0 && len2 > 0) /* stat > 0 */ {
138
1.10k
      memmove(ptr, s2, len2 * sizeof(int));
139
1.10k
      ptr += len2;
140
1.10k
      n2 -= len2;
141
1.10k
      if (n2 == 0) {
142
363
        memmove(ptr, s1, n1 * sizeof(int));
143
363
        return result;
144
363
      }
145
742
      s2 += len2;
146
742
    } else {
147
      assert(0);
148
0
    }
149
199k
  }
150
196k
}
Unexecuted instantiation: bool RDKit::detail::hanoi<RDKit::Canon::ChiralAtomCompareFunctor>(int*, int, int*, int*, int*, RDKit::Canon::ChiralAtomCompareFunctor)
151
}  // namespace detail
152
template <typename CompareFunc>
153
void hanoisort(std::span<int> &base, std::vector<int> &count,
154
3.03M
               std::vector<int> &changed, CompareFunc compar) {
155
3.03M
  std::vector<int> tempVec(base.size());
156
3.03M
  if (detail::hanoi(base.data(), base.size(), tempVec.data(), count.data(),
157
3.03M
                    changed.data(), compar)) {
158
1.22M
    std::copy(tempVec.begin(), tempVec.end(), base.begin());
159
1.22M
  }
160
3.03M
}
void RDKit::hanoisort<RDKit::Canon::AtomCompareFunctor>(std::__1::span<int, 18446744073709551615ul>&, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&, RDKit::Canon::AtomCompareFunctor)
Line
Count
Source
154
2.77M
               std::vector<int> &changed, CompareFunc compar) {
155
2.77M
  std::vector<int> tempVec(base.size());
156
2.77M
  if (detail::hanoi(base.data(), base.size(), tempVec.data(), count.data(),
157
2.77M
                    changed.data(), compar)) {
158
1.12M
    std::copy(tempVec.begin(), tempVec.end(), base.begin());
159
1.12M
  }
160
2.77M
}
void RDKit::hanoisort<RDKit::Canon::SpecialChiralityAtomCompareFunctor>(std::__1::span<int, 18446744073709551615ul>&, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&, RDKit::Canon::SpecialChiralityAtomCompareFunctor)
Line
Count
Source
154
200k
               std::vector<int> &changed, CompareFunc compar) {
155
200k
  std::vector<int> tempVec(base.size());
156
200k
  if (detail::hanoi(base.data(), base.size(), tempVec.data(), count.data(),
157
200k
                    changed.data(), compar)) {
158
69.5k
    std::copy(tempVec.begin(), tempVec.end(), base.begin());
159
69.5k
  }
160
200k
}
void RDKit::hanoisort<RDKit::Canon::SpecialSymmetryAtomCompareFunctor>(std::__1::span<int, 18446744073709551615ul>&, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&, RDKit::Canon::SpecialSymmetryAtomCompareFunctor)
Line
Count
Source
154
67.6k
               std::vector<int> &changed, CompareFunc compar) {
155
67.6k
  std::vector<int> tempVec(base.size());
156
67.6k
  if (detail::hanoi(base.data(), base.size(), tempVec.data(), count.data(),
157
67.6k
                    changed.data(), compar)) {
158
29.5k
    std::copy(tempVec.begin(), tempVec.end(), base.begin());
159
29.5k
  }
160
67.6k
}
Unexecuted instantiation: void RDKit::hanoisort<RDKit::Canon::ChiralAtomCompareFunctor>(std::__1::span<int, 18446744073709551615ul>&, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&, RDKit::Canon::ChiralAtomCompareFunctor)
161
}  // namespace RDKit
162
163
#if defined(_MSC_VER)
164
#pragma warning(pop)
165
#endif
166
167
#endif /* HANOISORT_H_ */