9 #ifndef IMPKERNEL_CONTAINER_MACROS_H
10 #define IMPKERNEL_CONTAINER_MACROS_H
12 #include <IMP/kernel/kernel_config.h>
14 #include <IMP/base/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 base::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::base::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
308 #define IMP_CONTAINER_DEPENDENCIES(Name, input_deps) \
309 class DependenciesScoreState : public ScoreState { \
313 DependenciesScoreState(Name* n) \
314 : ScoreState(n->get_name() + " dependencies"), back_(n) {} \
315 ContainersTemp get_input_containers() const { \
316 ContainersTemp ret; \
317 input_deps return ret; \
319 ContainersTemp get_output_containers() const { \
320 return ContainersTemp(1, back_); \
322 ParticlesTemp get_input_particles() const { return ParticlesTemp(); } \
323 ParticlesTemp get_output_particles() const { return ParticlesTemp(); } \
324 void do_before_evaluate() {} \
325 void do_after_evaluate(DerivativeAccumulator*) {} \
326 IMP_OBJECT_METHODS( \
327 DependenciesScoreState) friend class DependenciesScoreState; \
328 ScopedScoreState deps_
331 #define IMP_CONTAINER_DEPENDENCIES(Name, input_deps)
334 #define IMP_CONTAINER_FOREACH_LOOP(ContainerType, container, operation, tname) \
335 for (unsigned int _2 = 0; _2 < imp_foreach_indexes.size(); ++_2) { \
336 tname ContainerType::ContainedIndexType _1 = imp_foreach_indexes[_2]; \
337 bool imp_foreach_break = false; \
339 if (imp_foreach_break) { \
344 #define IMP_CONTAINER_FOREACH_IMPL(ContainerType, container, operation, tname) \
346 if (container->get_provides_access()) { \
347 const tname ContainerType::ContainedIndexTypes& imp_foreach_indexes = \
348 container->get_access(); \
349 IMP_CONTAINER_FOREACH_LOOP(ContainerType, container, operation, tname); \
351 tname ContainerType::ContainedIndexTypes imp_foreach_indexes = \
352 container->get_indexes(); \
353 IMP_CONTAINER_FOREACH_LOOP(ContainerType, container, operation, tname); \
362 #define IMP_CONTAINER_FOREACH_TEMPLATE(ContainerType, container, operation) \
363 IMP_CONTAINER_FOREACH_IMPL(ContainerType, container, operation, typename)
381 #define IMP_CONTAINER_FOREACH(ContainerType, container, operation) \
382 IMP_CONTAINER_FOREACH_IMPL(ContainerType, container, operation, )
387 #define IMP_CONTAINER_ACCESS(ContainerType, container, operation) \
389 if (container->get_provides_access()) { \
390 const ContainerType::ContainedIndexTypes& imp_indexes = \
391 container->get_access(); \
394 ContainerType::ContainedIndexTypes imp_indexes = \
395 container->get_indexes(); \
Various general useful macros for IMP.
Checkging and error reporting support.
Logging and error reporting support.
Exception definitions and assertions.