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 #else
83 
84 #define RMF_HASHABLE(name, hashret) \
85  std::size_t __hash__() const { hashret; }
86 
87 #endif
88 
89 #ifdef SWIG
90 #define RMF_SHOWABLE(Name, streamed) \
91  std::string __str__() const { \
92  std::ostringstream out; \
93  show(out); \
94  return out.str(); \
95  } \
96  std::string __repr__() const { \
97  std::ostringstream out; \
98  show(out); \
99  return out.str(); \
100  }
101 
102 #elif defined(RMF_DOXYGEN)
103 #define RMF_SHOWABLE(Name, streamed)
104 
105 #else
106 #define RMF_SHOWABLE(Name, streamed) \
107  operator Showable() const { \
108  std::ostringstream oss; \
109  oss << streamed; \
110  return Showable(oss.str(), Showable::Special()); \
111  } \
112  void show(std::ostream& out) const { out << streamed; } \
113  std::string __str__() const { \
114  std::ostringstream out; \
115  show(out); \
116  return out.str(); \
117  } \
118  std::string __repr__() const { \
119  std::ostringstream out; \
120  show(out); \
121  return out.str(); \
122  }
123 #endif
124 
125 /** Suppress the unused variable compiler warning. */
126 #define RMF_UNUSED(variable) RMF::internal::use(variable);
127 
128 /** Provide a dummy return for something that doesn't return.
129 
130  This is a nasty hack to suppress warnings in some compilers.
131 */
132 #define RMF_NO_RETURN(type) return type()
133 
134 /** Apply the macro to each supported constant size type (e.g. int as opposed
135  to string).
136 
137  \see RMF_FOREACH_TYPE()
138  */
139 #define RMF_FOREACH_SIMPLE_TYPE(macroname) \
140  macroname(int, Int, int, int, const Ints&, Ints); \
141  macroname(float, Float, float, float, const Floats&, Floats); \
142  macroname(index, Index, int, int, const Ints&, Ints)
143 
144 /** Expand to applying the macro to each type supported by
145  the RMF library. The macro should take six arguments
146  - the lower case name of the type
147  - the upper case name
148  - the C++ type for accepting the value
149  - the C++ type for returning the value
150  - the C++ type for accepting more than one value
151  - the C++ type for returning more than one value
152 */
153 #define RMF_FOREACH_TYPE(macroname) \
154  macroname(RMF::IntTraits, Int) macroname(RMF::FloatTraits, Float) \
155  macroname(RMF::StringTraits, String) macroname(RMF::IntsTraits, Ints) \
156  macroname(RMF::FloatsTraits, Floats) \
157  macroname(RMF::StringsTraits, Strings) \
158  macroname(RMF::Vector3Traits, Vector3) \
159  macroname(RMF::Vector4Traits, Vector4) \
160  macroname(RMF::Vector3sTraits, Vector3s)
161 
162 #define RMF_DECORATOR_CATCH(extra_info) \
163  catch (Exception& e) { \
164  RMF_RETHROW(Decorator(get_decorator_type_name()) extra_info, e); \
165  }
166 
167 /** Register a validator function. See Validator for more
168  information.*/
169 #define RMF_VALIDATOR(Type) RMF::Registrar<Type> Type##Reg(#Type);
170 namespace RMF {
171 
172 template <class Tr>
173 class Nullable;
174 
175 #if !defined(RMF_DOXYGEN) && !defined(SWIG)
176 struct Showable;
177 inline std::ostream& operator<<(std::ostream& out, const Showable& t);
178 
179 /** An adaptor class to provide operator<< for classes easily. */
180 struct Showable {
181  std::string t_;
182  template <class T>
183  explicit Showable(const T& t) {
184  std::ostringstream oss;
185  oss << t;
186  t_ = oss.str();
187  }
188  template <class T, class TT>
189  Showable(const std::pair<T, TT>& p) {
190  std::ostringstream oss;
191  oss << "(" << p.first << ", " << p.second << ")";
192  t_ = oss.str();
193  }
194  Showable(std::string t) : t_(std::string("\"") + t + "\"") {}
195  struct Special {};
196  Showable(std::string t, Special) : t_(t) {}
197  template <class T>
198  Showable(const std::vector<T>& t) {
199  std::ostringstream out;
200  out << "[";
201  for (unsigned int i = 0; i < t.size(); ++i) {
202  if (i != 0) {
203  out << ", ";
204  }
205  out << t[i];
206  }
207  out << "]";
208  t_ = out.str();
209  }
210  template <class Tr>
211  Showable(const Nullable<Tr>& t) {
212  std::ostringstream out;
213  if (t.get_is_null())
214  out << "<None>";
215  else
216  out << t.get();
217  t_ = out.str();
218  }
219 };
220 
221 inline std::ostream& operator<<(std::ostream& out, const Showable& t) {
222  out << t.t_;
223  return out;
224 }
225 
226 #endif
227 }
228 
229 RMF_DISABLE_WARNINGS
230 
231 #endif /* RMF_INFRASTRUCTURE_MACROS_H */
Return a possibly null value.
Various compiler workarounds.