RMF
infrastructure_macros.h
Go to the documentation of this file.
1 /**
2  * \file RMF/infrastructure_macros.h
3  * \brief Various general useful macros for IMP.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef RMF_INFRASTRUCTURE_MACROS_H
10 #define RMF_INFRASTRUCTURE_MACROS_H
11 
12 #include <sstream>
13 #include <iostream>
14 #include <string>
15 #include "RMF/compiler_macros.h"
16 #include "internal/use.h"
17 #include <vector>
18 #include <boost/config.hpp>
19 #include <boost/version.hpp>
20 
21 // Deprecated: just use range-based for directly
22 #define RMF_FOREACH(v, r) for (v : r)
23 
24 RMF_ENABLE_WARNINGS
25 
26 #ifdef NDEBUG
27 #define RMF_NDEBUG
28 #endif
29 
30 #if defined(RMF_DOXYGEN)
31 /** \name Comparisons
32  Helper macros for implementing comparisons in terms of
33  either member variables or a member compare function.
34  All of the <,>,== etc are implemented for both C++
35  and Python.
36  @{
37  */
38 
39 //! Implement comparison in a class using field as the variable to compare
40 /** \param[in] Name the name of the class
41  */
42 #define RMF_COMPARISONS(Name)
43 
44 /** @} */
45 #elif defined(SWIG)
46 #define RMF_SWIG_COMPARISONS(Name) \
47  bool __eq__(const Name& o) const; \
48  bool __ne__(const Name& o) const; \
49  bool __lt__(const Name& o) const; \
50  bool __gt__(const Name& o) const; \
51  bool __ge__(const Name& o) const; \
52  bool __le__(const Name& o) const
53 
54 #define RMF_COMPARISONS(Name) RMF_SWIG_COMPARISONS(Name)
55 
56 #else // not doxygen
57 
58 #define RMF_SWIG_COMPARISONS(Name) \
59  bool __eq__(const Name& o) const { return operator==(o); } \
60  bool __ne__(const Name& o) const { return operator!=(o); } \
61  bool __lt__(const Name& o) const { return operator<(o); } \
62  bool __gt__(const Name& o) const { return operator>(o); } \
63  bool __ge__(const Name& o) const { return operator>=(o); } \
64  bool __le__(const Name& o) const { return operator<=(o); } \
65  int __cmp__(const Name& o) const { return compare(o); }
66 
67 #define RMF_COMPARISONS(Name) \
68  bool operator==(const Name& o) const { return compare(o) == 0; } \
69  bool operator!=(const Name& o) const { return compare(o) != 0; } \
70  bool operator<(const Name& o) const { return compare(o) < 0; } \
71  bool operator>(const Name& o) const { return compare(o) > 0; } \
72  bool operator>=(const Name& o) const { return compare(o) >= 0; } \
73  bool operator<=(const Name& o) const { return compare(o) <= 0; } \
74  RMF_SWIG_COMPARISONS(Name)
75 
76 #endif
77 
78 #ifdef RMF_DOXYGEN
79 
80 //! Implement a hash function for the class
81 #define RMF_HASHABLE(name, hashret)
82 /** @} */
83 #else
84 
85 #define RMF_HASHABLE(name, hashret) \
86  std::size_t __hash__() const { hashret; }
87 
88 #endif
89 
90 /** @} */
91 
92 #ifdef SWIG
93 #define RMF_SHOWABLE(Name, streamed) \
94  std::string __str__() const { \
95  std::ostringstream out; \
96  show(out); \
97  return out.str(); \
98  } \
99  std::string __repr__() const { \
100  std::ostringstream out; \
101  show(out); \
102  return out.str(); \
103  }
104 
105 #elif defined(RMF_DOXYGEN)
106 #define RMF_SHOWABLE(Name, streamed)
107 
108 #else
109 #define RMF_SHOWABLE(Name, streamed) \
110  operator Showable() const { \
111  std::ostringstream oss; \
112  oss << streamed; \
113  return Showable(oss.str(), Showable::Special()); \
114  } \
115  void show(std::ostream& out) const { out << streamed; } \
116  std::string __str__() const { \
117  std::ostringstream out; \
118  show(out); \
119  return out.str(); \
120  } \
121  std::string __repr__() const { \
122  std::ostringstream out; \
123  show(out); \
124  return out.str(); \
125  }
126 #endif
127 
128 /** Suppress the unused variable compiler warning. */
129 #define RMF_UNUSED(variable) RMF::internal::use(variable);
130 
131 /** Provide a dummy return for something that doesn't return.
132 
133  This is a nasty hack to suppress warnings in some compilers.
134 */
135 #define RMF_NO_RETURN(type) return type()
136 
137 /** Apply the macro to each supported constant size type (e.g. int as opposed
138  to string).
139 
140  \see RMF_FOREACH_TYPE()
141  */
142 #define RMF_FOREACH_SIMPLE_TYPE(macroname) \
143  macroname(int, Int, int, int, const Ints&, Ints); \
144  macroname(float, Float, float, float, const Floats&, Floats); \
145  macroname(index, Index, int, int, const Ints&, Ints)
146 
147 /** Expand to applying the macro to each type supported by
148  the RMF library. The macro should take six arguments
149  - the lower case name of the type
150  - the upper case name
151  - the C++ type for accepting the value
152  - the C++ type for returning the value
153  - the C++ type for accepting more than one value
154  - the C++ type for returning more than one value
155 */
156 #define RMF_FOREACH_TYPE(macroname) \
157  macroname(RMF::IntTraits, Int) macroname(RMF::FloatTraits, Float) \
158  macroname(RMF::StringTraits, String) macroname(RMF::IntsTraits, Ints) \
159  macroname(RMF::FloatsTraits, Floats) \
160  macroname(RMF::StringsTraits, Strings) \
161  macroname(RMF::Vector3Traits, Vector3) \
162  macroname(RMF::Vector4Traits, Vector4) \
163  macroname(RMF::Vector3sTraits, Vector3s)
164 
165 #define RMF_DECORATOR_CATCH(extra_info) \
166  catch (Exception& e) { \
167  RMF_RETHROW(Decorator(get_decorator_type_name()) extra_info, e); \
168  }
169 
170 /** Register a validator function. See Validator for more
171  information.*/
172 #define RMF_VALIDATOR(Type) RMF::Registrar<Type> Type##Reg(#Type);
173 namespace RMF {
174 
175 template <class Tr>
176 class Nullable;
177 
178 #if !defined(RMF_DOXYGEN) && !defined(SWIG)
179 struct Showable;
180 inline std::ostream& operator<<(std::ostream& out, const Showable& t);
181 
182 /** An adaptor class to provide operator<< for classes easily. */
183 struct Showable {
184  std::string t_;
185  template <class T>
186  explicit Showable(const T& t) {
187  std::ostringstream oss;
188  oss << t;
189  t_ = oss.str();
190  }
191  template <class T, class TT>
192  Showable(const std::pair<T, TT>& p) {
193  std::ostringstream oss;
194  oss << "(" << p.first << ", " << p.second << ")";
195  t_ = oss.str();
196  }
197  Showable(std::string t) : t_(std::string("\"") + t + "\"") {}
198  struct Special {};
199  Showable(std::string t, Special) : t_(t) {}
200  template <class T>
201  Showable(const std::vector<T>& t) {
202  std::ostringstream out;
203  out << "[";
204  for (unsigned int i = 0; i < t.size(); ++i) {
205  if (i != 0) {
206  out << ", ";
207  }
208  out << t[i];
209  }
210  out << "]";
211  t_ = out.str();
212  }
213  template <class Tr>
214  Showable(const Nullable<Tr>& t) {
215  std::ostringstream out;
216  if (t.get_is_null())
217  out << "<None>";
218  else
219  out << t.get();
220  t_ = out.str();
221  }
222 };
223 
224 inline std::ostream& operator<<(std::ostream& out, const Showable& t) {
225  out << t.t_;
226  return out;
227 }
228 
229 #endif
230 }
231 
232 RMF_DISABLE_WARNINGS
233 
234 #endif /* RMF_INFRASTRUCTURE_MACROS_H */
Return a possibly null value.
Various compiler workarounds.