hexed 0.4.0
 
Loading...
Searching...
No Matches
Contributing Guidelines

When contributing to Hexed, please adhere to these guidelines. Some are standard practice in software development, which I feel the need to specify since people contributing to Hexed may not be software engineers by training. Others are meant to standardize what is otherwise a matter of personal preference.

General Procedures

Please do not commit or push to the main branch. The standard workflow should be the following:

  1. Create a new branch.
  2. Implement changes.
  3. Open pull request.

After reviewing the pull request, the maintainer will merge it and delete the branch. You are encouraged to create as many new branches as you like, for any reason, even if they are just experiments you don't intend to merge. However, if you are completely done with a branch, please delete it. You are also encouraged to push frequently (at least once per work day)—productivity is maximized when everyone can see the latest version of everything. Finally, development should be test-driven as much as possible, granted the inherent difficulty of testing a computational physics solver.

Pull Requests

A pull request will not be merged until it meets the following requirements:

  • No merge conflicts.
  • Must compile and run both in Release and in Debug mode with sanitizers.
  • No unit test failures or sanitizer errors.
  • No compiler warnings.

Code Style

Please adhere to the following style conventions whenever possible.

File Formatting

  • File names must not contain whitespace or other characters that have meaning in shell commands.
  • Lines shall be no longer than 120 characters.
  • Prefer underscores (_) to hyphens (-) or camel case as word separators in file names.
  • Source files must not contain the tab character. C++ code should be indented with 2 spaces and Python code should be indented with 4 spaces.
  • There should be no trailing spaces at the ends of lines.
  • Use blank lines sparingly.

Brace Style

All C++ code shall use One True Brace Style, a derivative of K&R, with a few additional stipulations. Specifically:

  • Every multi-statement block has its opening brace on the same line as its control clause, including function, class, and namespace declarations.
  • Every closing brace is placed on a new line with the same indentation level as the opening control clause.
  • A single-statement block must be either enclosed in braces or placed on the same line as its control clause. This ensures that inserting another line later cannot inadvertently cause control flow to disagree with indentation.
  • A closing brace of an if block is placed on the same line as an accompanying else clause, and a closing brace of a do block is placed on the same line as the accompanying while clause.

Class Style

  • Private members shall begin with a single underscore (_).
  • public, protected, and private are indented to the same level as the class body.

Names

(of variables, functions, namespaces, classes, macros, etc. Anything in the code.)

  • Should contain words, abbreviations, and/or numbers separated by underscores (not camelCase, and not multiplewordswithoutspaces).
  • Names of classes should begin with a capital letter and macros should be all-capital. Otherwise, all letters should be lowercase.
  • A name should be a description of the variable it refers to. It should not reference mathematical symbols or the sound of words. For example, resist the temptation to use x to refer to horizontal position. Acceptable alternatives might be coord0, or position.
  • Maintain conventions in Notation and conventions.
  • When practical, avoid overly long names. Abbreviations are encouraged, especially in a local scope where there are fewer opportunities to confuse similar names.

Some examples of names I do not approve of:

  • eye to refer to the identity matrix. References the pronunciation of the mathematical symbol, two levels removed from any descriptive meaning. I prefer the name identity.
  • str2num to mean "string to number". Just call it str_to_num. Distinguishing between "2" and "to" is worth 3 extra characters.
  • I have seen names longer than this sentence. Save some for the comments.

Exceptions

If the code encounters a fatal problem, it should throw an exception (using the constructs of whatever language it is currently in) with a helpful error message. The message should identify what exactly was found to be wrong so that someone capable of understanding the problem has a clue where to start trying to figure out why. In the interest of performance, some functions in the C++ API may produce segmentation faults, memory leaks, or undefined behavior upon incorrect usage. However, the executable should catch incorrect usage and throw a useful exception. If an end user makes a mistake and obtains a segfault instead of an exception, I consider that a bug. Some common things I would like to avoid in this code are:

  • Don't say something vague like "something went wrong", "the operation could not be completed", or give a numeric error code that the user then has to look up to get any information. I'm thinking of the error messages commonly encountered in a certain operating system whose name ironically evokes transparency. Error messages should be as specific as possible.
  • Don't presume to guess exactly why the problem occurred or give verbose suggestions about how to fix it. Exceptions generally occur because you failed to anticipate what actually happened, so your speculations likely unhelpful and potentially misleading. Just say what the exact, concrete problem was. For example, if the code encounters a nonphysical state, don't say something like "The solver is unstable. Try reducing `max_safety` and verifying the boundary conditions are correct." Instead, say something like "nonpositive density encountered in flux computation".

Hexed provides the HEXED_ASSERT macro to facilitate generating exceptions with detailed information about where the error occurred in the code.

See also
Error Types

Miscellaneous

  • Avoid using namespace. The code is clearer when namespaces are referenced explicitly.
  • Everything in the library must be wrapped in the namespace hexed to avoid creating naming conflicts for library users.
    • Macros, which do not respect namespaces, should be either prefixed with HEXED_ or #undef'd after they are no longer needed.
  • Code should conform to the ISO C++ standard. For example, don't use variable-length arrays or the constexpr form of std::pow, which are non-conforming features of GCC (for constexpr math functions, see hexed::math).
  • The default integral type should be int. For example, don't use unsigned for loop indices and array sizes unless there is a specific reason to.