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-2023 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"
46 #include "error.H"
47 #include "contiguous.H"
48 #include "tokenList.H"
49 #include "InfoProxy.H"
50 #include <typeinfo>
51 
52 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
53 
54 // Execute macro for known exprValue types, with more frequent ones first
55 #undef FOR_ALL_EXPR_VALUE_TYPES
56 #define FOR_ALL_EXPR_VALUE_TYPES(Macro, ...) \
57  Macro(scalar, __VA_ARGS__) \
58  Macro(vector, __VA_ARGS__) \
59  Macro(tensor, __VA_ARGS__) \
60  Macro(symmTensor, __VA_ARGS__) \
61  Macro(sphericalTensor, __VA_ARGS__) \
62  Macro(label, __VA_ARGS__) \
63  Macro(bool, __VA_ARGS__)
64 
65 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
66 
67 namespace Foam
68 {
69 
70 // Forward Declarations
71 class ITstream;
72 
73 namespace expressions
74 {
75 namespace Detail
76 {
77 
78 /*---------------------------------------------------------------------------*\
79  Class exprValueUnion Declaration
80 \*---------------------------------------------------------------------------*/
81 
82 //- The data content (as a union).
83 // The stem of the member names correspond identically to the data types
84 // to enable macro definitions (naming similar to Foam::token)
85 union exprValueUnion
86 {
87  // Member Data
88 
89  #undef declareUnionMember
90  #define declareUnionMember(Type, UnusedParam) \
91  \
92  \
93  Type Type##Value;
94 
96  #undef declareUnionMember
97 
98 
99  // Member Functions
100 
101  //- Runtime 'assert' for unimplemented generic methods
102  // This seems to be the best way to catch programming errors
103  // since static_assert does not help here.
104  // The 'noexcept' is slightly misleading (needed for the caller)
105  static void notSpecialized(const std::string& msg) noexcept
106  {
108  << "non-specialized: " << msg.c_str() << endl
109  << abort(FatalError);
110  }
111 
112  //- Return read pointer to typed union member,
113  //- which is nullptr for unspecialized versions
114  template<class Type>
115  inline const Type* get() const noexcept { return nullptr; }
116 
117  //- No generic set(), only specialized methods
118  template<class Type>
119  inline void set(const Type& val) noexcept
120  {
121  notSpecialized("set<" + std::string(typeid(Type).name()) + '>');
122  }
123 };
125 
126 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
127 
128 // Type-specific get/set (definitions)
129 #undef defineMultiTypeValueUnionMethods
130 #define defineMultiTypeValueUnionMethods(Type, UnusedParam) \
131  \
132  \
133 template<> \
134 inline const Type* exprValueUnion::get<Type>() const noexcept \
135 { \
136  return &(Type##Value); \
137 } \
138  \
139  \
140 template<> \
141 inline void exprValueUnion::set<Type>(const Type& val) noexcept \
142 { \
143  Type##Value = val; \
144 }
145 
146 // Type-specific methods
148 #undef defineMultiTypeValueUnionMethods
149 
150 } // End namespace Detail
151 
152 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
153 
154 
155 /*---------------------------------------------------------------------------*\
156  Class exprValue Declaration
157 \*---------------------------------------------------------------------------*/
158 
159 class exprValue
160 {
161  // Private Data
162 
163  //- The data content (as a union)
165 
166  //- The data type (as a type-code)
168 
169 
170  // Private Member Functions
171 
172  //- Fill the data with zero, preserving the data type
173  inline void fill_zero();
174 
175  //- Copy assignment
176  void deepCopy(const exprValue& rhs);
177 
178 
179 public:
180 
181  //- Runtime type information
182  ClassName("exprValue");
183 
184 
185  // Constructors
186 
187  //- Default construct (zero-initialized) as 'none'
188  inline exprValue();
189 
190  //- Copy construct (deep copy)
191  inline exprValue(const exprValue& rhs);
192 
193  //- Construct from Type. Fatal for unsupported types
194  template<class Type>
195  inline explicit exprValue(const Type& val);
196 
197 
198  // Static Methods (valueTypeCode)
199 
200  //- True if valueTypeCode is not none/invalid
201  inline static bool good
202  (
204  ) noexcept;
205 
206  //- True if valueTypeCode is bool/label
207  inline static bool is_integral
208  (
210  ) noexcept;
211 
212  //- The number of components associated with the valueTypeCode
213  inline static direction nComponents
214  (
216  ) noexcept;
217 
218  //- The vector-space rank associated with the valueTypeCode
219  inline static direction rank
220  (
222  ) noexcept;
223 
224  //- True if the specified type is supported
225  template<class Type>
226  inline static bool supportedType();
227 
228 
229  // Static Methods
230 
231  //- Detect the type from the available tokens.
232  // Possible ambiguity between label and scalar.
233  // \return INVALID for unsupported type
234  static expressions::valueTypeCode peekType(const ITstream& is);
235 
236  //- Read entire string as a exprValue,
237  //- skipping leading/trailing whitespace.
238  // \return True if successful.
239  static bool read(const std::string& str, exprValue& val);
240 
241 
242  // Member Functions
243 
244  //- The value type code
246  {
247  return typeCode_;
248  }
249 
250  //- True if the value type is not none/invalid
251  inline bool good() const noexcept;
252 
253  //- True if the value type is an integral (bool or label)
254  inline bool is_integral() const noexcept;
255 
256  //- The number of components associated with the value type
257  inline direction nComponents() const noexcept;
258 
259  //- The vector-space rank associated with the value type
260  inline direction rank() const noexcept;
261 
262  //- The name for the value type. Similar to pTraits typeName
263  inline word valueTypeName() const;
264 
265  //- The name for the compound token (for a List of values).
266  //- Eg, \c List<scalar>, \c List<vector> ...
267  inline word listCompoundName() const;
268 
269  //- Reset to 'none'
270  void clear();
271 
272  //- Read read tokens (if possible)
273  // \return True on success
274  bool read(Istream& is);
275 
276  //- Guess type and read tokens (if possible)
277  // \return True on success
278  bool readTokens(ITstream& is);
279 
280 
281  // Typed Access
282 
283  //- Return non-null pointer to the data element (if types match).
284  //- Can also be tested as a bool.
285  template<class Type>
286  inline const Type* isA() const noexcept;
287 
288  //- Assign from type.
289  //- Returns false and sets to 'none' for unsupported types
290  template<class Type>
291  inline bool set(const Type& val);
292 
293  //- Return the value. Return pTraits zero if the types mismatch
294  template<class Type>
295  inline const Type& get() const;
296 
297 
298  // Type-specific methods, operators
299 
300  #undef defineUnionMethods
301  #define defineUnionMethods(Type, UnusedParam) \
302  \
303  \
304  bool is_##Type() const noexcept \
305  { \
306  return (typeCode_ == exprTypeTraits<Type>::value); \
307  } \
308  \
309  \
310  void operator=(const Type& val) { this->set<Type>(val); }
311 
313  #undef defineUnionMethods
314 
315 
316  //- Copy assignment
317  void operator=(const exprValue& rhs) { deepCopy(rhs); }
318 
319  //- Assign from zero. Changes value but not type
320  void operator=(const Foam::zero) { fill_zero(); }
321 
322 
323  // Low-level access
324 
325  //- Pointer to the data content as byte data
326  const char* cdata_bytes() const noexcept
327  {
328  return reinterpret_cast<const char*>(this);
329  }
330 
331  //- Pointer to the data content as byte data
332  char* data_bytes() noexcept
333  {
334  return reinterpret_cast<char*>(this);
335  }
336 
337  //- Size of the (contiguous) data content as byte data
338  //- is compile-time constant
339  static constexpr unsigned size_bytes() noexcept
340  {
341  return sizeof(exprValue);
342  }
343 
344 
345  // Member Functions
346 
347  //- Compare (type,value) for equality
348  bool operator==(const exprValue& rhs) const;
349 
350  //- Compare (type,value) for inequality
351  bool operator!=(const exprValue& rhs) const { return !(*this == rhs); }
352 
353  //- Compare (type,value) - currently not implemented.
354  bool operator<(const exprValue& rhs) const;
355 
356 
357  // Output
358 
359  //- Return info proxy for printing information to a stream
360  InfoProxy<exprValue> info() const { return *this; }
361 
362  //- The exprValue as tokens.
363  // For none : emits pair of brackets.
364  // For invalid : emits "bad".
365  //
366  // \param prune suppress the output for none/invalid
367  tokenList tokens(bool prune = false) const;
368 
369  //- Write the (type-specific) content.
370  // For none : emits pair of brackets.
371  // For invalid : emits "bad".
372  //
373  // \param prune suppress the output for none/invalid
374  void write(Ostream& os, bool prune = false) const;
375 };
376 
378 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
379 
380 } // End namespace expressions
381 
382 //- The data content are contiguous
383 template<> struct is_contiguous<expressions::exprValue> : std::true_type {};
384 
385 
386 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
387 
388 //- Read/parse value from input stream (uses ASCII format).
390 
391 //- Write value to output stream (uses ASCII format).
392 //- Writes 'none' or 'bad' for unknown/unsupported types.
394 
395 template<>
396 Ostream& operator<<(Ostream& os, const InfoProxy<expressions::exprValue>&);
397 
398 
399 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
400 
401 } // End namespace Foam
402 
403 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
405 #include "exprValueI.H"
406 
407 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
408 
409 #endif
410 
411 // ************************************************************************* //
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
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
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:164
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:404
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
No type, or default initialized type.
void operator=(const scalar &val)
Definition: exprValue.H:377
List< token > tokenList
List of token, used for dictionary primitive entry (for example)
Definition: tokenList.H:32
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:83
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:99
static constexpr unsigned size_bytes() noexcept
Size of the (contiguous) data content as byte data is compile-time constant.
Definition: exprValue.H:413
static bool read(const std::string &str, exprValue &val)
Read entire string as a exprValue, skipping leading/trailing whitespace.
Definition: exprValue.C:197
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
static void notSpecialized(const std::string &msg) noexcept
Runtime &#39;assert&#39; for unimplemented generic methods.
Definition: exprValue.H:106
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:396
errorManip< error > abort(error &err)
Definition: errorManip.H:139
bool operator<(const exprValue &rhs) const
Compare (type,value) - currently not implemented.
Definition: exprValue.C:470
void write(Ostream &os, bool prune=false) const
Write the (type-specific) content.
Definition: exprValue.C:281
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:377
bool operator==(const exprValue &rhs) const
Compare (type,value) for equality.
Definition: exprValue.C:434
OBJstream os(runTime.globalPath()/outputName)
#define defineMultiTypeValueUnionMethods(Type, UnusedParam)
Definition: exprValue.H:135
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:429
#define FOR_ALL_EXPR_VALUE_TYPES(Macro,...)
Definition: exprValue.H:51
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:284
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:442
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:211
ClassName("exprValue")
Runtime type information.
#define defineUnionMethods(Type, UnusedParam)
Definition: exprValue.H:366
#define declareUnionMember(Type, UnusedParam)
Definition: exprValue.H:88
An input stream of tokens.
Definition: ITstream.H:52
Namespace for OpenFOAM.
tokenList tokens(bool prune=false) const
The exprValue as tokens.
Definition: exprValue.C:228