IMP logo
IMP Manual  for IMP version 2.5.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](http://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 ensure that your Python code
24 is correctly indented by using the
25 [cleanup_code.py script](\ref dev_tools_cleanup_code).
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