diff --git a/mkdocs/contributor_guide/interface_design.md b/mkdocs/contributor_guide/interface_design.md index 0320edc5..a93712c5 100644 --- a/mkdocs/contributor_guide/interface_design.md +++ b/mkdocs/contributor_guide/interface_design.md @@ -306,3 +306,32 @@ each function call. What we are allowed to do is the following: 3. Add additional non-pure virtual APIs below the current set of virtual APIs (should avoid this). 4. Add additional fields to a settings `struct` that is passed by reference. + +## Interface Independence Principle + +Interfaces should not be designed to have a relationship with each other +outside of an IS-A or inheritance relationship. An allowable relationship is +one where an interface inherits from another, such as `hal::advanced_can` +inheriting from `hal::can` because it has all the same requirements and some +additional ones. + +An example of a relationship that is not acceptable would be if there existed a +`wifi` interface and a network `socket` interface. Technically, there is a +relationship between these two interfaces. One could even consider that +the wifi interface could be a "producer" or "provider" of sockets once a wifi +connection is established. An API from the `wifi` interface could be added that +returns a reference to an available `socket`. This couples `socket` to `wifi` +and complicates the implementation of wifi, ensuring that sockets can be +returned. The memory and lifetime of that socket then becomes a concern of +`wifi` as well as any of its users. Overall, this results in more complex code +and more coupling than necessary. A better option is to keep everything +independent from each other. + +To follow this rule, refrain from: + +1. Returning an interface from a function in any way +2. Taking another interface as an input parameter + +Instead, if there needs to be some sort of relationship between interfaces, +then this type of relationship should be managed by concrete classes that can +take dependent objects with a relationship and manage that relationship. diff --git a/mkdocs/contributor_guide/style.md b/mkdocs/contributor_guide/style.md index b62cafef..44103cf9 100644 --- a/mkdocs/contributor_guide/style.md +++ b/mkdocs/contributor_guide/style.md @@ -29,7 +29,7 @@ Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines). - Every file must end with a newline character. - Every line in a file must stay within a 80 character limit. - Exceptions to this rule are allowed. Use `// NOLINT` in these cases. -- Radix for bit manipulation: +- Allowed number radix's for bit manipulation: - Only use binary (`0b1000'0011`) or hex (`0x0FF0`) for bit manipulation. - Never use decimal or octal as this is harder to reason about for most programmers. @@ -322,3 +322,36 @@ Here is an example of how this should look: **Exception:** `boost.ut` must ALWAYS be the last include in the code in order to allow `ostream` `operator<<` overloading to work. + +## S.15 Classes + +### S.15.1 Declaration Order + +A class's visibility specifiers and member sections should appear in the +following order: + +1. Public +2. Protected +3. Private + +Omit any sections that would be empty. + +Within each section, group similar declarations together and follow this order: + +1. Types and type aliases: + - Using directives (`using`) + - Enum classes + - Nested structs and classes + - Friend classes and structs +2. Static constants +3. Factory functions (if applicable) +4. Constructors and assignment operators +5. Destructor +6. All other member functions (static and non-static member functions, as well + as friend functions) +7. All other data members (static and non-static) + +Do not put large method definitions inline within the class definition. +Typically, only trivial or performance-critical methods that are very short may +be defined inline. If the class is a template, then all functions must be +defined inline in the header file.