IMP logo
IMP Manual  for IMP version 2.16.0
code_conventions.md
1 Coding conventions {#code_conventions}
2 ==================
3 
4 To ensure code consistency and readability, certain conventions
5 must be adhered to when writing code for %IMP. Some of these
6 conventions are automatically checked for by source control before
7 allowing a new commit, and can also be checked yourself in new
8 code by running [check_standards.py](#devguide_check_standards).
9 
10 All new code should also conform to the previously-described
11 [naming and interface conventions](@ref conventions).
12 
13 
14 # Indentation {#codeconv_indentation}
15 
16 All C++ headers and code should be indented with 2-space indents. Do not use
17 tabs. [cleanup_code.py](\ref dev_tools_cleanup_code) can help you do this formatting
18 automatically.
19 
20 All Python code should conform to the [Python style
21 guide](https://www.python.org/dev/peps/pep-0008/). In essence this
22 translates to 4-space indents, no tabs, and similar class, method and
23 variable naming to the C++ code. You can check that your Python code
24 is correctly formatted using the [flake8](https://pypi.org/project/flake8/)
25 tool.
26 
27 # Names {#codeconv_names}
28 
29 In addition to the previously-described
30 [naming and interface conventions](@ref conventions),
31 developers should be aware that
32 - all preprocessor symbols must begin with `%IMP`.
33 - names of files that implement a single class should be named for that
34  class; for example the `SpecialVector` class could be implemented in
35  `SpecialVector.h` and `SpecialVector.cpp`
36 - files that provide free functions or macros should be given names
37  `separated_by_underscores`, for %example `%container_macros.h`
38 - [command line tools](@ref cmdline) should also be given names
39  `separated_by_underscores` and should not have a file extension
40  (such as `.py`). (Note also that since tools are installed, care should be
41  taken to give them non-generic names so they don't conflict with other
42  programs users may have installed on their system. Also consider using
43  IMP::CommandDispatcher to provide a single command line interface to many
44  individual Python scripts, rather than making each one a command line tool.)
45 - Functions which take a parameter which has [units](@ref units) should have the
46  unit as part of the function name, for %example
47  IMP::atom::SimulationParameters::set_maximum_time_step_in_femtoseconds().
48  Remember the Mars orbiter. The exception to this is distance and
49  force numbers which should always be in angstroms and
50  kcal/mol/angstrom respectively unless otherwise stated.
51 
52 # Passing and storing data {#codeconv_passing}
53 
54 - When a class or function takes a set of particles which are expected to
55  be those of a particular type of decorator, it should take a list of
56  decorators instead. eg IMP::core::transform() takes a IMP::core::XYZ.
57  This makes it clearer what attributes the particle is required to have
58  as well as allows functions to be overloaded (so there can be an
59  IMP::core::transform() which takes IMP::core::RigidBody particles instead).
60 
61 - IMP::Restraint and IMP::ScoreState classes should generally use a
62  IMP::SingletonContainer (or other type of Container) to store the set of
63  IMP::Particle objects that they act on. Alternatively, take and store one
64  or more IMP::ParticleIndex objects (or related types, such as
65  IMP::ParticleIndexPair).
66 
67 - Store collections of IMP::Object-derived
68  objects of type `Name` using a `Names`. Declare functions that
69  accept them to take a `NamesTemp` (`Names` is a `NamesTemp)`.
70  `Names` are reference counted (see IMP::Object for details);
71  `NamesTemp` are not. Store collections of particles using
72  IMP::ParticleIndexes, rather than using IMP::Particles or decorators.
73 
74 - To handle floating-point data, use the standard C++ `double` type. (In most
75  cases on modern 64-bit systems, `float` isn't any more efficient.) Use the
76  IMP::Float type (and derived types, such as IMP::FloatPair) *only* to work
77  with floating-point attributes of IMP::Model objects. (Similarly, use `int`
78  and `std::string` for integer and string data, except for accessing
79  IMP::Model attributes where the IMP::Int and IMP::String types should
80  be utilized.)
81 
82 - To work with vectors of data, use IMP::Vector. It performs similarly to
83  `std::vector` but adds extra functionality, and turns on bounds checks when
84  %IMP is built in debug mode.
85 
86 # Display {#codeconv_display}
87 
88 All values must have a `show` method which takes an optional
89 `std::ostream` and prints information about the object (see
90 IMP::Array::show() for an example). Add a `write` method if you
91 want to provide output that can be read back in.
92 
93 # Errors {#codeconv_errors}
94 
95 Classes and methods should use %IMP exceptions to report errors. See
96 IMP::Exception for a list of existing exceptions (click on the "Inheritance
97 diagram" link on that page). See
98 [checks](../ref/exception_8h.html) for more information.
99 
100 # Namespaces {#codeconv_namespace}
101 
102 Use the provided `IMPMODULE_BEGIN_NAMESPACE`,
103 `IMPMODULE_END_NAMESPACE`, `IMPMODULE_BEGIN_INTERNAL_NAMESPACE` and
104 `IMPMODULE_END_INTERNAL_NAMESPACE` macros to put declarations in a
105 namespace appropriate for module `MODULE`.
106 
107 Each module has an internal namespace, eg `IMP::atom::internal`, and an internal
108 include directory `IMP/atom/internal`. Any function which is
109  - not intended to be part of the API,
110  - not documented,
111  - liable to change without notice,
112  - or not tested
113 
114 should be declared in an internal header and placed in the internal namespace.
115 
116 The functionality in such internal headers is
117  - not exported to Python
118  - and not part of the documented API
119 
120 As a result, such functions do not need to obey all the coding conventions
121 (but we recommend that they do).
122 
123 # C++ 11 {#codeconv_cxx11}
124 %IMP now turns on C++ 11 support when it can. However, since compilers
125 are still quite variable in which C++ 11 features they support, it is
126 not advisable to use them directly in %IMP code at this point. To aid
127 in their use when practical we provide several helper macros:
128 - `IMP_OVERRIDE` inserts the `override` keyword when available
129 - `IMP_FINAL` inserts the `final` keyword when available
130 
131 More will come.
void report(std::string benchmark, std::string algorithm, double time, double check)
#define IMP_FINAL
std::pair< double, double > FloatPair
std::ostream & show(Hierarchy h, std::ostream &out=std::cout)
double Float
int Int
std::string String
#define IMP_OVERRIDE