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 check that your Python code
24 is correctly formatted
using the [flake8](https:
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)