9 #ifndef IMPKERNEL_CONTAINER_MACROS_H
10 #define IMPKERNEL_CONTAINER_MACROS_H
12 #include <IMP/kernel_config.h>
14 #include <IMP/internal/Vector.h>
21 #ifdef IMP_SWIG_WRAPPER
22 #define IMP_PROTECTION(protection) public:
24 #define IMP_PROTECTION(protection) protection:
29 #define IMP_EXPOSE_ITERATORS(ContainerType, container_name, Ucname, Ucnames, \
32 class Ucname##Iterator; \
33 class Ucname##ConstIterator, \
34 typedef ContainerType::iterator Ucname##Iterator; \
35 typedef ContainerType::const_iterator Ucname##ConstIterator); \
36 Ucname##Iterator lcnames##_begin() { return container_name.begin(); } \
37 Ucname##Iterator lcnames##_end() { return container_name.end(); } \
38 Ucname##ConstIterator lcnames##_begin() const { \
39 return container_name.begin(); \
41 Ucname##ConstIterator lcnames##_end() const { return container_name.end(); }
44 #define IMP_EXPOSE_ITERATORS(ContainerType, container_name, Ucname, Ucnames, \
49 #define IMP_FORCE_EXPORT(x) __attribute__((visibility("default"))) x
51 #define IMP_FORCE_EXPORT(x) x
90 #define IMP_LIST(protection, Ucname, lcname, Data, PluralData) \
91 IMP_LIST_ACTION(protection, Ucname, Ucname##s, lcname, lcname##s, Data, \
94 #if defined(SWIG) || defined(IMP_DOXYGEN)
96 #define IMP_LIST_ACTION(protection, Ucname, Ucnames, lcname, lcnames, Data, \
97 PluralData, OnAdd, OnChanged, OnRemoved) \
99 void remove_##lcname(Data d); \
100 void remove_##lcnames(const PluralData& d); \
101 void set_##lcnames(const PluralData& ps); \
102 void set_##lcnames##_order(const PluralData& objs); \
103 unsigned int add_##lcname(Data obj); \
104 void add_##lcnames(const PluralData& objs); \
105 void clear_##lcnames(); \
106 unsigned int get_number_of_##lcnames() const; \
107 bool get_has_##lcnames(); \
108 Data get_##lcname(unsigned int i) const; \
109 PluralData get_##lcnames() const; \
110 void reserve_##lcnames(unsigned int sz)
128 #define IMP_LIST_ACTION(protection, Ucname, Ucnames, lcname, lcnames, Data, \
129 PluralData, OnAdd, OnChanged, OnRemoved) \
130 IMP_PROTECTION(protection) \
132 void remove_##lcname(Data d) { \
134 bool found = false; \
135 for (Ucname##Iterator it = lcnames##_begin(); it != lcnames##_end(); \
138 lcname##_handle_remove(*it); \
140 lcname##_vector_.erase(it); \
145 IMP_USAGE_CHECK(found, d << " not found in container: " \
146 << get_as<PluralData>(lcname##_vector_)); \
147 lcname##_handle_change(); \
151 void remove_##lcnames##_if(const F& f) { \
153 for (Ucname##Iterator it = lcnames##_begin(); it != lcnames##_end(); \
155 if (f(*it)) lcname##_handle_remove(*it); \
157 lcname##_vector_.erase( \
158 std::remove_if(lcname##_vector_.begin(), lcname##_vector_.end(), f), \
159 lcname##_vector_.end()); \
160 lcname##_handle_change(); \
163 template <class List> \
164 void remove_##lcnames(List d) { \
166 Vector<Data> ds(d.begin(), d.end()); \
167 std::sort(ds.begin(), ds.end()); \
168 for (unsigned int i = 0; i < ds.size(); ++i) { \
169 lcname##_handle_remove(ds[i]); \
171 lcname##_vector_.erase( \
172 std::remove_if(lcname##_vector_.begin(), lcname##_vector_.end(), \
173 ::IMP::internal::list_contains(ds)), \
174 lcname##_vector_.end()); \
179 template <class List> \
180 void set_##lcnames(List ps) { \
189 void set_##lcnames##_order(List ps) { \
191 IMP_USAGE_CHECK(ps.size() == lcname##_vector_.size(), \
192 "Reordered elements don't match."); \
193 lcname##_vector_.clear(); \
194 lcname##_vector_.insert(lcname##_vector_.end(), ps.begin(), ps.end()); \
198 unsigned int add_##lcname(Data obj) { \
200 unsigned int index = lcname##_vector_.size(); \
201 lcname##_vector_.push_back(obj); \
205 lcname##_handle_change(); \
210 template <class List> \
211 void add_##lcnames(List objs) { \
213 unsigned int osz = lcname##_vector_.size(); \
214 lcname##_vector_.insert(lcname##_vector_.end(), objs.begin(), objs.end()); \
215 for (PluralData::size_type i = 0; i < objs.size(); ++i) { \
216 Data obj = lcname##_vector_[osz + i]; \
217 unsigned int index(osz + i); \
222 lcname##_handle_change(); \
224 void clear_##lcnames() { \
225 lcname##_vector_.clear(); \
226 lcname##_handle_change(); \
228 unsigned int get_number_of_##lcnames() const { \
229 return lcname##_vector_.size(); \
231 bool get_has_##lcnames() const { \
232 return !lcname##_vector_.empty(); \
236 Data get_##lcname(unsigned int i) const { return lcname##_vector_[i]; } \
237 PluralData get_##lcnames() const { \
238 return get_as<PluralData>(lcname##_vector_); \
240 void reserve_##lcnames(unsigned int sz) { lcname##_vector_.reserve(sz); } \
241 IMP_EXPOSE_ITERATORS(PluralData, lcname##_vector_, Ucname, Ucnames, lcname, \
247 PluralData& mutable_access_##lcnames() { return lcname##_vector_; } \
248 IMP_NO_DOXYGEN(const PluralData& access_##lcnames() const { \
249 return lcname##_vector_; \
250 }) private : void lcname##_handle_remove(Data obj) { \
251 Ucname##DataWrapper::do_handle_remove(obj, this); \
253 void lcname##_handle_change() { \
257 struct Ucname##DataWrapper : public PluralData { \
258 template <class TT> \
259 static void do_handle_remove(Data obj, TT* container) { \
260 IMP_UNUSED(container); \
269 IMP_FORCE_EXPORT(~Ucname##DataWrapper()); \
271 friend struct Ucname##DataWrapper; \
272 IMP_NO_DOXYGEN(Ucname##DataWrapper lcname##_vector_;) \
273 IMP_PROTECTION(protection) IMP_REQUIRE_SEMICOLON_CLASS(list##lcname)
289 #define IMP_LIST_IMPL(Class, Ucname, lcname, Data, PluralData) \
290 IMP_LIST_ACTION_IMPL(Class, Ucname, Ucname##s, lcname, lcname##s, Data, \
293 #define IMP_LIST_ACTION_IMPL(Class, Ucname, Ucnames, lcname, lcnames, Data, \
295 Class::Ucname##DataWrapper::~Ucname##DataWrapper() { \
296 for (unsigned int i = 0; i < size(); ++i) { \
297 do_handle_remove(operator[](i), static_cast<Class*>(0)); \
300 IMP_REQUIRE_SEMICOLON_NAMESPACE
302 #define IMP_CONTAINER_FOREACH_LOOP(ContainerType, container, operation, tname) \
303 for (unsigned int _2 = 0; _2 < imp_foreach_indexes.size(); ++_2) { \
304 tname ContainerType::ContainedIndexType _1 = imp_foreach_indexes[_2]; \
305 bool imp_foreach_break = false; \
307 if (imp_foreach_break) { \
312 #define IMP_CONTAINER_FOREACH_IMPL(ContainerType, container, operation, tname) \
313 IMPKERNEL_DEPRECATED_MACRO(2.2, \
314 "Use get_contents() and a for loop."); \
316 if (container->get_provides_access()) { \
317 const tname ContainerType::ContainedIndexTypes& imp_foreach_indexes = \
318 container->get_access(); \
319 IMP_CONTAINER_FOREACH_LOOP(ContainerType, container, operation, tname); \
321 tname ContainerType::ContainedIndexTypes imp_foreach_indexes = \
322 container->get_indexes(); \
323 IMP_CONTAINER_FOREACH_LOOP(ContainerType, container, operation, tname); \
332 #define IMP_CONTAINER_FOREACH_TEMPLATE(ContainerType, container, operation) \
333 IMP_CONTAINER_FOREACH_IMPL(ContainerType, container, operation, typename)
351 #define IMP_CONTAINER_FOREACH(ContainerType, container, operation) \
352 IMP_CONTAINER_FOREACH_IMPL(ContainerType, container, operation, )
357 #define IMP_CONTAINER_ACCESS(ContainerType, container, operation) \
359 if (container->get_provides_access()) { \
360 const ContainerType::ContainedIndexTypes& imp_indexes = \
361 container->get_access(); \
364 ContainerType::ContainedIndexTypes imp_indexes = \
365 container->get_indexes(); \
Helper macros for writing doxygen documentation.
Logging and error reporting support.
Checking and error reporting support.
Helper macros for throwing and handling exceptions.