1.. ## Copyright (c) 2017-2021, Lawrence Livermore National Security, LLC and
2.. ## other Axom Project Developers. See the top-level LICENSE file for details.
3.. ##
4.. ## SPDX-License-Identifier: (BSD-3-Clause)
5
6.. _headerguide-label:
7
8=====================================
94 Header File Organization
10=====================================
11
12The goal of these guidelines is to make it easy to find essential information
13in header files easily and quickly. Header files define software interfaces so
14consistently-applied conventions for file organization can significantly
15improve user understanding and developer productivity.
16
17---------------------------------------------------------
18All header file contents should be related
19---------------------------------------------------------
20
214.1 A header file **may** contain multiple type definitions (e.g., structs,
22classes, enums, etc.). However, type definitions and function declarations in
23a header file **must** be related closely and/or support the primary type for
24which the file is named.
25
264.2 A "typedef" statement, when used, **should** appear in the header file
27where the type is defined.
28
29      This practice helps ensure that all names associated with a given type
30      are available when the appropriate header file is used and eliminates
31      potentially inconsistent type names.
32
33
34-----------------------------------------------------------------------
35Include in a header file only what's needed to compile it
36-----------------------------------------------------------------------
37
384.3 A header file **must** be self-contained and self-sufficient.
39
40    Specifically, each header file
41
42      * **Must** have proper header file include guards
43        (see :ref:`headerlayout-label`) to prevent multiple inclusion. The
44        macro symbol name for each guard must be chosen to guarantee uniqueness
45        within *every* compilation unit in which it appears.
46      * **Must** include all other headers and/or forward declarations it
47        needs to be compiled standalone. In addition, a file **should not**
48        rely on symbols defined in other header files it includes; the
49        other files **should** be included explicitly.
50      * **Must** contain implementations of all generic templates and inline
51        methods defined in it. A compiler will require the full definitions of
52        these constructs to be seen in every source file that uses them.
53
54.. note:: Function templates or class template members whose implementations
55          are fully specialized with all template arguments **must** be
56          defined in an associated source file to avoid linker errors
57          (e.g., multiply-defined symbols). Fully specialized templates
58          *are not* templates and are treated just like regular functions.
59
604.4 Extraneous header files or forward declarations (i.e., those not
61required for standalone compilation) **must not** be included in header files.
62
63      Spurious header file inclusions, in particular, introduce spurious file
64      dependencies, which can increase compilation time unnecessarily.
65
66
67---------------------------------------------------------
68Use forward declarations when you can
69---------------------------------------------------------
70
714.5 Header files **should** use forward declarations instead of header file
72inclusions when possible. This may speed up compilation, especially when
73recompiling after header file changes.
74
75.. note:: **Exceptions to this guideline:**
76
77    * Header files that define external APIs for the Axom
78      project **must** include all header files for all types that
79      appear in the API. This makes use of the API much easier.
80
81    * When using a function, such as an inline method or template, that
82      is implemented in a header file, the header file containing the
83      implementation **must** be included.
84
85    * When using C++ standard library types in a header file, it **may** be
86      preferable to include the actual headers rather than forward reference
87      headers, such as 'iosfwd', to make the header file easier to use. This
88      prevents users from having to explicitly include standard headers
89      wherever your header file is used.
90
914.6 A forward type declaration **must** be used in a header file when an
92include statement would result in a circular dependency among header files.
93
94.. note:: Forward references, or C++ standard 'fwd' headers, are preferred
95          over header file inclusions when they are sufficient.
96
97
98.. _headerincludeorder-label:
99
100---------------------------------------------------------
101Organize header file contents for easy understanding
102---------------------------------------------------------
103
1044.7 Header file include statements **should** use the same ordering pattern
105for all files.
106
107      This improves code readability, helps to avoid misunderstood
108      dependencies, and insures successful compilation regardless of
109      dependencies in other files. A common, recommended header file
110      inclusion ordering scheme is (only some of these may be needed):
111
112      #. Headers in the same Axom component
113      #. Other headers within the project
114      #. TPL headers; e.g., MPI, OpenMP, HDF5, etc.
115      #. C++ and C standard library headers
116      #. System headers
117
118      Also, code is easier to understand when include files are ordered
119      alphabetically within each of these sections and a blank line is
120      inserted between sections. Adding comments that describe the
121      header file categories can be helpful as well.  For example,
122
123.. code-block:: cpp
124
125         // Headers from this component
126         #include "OtherClassInThisComponent.hpp"
127
128         // "other" component headers
129         #include "other/SomeOtherClass.hpp"
130
131         // C standard library
132         #include <stdio.h>
133
134         // C++ standard library
135         #include <unordered_map>
136         #include <vector>
137
138         // Non-std system header
139         #include <unistd.h>
140
141.. note:: Ideally, header file inclusion ordering should not matter.
142          Inevitably, this will not always be the case. Following the
143          ordering prescription above helps to avoid problems when others'
144          header files are not constructed following best practices.
145
146
1474.8 Routines **should** be ordered and grouped in a header file so that
148code readability and understanding are enhanced.
149
150      For example, all related methods should be grouped together. Also,
151      public methods, which are part of an interface, should appear before
152      private methods.
153
154
155---------------------------------------------------------
156All function arguments should have names
157---------------------------------------------------------
158
1594.9 The name of each function argument **must** be specified in a header
160file declaration. Also, names in function declarations and definitions
161**must** match.
162
163       For example, this is not an acceptable function declaration::
164
165          void doSomething(int, int, int);
166
167       Without argument names, the only way to tell what the arguments mean is
168       to look at the implementation or hope that the method is documented
169       well.
170
171
172.. _headerlayout-label:
173
174---------------------------------------------------------
175Header file layout details
176---------------------------------------------------------
177
178Content **must** be organized consistently in all header files.
179This section summarizes the recommended header file layout using numbers
180and text to illustrate the basic structure. Details about individual items
181are contained in the guidelines after the summary.
182
183.. code-block:: cpp
184
185   // (1) Axom copyright and release statement
186
187   // (2) Doxygen file prologue
188
189   // (3a) Header file include guard, e.g.,
190   #ifndef MYCLASS_HPP
191   #define MYCLASS_HPP
192
193   // (4) Header file inclusions (when NEEDED in lieu of forward declarations)
194   #include "myHeader.hpp"
195
196   // (5) Forward declarations NEEDED in header file (outside of project namespace)
197   class ForwardDeclaredClass;
198
199   // (6a) Axom project namespace declaration
200   namespace axom {
201
202   // (7a) Internal namespace (if used); e.g.,
203   namespace awesome {
204
205   // (8) Forward declarations NEEDED in header file (in project namespace(s))
206   class AnotherForwardDeclaredClass;
207
208   // (9) Type definitions (class, enum, etc.) with Doxygen comments e.g.,
209   /*!
210    * \brief Brief ...summary comment text...
211    *
212    * ...detailed comment text...
213    */
214   class MyClass {
215      int m_classMember;
216   };
217
218   // (7b) Internal namespace closing brace (if needed)
219   } // awesome namespace closing brace
220
221   // (6b) Project namespace closing brace
222   } // axom namespace closing brace
223
224   // (3b) Header file include guard closing endif */
225   #endif // closing endif for header file include guard
226
227
2284.10 **(Item 1)** Each header file **must** contain a comment section that
229includes the Axom copyright and release statement.
230
231      See :ref:`docsec-label` for details.
232
2334.11 **(Item 2)** Each header file **must** begin with a Doxygen file prologue.
234
235      See :ref:`docsec-label` for details.
236
2374.12 **(Items 3a,3b)** The contents of each header file **must** be guarded
238using a preprocessor directive that defines a unique "guard name" for the file.
239
240      The guard must appear immediately after the file prologue and use the
241      '#ifndef' directive (item 2a); this requires a closing '#endif'
242      statement at the end of the file (item 2b).
243
244      The preprocessor constant must use the file name followed by "_HPP" for
245      C++ header files; e.g., "MYCLASS_HPP" as above.
246
247      The preprocessor constant must use the file name followed by "_H" for
248      C header files.
249
2504.13 **(Item 4)** All necessary header file inclusion statements **must**
251appear immediately after copyright and release statement and before any
252forward declarations, type definitions, etc.
253
2544.14 **(Item 5)** Any necessary forward declarations for types defined outside
255the project namespace **must** appear after the header include statements
256and before the Axom project namespace statement.
257
2584.15 **(Items 6a, 6b, 7a, 7b)** All types defined and methods defined in a
259header file **must** be included in a namespace.
260
261      Either the project "axom" namespace (item 6a) or a namespace
262      nested within the project namespace (item 7a) may be used, or
263      both may be used. A closing brace ( "}" ) is required to close each
264      namespace declaration (items 6b and 7b) before the closing '#endif'
265      for the header file include guard.
266
2674.16 **(Item 8)** Forward declarations needed **must** appear in the
268appropriate  namespace before any other statements (item 8).
269
2704.17 **(Item 9)** All class and other type definitions **must** appear
271after header file inclusions and forward declarations. A proper class
272prologue **must** appear before the class definition. See :ref:`docsec-label`
273for details.
274