exprValue.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) 2021-2024 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 Class
27  Foam::expressions::exprValue
28 
29 Description
30  A polymorphic typed union of simple primitive and VectorSpace types.
31  It uses a 'fatter' representation that includes standard VectorSpace
32  types, which avoids heap allocations at the expense of more storage.
33  This is mostly not an issue since lists and fields would box/unbox
34  an entire field, not individual values.
35 
36 SourceFiles
37  exprValue.C
38  exprValueI.H
39 
40 \*---------------------------------------------------------------------------*/
41 
42 #ifndef Foam_expressions_exprValue_H
43 #define Foam_expressions_exprValue_H
44 
45 #include "exprTraits.H" // For valueTypeCode and label, scalar, vector etc.
46 #include "contiguous.H"
47 #include "InfoProxy.H"
48 #include <typeinfo>
49 
50 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
51 
52 // Execute macro for known exprValue types, with more frequent ones first
53 #undef FOR_ALL_EXPR_VALUE_TYPES
54 #define FOR_ALL_EXPR_VALUE_TYPES(Macro, ...) \
55  Macro(scalar, __VA_ARGS__) \
56  Macro(vector, __VA_ARGS__) \
57  Macro(tensor, __VA_ARGS__) \
58  Macro(symmTensor, __VA_ARGS__) \
59  Macro(sphericalTensor, __VA_ARGS__) \
60  Macro(label, __VA_ARGS__) \
61  Macro(bool, __VA_ARGS__)
62 
63 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
64 
65 namespace Foam
66 {
67 
68 // Forward Declarations
69 class ITstream;
70 
71 namespace expressions
72 {
73 namespace Detail
74 {
75 
76 /*---------------------------------------------------------------------------*\
77  Class exprValueUnion Declaration
78 \*---------------------------------------------------------------------------*/
79 
80 //- The data content (as a union).
81 // The stem of the member names correspond identically to the data types
82 // to enable macro definitions (naming similar to Foam::token)
83 union exprValueUnion
84 {
85  // Member Data
86 
87  #undef declareUnionMember
88  #define declareUnionMember(Type, UnusedParam) \
89  \
90  \
91  Type Type##Value;
92 
94  #undef declareUnionMember
95 
96 
97  // Member Functions
98 
99  //- Runtime 'assert' for unimplemented generic methods
100  // This seems to be the best way to catch programming errors
101  // since static_assert does not help here.
102  // The 'noexcept' is slightly misleading (needed for the caller)
103  static void notSpecialized(const std::string& msg) noexcept;
104 
105  //- Return read pointer to typed union member,
106  //- which is nullptr for unspecialized versions
107  template<class Type>
108  inline const Type* get() const noexcept { return nullptr; }
109 
110  //- No generic set(), only specialized methods
111  template<class Type>
112  inline void set(const Type& val) noexcept
113  {
114  notSpecialized("set<" + std::string(typeid(Type).name()) + '>');
115  }
116 };
118 
119 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
120 
121 // Type-specific get/set (definitions)
122 #undef defineMultiTypeValueUnionMethods
123 #define defineMultiTypeValueUnionMethods(Type, UnusedParam) \
124  \
125  \
126 template<> \
127 inline const Type* exprValueUnion::get<Type>() const noexcept \
128 { \
129  return &(Type##Value); \
130 } \
131  \
132  \
133 template<> \
134 inline void exprValueUnion::set<Type>(const Type& val) noexcept \
135 { \
136  Type##Value = val; \
137 }
138 
139 // Type-specific methods
141 #undef defineMultiTypeValueUnionMethods
142 
143 } // End namespace Detail
144 
145 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
146 
147 
148 /*---------------------------------------------------------------------------*\
149  Class exprValue Declaration
150 \*---------------------------------------------------------------------------*/
151 
152 class exprValue
153 {
154  // Private Data
155 
156  //- The data content (as a union)
158 
159  //- The data type (as a type-code)
161 
162 
163  // Private Member Functions
164 
165  //- Fill the data with zero, preserving the data type
166  inline void fill_zero();
167 
168  //- Copy assignment
169  void deepCopy(const exprValue& rhs);
170 
171 public:
172 
173  // Constructors
174 
175  //- Default construct (zero-initialized) as 'none'
176  inline exprValue();
177 
178  //- Copy construct (deep copy)
179  inline exprValue(const exprValue& rhs);
180 
181  //- Construct from Type. Fatal for unsupported types
182  template<class Type>
183  inline explicit exprValue(const Type& val);
184 
185 
186  // Static Methods (valueTypeCode)
187 
188  //- True if valueTypeCode is not none/invalid
189  inline static bool good
190  (
192  ) noexcept;
193 
194  //- True if valueTypeCode is bool/label
195  inline static bool is_integral
196  (
198  ) noexcept;
199 
200  //- The number of components associated with the valueTypeCode
201  inline static direction nComponents
202  (
204  ) noexcept;
205 
206  //- The vector-space rank associated with the valueTypeCode
207  inline static direction rank
208  (
210  ) noexcept;
211 
212  //- True if the specified type is supported
213  template<class Type>
214  inline static bool supportedType();
215 
216 
217  // Static Methods
218 
219  //- Detect the type from the available tokens.
220  // Possible ambiguity between label and scalar.
221  // \return INVALID for unsupported type
222  static expressions::valueTypeCode peekType(const ITstream& is);
223 
224  //- Read entire string as a exprValue,
225  //- skipping leading/trailing whitespace.
226  // \return True if successful.
227  static bool read(const std::string& str, exprValue& val);
228 
229 
230  // Member Functions
231 
232  //- The value type code
234  {
235  return typeCode_;
236  }
237 
238  //- True if the value type is not none/invalid
239  inline bool good() const noexcept;
240 
241  //- True if the value type is an integral (bool or label)
242  inline bool is_integral() const noexcept;
243 
244  //- The number of components associated with the value type
245  inline direction nComponents() const noexcept;
246 
247  //- The vector-space rank associated with the value type
248  inline direction rank() const noexcept;
249 
250  //- The name for the value type. Similar to pTraits typeName
251  inline word valueTypeName() const;
252 
253  //- The name for the compound token (for a List of values).
254  //- Eg, \c List<scalar>, \c List<vector> ...
255  inline word listCompoundName() const;
256 
257  //- Reset to 'none'
258  void clear();
259 
260  //- Read read tokens (if possible)
261  // \return True on success
262  bool read(Istream& is);
263 
264  //- Guess type and read tokens (if possible)
265  // \return True on success
266  bool readTokens(ITstream& is);
267 
268  //- Compare (type,value)
269  int compare(const exprValue& rhs) const;
271 
272  // Typed Access
273 
274  //- Return non-null pointer to the data element (if types match).
275  //- Can also be tested as a bool.
276  template<class Type>
277  inline const Type* isA() const noexcept;
278 
279  //- Assign from type.
280  //- Returns false and sets to 'none' for unsupported types
281  template<class Type>
282  inline bool set(const Type& val);
283 
284  //- Return the value. Return pTraits zero if the types mismatch
285  template<class Type>
286  inline const Type& get() const;
287 
288 
289  // Type-specific methods, operators
290 
291  #undef defineUnionMethods
292  #define defineUnionMethods(Type, UnusedParam) \
293  \
294  \
295  bool is_##Type() const noexcept \
296  { \
297  return (typeCode_ == exprTypeTraits<Type>::value); \
298  } \
299  \
300  \
301  void operator=(const Type& val) { this->set<Type>(val); }
302 
304  #undef defineUnionMethods
305 
306 
307  //- Copy assignment
308  void operator=(const exprValue& rhs) { deepCopy(rhs); }
309 
310  //- Assign from zero. Changes value but not type
311  void operator=(const Foam::zero) { fill_zero(); }
312 
313 
314  // Low-level access
315 
316  //- Pointer to the data content as byte data
317  const char* cdata_bytes() const noexcept
318  {
319  return reinterpret_cast<const char*>(this);
320  }
321 
322  //- Pointer to the data content as byte data
323  char* data_bytes() noexcept
324  {
325  return reinterpret_cast<char*>(this);
326  }
327 
328  //- Size of the (contiguous) data content as byte data
329  //- is compile-time constant
330  static constexpr unsigned size_bytes() noexcept
331  {
332  return sizeof(exprValue);
333  }
334 
335 
336  // Member Functions
337 
338  //- Compare (type,value) for equality
339  bool operator==(const exprValue& rhs) const;
340 
341  //- Compare (type,value) for inequality
342  bool operator!=(const exprValue& rhs) const { return !(*this == rhs); }
343 
344  //- Compare (type,value)
345  bool operator<(const exprValue& rhs) const;
346 
347 
348  // Output
349 
350  //- Return info proxy for printing information to a stream
351  InfoProxy<exprValue> info() const { return *this; }
352 
353  //- Write the (type-specific) content.
354  // For none : emits pair of brackets.
355  // For invalid : emits "bad".
356  //
357  // Use OTstream for the stream to recover as tokens.
358  //
359  // \param prune suppress the output for none/invalid
360  void write(Ostream& os, bool prune = false) const;
361 };
362 
363 
364 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
365 
366 } // End namespace expressions
367 
368 //- The data content are contiguous
369 template<> struct is_contiguous<expressions::exprValue> : std::true_type {};
370 
371 
372 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
373 
374 //- Read/parse value from input stream (uses ASCII format).
376 
377 //- Write value to output stream (uses ASCII format).
378 //- Writes 'none' or 'bad' for unknown/unsupported types.
380 
381 template<>
382 Ostream& operator<<(Ostream& os, const InfoProxy<expressions::exprValue>&);
383 
384 
385 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
386 
387 } // End namespace Foam
388 
389 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
390 
391 #include "exprValueI.H"
392 
393 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
394 
395 #endif
396 
397 // ************************************************************************* //
const Type * isA() const noexcept
Return non-null pointer to the data element (if types match). Can also be tested as a bool...
Definition: exprValueI.H:209
bool good() const noexcept
True if the value type is not none/invalid.
Definition: exprValueI.H:123
uint8_t direction
Definition: direction.H:46
static void notSpecialized(const std::string &msg) noexcept
Runtime &#39;assert&#39; for unimplemented generic methods.
Definition: exprValue.C:30
const Type & get() const
Return the value. Return pTraits zero if the types mismatch.
Definition: exprValueI.H:191
direction nComponents() const noexcept
The number of components associated with the value type.
Definition: exprValueI.H:136
A polymorphic typed union of simple primitive and VectorSpace types. It uses a &#39;fatter&#39; representatio...
Definition: exprValue.H:157
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
char * data_bytes() noexcept
Pointer to the data content as byte data.
Definition: exprValue.H:395
No type, or default initialized type.
void operator=(const scalar &val)
Definition: exprValue.H:368
bool set(const Type &val)
Assign from type. Returns false and sets to &#39;none&#39; for unsupported types.
Definition: exprValueI.H:169
static bool supportedType()
True if the specified type is supported.
Definition: exprValueI.H:70
The data content (as a union).
Definition: exprValue.H:81
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
A class for handling words, derived from Foam::string.
Definition: word.H:63
Istream & operator>>(Istream &, directionInfo &)
static expressions::valueTypeCode peekType(const ITstream &is)
Detect the type from the available tokens.
Definition: exprValue.C:150
static constexpr unsigned size_bytes() noexcept
Size of the (contiguous) data content as byte data is compile-time constant.
Definition: exprValue.H:404
static bool read(const std::string &str, exprValue &val)
Read entire string as a exprValue, skipping leading/trailing whitespace.
Definition: exprValue.C:248
valueTypeCode
An enumeration of known and expected expression value types.
Definition: exprTraits.H:81
direction rank() const noexcept
The vector-space rank associated with the value type.
Definition: exprValueI.H:143
int compare(const exprValue &rhs) const
Compare (type,value)
Definition: exprValue.C:487
bool is_integral() const noexcept
True if the value type is an integral (bool or label)
Definition: exprValueI.H:129
const char * cdata_bytes() const noexcept
Pointer to the data content as byte data.
Definition: exprValue.H:387
bool operator<(const exprValue &rhs) const
Compare (type,value)
Definition: exprValue.C:576
void write(Ostream &os, bool prune=false) const
Write the (type-specific) content.
Definition: exprValue.C:338
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: Scalar.H:258
word valueTypeName() const
The name for the value type. Similar to pTraits typeName.
Definition: exprValueI.H:150
bool readTokens(ITstream &is)
Guess type and read tokens (if possible)
Definition: exprValue.C:438
bool operator==(const exprValue &rhs) const
Compare (type,value) for equality.
Definition: exprValue.C:540
OBJstream os(runTime.globalPath()/outputName)
#define defineMultiTypeValueUnionMethods(Type, UnusedParam)
Definition: exprValue.H:128
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:77
bool operator!=(const exprValue &rhs) const
Compare (type,value) for inequality.
Definition: exprValue.H:420
#define FOR_ALL_EXPR_VALUE_TYPES(Macro,...)
Definition: exprValue.H:49
A template class to specify that a data type can be considered as being contiguous in memory...
Definition: contiguous.H:70
expressions::valueTypeCode typeCode() const noexcept
The value type code.
Definition: exprValue.H:270
word listCompoundName() const
The name for the compound token (for a List of values). Eg, List<scalar>, List<vector> ...
Definition: exprValueI.H:156
InfoProxy< exprValue > info() const
Return info proxy for printing information to a stream.
Definition: exprValue.H:433
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
exprValue()
Default construct (zero-initialized) as &#39;none&#39;.
Definition: exprValueI.H:92
void clear()
Reset to &#39;none&#39;.
Definition: exprValue.C:262
#define defineUnionMethods(Type, UnusedParam)
Definition: exprValue.H:357
#define declareUnionMember(Type, UnusedParam)
Definition: exprValue.H:86
An input stream of tokens.
Definition: ITstream.H:52
Namespace for OpenFOAM.