IMP  2.0.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-2013 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 
60 #define IMP_COMPARISONS(Name) \
61  IMP_SWIG_COMPARISONS(Name)
62 
63 #define IMP_COMPARISONS_1(Name, field) \
64  IMP_SWIG_COMPARISONS(Name)
65 
66 #define IMP_COMPARISONS_2(Name, f0, f1) \
67  IMP_SWIG_COMPARISONS(Name)
68 
69 #define IMP_COMPARISONS_3(Name, f0, f1, f2) \
70  IMP_SWIG_COMPARISONS(Name)
71 
72 #else // not doxygen
73 #define IMP_SWIG_COMPARISONS(Name) \
74  IMP_HELPER_MACRO_PUSH_WARNINGS \
75  bool __eq__(const Name &o) const { \
76  return operator==(o); \
77  } \
78  bool __ne__(const Name &o) const { \
79  return operator!=(o); \
80  } \
81  bool __lt__(const Name &o) const { \
82  return operator<(o); \
83  } \
84  bool __gt__(const Name &o) const { \
85  return operator>(o); \
86  } \
87  bool __ge__(const Name &o) const { \
88  return operator>=(o); \
89  } \
90  bool __le__(const Name &o) const { \
91  return operator<=(o); \
92  } \
93  int __cmp__(const Name &o) const { \
94  return compare(o); \
95  } \
96  IMP_HELPER_MACRO_POP_WARNINGS \
97  IMP_REQUIRE_SEMICOLON_CLASS(comparisons)
98 
99 #define IMP_COMPARISONS(Name) \
100  IMP_SWIG_COMPARISONS(Name); \
101  IMP_HELPER_MACRO_PUSH_WARNINGS \
102  bool operator==(const Name &o) const { \
103  return (Name::compare(o) == 0); \
104  } \
105  bool operator!=(const Name &o) const { \
106  return (Name::compare(o) != 0); \
107  } \
108  bool operator<(const Name &o) const { \
109  return (Name::compare(o) <0); \
110  } \
111  bool operator>(const Name &o) const { \
112  return (compare(o) > 0); \
113  } \
114  bool operator>=(const Name &o) const { \
115  return !(Name::compare(o) < 0); \
116  } \
117  bool operator<=(const Name &o) const { \
118  return !(Name::compare(o) > 0); \
119  } \
120  IMP_HELPER_MACRO_POP_WARNINGS \
121  template <class T> friend int compare(const T&a, const T&b)
122 
123 #define IMP_COMPARISONS_1(Name, field) \
124  IMP_SWIG_COMPARISONS(Name); \
125  IMP_HELPER_MACRO_PUSH_WARNINGS \
126  bool operator==(const Name &o) const { \
127  return (field== o.field); \
128  } \
129  bool operator!=(const Name &o) const { \
130  return (field!= o.field); \
131  } \
132  bool operator<(const Name &o) const { \
133  return (field< o.field); \
134  } \
135  bool operator>(const Name &o) const { \
136  return (field> o.field); \
137  } \
138  bool operator>=(const Name &o) const { \
139  return (field>= o.field); \
140  } \
141  bool operator<=(const Name &o) const { \
142  return (field<= o.field); \
143  } \
144  int compare(const Name &o) const { \
145  if (operator<(o)) return -1; \
146  else if (operator>(o)) return 1; \
147  else return 0; \
148  } \
149  IMP_HELPER_MACRO_POP_WARNINGS \
150 
151 #define IMP_COMPARISONS_2(Name, f0, f1) \
152  IMP_SWIG_COMPARISONS(Name); \
153  IMP_HELPER_MACRO_PUSH_WARNINGS \
154  bool operator==(const Name &o) const { \
155  return (f0== o.f0 && f1==o.f1); \
156  } \
157  bool operator!=(const Name &o) const { \
158  return (f0!= o.f0 || f1 != o.f1); \
159  } \
160  bool operator<(const Name &o) const { \
161  if (f0< o.f0) return true; \
162  else if (f0 > o.f0) return false; \
163  else return f1 < o.f1; \
164  } \
165  bool operator>(const Name &o) const { \
166  if (f0 > o.f0) return true; \
167  else if (f0 < o.f0) return false; \
168  else return f1 > o.f1; \
169  } \
170  bool operator>=(const Name &o) const { \
171  return operator>(o) || operator==(o); \
172  } \
173  bool operator<=(const Name &o) const { \
174  return operator<(o) || operator==(o); \
175  } \
176  int compare(const Name &o) const { \
177  if (operator<(o)) return -1; \
178  else if (operator>(o)) return 1; \
179  else return 0; \
180  } \
181  IMP_HELPER_MACRO_POP_WARNINGS
182 
183 #define IMP_COMPARISONS_3(Name, f0, f1, f2) \
184  IMP_SWIG_COMPARISONS(Name); \
185  IMP_HELPER_MACRO_PUSH_WARNINGS \
186  bool operator==(const Name &o) const { \
187  return (f0== o.f0 && f1==o.f1 && f2 == o.f2); \
188  } \
189  bool operator!=(const Name &o) const { \
190  return (f0!= o.f0 || f1 != o.f1 || f2 != o.f2); \
191  } \
192  bool operator<(const Name &o) const { \
193  if (f0< o.f0) return true; \
194  else if (f0 > o.f0) return false; \
195  if (f1< o.f1) return true; \
196  else if (f1 > o.f1) return false; \
197  else return f2 < o.f2; \
198  } \
199  bool operator>(const Name &o) const { \
200  if (f0 > o.f0) return true; \
201  else if (f0 < o.f0) return false; \
202  if (f1 > o.f1) return true; \
203  else if (f1 < o.f1) return false; \
204  else return f2 > o.f2; \
205  } \
206  bool operator>=(const Name &o) const { \
207  return operator>(o) || operator==(o); \
208  } \
209  bool operator<=(const Name &o) const { \
210  return operator<(o) || operator==(o); \
211  } \
212  int compare(const Name &o) const { \
213  if (operator<(o)) return -1; \
214  else if (operator>(o)) return 1; \
215  else return 0; \
216  } \
217  IMP_HELPER_MACRO_POP_WARNINGS
218 #endif
219 
220 
221 
222 #ifdef SWIG
223 #define IMP_SAFE_BOOL(Name, expr)
224 #else
225 /** Implement the safe bool idiom in a class. The expression must
226  evaluate to a boolean.
227  */
228 #define IMP_SAFE_BOOL(Name, expr) \
229  private: \
230  typedef void (Name::*bool_type)() const; \
231  void this_type_does_not_support_comparisons() const {} \
232 public: \
233  operator bool_type() const { \
234  return (expr) ? \
235  &Name::this_type_does_not_support_comparisons : 0; \
236  }
237 
238 #endif
239 
240 /** Compare one value and return -1 or 1 as appriate. If they are
241  equal, control returns to the current scope.
242 */
243 #define IMP_COMPARE_ONE(vara, varb) \
244  if (vara < varb) return -1; \
245  else if (varb < vara) return 1
246 
247 #endif /* IMPBASE_COMPARISON_MACROS_H */