1 Coding conventions {#code_conventions}
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).
10 All
new code should also conform to the previously-described
11 [naming and interface conventions](@ref conventions).
14 # Indentation {#codeconv_indentation}
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
20 All Python code should conform to the [Python style
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).
27 # Names {#codeconv_names}
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.
52 # Passing and storing data {#codeconv_passing}
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).
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).
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.
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
77 with floating-point attributes of
IMP::Model objects. (Similarly, use `
int`
78 and `std::string`
for integer and
string data, except
for accessing
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.
86 # Display {#codeconv_display}
88 All values must have a `
show` method which takes an optional
89 `std::ostream` and prints information about the object (see
91 want to provide output that can be read back in.
93 # Errors {#codeconv_errors}
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.
100 # Namespaces {#codeconv_namespace}
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`.
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,
111 - liable to change without notice,
114 should be declared in an
internal header and placed in the
internal namespace.
116 The functionality in such
internal headers is
117 - not exported to Python
118 - and not part of the documented API
120 As a result, such functions
do not need to obey all the coding conventions
121 (but we recommend that they
do).
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
void report(std::string benchmark, std::string algorithm, double time, double check)
std::pair< double, double > FloatPair
std::ostream & show(Hierarchy h, std::ostream &out=std::cout)