ListPolicy.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2019-2025 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 Namespace
27  Foam::ListPolicy
28 
29 Description
30  Additional compile-time controls of List behaviour
31 
32 \*---------------------------------------------------------------------------*/
33 
34 #ifndef Foam_ListPolicy_H
35 #define Foam_ListPolicy_H
36 
37 #include "contiguous.H" // Also includes <type_traits>
38 
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 
41 namespace Foam
42 {
43 
44 // Forward Declarations
45 class keyType;
46 class word;
47 class wordRe;
48 
49 namespace ListPolicy
50 {
51 
52 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
53 
54 //- Number of items before requiring line-breaks in the list output.
55 //
56 // Default definition: 10
57 template<class T>
58 struct short_length : std::integral_constant<int,10> {};
59 
60 // Can override on a per-type basis
61 // Eg,
62 // template<> struct short_length<label> : std::integral_constant<int,20> {};
63 
64 
65 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
66 
67 //- Can suppress additional line breaks separate ASCII data content
68 //- when the data elements are primitives, or contiguous
69 //
70 // Default definition: (integral | floating-point) are contiguous and thus
71 // never need any line breaks
72 template<class T>
73 struct no_linebreak : std::is_arithmetic<std::remove_cv_t<T>> {};
74 
75 // Specialization for word-like classes
76 // These elements are normally fairly short, so ok to output a few (eg, 10)
77 // of them on a single line.
78 
79 //- Suppress line-breaks for keyType
80 template<> struct no_linebreak<keyType> : std::true_type {};
81 
82 //- Suppress line-breaks for word
83 template<> struct no_linebreak<word> : std::true_type {};
84 
85 //- Suppress line-breaks for wordRe
86 template<> struct no_linebreak<wordRe> : std::true_type {};
87 
88 
89 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
90 //
91 // Memory allocation/deallocation handling - primarily used by List and Matrix
92 //
93 // - is_aligned_type() :
94 // Defines which types may be aligned
95 //
96 // - use_alignment(n) :
97 // Lower threshold for using memory alignment
98 //
99 // - use_memory_pool(n) :
100 // Lower threshold for using a memory pool.
101 // Must be larger than use_alignment() value.
102 //
103 // - use_offload(n) :
104 // Lower threshold for switching to device offloading
105 //
106 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
107 
108 //- Consider aligned allocation for the given type?
109 // Benefits for field data (floating-point, ints, vectorspace),
110 // but avoid for char data, strings, pointers etc
111 template<class T>
112 inline constexpr bool is_aligned_type() noexcept
113 {
114  return
115  (
116  !std::is_enum_v<T>
117  && !std::is_pointer_v<T>
118  && !std::is_union_v<T>
119  && (sizeof(T) >= 4) // skip small data (eg, char)
120  && is_contiguous_v<T>
121  );
122 }
123 
124 
125 //- True if size exceeds the min-size for using memory alignment
126 template<class IntType>
127 inline constexpr bool use_alignment(IntType n) noexcept
128 {
129  return (n >= IntType(200));
130 }
131 
132 
133 //- True if size exceeds the min-size for using the memory pool
134 template<class IntType>
135 inline constexpr bool use_memory_pool(IntType n) noexcept
136 {
137  return (n >= IntType(3000));
138 }
139 
140 
141 //- True if size exceeds the min-size for offloading
142 template<class IntType>
143 inline constexpr bool use_offload(IntType n) noexcept
144 {
145  return (n >= IntType(1000));
146 }
147 
149 template<class T, class IntType>
150 inline T* allocate(IntType n)
151 {
152  // Plain new
153  return new T[n];
154 }
155 
156 
157 template<class T, class IntType>
158 inline void deallocate(T* ptr)
159 {
160  // Plain new
161  delete[] ptr;
162 }
163 
164 
165 template<class T, class IntType>
166 inline void deallocate(T* ptr, [[maybe_unused]] IntType n)
167 {
168  // Plain new
169  delete[] ptr;
170 }
171 
172 
173 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
174 
175 //- Calculate a reserve size (eg, doubling) based on the requested length
176 //- and the current capacity
177 template<int SizeMin, int Numerator, class IntType>
178 inline IntType reserve_size(IntType requested, IntType capacity) noexcept
179 {
180  static_assert(Numerator > 1, "Invalid numerator");
182  // The caller already checks this:
183  // if (requested < capacity) { return capacity; }
184 
185  IntType size(capacity*Numerator);
186  if (size < requested)
187  {
188  size = requested;
189  }
190  if constexpr (SizeMin > 0) // The min size is optional
191  {
192  if (size < SizeMin)
193  {
194  size = SizeMin;
195  }
196  }
197  return size;
198 }
199 
200 
201 //- Calculate a reserve size based on the requested length
202 //- and the current capacity
203 template<int SizeMin, int Numerator, int Denominator, class IntType>
204 inline IntType reserve_size(IntType requested, IntType capacity) noexcept
205 {
206  static_assert(Numerator > Denominator, "Invalid numerator");
207  static_assert(Denominator > 0, "Invalid denominator");
208 
209  // The caller already checks this:
210  // if (requested < capacity) { return capacity; }
211 
212  // Very unlikely that capacity is less than Denominator,
213  // so divide before multiply to avoid overflow
214  IntType size((capacity/Denominator)*Numerator);
215  if (size < requested)
216  {
217  size = requested;
218  }
219  if constexpr (SizeMin > 0) // The min size is optional
220  {
221  if (size < SizeMin)
222  {
223  size = SizeMin;
224  }
225  }
226  return size;
227 }
228 
229 
230 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
231 
232 //- Classification of list/container uniformity.
233 //- The values can be used with bit-wise \c or reduction
234 enum uniformity : unsigned char
235 {
236  EMPTY = 0,
237  UNIFORM = 0x1,
238  NONUNIFORM = 0x2,
239  MIXED = 0x3
240 };
241 
242 //- Algorithm to determine list/container uniformity
243 template<class InputIt>
244 enum uniformity check_uniformity(InputIt first, InputIt last)
245 {
246  if (first == last) return uniformity::EMPTY;
247 
248  // Like std::all_of() with checking against element 0,
249  // but without using a lambda with auto type (pre C++14) etc.
250 
251  const auto& elem0 = *first;
252 
253  for ((void)++first; (first != last); (void)++first)
254  {
255  if (elem0 != *first)
256  {
258  }
259  }
261  return uniformity::UNIFORM;
262 }
263 
264 
265 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
266 
267 } // End namespace ListPolicy
268 } // End namespace Foam
269 
270 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
271 
272 #endif
273 
274 // ************************************************************************* //
A class for handling keywords in dictionaries.
Definition: keyType.H:66
constexpr bool use_memory_pool(IntType n) noexcept
True if size exceeds the min-size for using the memory pool.
Definition: ListPolicy.H:148
enum uniformity check_uniformity(InputIt first, InputIt last)
Algorithm to determine list/container uniformity.
Definition: ListPolicy.H:267
constexpr bool use_offload(IntType n) noexcept
True if size exceeds the min-size for offloading.
Definition: ListPolicy.H:158
T * allocate(IntType n)
Definition: ListPolicy.H:165
IntType reserve_size(IntType requested, IntType capacity) noexcept
Calculate a reserve size (eg, doubling) based on the requested length and the current capacity...
Definition: ListPolicy.H:195
constexpr bool use_alignment(IntType n) noexcept
True if size exceeds the min-size for using memory alignment.
Definition: ListPolicy.H:138
A class for handling words, derived from Foam::string.
Definition: word.H:63
void deallocate(T *ptr)
Definition: ListPolicy.H:173
Container (non-empty) with identical values.
Definition: ListPolicy.H:258
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings...
Definition: wordRe.H:78
Container (non-empty) with different values.
Definition: ListPolicy.H:259
const direction noexcept
Definition: scalarImpl.H:255
constexpr bool is_aligned_type() noexcept
Consider aligned allocation for the given type?
Definition: ListPolicy.H:121
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
An empty container.
Definition: ListPolicy.H:257
label n
Mixed uniform/non-uniform (eg, after reduction)
Definition: ListPolicy.H:260
Number of items before requiring line-breaks in the list output.
Definition: ListPolicy.H:55
uniformity
Classification of list/container uniformity. The values can be used with bit-wise or reduction...
Definition: ListPolicy.H:255
Namespace for OpenFOAM.
Can suppress additional line breaks separate ASCII data content when the data elements are primitives...
Definition: ListPolicy.H:73