IMP  2.3.0
The Integrative Modeling Platform
comparison_macros.h
Go to the documentation of this file.
1 /**
2  * \file IMP/base/comparison_macros.h
3  * \brief Various general useful macros for IMP.
4  *
5  * Copyright 2007-2014 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPBASE_COMPARISON_MACROS_H
10 #define IMPBASE_COMPARISON_MACROS_H
11 #include <IMP/base/base_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  int __cmp__(const Name& o) const { return compare(o); } \
78  IMP_HELPER_MACRO_POP_WARNINGS IMP_REQUIRE_SEMICOLON_CLASS(comparisons)
79 
80 #define IMP_COMPARISONS(Name) \
81  IMP_SWIG_COMPARISONS(Name); \
82  IMP_HELPER_MACRO_PUSH_WARNINGS bool operator==(const Name& o) const { \
83  return (Name::compare(o) == 0); \
84  } \
85  bool operator!=(const Name& o) const { return (Name::compare(o) != 0); } \
86  bool operator<(const Name& o) const { return (Name::compare(o) < 0); } \
87  bool operator>(const Name& o) const { return (compare(o) > 0); } \
88  bool operator>=(const Name& o) const { return !(Name::compare(o) < 0); } \
89  bool operator<=(const Name& o) const { return !(Name::compare(o) > 0); } \
90  IMP_HELPER_MACRO_POP_WARNINGS template <class T> \
91  friend int compare(const T& a, const T& b)
92 
93 #define IMP_COMPARISONS_1(Name, field) \
94  IMP_SWIG_COMPARISONS(Name); \
95  IMP_HELPER_MACRO_PUSH_WARNINGS bool operator==(const Name& o) const { \
96  return (field == o.field); \
97  } \
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  bool operator<=(const Name& o) const { return (field <= o.field); } \
103  int compare(const Name& o) const { \
104  if (operator<(o)) \
105  return -1; \
106  else if (operator>(o)) \
107  return 1; \
108  else \
109  return 0; \
110  } \
111  IMP_HELPER_MACRO_POP_WARNINGS
112 
113 #define IMP_COMPARISONS_2(Name, f0, f1) \
114  IMP_SWIG_COMPARISONS(Name); \
115  IMP_HELPER_MACRO_PUSH_WARNINGS bool operator==(const Name& o) const { \
116  return (f0 == o.f0 && f1 == o.f1); \
117  } \
118  bool operator!=(const Name& o) const { return (f0 != o.f0 || f1 != o.f1); } \
119  bool operator<(const Name& o) const { \
120  if (f0 < o.f0) \
121  return true; \
122  else if (f0 > o.f0) \
123  return false; \
124  else \
125  return f1 < o.f1; \
126  } \
127  bool operator>(const Name& o) const { \
128  if (f0 > o.f0) \
129  return true; \
130  else if (f0 < o.f0) \
131  return false; \
132  else \
133  return f1 > o.f1; \
134  } \
135  bool operator>=(const Name& o) const { return operator>(o) || operator==( \
136  o); } \
137  bool operator<=(const Name& o) const { return operator<(o) || operator==( \
138  o); } \
139  int compare(const Name& o) const { \
140  if (operator<(o)) \
141  return -1; \
142  else if (operator>(o)) \
143  return 1; \
144  else \
145  return 0; \
146  } \
147  IMP_HELPER_MACRO_POP_WARNINGS
148 
149 #define IMP_COMPARISONS_3(Name, f0, f1, f2) \
150  IMP_SWIG_COMPARISONS(Name); \
151  IMP_HELPER_MACRO_PUSH_WARNINGS bool operator==(const Name& o) const { \
152  return (f0 == o.f0 && f1 == o.f1 && f2 == o.f2); \
153  } \
154  bool operator!=(const Name& o) const { \
155  return (f0 != o.f0 || f1 != o.f1 || f2 != o.f2); \
156  } \
157  bool operator<(const Name& o) const { \
158  if (f0 < o.f0) \
159  return true; \
160  else if (f0 > o.f0) \
161  return false; \
162  if (f1 < o.f1) \
163  return true; \
164  else if (f1 > o.f1) \
165  return false; \
166  else \
167  return f2 < o.f2; \
168  } \
169  bool operator>(const Name& o) const { \
170  if (f0 > o.f0) \
171  return true; \
172  else if (f0 < o.f0) \
173  return false; \
174  if (f1 > o.f1) \
175  return true; \
176  else if (f1 < o.f1) \
177  return false; \
178  else \
179  return f2 > o.f2; \
180  } \
181  bool operator>=(const Name& o) const { return operator>(o) || operator==( \
182  o); } \
183  bool operator<=(const Name& o) const { return operator<(o) || operator==( \
184  o); } \
185  int compare(const Name& o) const { \
186  if (operator<(o)) \
187  return -1; \
188  else if (operator>(o)) \
189  return 1; \
190  else \
191  return 0; \
192  } \
193  IMP_HELPER_MACRO_POP_WARNINGS
194 #endif
195 
196 #ifdef SWIG
197 #define IMP_SAFE_BOOL(Name, expr)
198 #else
199 /** Implement the safe bool idiom in a class. The expression must
200  evaluate to a boolean.
201  */
202 #define IMP_SAFE_BOOL(Name, expr) \
203  private: \
204  typedef void (Name::*bool_type)() const; \
205  void this_type_does_not_support_comparisons() const {} \
206  \
207  public: \
208  operator bool_type() const { \
209  return (expr) ? &Name::this_type_does_not_support_comparisons : 0; \
210  }
211 
212 #endif
213 
214 /** Compare one value and return -1 or 1 as appropriate. If they are
215  equal, control returns to the current scope.
216 */
217 #define IMP_COMPARE_ONE(vara, varb) \
218  if (vara < varb) \
219  return -1; \
220  else if (varb < vara) \
221  return 1
222 
223 #endif /* IMPBASE_COMPARISON_MACROS_H */
Various general useful macros for IMP.