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
58 #define IMP_LIST_PYTHON_IMPL(lcname, lcnames, ucnames, Ucnames) \
60 def __get_##lcnames(self): \
61 return IMP._list_util.VarList(getdimfunc=self.get_number_of_##lcnames, \
62 getfunc=self.get_##lcname, erasefunc=self.erase_##lcname, \
63 appendfunc=self.add_##lcname, extendfunc=self.add_##lcnames, \
64 clearfunc=self.clear_##lcnames, indexfunc=self._python_index_##lcname) \
67 def __set_##lcnames(self, obj):\
68 IMP._list_util.set_varlist(self.##lcnames, obj) \
71 def __del_##lcnames(self): IMP._list_util.del_varlist(self.##lcnames) \
74 ##lcnames = property(__get_##lcnames, __set_##lcnames, __del_##lcnames,\
75 doc="List of ##ucnames") \
78 #elif defined(IMP_DOXYGEN)
79 #define IMP_LIST_PYTHON_IMPL(lcname, lcnames, ucnames, Ucnames) \
85 #define IMP_LIST_PYTHON_IMPL(lcname, lcnames, ucnames, Ucnames)
127 #define IMP_LIST(protection, Ucname, lcname, Data, PluralData) \
128 IMP_LIST_ACTION(protection, Ucname, Ucname##s, lcname, lcname##s, Data, \
131 #if defined(SWIG) || defined(IMP_DOXYGEN)
133 #define IMP_LIST_ACTION(protection, Ucname, Ucnames, lcname, lcnames, Data, \
134 PluralData, OnAdd, OnChanged, OnRemoved) \
135 IMP_LIST_PYTHON_IMPL(lcname, lcnames, ucnames, Ucnames) \
137 void remove_##lcname(Data d); \
138 unsigned int _python_index_##lcname(Data d, unsigned int start, \
139 unsigned int stop); \
140 void remove_##lcnames(const PluralData& d); \
141 void set_##lcnames(const PluralData& ps); \
142 void set_##lcnames##_order(const PluralData& objs); \
143 unsigned int add_##lcname(Data obj); \
144 void add_##lcnames(const PluralData& objs); \
145 void clear_##lcnames(); \
146 unsigned int get_number_of_##lcnames() const; \
147 bool get_has_##lcnames(); \
148 Data get_##lcname(unsigned int i) const; \
149 PluralData get_##lcnames() const; \
150 void erase_##lcname(unsigned int i); \
151 void reserve_##lcnames(unsigned int sz)
169 #define IMP_LIST_ACTION(protection, Ucname, Ucnames, lcname, lcnames, Data, \
170 PluralData, OnAdd, OnChanged, OnRemoved) \
171 IMP_PROTECTION(protection) \
173 void remove_##lcname(Data d) { \
175 bool found = false; \
176 for (Ucname##Iterator it = lcnames##_begin(); it != lcnames##_end(); \
179 lcname##_handle_remove(*it); \
181 lcname##_vector_.erase(it); \
186 IMP_USAGE_CHECK(found, d << " not found in container: " \
187 << get_as<PluralData>(lcname##_vector_)); \
188 lcname##_handle_change(); \
190 unsigned int _python_index_##lcname(Data d, unsigned int start, \
191 unsigned int stop) { \
192 bool found = false; \
193 unsigned int num_of = get_number_of_##lcnames(); \
194 start = std::min(start, num_of); \
195 stop = std::min(stop, num_of); \
196 unsigned int indx = start; \
197 for (Ucname##Iterator it = lcnames##_begin() + start; \
198 it != lcnames##_end(); ++it, ++indx) { \
205 IMP_THROW(d << " is not in list", ValueException); \
210 void erase_##lcname(unsigned int i) { \
211 Ucname##Iterator it = lcnames##_begin() + i; \
212 lcname##_handle_remove(*it); \
213 lcname##_vector_.erase(it); \
214 lcname##_handle_change(); \
218 void remove_##lcnames##_if(const F& f) { \
220 for (Ucname##Iterator it = lcnames##_begin(); it != lcnames##_end(); \
222 if (f(*it)) lcname##_handle_remove(*it); \
224 lcname##_vector_.erase( \
225 std::remove_if(lcname##_vector_.begin(), lcname##_vector_.end(), f), \
226 lcname##_vector_.end()); \
227 lcname##_handle_change(); \
230 template <class List> \
231 void remove_##lcnames(List d) { \
233 Vector<Data> ds(d.begin(), d.end()); \
234 std::sort(ds.begin(), ds.end()); \
235 for (unsigned int i = 0; i < ds.size(); ++i) { \
236 lcname##_handle_remove(ds[i]); \
238 lcname##_vector_.erase( \
239 std::remove_if(lcname##_vector_.begin(), lcname##_vector_.end(), \
240 ::IMP::internal::list_contains(ds)), \
241 lcname##_vector_.end()); \
246 template <class List> \
247 void set_##lcnames(List ps) { \
256 void set_##lcnames##_order(List ps) { \
258 IMP_USAGE_CHECK(ps.size() == lcname##_vector_.size(), \
259 "Reordered elements don't match."); \
260 lcname##_vector_.clear(); \
261 lcname##_vector_.insert(lcname##_vector_.end(), ps.begin(), ps.end()); \
265 unsigned int add_##lcname(Data obj) { \
267 unsigned int index = lcname##_vector_.size(); \
268 lcname##_vector_.push_back(obj); \
272 lcname##_handle_change(); \
277 template <class List> \
278 void add_##lcnames(List objs) { \
280 unsigned int osz = lcname##_vector_.size(); \
281 lcname##_vector_.insert(lcname##_vector_.end(), objs.begin(), objs.end()); \
282 for (PluralData::size_type i = 0; i < objs.size(); ++i) { \
283 Data obj = lcname##_vector_[osz + i]; \
284 unsigned int index(osz + i); \
289 lcname##_handle_change(); \
291 void clear_##lcnames() { \
292 lcname##_vector_.clear(); \
293 lcname##_handle_change(); \
295 unsigned int get_number_of_##lcnames() const { \
296 return lcname##_vector_.size(); \
298 bool get_has_##lcnames() const { \
299 return !lcname##_vector_.empty(); \
303 Data get_##lcname(unsigned int i) const { return lcname##_vector_[i]; } \
304 PluralData get_##lcnames() const { \
305 return get_as<PluralData>(lcname##_vector_); \
307 void reserve_##lcnames(unsigned int sz) { lcname##_vector_.reserve(sz); } \
308 IMP_EXPOSE_ITERATORS(PluralData, lcname##_vector_, Ucname, Ucnames, lcname, \
314 PluralData& mutable_access_##lcnames() { return lcname##_vector_; } \
315 IMP_NO_DOXYGEN(const PluralData& access_##lcnames() const { \
316 return lcname##_vector_; \
317 }) private : void lcname##_handle_remove(Data obj) { \
318 Ucname##DataWrapper::do_handle_remove(obj, this); \
320 void lcname##_handle_change() { \
324 struct Ucname##DataWrapper : public PluralData { \
325 template <class TT> \
326 static void do_handle_remove(Data obj, TT* container) { \
327 IMP_UNUSED(container); \
336 IMP_FORCE_EXPORT(~Ucname##DataWrapper()); \
338 friend struct Ucname##DataWrapper; \
339 IMP_NO_DOXYGEN(Ucname##DataWrapper lcname##_vector_;) \
340 IMP_PROTECTION(protection) IMP_REQUIRE_SEMICOLON_CLASS(list##lcname)
356 #define IMP_LIST_IMPL(Class, Ucname, lcname, Data, PluralData) \
357 IMP_LIST_ACTION_IMPL(Class, Ucname, Ucname##s, lcname, lcname##s, Data, \
360 #define IMP_LIST_ACTION_IMPL(Class, Ucname, Ucnames, lcname, lcnames, Data, \
362 Class::Ucname##DataWrapper::~Ucname##DataWrapper() { \
363 for (unsigned int i = 0; i < size(); ++i) { \
364 do_handle_remove(operator[](i), static_cast<Class*>(0)); \
367 IMP_REQUIRE_SEMICOLON_NAMESPACE
369 #define IMP_CONTAINER_FOREACH_LOOP(ContainerType, container, operation, tname) \
370 for (unsigned int _2 = 0; _2 < imp_foreach_indexes.size(); ++_2) { \
371 tname ContainerType::ContainedIndexType _1 = imp_foreach_indexes[_2]; \
372 bool imp_foreach_break = false; \
374 if (imp_foreach_break) { \
379 #define IMP_CONTAINER_FOREACH_IMPL(ContainerType, container, operation, tname) \
380 IMPKERNEL_DEPRECATED_MACRO(2.2, \
381 "Use get_contents() and a for loop."); \
383 if (container->get_provides_access()) { \
384 const tname ContainerType::ContainedIndexTypes& imp_foreach_indexes = \
385 container->get_access(); \
386 IMP_CONTAINER_FOREACH_LOOP(ContainerType, container, operation, tname); \
388 tname ContainerType::ContainedIndexTypes imp_foreach_indexes = \
389 container->get_indexes(); \
390 IMP_CONTAINER_FOREACH_LOOP(ContainerType, container, operation, tname); \
399 #define IMP_CONTAINER_FOREACH_TEMPLATE(ContainerType, container, operation) \
400 IMP_CONTAINER_FOREACH_IMPL(ContainerType, container, operation, typename)
418 #define IMP_CONTAINER_FOREACH(ContainerType, container, operation) \
419 IMP_CONTAINER_FOREACH_IMPL(ContainerType, container, operation, )
424 #define IMP_CONTAINER_ACCESS(ContainerType, container, operation) \
426 if (container->get_provides_access()) { \
427 const ContainerType::ContainedIndexTypes& imp_indexes = \
428 container->get_access(); \
431 ContainerType::ContainedIndexTypes imp_indexes = \
432 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.