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.. _scopesec-label:
7
8=====================================
96 Scope
10=====================================
11
12---------------------------------------------------------
13Use namespaces to avoid name collisions
14---------------------------------------------------------
15
166.1 All Axom code **must** be included in the project namespace
17'axom'; e.g.,::
18
19         namespace axom {
20              // . . .
21         }
22
23.. note::We will change the top-level namespace at some point to shorten it.
24
256.2 Each Axom component **must** define its own unique namespace within
26the "axom" namespace. All contents of each component **must** reside
27within that namespace.
28
29
30---------------------------------------------------------
31Use namespaces to hide non-API code in header files
32---------------------------------------------------------
33
346.3 Code that must be appear in header files (e.g., templates) that is not
35intended to be part of a public interface, such as helper classes/structs
36and methods, **should** be placed in an internal namespace.
37
38      Common names for such namespaces include 'internal' (for implementations
39      used only internally) and 'detailed' (for types, etc. used only
40      internally). Any reasonable choice is acceptable; however, the choice
41      **must** be the same within each Axom component.
42
43      Note that declaring helper classes/structs private within a class
44      definition is another good option. See :ref:`scopenestedclass-label`
45      for details.
46
47
48---------------------------------------------------------
49Use 'unnamed' namespace for hiding code in source files
50---------------------------------------------------------
51
526.4 Classes/structs and methods that are meant to be used only internally to a
53single source file **should** be placed in the 'unnamed' namespace to make
54them invisible outside the file.
55
56      This guarantees link-time name conflicts will not occur. For example::
57
58         namespace {
59            void myInternalFunction();
60         }
61
62
63---------------------------------------------------------
64Apply the 'using directive' carefully
65---------------------------------------------------------
66
676.5 The 'using directive' **must not** be used in any header file.
68
69      Applying this directive in a header file leverages a bad decision to
70      circumvent the namespace across every file that directly or indirectly
71      includes that header file.
72
73.. note:: This guideline implies that each type name appearing in a header
74          file **must be fully-qualified** (i.e., using the namespace
75          identifier and scope operator) if it resides in a different
76          namespace than the contents of the file.
77
786.6 The 'using directive' **may** be used in a source file to avoid using a
79fully-qualified type name at each declaration. Using directives **must** appear
80after all "#include" directives in a source file.
81
826.7 When only parts of a namespace are used in an implementation file, only
83those parts **should** be included with a using directive instead of the
84entire namespace contents.
85
86      For example, if you only need the standard library vector container form
87      the "std" namespace, it is preferable to use::
88
89         using std::vector;
90
91      rather than::
92
93         using namespace std;
94
95
96---------------------------------------------------------
97Use access qualifiers to control class interfaces
98---------------------------------------------------------
99
1006.8 Class members **must** be declared in the following order:
101
102      #. "public"
103      #. "protected"
104      #. "private"
105
106      That is, order members using these access qualifiers in terms of
107      "decreasing scope of visibility".
108
109.. note:: Declaring methods before data members is preferred because methods
110           are more commonly considered part of a class interface. Also,
111           separating methods and data into their own access qualified
112           sections usually helps make a class definition clearer.
113
1146.9 Class data members **should** be "private". The choice to use "public"
115or "protected" data members **must** be scrutinized by other team members.
116
117      Information hiding is an essential part of good software engineering
118      and private data is the best means for a class to preserve its
119      invariants. Specifically, a class should maintain control of how object
120      state can be modified to minimize side effects. In addition, restricting
121      direct access to class data enforces encapsulation and facilitates
122      design changes through refactoring.
123
124
125---------------------------------------------------------
126Use 'friend' and 'static' rarely
127---------------------------------------------------------
128
1296.10 "Friend" declarations **should** be used rarely. When used, they
130**must** appear within the body of a class definition before any class
131member declarations. This helps make the friend relationship obvious.
132
133      Note that placing "friend" declarations before the "public:" keyword
134      makes them private, which preserves encapsulation.
135
1366.11 Static class members (methods or data) **must** be used rarely. In
137every case, their usage **should** be carefully reviewed by the team.
138
139      When it is determined that a static member is needed, it **must** appear
140      first in the appropriate member section. Typically, static member
141      functions **should** be "public" and static data members **should** be
142      "private".
143
144
145.. _scopenestedclass-label:
146
147---------------------------------------------------------
148Hide nested classes when possible
149---------------------------------------------------------
150
1516.12 Nested classes **should** be private unless they are part of the
152enclosing class interface.
153
154      For example::
155
156         class Outer
157         {
158            // ...
159         private:
160            class Inner
161            {
162               // ...
163            };
164         };
165
166      When only the enclosing class uses a nested class, making it private
167      does not pollute the enclosing scope needlessly. Furthermore, nested
168      classes may be forward declared within the enclosing class definition
169      and then defined in the implementation file of the enclosing class.
170      For example::
171
172         class Outer
173         {
174            class Inner; // forward declaration
175
176            // use name 'Inner' in Outer class definition
177         };
178
179         // In Outer.cpp implementation file...
180         class Outer::Inner
181         {
182            // Inner class definition
183         }
184
185      This makes it clear that the nested class is only needed in the
186      implementation and does not clutter the class definition.
187
188
189---------------------------------------------------------
190Limit scope of local variables
191---------------------------------------------------------
192
1936.13 Local variables **should** be declared in the narrowest scope possible
194and as close to first use as possible.
195
196      Minimizing variable scope makes source code easier to comprehend and
197      may have performance and other benefits. For example, declaring a loop
198      index inside a for-loop statement such as::
199
200         for (int ii = 0; ...) {
201
202      is preferable to::
203
204         int ii;
205         ...
206         for (ii = 0; ...) {
207
208      Beyond readability, this rule has benefits for thread safety, etc.
209
210.. note:: **Exception:** When a local variable is an object, its constructor
211          and destructor may be invoked every time a scope (such as a loop)
212          is entered and exited, respectively.
213
214      Thus, instead of this::
215
216         for (int ii = 0; ii < 1000000; ++ii) {
217            Foo f;
218            f.doSomethingCool(ii);
219         }
220
221      it may be more efficient to do this::
222
223         Foo f;
224         for (int ii = 0; ii < 1000000; ++ii) {
225            f.doSomethingCool(ii);
226         }
227
2286.14 A local reference to any item in the global namespace (which should be
229rare if needed at all) **should** use the scope operator ("::") to make
230the fact that it resides in the global namespace clear.
231
232      For example::
233
234         int local_val = ::global_val;
235