IMP logo
IMP Reference Guide  develop.d97d4ead1f,2024/11/21
The Integrative Modeling Platform
tuple_macros.h
Go to the documentation of this file.
1 /**
2  * \file IMP/tuple_macros.h
3  * \brief Macros to help in defining tuple classes.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_TUPLE_MACROS_H
10 #define IMPKERNEL_TUPLE_MACROS_H
11 #include <IMP/kernel_config.h>
12 #include "Value.h"
13 #include "Showable.h"
14 #include "hash.h"
15 #include "hash_macros.h"
16 #include "showable_macros.h"
17 #include "value_macros.h"
18 #include "comparison_macros.h"
19 #include "swig_macros.h"
20 
21 /** Implementation macro */
22 #define IMP_TUPLE_VALUE(Name, type_name, data_name, var_name) \
23  private: \
24  type_name var_name; \
25  \
26  public: \
27  IMP_HELPER_MACRO_PUSH_WARNINGS const type_name &get_##data_name() const { \
28  return var_name; \
29  } \
30  void set_##data_name(const type_name &v) { var_name = v; } \
31  IMP_NO_SWIG(type_name &access_##data_name() { return var_name; }) \
32  IMP_HELPER_MACRO_POP_WARNINGS
33 
34 /** \name Named tuples
35  It is often useful to declare little structures to aid in the passing
36  of arguments by name or returning sets of values. One can use
37  boost::tuples, but these don't have names for their parts and so
38  don't lead to clear code. Instead we provide a macro to aid
39  declaring such classes. The resulting class is hashable and
40  comparable too.
41  @{
42 */
43 
44 #define IMP_NAMED_TUPLE_1(Name, Names, type0, var0, invariant) \
45  struct Name : public IMP::Value { \
46  Name(type0 i0 = type0()) : var0##_(i0) { invariant; } \
47  IMP_HASHABLE_INLINE(Name, { \
48  std::size_t value = IMP::hash_value(var0##_); \
49  return value; \
50  }); \
51  IMP_COMPARISONS_1(Name); \
52  IMP_SHOWABLE_INLINE(Name, out << "(" << #var0 << "=" \
53  << IMP::Showable(var0##_) << ")"); \
54  IMP_TUPLE_VALUE(Name, type0, var0, var0##_); \
55  \
56  private: \
57  int compare(const Name &o) const { \
58  IMP_COMPARE_ONE(var0##_, o.var0##_); \
59  return 0; \
60  } \
61  }; \
62  IMP_VALUES(Name, Names)
63 
64 #define IMP_NAMED_TUPLE_2(Name, Names, type0, var0, type1, var1, invariant) \
65  struct Name : public IMP::Value { \
66  Name(type0 i0 = type0(), type1 i1 = type1()) : var0##_(i0), var1##_(i1) { \
67  invariant; \
68  } \
69  IMP_HASHABLE_INLINE(Name, { \
70  std::size_t value = IMP::hash_value(var0##_); \
71  boost::hash_combine(value, IMP::hash_value(var1##_)); \
72  return value; \
73  }); \
74  IMP_SHOWABLE_INLINE(Name, out << "(" << #var0 << "=" \
75  << IMP::Showable(var0##_) << " " \
76  << #var1 << "=" \
77  << IMP::Showable(var1##_) << ")"); \
78  IMP_COMPARISONS(Name); \
79  IMP_TUPLE_VALUE(Name, type0, var0, var0##_); \
80  IMP_TUPLE_VALUE(Name, type1, var1, var1##_); \
81  \
82  private: \
83  int compare(const Name &o) const { \
84  IMP_COMPARE_ONE(var0##_, o.var0##_); \
85  IMP_COMPARE_ONE(var1##_, o.var1##_); \
86  return 0; \
87  } \
88  }; \
89  IMP_VALUES(Name, Names)
90 
91 #define IMP_NAMED_TUPLE_3(Name, Names, type0, var0, type1, var1, type2, var2, \
92  invariant) \
93  struct Name : public IMP::Value { \
94  Name(type0 i0 = type0(), type1 i1 = type1(), type2 i2 = type2()) \
95  : var0##_(i0), var1##_(i1), var2##_(i2) { \
96  invariant; \
97  } \
98  IMP_HASHABLE_INLINE(Name, { \
99  std::size_t value = IMP::hash_value(var0##_); \
100  boost::hash_combine(value, IMP::hash_value(var1##_)); \
101  boost::hash_combine(value, IMP::hash_value(var2##_)); \
102  return value; \
103  }); \
104  IMP_COMPARISONS(Name); \
105  IMP_SHOWABLE_INLINE( \
106  Name, out << "(" << #var0 << "=" << IMP::Showable(var0##_) \
107  << " " << #var1 << "=" << IMP::Showable(var1##_) \
108  << " " << #var2 << "=" << IMP::Showable(var2##_) \
109  << ")"); \
110  IMP_TUPLE_VALUE(Name, type0, var0, var0##_); \
111  IMP_TUPLE_VALUE(Name, type1, var1, var1##_); \
112  IMP_TUPLE_VALUE(Name, type2, var2, var2##_); \
113  \
114  private: \
115  int compare(const Name &o) const { \
116  IMP_COMPARE_ONE(var0##_, o.var0##_); \
117  IMP_COMPARE_ONE(var1##_, o.var1##_); \
118  IMP_COMPARE_ONE(var2##_, o.var2##_); \
119  return 0; \
120  } \
121  }; \
122  IMP_VALUES(Name, Names)
123 
124 #define IMP_NAMED_TUPLE_4(Name, Names, type0, var0, type1, var1, type2, var2, \
125  type3, var3, invariant) \
126  struct Name : public IMP::Value { \
127  Name(type0 i0 = type0(), type1 i1 = type1(), type2 i2 = type2(), \
128  type3 i3 = type3()) \
129  : var0##_(i0), var1##_(i1), var2##_(i2), var3##_(i3) { \
130  invariant; \
131  } \
132  IMP_HASHABLE_INLINE(Name, { \
133  std::size_t value = IMP::hash_value(var0##_); \
134  boost::hash_combine(value, IMP::hash_value(var1##_)); \
135  boost::hash_combine(value, IMP::hash_value(var2##_)); \
136  boost::hash_combine(value, IMP::hash_value(var3##_)); \
137  return value; \
138  }); \
139  IMP_COMPARISONS(Name); \
140  IMP_SHOWABLE_INLINE( \
141  Name, out << "(" << #var0 << "=" << IMP::Showable(var0##_) \
142  << " " << #var1 << "=" << IMP::Showable(var1##_) \
143  << " " << #var2 << "=" << IMP::Showable(var2##_) \
144  << " " << #var3 << "=" << IMP::Showable(var3##_) \
145  << ")"); \
146  IMP_TUPLE_VALUE(Name, type0, var0, var0##_); \
147  IMP_TUPLE_VALUE(Name, type1, var1, var1##_); \
148  IMP_TUPLE_VALUE(Name, type2, var2, var2##_); \
149  IMP_TUPLE_VALUE(Name, type3, var3, var3##_); \
150  \
151  private: \
152  int compare(const Name &o) const { \
153  IMP_COMPARE_ONE(var0##_, o.var0##_); \
154  IMP_COMPARE_ONE(var1##_, o.var1##_); \
155  IMP_COMPARE_ONE(var2##_, o.var2##_); \
156  IMP_COMPARE_ONE(var3##_, o.var3##_); \
157  return 0; \
158  } \
159  }; \
160  IMP_VALUES(Name, Names)
161 
162 #define IMP_NAMED_TUPLE_5(Name, Names, type0, var0, type1, var1, type2, var2, \
163  type3, var3, type4, var4, invariant) \
164  struct Name : public IMP::Value { \
165  Name(type0 i0 = type0(), type1 i1 = type1(), type2 i2 = type2(), \
166  type3 i3 = type3(), type4 i4 = type4()) \
167  : var0##_(i0), var1##_(i1), var2##_(i2), var3##_(i3), var4##_(i4) { \
168  invariant; \
169  } \
170  IMP_HASHABLE_INLINE(Name, { \
171  std::size_t value = IMP::hash_value(var0##_); \
172  boost::hash_combine(value, IMP::hash_value(var1##_)); \
173  boost::hash_combine(value, IMP::hash_value(var2##_)); \
174  boost::hash_combine(value, IMP::hash_value(var3##_)); \
175  boost::hash_combine(value, IMP::hash_value(var4##_)); \
176  return value; \
177  }); \
178  IMP_COMPARISONS(Name); \
179  IMP_SHOWABLE_INLINE( \
180  Name, out << "(" << #var0 << "=" << IMP::Showable(var0##_) \
181  << " " << #var1 << "=" << IMP::Showable(var1##_) \
182  << " " << #var2 << "=" << IMP::Showable(var2##_) \
183  << " " << #var3 << "=" << IMP::Showable(var3##_) \
184  << " " << #var4 << "=" << IMP::Showable(var4##_) \
185  << ")"); \
186  IMP_TUPLE_VALUE(Name, type0, var0, var0##_); \
187  IMP_TUPLE_VALUE(Name, type1, var1, var1##_); \
188  IMP_TUPLE_VALUE(Name, type2, var2, var2##_); \
189  IMP_TUPLE_VALUE(Name, type3, var3, var3##_); \
190  IMP_TUPLE_VALUE(Name, type4, var4, var4##_); \
191  \
192  private: \
193  int compare(const Name &o) const { \
194  IMP_COMPARE_ONE(var0##_, o.var0##_); \
195  IMP_COMPARE_ONE(var1##_, o.var1##_); \
196  IMP_COMPARE_ONE(var2##_, o.var2##_); \
197  IMP_COMPARE_ONE(var3##_, o.var3##_); \
198  IMP_COMPARE_ONE(var4##_, o.var4##_); \
199  return 0; \
200  } \
201  }; \
202  IMP_VALUES(Name, Names)
203 
204 /**@}*/
205 
206 #endif /* IMPKERNEL_TUPLE_MACROS_H */
Macros to hide code from SWIG.
Helper macros for implementing comparisons of IMP objects.
Helper functions for implementing hashes.
Helper class to aid in output of IMP classes to streams.
Helper macros for implementing hashable classes.
Base class for a simple primitive-like type.
Macros to help in implementing Value objects.
Macros to help with objects that can be printed to a stream.