Contributing Code

Design Guidelines

  • Header files should use the hpp suffix, and source files should use the cpp suffix
  • Includes should follow the “Lakos” include order, that is
    • The prototype/interface header for this implementation (ie, the .h/.hh file that corresponds to this .cpp/.cc file).
    • Other headers from the same project, as needed.
    • Headers from other non-standard, non-system libraries (for example, Qt, Eigen, etc).
    • Headers from other “almost-standard” libraries (for example, Boost)
    • Standard C++ headers (for example, iostream, functional, etc.)
    • Standard C headers (for example, cstdint, dirent.h, etc.)
  • Prefer returning std::optional as a mechanism of error handling
  • This is a scientific computing library. Performance is critical. Helping the user to understand where errors have occurred is helpful, but keeping the program alive after an error is not critical. Functions should fail gracefully and provide informative error messages when they do. Logging should use spdlog.
  • Prefer free functions as much as possible. Ideally, class member functions will be simple and pass member variables to free functions.
  • Prefer standard library algorithms where possible
  • Public member functions and free function declarations should include doxygen comments above them. Private member function definitions should include doxygen comments above them.
  • Prefer forward declarations in header files
  • Document pre-conditions and post-conditions in doxygen comments uses the @pre and @post tags.
  • This is a C++20 project. Prefer standard library algorithms and std::ranges where possible.
  • Private member variables and functions in classes should be prefaced with an underscore operator (e.g. calculateMean). In a struct with public facing member variables, they should be prefaced with m followed by an underscore (e.g. m_height).

Before You Submit a Pull Request

Clang Format

Please make sure to run clang-format on all of your submitted files with the style guidelines in the base directory. A CI check will ensure that this happens upon pull request. You can read more about clang-format here:
https://clang.llvm.org/docs/ClangFormat.html

Clang Tidy

Please make sure to run clang-tidy on all of your submitted files with the style guidelines in the base directory. A CI check will ensure that this happens upon pull request. You can read more about clang-tidy here:

https://clang.llvm.org/extra/clang-tidy/

Testing

  • Testing is performed with Catch2. 

  • The component being tested generally has two TEST_CASE parts. The first will test the “happy path” to ensure that the computations work as expected. Different SECTIONs will be used for different computations. A second TEST_CASE will handle error handling and edge cases. Each SECTION will be for a different edge case / error.

  • Use descriptive names for each test.

  • TEST_CASES should also use useful tags.

  • Use REQUIRE instead of CHECK

  • Simple setup can be performed in the beginning of a TEST_CASE. Fixtures are only necessary for complex setup/teardown.

  • Prefer Catch::Matchers::WithinRel to Catch::Approx

  • Test files are included in the same folder as a given translation unit. They should have the same name as the header file with the extension “.test.cpp”. For example mask_to_line.hpp and mask_to_line.cpp will have the test file mask_to_line.test.cpp.

Further Resources and References

LLM Support

A configuration file for a plain text generator, repo-to-text, is included in the top level source directory. This can generate a single text file for the entire Neuralyzer repository which can be easily pasted into a LLM of choice.

Testing

C++ Development

Mike Shah has an excellent modern C++ design series on youtube. Episodes are a nice ~20 minute length:

Modern Cpp series by Mike Shah

Graphics Programming

Mike Shah also has a series on modern OpenGL on youtube:

Introduction to OpenGL