IMP logo
IMP Reference Guide  2.6.1
The Integrative Modeling Platform
bracket_macros.h
Go to the documentation of this file.
1 /**
2  * \file IMP/bracket_macros.h
3  * \brief Various general useful macros for IMP.
4  *
5  * Copyright 2007-2016 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_BRACKET_MACROS_H
10 #define IMPKERNEL_BRACKET_MACROS_H
11 #include <IMP/kernel_config.h>
12 
13 #ifdef IMP_DOXYGEN
14 /** Implement operator[] and at() for C++, and __getitem__ for Python.
15  The index type is Index and the expression that returns the value is expr.
16  Like the equivalent methods in std::vector, at() performs bound checking;
17  if the bounds_check_expr is false, then a UsageException is thrown.
18  operator[] does no bounds checks, except in debug mode. In Python, bounds
19  checking is always done and results in an IndexException if
20  bounds_check_expr is false.
21 */
22 #define IMP_BRACKET(Value, Index, bounds_check_expr, expr) \
23  const Value at(Index) const; \
24  Value& at(Index); \
25  const Value operator[](Index) const; \
26  Value& operator[](Index);
27 
28 /** Implement operator[] and at() for C++, and __getitem__ for Python.
29  The index type is Index and the expression that returns the value is expr.
30  The value returned is not mutable.
31  Like the equivalent methods in std::vector, at() performs bound checking;
32  if the bounds_check_expr is false, then a UsageException is thrown.
33  operator[] does no bounds checks, except in debug mode. In Python, bounds
34  checking is always done and results in an IndexException if
35  bounds_check_expr is false.
36 */
37 #define IMP_CONST_BRACKET(Value, Index, bounds_check_expr, expr) \
38  const Value at(Index) const; \
39  const Value operator[](Index) const;
40 
41 #elif !defined(SWIG)
42 #define IMP_CONST_BRACKET(Value, Index, bounds_check_expr, expr) \
43  const Value& operator[](Index i) const { \
44  IMP_INTERNAL_CHECK((bounds_check_expr), "Index out of range: " << i); \
45  expr; \
46  } \
47  const Value& at(Index i) const { \
48  IMP_USAGE_CHECK((bounds_check_expr), "Index out of range: " << i); \
49  expr; \
50  } \
51  const Value& __getitem__(Index i) const { \
52  if (!(bounds_check_expr)) { \
53  IMP_THROW("Bad index " << i, IMP::IndexException); \
54  } \
55  expr; \
56  }
57 
58 #define IMP_BRACKET(Value, Index, bounds_check_expr, expr) \
59  Value& at(Index i) { \
60  IMP_USAGE_CHECK((bounds_check_expr), "Index out of range: " << i); \
61  expr; \
62  } \
63  Value& operator[](Index i) { \
64  IMP_INTERNAL_CHECK((bounds_check_expr), "Index out of range: " << i); \
65  expr; \
66  } \
67  void __setitem__(Index i, const Value& v) { at(i) = v; } \
68  IMP_CONST_BRACKET(Value, Index, bounds_check_expr, expr)
69 
70 #else
71 #define IMP_CONST_BRACKET(Value, Index, bounds_check_expr, expr) \
72  const Value& __getitem__(Index i) const { \
73  if (!(bounds_check_expr)) { \
74  IMP_THROW("Bad index " << i, IMP::IndexException); \
75  } \
76  expr; \
77  }
78 
79 #define IMP_BRACKET(Value, Index, bounds_check_expr, expr) \
80  void __setitem__(Index i, const Value& v) { at(i) = v; } \
81  IMP_CONST_BRACKET(Value, Index, bounds_check_expr, expr)
82 
83 #endif
84 
85 #endif /* IMPKERNEL_BRACKET_MACROS_H */