General Coding and Naming

This section covers formatting, headers, naming, members, reserved identifiers, whitespace, braces, switches, inheritance, comments, variables, and line length.

1. Formatting & Tools

  • Use .clang-format at the repo root; Allman braces, 4 spaces, column ≤ 100.

  • Run git clang-format before committing. Style violations fail CI.

Example (auto-formatted spacing & braces):

// Wrong
if(ok){doWork();}

// Correct
if (ok)
{
    doWork();
}

2. Headers & Include Guards

  • Every header uses a FEELPP-style include guard.

// feel/mesh/my_header.hpp
#if !defined(FEELPP_MESH_MY_HEADER_HPP)
#define FEELPP_MESH_MY_HEADER_HPP 1

// header content

#endif // FEELPP_MESH_MY_HEADER_HPP

Include order (in .cpp): own header, C std, 3rd-party, Feel headers.

// Correct
#include "feel/mesh/my_header.hpp"
#include <string>
#include <vector>
#include <boost/mpi3/communicator.hpp>
#include "feel/mesh/mesh.hpp"

3. Namespaces

  • Put code in Feel (and sub-namespaces). No extra indent inside namespaces.

namespace Feel::mesh
{
class A
{
public:
    A() = default;
};
} // namespace Feel::mesh

4. Naming Conventions

  • Classes/structs: PascalCase (MeshAdaptation)

  • Functions/variables: camelCase (getValue, counter)

  • Accessors: property name (e.g., matrix()); bool as isXxx()/hasXxx()

  • Acronyms lowercased inside names (e.g., isFemEnabled())

// Wrong
class meshadapter {};
int Counter;
bool isFEMEnabled();

// Correct
class MeshAdapter {};
int counter;
bool isFemEnabled();

5. Data Members & Statics

  • Official: non-static members use M_ (e.g., int M_value;).

  • Statics: S_ (e.g., static inline int S_counter = 0;).

  • A trailing underscore (e.g., value_) is tolerated, but M_ is the rule for new code.

// Tolerated
class Foo { int value_; };

// Preferred (official)
class Foo { int M_value = 0; };

// Static
class Bar { static inline int S_instances = 0; };

6. Reserved Identifiers

  • Don’t start identifiers with and never use _.

// Wrong
int _count, __impl;

// Correct
int count, impl;

7. Indentation & Whitespace

  • 4 spaces; no tabs; no extra indent in namespaces.

  • Space around binary operators; one space after keywords.

  • Pointer/reference style: char *p, const T &x.

// Wrong
if(foo){a=b+1;}

// Correct
if (foo)
{
    a = b + 1;
}

8. Braces & Parentheses

  • Allman braces; always use braces for multi-line or complex bodies.

  • Parenthesize to make precedence explicit.

// Wrong
if (a && b || c)

// Correct
if ((a && b) || c)

9. Switch

  • Align case with switch; always end each case with break/return or ;.

switch (mode)
{
case Mode::A:
    doA();
    break;
case Mode::B:
    doB();
    [[fallthrough]];
case Mode::C:
    doC();
    break;
default:
    handleDefault();
    break;
}

10. Inheritance & Virtuals

  • Don’t repeat virtual in overrides; use override. Consider final where relevant.

  • Polymorphic base classes need a virtual (or protected) destructor.

// Wrong
class Derived : public Base
{
    virtual void run();
};

// Correct
class Derived : public Base
{
    void run() override;
};

11. Comments & Doxygen

  • Prefer // comments; reserve /* …​ */ for license blocks.

  • Use //! Doxygen for public APIs (\param, \return, \tparam).

//!
//! \brief Compute flux on a boundary.
//! \param mesh  input mesh
//! \param bid   boundary id
//! \return integrated flux
double computeFlux(const Mesh &mesh, int bid);

12. Declaring Variables

  • One per line; meaningful names; declare near first use.

// Wrong
int a,b;

// Correct
int width;
int height;

13. Line Length

  • Keep lines ≤ 100 chars; wrap long expressions/operators on new lines.

if (longExpr
    + otherExpr
    + finalExpr)
{
}