IMP
2.1.1
The Integrative Modeling Platform
IMP Mainpage
All IMP Modules
Related Pages
Modules
Namespaces
Classes
Files
Examples
Indexes
File List
File Members
kernel/decorator_macros.h
Go to the documentation of this file.
1
/**
2
* \file IMP/kernel/decorator_macros.h
3
* \brief Various general useful macros for IMP.
4
*
5
* Copyright 2007-2013 IMP Inventors. All rights reserved.
6
*
7
*/
8
9
#ifndef IMPKERNEL_DECORATOR_MACROS_H
10
#define IMPKERNEL_DECORATOR_MACROS_H
11
#include <IMP/kernel/kernel_config.h>
12
#include "
particle_index.h
"
13
#include "
Particle.h
"
14
#include "
Decorator.h
"
15
#include <
IMP/base/check_macros.h
>
16
#include <
IMP/base/log_macros.h
>
17
#include <
IMP/base/showable_macros.h
>
18
#include <
IMP/base/warning_macros.h
>
19
20
#ifdef IMP_DOXYGEN
21
/** \deprecated_at{2.1} Use IMP_DECORATOR_METHODS() instead.
22
*/
23
#define IMP_DECORATOR(Name, Parent) \
24
public: \
25
/* Should be private but SWIG accesses it through the \
26
comparison \
27
macros*/
IMP_NO_DOXYGEN( \
28
typedef Parent ParentDecorator); \
29
Name() : Parent() {} \
30
Name(kernel::Model *m, ParticleIndex id) : Parent(m, id) { \
31
IMP_INTERNAL_CHECK( \
32
get_is_setup(m->get_particle(id)), \
33
"Particle " << m->get_particle(id)->get_name() \
34
<< " missing required attributes for decorator " \
35
<< #Name \
36
<< "\n" << base::ShowFull(m->get_particle(id))); \
37
} \
38
IMP_SHOWABLE(Name)
39
40
#else
41
#define IMP_DECORATOR(Name, Parent) \
42
IMPKERNEL_DEPRECATED_MACRO(2.1, "Use IMP_DECORATOR_METHODS()"); \
43
\
44
public: \
45
/* Should be private but SWIG accesses it through the \
46
comparison \
47
macros*/
IMP_NO_DOXYGEN( \
48
typedef Parent ParentDecorator); \
49
Name() : Parent() {} \
50
Name(kernel::Model *m, ParticleIndex id) : Parent(m, id) { \
51
IMP_INTERNAL_CHECK( \
52
get_is_setup(m->get_particle(id)), \
53
"Particle " << m->get_particle(id)->get_name() \
54
<< " missing required attributes for decorator " \
55
<< #Name \
56
<< "\n" << base::ShowFull(m->get_particle(id))); \
57
} \
58
explicit Name(::IMP::kernel::Particle *p) : Parent(p) { \
59
IMP_INTERNAL_CHECK( \
60
get_is_setup(p), \
61
"Particle " << p->get_name() \
62
<< " missing required attributes for decorator " \
63
<< #Name \
64
<< "\n" << base::ShowFull(p)); \
65
} \
66
static bool get_is_setup(Particle *p) { return particle_is_instance(p); } \
67
static bool get_is_setup(kernel::Model *m, ParticleIndex pi) { \
68
return particle_is_instance(m->get_particle(pi)); \
69
} \
70
static bool particle_is_instance(kernel::Model *m, ParticleIndex pi) { \
71
return particle_is_instance(m->get_particle(pi)); \
72
} \
73
static Name decorate_particle(::IMP::kernel::Particle *p) { \
74
IMP_CHECK_OBJECT(p); \
75
if (!get_is_setup(p)) { \
76
return Name(); \
77
} \
78
return Name(p); \
79
} \
80
IMP_SHOWABLE(Name)
81
#endif
82
83
/** Implement the needed methods for a decorator based on
84
- setup_particle()
85
- get_is_setup()
86
methods that you provide.
87
*/
88
#define IMP_DECORATOR_METHODS(Name, Parent) \
89
public: \
90
/* Should be private but SWIG accesses it through the \
91
comparison \
92
macros*/
IMP_NO_DOXYGEN( \
93
typedef Parent ParentDecorator); \
94
Name() : Parent() {} \
95
Name(::IMP::kernel::Model *m, ::IMP::kernel::ParticleIndex id) \
96
: Parent(m, id) { \
97
IMP_INTERNAL_CHECK( \
98
get_is_setup(m, id), \
99
"Particle " << m->get_particle_name(id) \
100
<< " missing required attributes for decorator " \
101
<< #Name); \
102
} \
103
explicit Name(const IMP::kernel::ParticleAdaptor &d) : Parent(d) { \
104
IMP_INTERNAL_CHECK( \
105
get_is_setup(d.get_model(), d.get_particle_index()), \
106
"Particle " << d.get_model()->get_particle_name( \
107
d.get_particle_index()) \
108
<< " missing required attributes for decorator " \
109
<< #Name); \
110
} \
111
/** \deprecated_at{2.1} Check explicitly instead. */
\
112
static Name decorate_particle(::IMP::kernel::Particle *p) { \
113
IMP_CHECK_OBJECT(p); \
114
if (!get_is_setup(p->get_model(), p->get_index())) { \
115
return Name(); \
116
} \
117
return Name(p); \
118
} \
119
/** \deprecated_at{2.1} Use get_is_setup() instead. */
\
120
IMPKERNEL_DEPRECATED_METHOD_DECL(2.1) static bool particle_is_instance( \
121
::IMP::kernel::Particle *p) { \
122
IMPKERNEL_DEPRECATED_METHOD_DEF(2.1, "Use get_is_setup instead."); \
123
return get_is_setup(p->get_model(), p->get_index()); \
124
} \
125
/** \deprecated_at{2.1} Use get_is_setup() instead. */
\
126
IMPKERNEL_DEPRECATED_METHOD_DECL(2.1) static bool particle_is_instance( \
127
IMP::kernel::Model *m, IMP::kernel::ParticleIndex pi) { \
128
IMPKERNEL_DEPRECATED_METHOD_DEF(2.1, "Use get_is_setup instead."); \
129
return get_is_setup(m, pi); \
130
} \
131
static bool get_is_setup(const IMP::kernel::ParticleAdaptor &p) { \
132
return get_is_setup(p.get_model(), p.get_particle_index()); \
133
} \
134
IMP_SHOWABLE(Name)
135
136
/** \deprecated_at{2.1} Use IMP_DECORATOR_WITH_TRAITS_METHODS()
137
*/
138
#define IMP_DECORATOR_WITH_TRAITS(Name, Parent, TraitsType, traits_name, \
139
default_traits) \
140
private: \
141
TraitsType traits_; \
142
\
143
public: \
144
IMPKERNEL_DEPRECATED_MACRO(2.1, "Use IMP_DECORATOR_METHODS()"); \
145
IMP_NO_DOXYGEN(typedef Parent ParentDecorator); \
146
Name() {} \
147
Name(kernel::Model *m, ParticleIndex id, const TraitsType &tr) \
148
: Parent(m, id), traits_(tr) { \
149
IMP_INTERNAL_CHECK( \
150
get_is_setup(m->get_particle(id), tr), \
151
"Particle " << m->get_particle(id)->get_name() \
152
<< " missing required attributes for decorator " << #Name \
153
<< "\n" << Showable(m->get_particle(id))); \
154
} \
155
Name(const TraitsType &tr) : traits_(tr) {} \
156
explicit Name(::IMP::kernel::Particle *p, \
157
const TraitsType &tr = default_traits) \
158
: Parent(p), traits_(tr) { \
159
IMP_INTERNAL_CHECK( \
160
get_is_setup(p, tr), \
161
"Particle " << p->get_name() << " missing required attributes " \
162
<< " for decorator " << #Name << "\n" << Showable(p)); \
163
} \
164
static Name decorate_particle(::IMP::kernel::Particle *p, \
165
const TraitsType &tr = default_traits) { \
166
if (!get_is_setup(p, tr)) \
167
return Name(); \
168
else \
169
return Name(p, tr); \
170
} \
171
IMP_SHOWABLE(Name); \
172
const TraitsType &get_##traits_name() \
173
const { return get_decorator_traits(); } \
174
typedef Parent DecoratorTraitsBase; \
175
typedef TraitsType DecoratorTraits; \
176
const DecoratorTraits &get_decorator_traits() const { return traits_; } \
177
static const DecoratorTraits &get_default_decorator_traits() { \
178
static TraitsType dt = default_traits; \
179
return dt; \
180
} \
181
IMP_NO_DOXYGEN(typedef boost::true_type DecoratorHasTraits)
182
183
/** Implement the needed methods for a decorator based on
184
- setup_particle()
185
- get_is_setup()
186
methods that you provide.
187
*/
188
#define IMP_DECORATOR_WITH_TRAITS_METHODS(Name, Parent, TraitsType, \
189
traits_name, default_traits) \
190
private: \
191
TraitsType traits_; \
192
public: \
193
typedef TraitsType DecoratorTraits; \
194
const DecoratorTraits &get_decorator_traits() const { return traits_; } \
195
static const DecoratorTraits &get_default_decorator_traits() { \
196
static TraitsType dt = default_traits; \
197
return dt; \
198
} \
199
/* Should be private but SWIG accesses it through the \
200
comparison \
201
macros*/
IMP_NO_DOXYGEN( \
202
typedef Parent ParentDecorator); \
203
IMP_NO_DOXYGEN(typedef boost::true_type DecoratorHasTraits); \
204
Name() : Parent() {} \
205
Name(::IMP::kernel::Model *m, ::IMP::kernel::ParticleIndex id, \
206
const TraitsType &tr = default_traits) \
207
: Parent(m, id), traits_(tr) { \
208
IMP_INTERNAL_CHECK( \
209
get_is_setup(m, id, tr), \
210
"Particle " << m->get_particle_name(id) \
211
<< " missing required attributes for decorator " \
212
<< #Name); \
213
} \
214
explicit Name(const IMP::kernel::ParticleAdaptor &d, \
215
const TraitsType &tr = default_traits) \
216
: Parent(d), traits_(tr) { \
217
IMP_INTERNAL_CHECK( \
218
get_is_setup(d.get_model(), d.get_particle_index(), tr), \
219
"Particle " << d.get_model()->get_particle_name( \
220
d.get_particle_index()) \
221
<< " missing required attributes for decorator " \
222
<< #Name); \
223
} \
224
/** \deprecated_at{2.1} Check explicitly instead. */
\
225
static Name decorate_particle(::IMP::kernel::Particle *p, \
226
const TraitsType &tr = default_traits) { \
227
IMP_CHECK_OBJECT(p); \
228
if (!get_is_setup(p->get_model(), p->get_index(), tr)) { \
229
return Name(); \
230
} \
231
return Name(p); \
232
} \
233
/** \deprecated_at{2.1} Use get_is_setup() instead. */
\
234
IMPKERNEL_DEPRECATED_METHOD_DECL(2.1) static bool particle_is_instance( \
235
::IMP::kernel::Particle *p, const TraitsType &tr = default_traits) { \
236
IMPKERNEL_DEPRECATED_METHOD_DEF(2.1, "Use get_is_setup instead."); \
237
return get_is_setup(p->get_model(), p->get_index(), tr); \
238
} \
239
/** \deprecated_at{2.1} Use get_is_setup() instead. */
\
240
IMPKERNEL_DEPRECATED_METHOD_DECL(2.1) static bool particle_is_instance( \
241
IMP::kernel::Model *m, IMP::kernel::ParticleIndex pi, \
242
const TraitsType &tr = default_traits) { \
243
IMPKERNEL_DEPRECATED_METHOD_DEF(2.1, "Use get_is_setup instead."); \
244
return get_is_setup(m, pi, tr); \
245
} \
246
static bool get_is_setup(const IMP::kernel::ParticleAdaptor &p, \
247
const TraitsType &tr = default_traits) { \
248
return get_is_setup(p.get_model(), p.get_particle_index(), tr); \
249
} \
250
IMP_SHOWABLE(Name)
251
252
/** Decorators need to be able to be set up from Particles, ParticleIndexes
253
and other Decorators. To help keep things uniform, we provide macros
254
to declare the setup functions. These macros expect that an appropriate
255
`do_setup_particle(kernel::Model *, ParticleIndex, args...)` function is
256
defined. But any docs needed before the macro invocation.
257
*/
258
#define IMP_DECORATOR_SETUP_0(Name) \
259
/** Setup the particle so it can be used with this decorator. */
\
260
static Name setup_particle(kernel::Model *m, ParticleIndex pi) { \
261
IMP_USAGE_CHECK(!get_is_setup(m, pi), \
262
"Particle " << m->get_particle_name(pi) \
263
<< " already set up as " << #Name); \
264
do_setup_particle(m, pi); \
265
return Name(m, pi); \
266
} \
267
static Name setup_particle(IMP::kernel::ParticleAdaptor decorator) { \
268
return setup_particle(decorator.get_model(), \
269
decorator.get_particle_index()); \
270
}
271
/** \see IMP_DECORATOR_SETUP_0() */
272
#define IMP_DECORATOR_SETUP_1(Name, FirstArgumentType, first_argument_name) \
273
/** Setup the particle so it can be used with this decorator. */
\
274
static Name setup_particle(kernel::Model *m, ParticleIndex pi, \
275
FirstArgumentType first_argument_name) { \
276
IMP_USAGE_CHECK(!get_is_setup(m, pi), \
277
"Particle " << m->get_particle_name(pi) \
278
<< " already set up as " << #Name); \
279
do_setup_particle(m, pi, first_argument_name); \
280
return Name(m, pi); \
281
} \
282
static Name setup_particle(IMP::kernel::ParticleAdaptor decorator, \
283
FirstArgumentType first_argument_name) { \
284
return setup_particle(decorator.get_model(), \
285
decorator.get_particle_index(), \
286
first_argument_name); \
287
}
288
/** \see IMP_DECORATOR_SETUP_0() */
289
#define IMP_DECORATOR_SETUP_2(Name, FirstArgumentType, first_argument_name, \
290
SecondArgumentType, second_argument_name) \
291
/** Setup the particle so it can be used with this decorator. */
\
292
static Name setup_particle(kernel::Model *m, ParticleIndex pi, \
293
FirstArgumentType first_argument_name, \
294
SecondArgumentType second_argument_name) { \
295
IMP_USAGE_CHECK(!get_is_setup(m, pi), \
296
"Particle " << m->get_particle_name(pi) \
297
<< " already set up as " << #Name); \
298
do_setup_particle(m, pi, first_argument_name, second_argument_name); \
299
return Name(m, pi); \
300
} \
301
static Name setup_particle(IMP::kernel::ParticleAdaptor decorator, \
302
FirstArgumentType first_argument_name, \
303
SecondArgumentType second_argument_name) { \
304
return setup_particle(decorator.get_model(), \
305
decorator.get_particle_index(), first_argument_name, \
306
second_argument_name); \
307
}
308
/** \see IMP_DECORATOR_SETUP_0() */
309
#define IMP_DECORATOR_SETUP_3(Name, FirstArgumentType, first_argument_name, \
310
SecondArgumentType, second_argument_name, \
311
ThirdArgumentType, third_argument_name) \
312
/** Setup the particle so it can be used with this decorator. */
\
313
static Name setup_particle(kernel::Model *m, ParticleIndex pi, \
314
FirstArgumentType first_argument_name, \
315
SecondArgumentType second_argument_name, \
316
ThirdArgumentType third_argument_name) { \
317
IMP_USAGE_CHECK(!get_is_setup(m, pi), \
318
"Particle " << m->get_particle_name(pi) \
319
<< " already set up as " << #Name); \
320
do_setup_particle(m, pi, first_argument_name, second_argument_name, \
321
third_argument_name); \
322
return Name(m, pi); \
323
} \
324
static Name setup_particle(IMP::kernel::ParticleAdaptor decorator, \
325
FirstArgumentType first_argument_name, \
326
SecondArgumentType second_argument_name, \
327
ThirdArgumentType third_argument_name) { \
328
return setup_particle(decorator.get_model(), \
329
decorator.get_particle_index(), first_argument_name, \
330
second_argument_name, third_argument_name); \
331
}
332
/** \see IMP_DECORATOR_SETUP_0() */
333
#define IMP_DECORATOR_SETUP_4(Name, FirstArgumentType, first_argument_name, \
334
SecondArgumentType, second_argument_name, \
335
ThirdArgumentType, third_argument_name, \
336
FourthArgumentType, fourth_argument_name) \
337
/** Setup the particle so it can be used with this decorator. */
\
338
static Name setup_particle(kernel::Model *m, ParticleIndex pi, \
339
FirstArgumentType first_argument_name, \
340
SecondArgumentType second_argument_name, \
341
ThirdArgumentType third_argument_name, \
342
FourthArgumentType fourth_argument_name) { \
343
IMP_USAGE_CHECK(!get_is_setup(m, pi), \
344
"Particle " << m->get_particle_name(pi) \
345
<< " already set up as " << #Name); \
346
do_setup_particle(m, pi, first_argument_name, second_argument_name, \
347
third_argument_name, fourth_argument_name); \
348
return Name(m, pi); \
349
} \
350
static Name setup_particle(IMP::kernel::ParticleAdaptor decorator, \
351
FirstArgumentType first_argument_name, \
352
SecondArgumentType second_argument_name, \
353
ThirdArgumentType third_argument_name, \
354
FourthArgumentType fourth_argument_name) { \
355
return setup_particle(decorator.get_model(), \
356
decorator.get_particle_index(), first_argument_name, \
357
second_argument_name, third_argument_name, \
358
fourth_argument_name); \
359
}
360
361
/** Decorators need to be able to be set up from Particles, ParticleIndexes
362
and other Decorators. To help keep things uniform, we provide macros
363
to declare the setup functions. These macros expect that an appropriate
364
`do_setup_particle(kernel::Model *, ParticleIndex, args...)` function is
365
defined. But any docs needed before the macro invocation.
366
*/
367
#define IMP_DECORATOR_TRAITS_SETUP_0(Name) \
368
/** Setup the particle so it can be used with this decorator. */
\
369
static Name setup_particle( \
370
kernel::Model *m, ParticleIndex pi, \
371
DecoratorTraits tr = get_default_decorator_traits()) { \
372
do_setup_particle(m, pi, tr); \
373
return Name(m, pi, tr); \
374
} \
375
static Name setup_particle( \
376
IMP::kernel::ParticleAdaptor d, \
377
DecoratorTraits tr = get_default_decorator_traits()) { \
378
do_setup_particle(d.get_model(), d.get_particle_index(), tr); \
379
return Name(d.get_model(), d.get_particle_index(), tr); \
380
}
381
/** \see IMP_DECORATOR_TRAITS_SETUP_0() */
382
#define IMP_DECORATOR_TRAITS_SETUP_1(Name, FirstArgumentType, \
383
first_argument_name) \
384
static Name setup_particle( \
385
kernel::Model *m, ParticleIndex pi, \
386
FirstArgumentType first_argument_name, \
387
DecoratorTraits tr = get_default_decorator_traits()) { \
388
do_setup_particle(m, pi, first_argument_name, tr); \
389
return Name(m, pi, tr); \
390
} \
391
static Name setup_particle( \
392
IMP::kernel::ParticleAdaptor d, FirstArgumentType first_argument_name, \
393
DecoratorTraits tr = get_default_decorator_traits()) { \
394
do_setup_particle(d.get_model(), d.get_particle_index(), \
395
first_argument_name, tr); \
396
return Name(d.get_model(), d.get_particle_index(), tr); \
397
}
398
/** \see IMP_DECORATOR_TRAITS_SETUP_0() */
399
#define IMP_DECORATOR_TRAITS_SETUP_2(Name, FirstArgumentType, \
400
first_argument_name, SecondArgumentType, \
401
second_argument_name) \
402
static Name setup_particle( \
403
kernel::Model *m, ParticleIndex pi, \
404
FirstArgumentType first_argument_name, \
405
SecondArgumentType second_argument_name, \
406
DecoratorTraits tr = get_default_decorator_traits()) { \
407
do_setup_particle(m, pi, first_argument_name, second_argument_name, tr); \
408
return Name(m, pi, tr); \
409
} \
410
static Name setup_particle( \
411
IMP::kernel::ParticleAdaptor d, FirstArgumentType first_argument_name, \
412
SecondArgumentType second_argument_name, \
413
DecoratorTraits tr = get_default_decorator_traits()) { \
414
do_setup_particle(d.get_model(), d.get_particle_index(), \
415
first_argument_name, second_argument_name, tr); \
416
return Name(d.get_model(), d.get_particle_index(), tr); \
417
}
418
419
//! Perform actions dependent on whether a particle has an attribute.
420
/** A common pattern is to check if a particle has a particular attribute,
421
do one thing if it does and another if it does not. This macro implements
422
that pattern. It requires that the method get_particle() return the
423
particle being used.
424
425
\param[in] AttributeKey The key for the attribute
426
\param[in] Type The type for the attribute ("Int", "Float", "String")
427
\param[in] has_action The action to take if the Particle has the attribute.
428
The attribute value is stored in the variable VALUE.
429
\param[in] not_has_action The action to take if the Particle does not have
430
the attribute.
431
\see IMP_DECORATOR_GET()
432
\see IMP_DECORATOR_GET_SET()
433
434
*/
435
#define IMP_DECORATOR_GET(AttributeKey, Type, has_action, not_has_action) \
436
do { \
437
if (get_model()->get_has_attribute(AttributeKey, get_particle_index())) { \
438
Type VALUE = \
439
get_model()->get_attribute(AttributeKey, get_particle_index()); \
440
has_action; \
441
} else { \
442
not_has_action; \
443
} \
444
} while (false)
445
446
//! Set an attribute, creating it if it does not already exist.
447
/** Another common pattern is to have an assumed value if the attribute
448
is not there. Then, you sometimes need to set the value whether it
449
is there or not.
450
\see IMP_DECORATOR_GET()
451
\see IMP_DECORATOR_GET_SET()
452
*/
453
#define IMP_DECORATOR_SET(AttributeKey, value) \
454
do { \
455
if (get_model()->get_has_attribute(AttributeKey, get_particle_index())) { \
456
get_model()->set_attribute(AttributeKey, get_particle_index(), value); \
457
} else { \
458
get_model()->add_attribute(AttributeKey, get_particle_index(), value); \
459
} \
460
} while (false)
461
462
//! Define methods for getting and setting a particular simple field
463
/** This macro defines methods to get and set a particular attribute.
464
465
\param[in] name The lower case name of the attribute
466
\param[in] AttributeKey The AttributeKey object controlling
467
the attribute.
468
\param[in] Type The type of the attribute (upper case).
469
\param[in] ReturnType The type to return from the get.
470
\see IMP_DECORATOR_GET()
471
\see IMP_DECORATOR_SET()
472
*/
473
#define IMP_DECORATOR_GET_SET(name, AttributeKey, Type, ReturnType) \
474
ReturnType get_##name() const { \
475
return static_cast<ReturnType>( \
476
get_model()->get_attribute(AttributeKey, get_particle_index())); \
477
} \
478
void set_##name(ReturnType t) { \
479
get_model()->set_attribute(AttributeKey, get_particle_index(), t); \
480
} \
481
IMP_REQUIRE_SEMICOLON_CLASS(getset##name)
482
483
//! Define methods for getting and setting an optional simple field.
484
/** See IMP_DECORATOR_GET_SET(). The difference is that here you can provide
485
a default value to use if the decorator does not have the attribute.
486
487
\param[in] name The lower case name of the attribute
488
\param[in] AttributeKey The expression to get the required attribute key.
489
\param[in] Type The type of the attribute (upper case).
490
\param[in] ReturnType The type to return from the get.
491
\param[in] default_value The value returned if the attribute is missing.
492
*/
493
#define IMP_DECORATOR_GET_SET_OPT(name, AttributeKey, Type, ReturnType, \
494
default_value) \
495
ReturnType get_##name() const { \
496
IMP_DECORATOR_GET(AttributeKey, Type, \
497
return static_cast<ReturnType>(VALUE), \
498
return default_value); \
499
} \
500
void set_##name(ReturnType t) { IMP_DECORATOR_SET(AttributeKey, t); } \
501
IMP_REQUIRE_SEMICOLON_CLASS(getset_##name)
502
503
#define IMP_DECORATORS_DECL(Name, PluralName) \
504
class Name; \
505
typedef IMP::base::Vector<Name> PluralName
506
507
#ifndef IMP_DOXYGEN
508
#define IMP_DECORATORS_DEF(Name, PluralName) \
509
/* needed so there is no ambiguity with operator->*/
\
510
inline std::ostream &operator<<(std::ostream &out, Name n) { \
511
n.show(out); \
512
return out; \
513
}
514
#else
515
#define IMP_DECORATORS_DEF(Name, PluralName)
516
#endif
517
518
//! Define the types for storing sets of decorators
519
/** The macro defines the types PluralName and PluralNameTemp.
520
*/
521
#define IMP_DECORATORS(Name, PluralName, Parent) \
522
IMP_DECORATORS_DECL(Name, PluralName); \
523
IMP_DECORATORS_DEF(Name, PluralName)
524
525
//! Define the types for storing sets of decorators
526
/** The macro defines the types PluralName and PluralNameTemp.
527
*/
528
#define IMP_DECORATORS_WITH_TRAITS(Name, PluralName, Parent) \
529
/* needed so there is no ambiguity with operator->*/
\
530
inline std::ostream &operator<<(std::ostream &out, Name n) { \
531
n.show(out); \
532
return out; \
533
} \
534
typedef IMP::base::Vector<Name> PluralName
535
536
//! Create a decorator that computes some sort of summary info on a set
537
/** Examples include a centroid or a cover for a set of particles.
538
539
\param[in] Name The name for the decorator
540
\param[in] Parent the parent decorator type
541
\param[in] Members the way to pass a set of particles in
542
*/
543
#define IMP_SUMMARY_DECORATOR_DECL(Name, Parent, Members) \
544
class IMPCOREEXPORT Name : public Parent { \
545
IMP_CONSTRAINT_DECORATOR_DECL(Name); \
546
static void do_setup_particle(kernel::Model *m, ParticleIndex pi, \
547
const ParticleIndexes &pis); \
548
static void do_setup_particle(kernel::Model *m, ParticleIndex pi, \
549
Refiner *ref); \
550
\
551
public: \
552
IMP_DECORATOR_METHODS(Name, Parent); \
553
IMP_DECORATOR_SETUP_1(Name, ParticleIndexesAdaptor, members); \
554
IMP_DECORATOR_SETUP_1(Name, Refiner *, refiner); \
555
static bool get_is_setup(kernel::Model *m, ParticleIndex pi) { \
556
return m->get_has_attribute(get_constraint_key(), pi); \
557
} \
558
IMP_NO_DOXYGEN(typedef boost::false_type DecoratorHasTraits); \
559
\
560
private: \
561
/* hide set methods*/
\
562
void set_coordinates() {}; \
563
void set_coordinates_are_optimized() const {} \
564
void set_coordinate() const {} \
565
void set_radius() const {} \
566
}; \
567
IMP_DECORATORS(Name, Name##s, Parent##s)
568
569
/** See IMP_SUMMARY_DECORATOR_DECL()
570
\param[in] Name The name for the decorator
571
\param[in] Parent the parent decorator type
572
\param[in] Members the way to pass a set of particles in
573
\param[in] create_modifier the statements to create the modifier
574
which computes the summary info. It should be called mod.
575
*/
576
#define IMP_SUMMARY_DECORATOR_DEF(Name, Parent, Members, create_modifier) \
577
void Name::do_setup_particle(kernel::Model *m, ParticleIndex pi, \
578
const ParticleIndexes &pis) { \
579
Refiner *ref = new FixedRefiner(IMP::kernel::get_particles(m, pis)); \
580
create_modifier; \
581
if (!Parent::get_is_setup(m, pi)) Parent::setup_particle(m, pi); \
582
set_constraint(mod, new DerivativesToRefined(ref), m, pi); \
583
} \
584
void Name::do_setup_particle(kernel::Model *m, ParticleIndex pi, \
585
Refiner *ref) { \
586
create_modifier; \
587
if (!Parent::get_is_setup(m, pi)) Parent::setup_particle(m, pi); \
588
set_constraint(mod, new DerivativesToRefined(ref), m, pi); \
589
} \
590
void Name::show(std::ostream &out) const { \
591
out << #Name << " at " << static_cast<Parent>(*this); \
592
} \
593
IMP_CONSTRAINT_DECORATOR_DEF(Name)
594
595
#endif
/* IMPKERNEL_DECORATOR_MACROS_H */
particle_index.h
Various general useful functions for IMP.
Decorator.h
The base class for decorators.
log_macros.h
Logging and error reporting support.
warning_macros.h
Various general useful macros for IMP.
Particle.h
Classes to handle individual model particles.
showable_macros.h
Various general useful macros for IMP.
check_macros.h
Exception definitions and assertions.