IMP logo
IMP Reference Guide  develop.d36d3deffb,2026/11/09
The Integrative Modeling Platform
comparison_macros.h
Go to the documentation of this file.
1 /**
2  * \file IMP/comparison_macros.h
3  * \brief Helper macros for implementing comparisons of \imp objects
4  *
5  * Copyright 2007-2026 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_COMPARISON_MACROS_H
10 #define IMPKERNEL_COMPARISON_MACROS_H
11 #include <IMP/kernel_config.h>
12 #include "warning_macros.h"
13 
14 #if defined(IMP_DOXYGEN)
15 /** \name Comparisons
16  Helper macros for implementing comparisons in terms of
17  either member variables or a member compare function.
18  All of the <,>,== etc are implemented for both C++
19  and Python.
20  @{
21 */
22 
23 //! Implement comparison in a class using a compare function
24 /** The compare function should take a const Name & and return -1, 0, 1 as
25  appropriate.
26 */
27 #define IMP_COMPARISONS(Name)
28 
29 //! Implement comparison in a class using field as the variable to compare
30 /** \param[in] Name the name of the class
31  \param[in] field the first field to compare on
32  */
33 #define IMP_COMPARISONS_1(Name, field)
34 
35 //! Implement comparison in a class using field as the variable to compare
36 /** \param[in] Name the name of the class
37  \param[in] f0 the first field to compare on
38  \param[in] f1 the second field to compare on
39  */
40 #define IMP_COMPARISONS_2(Name, f0, f1)
41 
42 //! Implement comparison in a class using field as the variable to compare
43 /** \param[in] Name the name of the class
44  \param[in] f0 the first field to compare on
45  \param[in] f1 the second field to compare on
46  \param[in] f2 the third field to compare on
47  */
48 #define IMP_COMPARISONS_3(Name, f0, f1, f2)
49 /** @} */
50 #elif defined(SWIG)
51 #define IMP_SWIG_COMPARISONS(Name) \
52  bool __eq__(const Name& o) const; \
53  bool __ne__(const Name& o) const; \
54  bool __lt__(const Name& o) const; \
55  bool __gt__(const Name& o) const; \
56  bool __ge__(const Name& o) const; \
57  bool __le__(const Name& o) const
58 
59 #define IMP_COMPARISONS(Name) IMP_SWIG_COMPARISONS(Name)
60 
61 #define IMP_COMPARISONS_1(Name, field) IMP_SWIG_COMPARISONS(Name)
62 
63 #define IMP_COMPARISONS_2(Name, f0, f1) IMP_SWIG_COMPARISONS(Name)
64 
65 #define IMP_COMPARISONS_3(Name, f0, f1, f2) IMP_SWIG_COMPARISONS(Name)
66 
67 #else // not doxygen
68 #define IMP_SWIG_COMPARISONS(Name) \
69  IMP_HELPER_MACRO_PUSH_WARNINGS bool __eq__(const Name& o) const { \
70  return operator==(o); \
71  } \
72  bool __ne__(const Name& o) const { return operator!=(o); } \
73  bool __lt__(const Name& o) const { return operator<(o); } \
74  bool __gt__(const Name& o) const { return operator>(o); } \
75  bool __ge__(const Name& o) const { return operator>=(o); } \
76  bool __le__(const Name& o) const { return operator<=(o); } \
77  IMP_HELPER_MACRO_POP_WARNINGS IMP_REQUIRE_SEMICOLON_CLASS(comparisons)
78 
79 #define IMP_COMPARISONS(Name) \
80  IMP_SWIG_COMPARISONS(Name); \
81  IMP_HELPER_MACRO_PUSH_WARNINGS bool operator==(const Name& o) const { \
82  return (Name::compare(o) == 0); \
83  } \
84  bool operator!=(const Name& o) const { return (Name::compare(o) != 0); } \
85  bool operator<(const Name& o) const { return (Name::compare(o) < 0); } \
86  bool operator>(const Name& o) const { return (compare(o) > 0); } \
87  bool operator>=(const Name& o) const { return !(Name::compare(o) < 0); } \
88  bool operator<=(const Name& o) const { return !(Name::compare(o) > 0); } \
89  IMP_HELPER_MACRO_POP_WARNINGS template <class T> \
90  friend int compare(const T& a, const T& b)
91 
92 #define IMP_COMPARISONS_1(Name, field) \
93  IMP_SWIG_COMPARISONS(Name); \
94  IMP_HELPER_MACRO_PUSH_WARNINGS bool operator==(const Name& o) const { \
95  return (field == o.field); \
96  } \
97  bool operator!=(const Name& o) const { return (field != o.field); } \
98  bool operator<(const Name& o) const { return (field < o.field); } \
99  bool operator>(const Name& o) const { return (field > o.field); } \
100  bool operator>=(const Name& o) const { return (field >= o.field); } \
101  bool operator<=(const Name& o) const { return (field <= o.field); } \
102  int compare(const Name& o) const { \
103  if (operator<(o)) \
104  return -1; \
105  else if (operator>(o)) \
106  return 1; \
107  else \
108  return 0; \
109  } \
110  IMP_HELPER_MACRO_POP_WARNINGS
111 
112 #define IMP_COMPARISONS_2(Name, f0, f1) \
113  IMP_SWIG_COMPARISONS(Name); \
114  IMP_HELPER_MACRO_PUSH_WARNINGS bool operator==(const Name& o) const { \
115  return (f0 == o.f0 && f1 == o.f1); \
116  } \
117  bool operator!=(const Name& o) const { return (f0 != o.f0 || f1 != o.f1); } \
118  bool operator<(const Name& o) const { \
119  if (f0 < o.f0) \
120  return true; \
121  else if (f0 > o.f0) \
122  return false; \
123  else \
124  return f1 < o.f1; \
125  } \
126  bool operator>(const Name& o) const { \
127  if (f0 > o.f0) \
128  return true; \
129  else if (f0 < o.f0) \
130  return false; \
131  else \
132  return f1 > o.f1; \
133  } \
134  bool operator>=(const Name& o) const { return operator>(o) || operator==( \
135  o); } \
136  bool operator<=(const Name& o) const { return operator<(o) || operator==( \
137  o); } \
138  int compare(const Name& o) const { \
139  if (operator<(o)) \
140  return -1; \
141  else if (operator>(o)) \
142  return 1; \
143  else \
144  return 0; \
145  } \
146  IMP_HELPER_MACRO_POP_WARNINGS
147 
148 #define IMP_COMPARISONS_3(Name, f0, f1, f2) \
149  IMP_SWIG_COMPARISONS(Name); \
150  IMP_HELPER_MACRO_PUSH_WARNINGS bool operator==(const Name& o) const { \
151  return (f0 == o.f0 && f1 == o.f1 && f2 == o.f2); \
152  } \
153  bool operator!=(const Name& o) const { \
154  return (f0 != o.f0 || f1 != o.f1 || f2 != o.f2); \
155  } \
156  bool operator<(const Name& o) const { \
157  if (f0 < o.f0) \
158  return true; \
159  else if (f0 > o.f0) \
160  return false; \
161  if (f1 < o.f1) \
162  return true; \
163  else if (f1 > o.f1) \
164  return false; \
165  else \
166  return f2 < o.f2; \
167  } \
168  bool operator>(const Name& o) const { \
169  if (f0 > o.f0) \
170  return true; \
171  else if (f0 < o.f0) \
172  return false; \
173  if (f1 > o.f1) \
174  return true; \
175  else if (f1 < o.f1) \
176  return false; \
177  else \
178  return f2 > o.f2; \
179  } \
180  bool operator>=(const Name& o) const { return operator>(o) || operator==( \
181  o); } \
182  bool operator<=(const Name& o) const { return operator<(o) || operator==( \
183  o); } \
184  int compare(const Name& o) const { \
185  if (operator<(o)) \
186  return -1; \
187  else if (operator>(o)) \
188  return 1; \
189  else \
190  return 0; \
191  } \
192  IMP_HELPER_MACRO_POP_WARNINGS
193 #endif
194 
195 #ifdef SWIG
196 #define IMP_SAFE_BOOL(Name, expr)
197 #else
198 /** Implement the safe bool idiom in a class. The expression must
199  evaluate to a boolean.
200  */
201 #define IMP_SAFE_BOOL(Name, expr) \
202  private: \
203  typedef void (Name::*bool_type)() const; \
204  void this_type_does_not_support_comparisons() const {} \
205  \
206  public: \
207  operator bool_type() const { \
208  return (expr) ? &Name::this_type_does_not_support_comparisons : 0; \
209  }
210 
211 #endif
212 
213 /** Compare one value and return -1 or 1 as appropriate. If they are
214  equal, control returns to the current scope.
215 */
216 #define IMP_COMPARE_ONE(vara, varb) \
217  if (vara < varb) \
218  return -1; \
219  else if (varb < vara) \
220  return 1
221 
222 #endif /* IMPKERNEL_COMPARISON_MACROS_H */
Macros to control compiler warnings.