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