Contributions are welcome, although the response may be slow.
- Open pull requests against the
mainbranch. - Make sure the relevant CI checks pass before requesting review.
- Keep documentation in sync with code changes when behavior or interfaces change.
This page describes the code standards used in elastica++. It is intended to
help new developers follow the existing conventions in the codebase. Issues
such as style and layout are often subjective, so treat the guidance below as
the collective opinion of the elastica++ developers.
Please use clang-format together with the configuration file shipped with the
repository for all C++ code formatting.
- The repository configuration lives in
.clang-format. - A typical invocation is:
clang-format -i -style=file path/to/file.cppPlease use cmake-format together with the configuration file shipped with the
repository for CMake formatting.
- The repository configuration lives in
.cmake-format.yaml. - A typical invocation is:
cmake-format -i path/to/CMakeLists.txtUse using rather than typedef when declaring type definitions.
// STL iterator requirements
using iterator_category = std::random_access_iterator_tag;
using value_type = int;
using pointer = int*;
using reference = int&;
using difference_type = std::ptrdiff_t;Type aliases should appear near the top of a class or logical scope and should preferably be collected in contiguous, coherent blocks.
template <typename math_types>
class MyCalculator {
public:
using real_type = typename math_types::real_type;
using size_type = typename math_types::size_type;
// ... details
};
template <typename point_container>
void do_iterate(point_container const& points) {
using point_type = typename point_container::value_type;
using point_reference = typename point_container::reference_type;
for (auto p = points.begin(); p != points.end(); ++p) {
auto q = static_cast<point_type&>(*p);
auto same_q = static_cast<point_reference>(*p);
// details...
}
}In elastica++, we use the east-const convention:
int const&rather than:
const int&The goal is to keep the codebase consistent and, in our view, easier to read. For example:
int const*is a pointer to a constant integer, whereas:
int* constis a constant pointer to an integer.
If you have written code with west-const and want to convert it to
elastica++ conventions, take a look at
westerly.
In templates, we prefer the keyword typename over the keyword class.
In cases where template-template arguments are needed, the keyword class must
be used.
template <template <typename T> class T2>
class SomeClass {
// ... details
};To ensure a consistent look and feel:
- The first letter of each word in a class name should be uppercase.
- If a class name consists of several words, they should be concatenated.
- Data members within a class should use a trailing underscore.
- Data members should be lowercase, with words separated by underscores.
- Methods should be lowercase, with words separated by underscores.
- Free functions should be lowercase, with words separated by underscores.
class MyClass {
public:
int my_member_;
public:
void my_method() {}
};
void my_function() {}If a template argument is used elsewhere in the code, alias it immediately inside the class with the semantic name you want to use later.
template <typename math_types_>
class MyClass {
public:
using math_type = math_types_;
// ... a bunch of other stuff ...
};This pattern makes it easier for descendants of the class, or external generic algorithms, to refer to the relevant type meaningfully.