********************************** ErbslandDEV C++ Code Style Summary ********************************** This guide defines the basic C++ style conventions used across ErbslandDEV codebases. It is focused on clarity, maintainability, and practical modern C++ usage. Naming Conventions ================== - **Classes**: PascalCase (e.g., ``Controller``, ``TestClassBase``) - **Methods and Functions**: camelCase (e.g., ``addTestClass``, ``parseCommandLine``) - **Member Variables**: ``_underscorePrefix`` (e.g., ``_console``, ``_testClasses``) - **Global Constants**: ``cExample`` if not in dedicated namespace. - **Namespaces**: all lowercase with nested structure (e.g., ``erbsland::unittest``) - **Preprocessor Macros**: all uppercase ``EXAMPLE`` File Organization ================= - **Header Guards**: Use ``#pragma once`` - **Include Order** (separate blocks with empty lines): 1. Corresponding header (if in ``.cpp``) — *followed by two empty lines* 2. Local includes: ``#include "Example.hpp"`` 3. Local subdirectory includes: ``#include "sub/sub/Example.hpp"`` 4. Local relative includes: ``#include "../../Example.hpp"`` 5. Project libraries: ``#include `` 6. Standard library headers: ``#include `` 7. *Two* empty lines after the include block - **File Extensions**: Use ``.hpp`` for headers, ``.cpp`` for implementations - **File Scope**: Aim for one class per file, with matching name - **Maximum File Length**: Try to keep files under 500 lines Formatting ========== - **Indentation**: 4 spaces, no tabs - **Line Length**: Target a maximum of 120 characters per line - **Braces**: Opening brace stays on the same line - **Spacing and Separation**: - Use empty lines to separate logical blocks - One empty line between function definitions if they span >3 lines or have documentation - Two empty lines around ``struct``, ``class``, or ``enum`` definitions - Two empty lines around function implementations in ``.cpp`` files Comments ======== - **Public API Docs**: Use ``///`` and Doxygen ``@``-syntax - **Inline Comments**: Use ``//`` for short clarifying notes - **Block Comments**: Avoid ``/* ... */`` unless necessary - **Special Doxygen Tags**: - ``@tested``: Indicates this is covered by a unit test (name or path to the tests) - ``@notest``: Explains why a unit test is not applicable - ``@needtest``: Flags untested functionality - ``@wip``: This part is work in progress—talk to the author before modifying Constants & Literals ==================== - Prefer ``constexpr`` or ``const`` where applicable - Never use macros for constants - Move mechanic requires mutable instances! Modern C++ Usage ================ - Use C++20 syntax - Always use **trailing return types** for all non-void functions: ``auto create() -> std::string;`` - Use ``auto`` when the type is obvious or improves readability - Use structured binding ``const auto &[a, b] =`` - Use ``[[nodiscard]]`` and ``noexcept`` where applicable - Use ``override`` for overwritten/implemented functions - Use ``final`` for final classes - Use **designated initialization** if it improves the readability of the code - Use ``std::unique_ptr`` / ``std::shared_ptr`` instead of raw pointers - Prefer range-based ``for`` loops - Use ``std::format`` and ``std::chrono`` for formatted output and timing - Prefer ``std::ranges`` and ``std::views`` for expressive algorithms Quality and Safety First ======================== - Avoid manual memory management and raw pointers - Trust the compiler to optimize; prioritize clarity over micro-optimization - Perform bounds and range checks - Write unit tests for all modules and key functions - Ensure good test coverage and fail clearly when things go wrong - A crash is better than silent failure or undefined behavior