Skip to content

Commit 2b85876

Browse files
authored
CXX-3061 Move coding guidelines into a separate document (#1168)
* "lifecycle methods" -> "special member functions" * Defer header include order to ClangFormat rules
1 parent 7d3f378 commit 2b85876

File tree

2 files changed

+174
-176
lines changed

2 files changed

+174
-176
lines changed

CONTRIBUTING.md

+28-176
Original file line numberDiff line numberDiff line change
@@ -1,199 +1,51 @@
11
# Contributing Guidelines
22

3-
When contributing code, in addition to following the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines), please follow the same
4-
[design guidelines](https://github.com/mongodb/mongo/wiki/Server-Design-Guidelines)
5-
and [style guidelines](https://github.com/mongodb/mongo/wiki/Style-Guidelines)
6-
as [mongodb/mongo.](https://github.com/mongodb/mongo) Additions and exceptions are listed
7-
below.
3+
Follow the [MongoDB C++ Driver Coding Guidelines](https://github.com/mongodb/mongo-cxx-driver/etc/coding_guidelines.md), ensure files are formatted properly, and follow guidelines for writing PR titles and commit messages.
84

9-
For anything that isn't explicitly covered here, default to the
10-
[Google C++ Style Guide.](https://google.github.io/styleguide/cppguide.html#Scoping)
11-
Running [clang-format](https://clang.llvm.org/docs/ClangFormat.html) with our
12-
configuration file,
13-
[mongo-cxx-driver/.clang-format](https://github.com/mongodb/mongo-cxx-driver/blob/master/.clang-format),
14-
will help ensure your code conforms to these standards.
5+
All contributions must be made via a GitHub pull request (PR).
156

16-
### Commit Messages
7+
## Commit Messages
178

18-
If a pull-request addresses a JIRA ticket, for a single-commit PR, prefix
19-
the subject line with the ticket ID. (For a multi-commit PR, we will add
20-
the ID later when we squash or merge it.)
9+
Prefix the PR title with the relevant JIRA ticket number when applicable. When multiple JIRA tickets are related, they may be suffixed to the title or mentioned within the commit message instead.
2110

22-
> CXX-883 Add commit message conventions to CONTRIBUTING.md
11+
Examples include:
2312

24-
Capitalize subject lines and don't use a trailing period. Keep the subject
25-
at most 70 characters long. Use active voice! Imagine this preamble to get
26-
your phrasing right:
27-
28-
> _If applied, this commit will..._ [your subject line]
29-
30-
See Chris Beams'
31-
[How to write a git commit message](http://chris.beams.io/posts/git-commit/)
32-
for more good guidelines to follow.
33-
34-
### Lifecycle Methods
35-
36-
- default-or-argument-bearing 'user' constructors
37-
38-
- declaration-or-deletion-of-move-constructor
39-
- declaration-or-deletion-of-move-assignment-operator
40-
41-
- declaration-or-deletion-of-copy-constructor
42-
- declaration-or-deletion-of-copy-assignment-operator
43-
44-
- declaration-of-dtor
45-
46-
### Headers
47-
48-
Public headers must have a ".hpp" suffix. Private headers must have a ".hh"
49-
suffix.
50-
51-
General structure:
52-
53-
- License
54-
- Include Guard (`#pragma once`)
55-
- Header Prelude
56-
- System Headers `<vector>` (alphabetical order)
57-
- Driver Headers `<path/to/header.hpp>` (alphabetical order)
58-
- Open Namespace mongocxx
59-
- `inline namespace v_noabi {`
60-
- Code
61-
- `} // namespace v_noabi`
62-
- Close Namespace mongocxx
63-
- Header Postlude
64-
65-
Example:
66-
67-
```{.cpp}
68-
// Copyright 2009-present MongoDB, Inc.
69-
//
70-
// Licensed under the Apache License, Version 2.0 (the "License");
71-
// you may not use this file except in compliance with the License.
72-
// You may obtain a copy of the License at
73-
//
74-
// http://www.apache.org/licenses/LICENSE-2.0
75-
//
76-
// Unless required by applicable law or agreed to in writing, software
77-
// distributed under the License is distributed on an "AS IS" BASIS,
78-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79-
// See the License for the specific language governing permissions and
80-
// limitations under the License.
81-
82-
#pragma once
83-
84-
#include <driver/config/prelude.hpp>
85-
86-
#include <vector>
87-
88-
#include <driver/blah.hpp>
89-
90-
namespace mongocxx {
91-
inline namespace v_noabi {
92-
93-
// Declarations
94-
95-
// Inline Implementations
96-
97-
} // namespace v_noabi
98-
} // namespace mongocxx
99-
100-
#include <driver/config/postlude.hpp>
10113
```
102-
103-
### Library Root Namespace
104-
105-
The library root namespace declares ABI namespaces (e.g. `mongocxx::v_noabi`, `mongocxx::v1`, etc.), within which symbols are declared according to their compatibility with an ABI version.
106-
107-
The library root namespace also redeclares ABI-specific entities without an ABI namespace qualifier (e.g. `mongocxx::v_noabi::document::view` as `mongocxx::document::view`) to allow users to automatically opt-into the latest supported ABI version of a given entity without requiring changes to source code. The root namespace redeclarations are intended to be the default method for using library entities. A user should only include the ABI namespace in a qualifier if they require compatibility with that specific ABI version.
108-
109-
To avoid being affected by changes to root namespace redeclarations, interfaces declared within an ABI namespace must not be written in terms of a root namespace redeclaration:
110-
111-
```cpp
112-
namespace mongocxx {
113-
namespace v_noabi {
114-
namespace example {
115-
116-
struct type {}; // The type intended to be referenced below.
117-
118-
// Problem: when `mongocxx::example::type` is changed from `v_noabi` to `v1`,
119-
// this parameter type will also (incorrectly) change from `v_noabi` to `v1`.
120-
void fn(mongocxx::example::type param);
121-
122-
} // namespace example
123-
} // namespace v_noabi
124-
} // namespace mongocxx
14+
CXX-XXXX Resolve an issue
12515
```
12616

127-
References to ABI-specific entities in ABI namespaces must always be (un)qualified such that it is not affected by changes to root namespace redeclarations:
128-
129-
```cpp
130-
namespace mongocxx {
131-
namespace v_noabi {
132-
namespace example {
133-
134-
struct type {}; // The type intended to be referenced below.
135-
136-
// OK: always resolves to `mongocxx::v_noabi::example::type`.
137-
void fn(type param);
138-
139-
// Also OK: unambiguously refers to the ABI-specific type.
140-
void fn(mongocxx::v_noabi::example::type param);
141-
142-
} // namespace example
143-
} // namespace v_noabi
144-
} // namespace mongocxx
14517
```
18+
Fix several related issues (CXX-AAAA, CXX-BBBB)
14619
147-
### Class Declarations
148-
149-
Guidelines:
150-
151-
- Blank line at beginning and end of class declaration
152-
- Public section up top / private at bottom
153-
- Lifecycle methods first (see rules above)
154-
- Private Member Ordering
155-
- Friendships
156-
- Private Constructors
157-
- Private Methods
158-
- Private Variables
159-
160-
Example:
161-
162-
```{.cpp}
163-
class foo {
164-
165-
public:
166-
foo();
167-
168-
foo(foo&& other) noexcept;
169-
foo& operator=(foo&& other) noexcept;
170-
171-
~foo();
172-
173-
private:
174-
friend baz;
175-
176-
class MONGOCXX_PRIVATE impl;
177-
std::unique_ptr<impl> _impl;
20+
* Commit A description
21+
* Commit B description
22+
* Commit C description
23+
```
17824

179-
};
18025
```
26+
CXX-XXXX Implement a feature resolving several related issues
18127
182-
### Inlines
28+
* CXX-AAAA Commit A description
29+
* CXX-BBBB Commit B description
30+
* Additional commit description
31+
```
18332

184-
- Define outside of class declaration
185-
- Specify inline keyword in declaration and definition (for clarity)
33+
Refer to Chris Beams' guidelines for
34+
[How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/).
18635

187-
### Relational Operators
36+
## Formatting
18837

189-
- Prefer to use free functions
38+
Format files with [ClangFormat](https://clang.llvm.org/docs/ClangFormat.html) using the [etc/clang_format.py](https://github.com/mongodb/mongo-cxx-driver/blob/master/etc/clang_format.py) script.
19039

191-
### Formatting
40+
The script must be run in the project root directory to ensure the [.clang-format](https://github.com/mongodb/mongo-cxx-driver/blob/master/.clang-format) configuration file is used properly.
19241

193-
The source includes a clang format definitions file (`.clang-format`) to enforce consistent style. Run clang-format (using 3.8) from the root of the repository or use the helper script included in the source:
42+
```bash
43+
# Allow the script to download the correct ClangFormat release version.
44+
python2 ./etc/clang-format.py format
19445

195-
```
196-
python ./etc/clang-format.py format
46+
# Provide a path to an existing ClangFormat binary to use instead.
47+
MONGO_CLANG_FORMAT="path/to/clang-format" python2 ./etc/clang-format.py format
19748
```
19849

199-
Note, this script will automatically download clang-format 3.8 if it cannot detect it on your system.
50+
> [!NOTE]
51+
> ClangFormat results may differ across release versions. When using a preinstalled ClangFormat binary, its version must be consistent with the `CLANG_FORMAT_VERSION` variable defined in the `etc/clang_format.py` script.

etc/coding_guidelines.md

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# MongoDB C++ Driver Coding Guidelines
2+
3+
For topics and situations not explicitly documented here, refer to the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines).
4+
5+
## Headers
6+
7+
Public headers must have a ".hpp" suffix. Private headers must have a ".hh"
8+
suffix.
9+
10+
General structure:
11+
12+
- License
13+
- Include Guard (`#pragma once`)
14+
- Include Directives
15+
- Open Namespace mongocxx
16+
- `inline namespace v_noabi {`
17+
- Code
18+
- `} // namespace v_noabi`
19+
- Close Namespace mongocxx
20+
- Header Postlude
21+
22+
Example:
23+
24+
```{.cpp}
25+
// Copyright 2009-present MongoDB, Inc.
26+
//
27+
// Licensed under the Apache License, Version 2.0 (the "License");
28+
// you may not use this file except in compliance with the License.
29+
// You may obtain a copy of the License at
30+
//
31+
// http://www.apache.org/licenses/LICENSE-2.0
32+
//
33+
// Unless required by applicable law or agreed to in writing, software
34+
// distributed under the License is distributed on an "AS IS" BASIS,
35+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36+
// See the License for the specific language governing permissions and
37+
// limitations under the License.
38+
39+
#pragma once
40+
41+
#include <driver/config/prelude.hpp>
42+
43+
#include <vector>
44+
45+
#include <driver/blah.hpp>
46+
47+
namespace mongocxx {
48+
inline namespace v_noabi {
49+
50+
// Declarations
51+
52+
// Inline Implementations
53+
54+
} // namespace v_noabi
55+
} // namespace mongocxx
56+
57+
#include <driver/config/postlude.hpp>
58+
```
59+
60+
## Library Root Namespace
61+
62+
The library root namespace declares ABI namespaces (e.g. `mongocxx::v_noabi`, `mongocxx::v1`, etc.), within which symbols are declared according to their compatibility with an ABI version.
63+
64+
The library root namespace also redeclares ABI-specific entities without an ABI namespace qualifier (e.g. `mongocxx::v_noabi::document::view` as `mongocxx::document::view`) to allow users to automatically opt-into the latest supported ABI version of a given entity without requiring changes to source code. The root namespace redeclarations are intended to be the default method for using library entities. A user should only include the ABI namespace in a qualifier if they require compatibility with that specific ABI version.
65+
66+
To avoid being affected by changes to root namespace redeclarations, interfaces declared within an ABI namespace must not be written in terms of a root namespace redeclaration:
67+
68+
```cpp
69+
namespace mongocxx {
70+
namespace v_noabi {
71+
namespace example {
72+
73+
struct type {}; // The type intended to be referenced below.
74+
75+
// Problem: when `mongocxx::example::type` is changed from `v_noabi` to `v1`,
76+
// this parameter type will also (incorrectly) change from `v_noabi` to `v1`.
77+
void fn(mongocxx::example::type param);
78+
79+
} // namespace example
80+
} // namespace v_noabi
81+
} // namespace mongocxx
82+
```
83+
84+
References to ABI-specific entities in ABI namespaces must always be (un)qualified such that it is not affected by changes to root namespace redeclarations:
85+
86+
```cpp
87+
namespace mongocxx {
88+
namespace v_noabi {
89+
namespace example {
90+
91+
struct type {}; // The type intended to be referenced below.
92+
93+
// OK: always resolves to `mongocxx::v_noabi::example::type`.
94+
void fn(type param);
95+
96+
// Also OK: unambiguously refers to the ABI-specific type.
97+
void fn(mongocxx::v_noabi::example::type param);
98+
99+
} // namespace example
100+
} // namespace v_noabi
101+
} // namespace mongocxx
102+
```
103+
104+
## Class Declarations
105+
106+
Guidelines:
107+
108+
- Blank line at beginning and end of class declaration
109+
- Public section up top / private at bottom
110+
- Special Member Functions
111+
- Private Member Ordering
112+
- Friendships
113+
- Private Constructors
114+
- Private Methods
115+
- Private Variables
116+
117+
Example:
118+
119+
```{.cpp}
120+
class foo {
121+
122+
public:
123+
foo();
124+
125+
foo(foo&& other) noexcept;
126+
foo& operator=(foo&& other) noexcept;
127+
128+
~foo();
129+
130+
private:
131+
friend baz;
132+
133+
class MONGOCXX_PRIVATE impl;
134+
std::unique_ptr<impl> _impl;
135+
136+
};
137+
```
138+
139+
## Inlines
140+
141+
- Define outside of class declaration
142+
- Specify inline keyword in declaration and definition (for clarity)
143+
144+
## Relational Operators
145+
146+
- Prefer to use free functions

0 commit comments

Comments
 (0)