Loading...
Searching...
No Matches
tokenI.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) 2011-2016,2024 OpenFOAM Foundation
9 Copyright (C) 2017-2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
27\*---------------------------------------------------------------------------*/
28
29#include <utility> // For std::move, std::swap
30
31// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
32
33inline Foam::token Foam::token::boolean(bool on) noexcept
34{
35 token tok;
36 tok.type_ = tokenType::BOOL;
37 tok.data_.flagVal = on;
38
39 return tok;
40}
41
42
43inline Foam::token Foam::token::flag(int bitmask) noexcept
44{
45 token tok;
46 tok.type_ = tokenType::FLAG;
47 tok.data_.flagVal = bitmask;
48
49 return tok;
50}
51
52
53inline bool Foam::token::is_integerToken(tokenType tokType) noexcept
54{
55 return
56 (
57 tokType == tokenType::INTEGER_32
58 || tokType == tokenType::INTEGER_64
59 || tokType == tokenType::UNSIGNED_INTEGER_32
60 || tokType == tokenType::UNSIGNED_INTEGER_64
61 );
62}
63
64
65inline bool Foam::token::is_wordToken(tokenType tokType) noexcept
66{
67 return
68 (
69 tokType == tokenType::WORD
70 || tokType == tokenType::DIRECTIVE
71 );
72}
73
74
75inline bool Foam::token::is_stringToken(tokenType tokType) noexcept
76{
77 return
78 (
79 tokType == tokenType::STRING
80 || tokType == tokenType::EXPRESSION
81 || tokType == tokenType::VARIABLE
82 || tokType == tokenType::VERBATIM
83 || tokType == tokenType::CHAR_DATA
84 );
85}
86
87
88inline bool Foam::token::isseparator(int c) noexcept
89{
90 // NOTE: keep synchronized with ISstream::read(token&)
91
92 switch (c)
93 {
96 case token::END_LIST :
97 case token::BEGIN_SQR :
98 case token::END_SQR :
100 case token::END_BLOCK :
101 case token::COLON :
102 case token::COMMA :
103 case token::ASSIGN :
104 case token::PLUS :
105 // Excluded token::MINUS since it could start a number
106 case token::MULTIPLY :
107 case token::DIVIDE :
108 {
109 return true;
110 }
111
112 default:
113 break;
114 }
115
116 return false;
117}
118
119
120// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
121
122inline void Foam::token::setUndefined() noexcept
123{
124 type_ = tokenType::UNDEFINED;
125 data_.int64Val = 0; // bit-wise zero for union content
126 // leave lineNumber untouched - may still be needed
127}
128
129
130// inline bool Foam::token:is_pointer() const noexcept
131// {
132// return (isWord() || isString() || isCompound());
133// }
134
135template<class Type>
136inline Type Foam::token::getIntegral(const char* expected) const
137{
138 switch (type_)
139 {
140 case tokenType::INTEGER_32 : return data_.int32Val;
141 case tokenType::INTEGER_64 : return data_.int64Val;
142 case tokenType::UNSIGNED_INTEGER_32 : return data_.uint32Val;
143 case tokenType::UNSIGNED_INTEGER_64 : return data_.uint64Val;
144 default: parseError(expected); return 0;
145 }
146}
147
148
149template<class Type>
150inline Type Foam::token::getArithmetic(const char* expected) const
151{
152 switch (type_)
153 {
154 case tokenType::INTEGER_32 : return data_.int32Val;
155 case tokenType::INTEGER_64 : return data_.int64Val;
156 case tokenType::UNSIGNED_INTEGER_32 : return data_.uint32Val;
157 case tokenType::UNSIGNED_INTEGER_64 : return data_.uint64Val;
158 case tokenType::FLOAT : return data_.floatVal;
159 case tokenType::DOUBLE : return data_.doubleVal;
160 default: parseError(expected); return 0;
161 }
162}
163
164
165// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
166
167inline constexpr Foam::token::token() noexcept
169 data_(), // bit-wise zero for union content
170 type_(tokenType::UNDEFINED),
171 line_(0)
172{}
173
174
175inline Foam::token::token(const token& tok)
176:
177 data_(tok.data_), // bit-wise copy of union content
178 type_(tok.type_),
179 line_(tok.line_)
180{
181 // Fundamental: values already handled by bit-wise copy
182 // Pointer: duplicate content or increase refCount
183
184 switch (type_)
185 {
186 // token::isWord()
187 case tokenType::WORD:
189 {
190 data_.wordPtr = new word(*tok.data_.wordPtr);
191 break;
192 }
193
194 // token::isString()
200 {
201 data_.stringPtr = new string(*tok.data_.stringPtr);
202 break;
203 }
204
206 {
207 // Identical pointers, but increase the refCount
208 data_.compoundPtr = tok.data_.compoundPtr;
209 data_.compoundPtr->refCount::operator++();
210 break;
211 }
213 default:
214 break;
215 }
216}
217
218
219inline Foam::token::token(token&& tok) noexcept
220:
221 data_(tok.data_), // bit-wise copy of union content
222 type_(tok.type_),
223 line_(tok.line_)
224{
225 tok.setUndefined(); // zero the union content without any checking
226 tok.line_ = 0;
227}
228
229
230inline Foam::token::token(punctuationToken p, label lineNum) noexcept
231:
232 data_(),
234 line_(lineNum)
235{
236 data_.punctuationVal = p;
237}
238
239
240inline Foam::token::token(int32_t val, label lineNum) noexcept
241:
242 data_(),
244 line_(lineNum)
245{
246 data_.int32Val = val;
247}
248
249
250inline Foam::token::token(int64_t val, label lineNum) noexcept
251:
252 data_(),
254 line_(lineNum)
255{
256 data_.int64Val = val;
257}
258
259
260inline Foam::token::token(uint32_t val, label lineNum) noexcept
261:
262 data_(),
264 line_(lineNum)
265{
266 data_.uint32Val = val;
267}
268
269
270inline Foam::token::token(uint64_t val, label lineNum) noexcept
271:
272 data_(),
274 line_(lineNum)
275{
276 data_.uint64Val = val;
277}
278
279
280inline Foam::token::token(float val, label lineNum) noexcept
281:
282 data_(),
284 line_(lineNum)
285{
286 data_.floatVal = val;
287}
288
289
290inline Foam::token::token(double val, label lineNum) noexcept
291:
292 data_(),
294 line_(lineNum)
295{
296 data_.doubleVal = val;
297}
298
299
300inline Foam::token::token(const word& w, label lineNum)
301:
302 data_(),
304 line_(lineNum)
305{
306 data_.wordPtr = new word(w);
307}
308
309
310inline Foam::token::token(const string& str, label lineNum)
311:
312 data_(),
314 line_(lineNum)
315{
316 data_.stringPtr = new string(str);
317}
318
319
320inline Foam::token::token(word&& w, label lineNum)
321:
322 data_(),
324 line_(lineNum)
325{
326 data_.wordPtr = new word(std::move(w));
327}
328
329
330inline Foam::token::token(string&& str, label lineNum)
331:
332 data_(),
334 line_(lineNum)
335{
336 data_.stringPtr = new string(std::move(str));
337}
338
339
341(
342 tokenType tokType,
343 const std::string& str,
344 label lineNum
345)
346:
347 data_(),
348 type_(tokenType::STRING),
349 line_(lineNum)
350{
351 if (is_wordToken(tokType))
352 {
353 type_ = tokType;
354 data_.wordPtr = new word(str, false); // no stripping
355 }
356 else
358 if (is_stringToken(tokType)) type_ = tokType;
359 data_.stringPtr = new string(str); // never strips
360 }
361}
362
363
365(
366 tokenType tokType,
367 std::string&& str,
368 label lineNum
369)
370:
371 data_(),
372 type_(tokenType::STRING),
373 line_(lineNum)
374{
375 if (is_wordToken(tokType))
376 {
377 type_ = tokType;
378 data_.wordPtr = new word(std::move(str), false); // no stripping
379 }
380 else
382 if (is_stringToken(tokType)) type_ = tokType;
383 data_.stringPtr = new string(std::move(str)); // never strips
384 }
385}
386
387
388inline Foam::token::token(token::compound* ptr, label lineNum)
389:
390 data_(),
391 type_(tokenType::COMPOUND),
392 line_(lineNum)
393{
394 data_.compoundPtr = ptr;
395 if (!data_.compoundPtr)
397 // Could handle nullptr as Fatal, but this is simpler
398 setUndefined();
399 }
400}
401
402
403inline Foam::token::token(autoPtr<token::compound>&& ptr, label lineNum)
405 token(ptr.release(), lineNum)
406{}
407
408
409// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
410
411inline Foam::token::~token()
413 reset();
414}
415
416
417// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
418
419inline void Foam::token::reset()
420{
421 switch (type_)
422 {
423 // token::isWord()
424 case tokenType::WORD:
425 case tokenType::DIRECTIVE:
426 {
427 delete data_.wordPtr;
428 break;
429 }
430
431 // token::isString()
432 case tokenType::STRING:
433 case tokenType::EXPRESSION:
434 case tokenType::VARIABLE:
435 case tokenType::VERBATIM:
436 case tokenType::CHAR_DATA:
437 {
438 delete data_.stringPtr;
439 break;
440 }
441
442 case tokenType::COMPOUND:
443 {
444 if (data_.compoundPtr->refCount::unique())
445 {
446 delete data_.compoundPtr;
447 }
448 else
449 {
450 data_.compoundPtr->refCount::operator--();
451 }
452 break;
453 }
454
455 default:
456 break;
457 }
458
459 setUndefined();
460}
461
462
464{
465 reset();
466 type_ = tokenType::ERROR;
467}
468
469
470inline void Foam::token::swap(token& tok) noexcept
471{
472 if (this == &tok)
473 {
474 return; // Self-swap is a no-op
475 }
477 std::swap(data_, tok.data_);
478 std::swap(type_, tok.type_);
479 std::swap(line_, tok.line_);
480}
481
483inline Foam::word Foam::token::name() const
484{
485 return token::name(type_);
486}
487
490{
491 return type_;
492}
493
494
495inline bool Foam::token::setType(token::tokenType tokType) noexcept
496{
497 if (type_ == tokType)
498 {
499 // No change required
500 return true;
501 }
502
503 switch (tokType)
504 {
505 case tokenType::FLAG:
506 case tokenType::BOOL:
507 {
508 switch (type_)
509 {
510 case tokenType::FLAG:
511 case tokenType::BOOL:
512 type_ = tokType;
513 return true;
514 break;
515
516 default:
517 break;
518 }
519 }
520 break;
521
522 // token::isWord()
523 case tokenType::WORD:
524 case tokenType::DIRECTIVE:
525 {
526 switch (type_)
527 {
528 // token::isWord()
529 case tokenType::WORD:
530 case tokenType::DIRECTIVE:
531 type_ = tokType;
532 return true;
533 break;
534
535 default:
536 break;
537 }
538 }
539 break;
540
541 // token::isString()
542 case tokenType::STRING:
543 case tokenType::EXPRESSION:
544 case tokenType::VARIABLE:
545 case tokenType::VERBATIM:
546 case tokenType::CHAR_DATA:
547 {
548 switch (type_)
549 {
550 // token::isWord()
551 // could also go from WORD to STRING etc - to be decided
552
553 // token::isString()
554 case tokenType::STRING:
555 case tokenType::EXPRESSION:
556 case tokenType::VARIABLE:
557 case tokenType::VERBATIM:
558 case tokenType::CHAR_DATA:
559 type_ = tokType;
560 return true;
561 break;
562
563 default:
564 break;
565 }
566 }
567 break;
568
569 default:
570 break;
571 }
572
573 return false;
574}
575
577inline Foam::label Foam::token::lineNumber() const noexcept
578{
579 return line_;
580}
581
582
583inline Foam::label Foam::token::lineNumber(const label lineNum) noexcept
585 label old(line_);
586 line_ = lineNum;
587 return old;
588}
589
591inline bool Foam::token::good() const noexcept
592{
593 return (type_ != tokenType::UNDEFINED && type_ != tokenType::ERROR);
594}
595
597inline bool Foam::token::undefined() const noexcept
598{
599 return (type_ == tokenType::UNDEFINED);
600}
601
603inline bool Foam::token::error() const noexcept
604{
605 return (type_ == tokenType::ERROR);
606}
607
609inline bool Foam::token::isBool() const noexcept
610{
611 return (type_ == tokenType::BOOL);
612}
613
614
615inline bool Foam::token::boolToken() const
616{
617 if (type_ == tokenType::BOOL)
618 {
619 return data_.flagVal;
620 }
621 else if (type_ == tokenType::INTEGER_32)
622 {
623 return data_.int32Val;
625
626 parseError("bool");
627 return false;
628}
629
630
631inline void Foam::token::boolToken(bool on)
633 reset();
634 type_ = tokenType::BOOL;
635 data_.flagVal = on;
636}
637
639inline bool Foam::token::isFlag() const noexcept
640{
641 return (type_ == tokenType::FLAG);
642}
643
644
645inline int Foam::token::flagToken() const
646{
647 if (type_ == tokenType::FLAG)
648 {
649 return data_.flagVal;
651
652 parseError("flag bitmask");
653 return flagType::NO_FLAG;
654}
655
657inline bool Foam::token::isPunctuation() const noexcept
658{
659 return (type_ == tokenType::PUNCTUATION);
660}
661
662
663inline bool Foam::token::isPunctuation(punctuationToken p) const noexcept
664{
665 return
668 && data_.punctuationVal == p
669 );
670}
671
672
673inline bool Foam::token::isSeparator() const noexcept
674{
675 return
678 && isseparator(data_.punctuationVal)
679 );
680}
681
682
684{
685 if (type_ == tokenType::PUNCTUATION)
686 {
687 return data_.punctuationVal;
689
690 parseError("punctuation");
691 return punctuationToken::NULL_TOKEN;
692}
693
694
695inline void Foam::token::pToken(punctuationToken p)
697 reset();
699 data_.punctuationVal = p;
700}
701
702
703inline bool Foam::token::isIntType() const noexcept
704{
705 return is_integerToken(type_);
706}
707
708
709// inline bool Foam::token::isSignedIntType() const noexcept
710// {
711// return
712// (
713// (type_ == tokenType::INTEGER_32)
714// || (type_ == tokenType::INTEGER_64)
715// );
716// }
717//
718//
719// inline bool Foam::token::isUnsignedIntType() const noexcept
720// {
721// return
722// (
723// (type_ == tokenType::UNSIGNED_INTEGER_32)
724// || (type_ == tokenType::UNSIGNED_INTEGER_64)
725// );
726// }
727
728
729inline bool Foam::token::is_int32() const noexcept
730{
731 return (type_ == tokenType::INTEGER_32) ||
732 (
733 (type_ == tokenType::INTEGER_64)
734 ? (data_.int64Val >= INT32_MIN && data_.int64Val <= INT32_MAX)
736 ? (data_.uint32Val <= INT32_MAX)
737 :
738 (
740 && data_.uint64Val <= INT32_MAX
741 )
742 );
743}
744
746inline int32_t Foam::token::int32Token() const
747{
748 return getIntegral<int32_t>("int32");
749}
750
751
752inline void Foam::token::int32Token(int32_t val)
754 reset();
755 type_ = tokenType::INTEGER_32;
756 data_.int32Val = val;
757}
758
759
760inline bool Foam::token::is_int64() const noexcept
761{
762 return (type_ == tokenType::INTEGER_64) ||
763 (
764 (type_ == tokenType::INTEGER_32)
765 || (type_ == tokenType::UNSIGNED_INTEGER_32)
766 || (
768 && data_.uint64Val <= INT64_MAX
769 )
770 );
771}
772
774inline int64_t Foam::token::int64Token() const
775{
776 return getIntegral<int64_t>("int64");
777}
778
779
780inline void Foam::token::int64Token(int64_t val)
782 reset();
783 type_ = tokenType::INTEGER_64;
784 data_.int64Val = val;
785}
786
787
788inline bool Foam::token::is_uint32() const noexcept
789{
790 return (type_ == tokenType::UNSIGNED_INTEGER_32) ||
791 (
792 (type_ == tokenType::INTEGER_32)
793 ? (data_.int32Val >= 0)
794 : (type_ == tokenType::INTEGER_64)
795 ? (data_.int64Val >= 0 && data_.int64Val <= UINT32_MAX)
796 :
797 (
799 && data_.uint64Val <= UINT32_MAX
800 )
801 );
802}
803
805inline uint32_t Foam::token::uint32Token() const
806{
807 return getIntegral<uint32_t>("uint32");
808}
809
810
811inline void Foam::token::uint32Token(uint32_t val)
813 reset();
815 data_.uint32Val = val;
816}
817
818
819inline bool Foam::token::is_uint64() const noexcept
820{
821 return
822 (
823 (
824 type_ == tokenType::UNSIGNED_INTEGER_32
825 || type_ == tokenType::UNSIGNED_INTEGER_64
826 )
827 ||
828 (
829 (type_ == tokenType::INTEGER_32) ? (data_.int32Val >= 0)
830 : (type_ == tokenType::INTEGER_64 && data_.int64Val >= 0)
831 )
832 );
833}
834
836inline uint64_t Foam::token::uint64Token() const
837{
838 return getIntegral<uint64_t>("uint64");
839}
840
841
842inline void Foam::token::uint64Token(uint64_t val)
844 reset();
846 data_.uint64Val = val;
847}
848
849
850inline bool Foam::token::isLabel() const noexcept
851{
852 if constexpr (sizeof(Foam::label) == sizeof(int32_t))
853 {
854 return is_int32();
855 }
856 else
857 {
858 return is_int64();
859 }
860}
861
862
863inline bool Foam::token::isULabel() const noexcept
864{
865 if constexpr (sizeof(Foam::label) == sizeof(int32_t))
866 {
867 return is_uint32();
868 }
869 else
870 {
871 return is_uint64();
872 }
873}
874
876inline Foam::label Foam::token::labelToken() const
877{
878 return getIntegral<label>("label");
879}
880
882inline Foam::uLabel Foam::token::uLabelToken() const
883{
884 return getIntegral<uLabel>("uLabel");
885}
886
887
888inline bool Foam::token::isLabel(const label value) const noexcept
889{
890 return
891 (
892 (type_ == tokenType::INTEGER_32)
893 ? (value == data_.int32Val)
894 : (type_ == tokenType::INTEGER_64)
895 ? (value == data_.int64Val)
896 : (type_ == tokenType::UNSIGNED_INTEGER_32)
897 ? (value >= 0 && uint32_t(value) == data_.uint32Val)
898 :
899 (
901 && (value >= 0 && uint64_t(value) == data_.uint64Val)
902 )
903 );
904}
905
906
907inline void Foam::token::labelToken(const label val)
908{
909 if constexpr (sizeof(Foam::label) == sizeof(int32_t))
910 {
911 reset();
912 type_ = tokenType::INTEGER_32;
913 data_.int32Val = val;
914 }
915 else
916 {
918 type_ = tokenType::INTEGER_64;
919 data_.int64Val = val;
920 }
921}
922
924inline bool Foam::token::isFloat() const noexcept
925{
926 return (type_ == tokenType::FLOAT);
927}
928
929
930inline float Foam::token::floatToken() const
931{
932 if (type_ == tokenType::FLOAT)
933 {
934 return data_.floatVal;
935 }
936 else
937 {
938 parseError("float"); return 0;
939 }
940}
941
942
943inline void Foam::token::floatToken(const float val)
945 reset();
946 type_ = tokenType::FLOAT;
947 data_.floatVal = val;
948}
949
951inline bool Foam::token::isDouble() const noexcept
952{
953 return (type_ == tokenType::DOUBLE);
954}
955
956
957inline double Foam::token::doubleToken() const
958{
959 if (type_ == tokenType::DOUBLE)
960 {
961 return data_.doubleVal;
962 }
963 else
964 {
965 parseError("double"); return 0;
966 }
967}
968
969
970inline void Foam::token::doubleToken(const double val)
972 reset();
973 type_ = tokenType::DOUBLE;
974 data_.doubleVal = val;
975}
976
977
978inline bool Foam::token::isScalar() const noexcept
979{
980 return
982 type_ == tokenType::FLOAT
983 || type_ == tokenType::DOUBLE
984 );
985}
986
987
988inline Foam::scalar Foam::token::scalarToken() const
989{
990 switch (type_)
991 {
992 case tokenType::FLOAT : return data_.floatVal;
993 case tokenType::DOUBLE : return data_.doubleVal;
994 default: parseError("scalar"); return 0;
995 }
996}
997
999inline bool Foam::token::isNumber() const noexcept
1000{
1001 return (is_integerToken(type_) || isScalar());
1002}
1003
1005inline Foam::scalar Foam::token::number() const
1006{
1007 return getArithmetic<scalar>("number (label or scalar)");
1008}
1009
1011inline bool Foam::token::isWord() const noexcept
1012{
1013 return is_wordToken(type_);
1014}
1015
1017inline bool Foam::token::isWord(const std::string& s) const
1018{
1019 return (isWord() && s == *data_.wordPtr);
1020}
1021
1023inline bool Foam::token::isDirective() const noexcept
1024{
1025 return (type_ == tokenType::DIRECTIVE);
1026}
1027
1028
1029inline const Foam::word& Foam::token::wordToken() const
1030{
1031 if (isWord())
1032 {
1033 return *data_.wordPtr;
1035
1036 parseError("word");
1037 return word::null;
1038}
1039
1041inline bool Foam::token::isQuotedString() const noexcept
1042{
1043 return (type_ == tokenType::STRING);
1044}
1045
1047inline bool Foam::token::isString() const noexcept
1048{
1049 return is_stringToken(type_);
1050}
1051
1053inline bool Foam::token::isExpression() const noexcept
1054{
1055 return (type_ == tokenType::EXPRESSION);
1056}
1057
1059inline bool Foam::token::isVariable() const noexcept
1060{
1061 return (type_ == tokenType::VARIABLE);
1062}
1063
1065inline bool Foam::token::isVerbatim() const noexcept
1066{
1067 return (type_ == tokenType::VERBATIM);
1068}
1069
1071inline bool Foam::token::isCharData() const noexcept
1072{
1073 return (type_ == tokenType::CHAR_DATA);
1074}
1075
1077inline bool Foam::token::isStringType() const noexcept
1078{
1079 return (isWord() || isString());
1080}
1081
1082
1083inline const Foam::string& Foam::token::stringToken() const
1084{
1085 if (isString())
1086 {
1087 return *data_.stringPtr;
1088 }
1089 else if (isWord())
1090 {
1091 // Foam::word derives from Foam::string, no need to cast.
1092 return *data_.wordPtr;
1093 }
1094
1095 parseError("string");
1097}
1098
1099
1100// Could also have reference to stringToken() - eg refStringToken() ?
1101// but not really sure where this would be useful...
1103inline bool Foam::token::isCompound() const noexcept
1104{
1105 return (type_ == tokenType::COMPOUND);
1106}
1107
1108
1109inline bool Foam::token::isCompound(const word& compoundType) const
1110{
1111 return
1112 (
1114 && data_.compoundPtr->type() == compoundType
1115 );
1116}
1117
1118
1119template<class Type>
1120inline const Type* Foam::token::isCompound() const
1121{
1122 return
1123 (
1125 ? dynamic_cast<const Type*>(data_.compoundPtr)
1126 : nullptr
1127 );
1128}
1129
1130
1132{
1133 if (type_ != tokenType::COMPOUND)
1135 parseError("compound");
1136 }
1137 return *data_.compoundPtr;
1138}
1139
1140
1142{
1143 if (type_ != tokenType::COMPOUND)
1144 {
1145 parseError("compound");
1146 }
1147 return *data_.compoundPtr;
1148}
1149
1150
1151template<class Type>
1152inline Type& Foam::token::refCompoundToken()
1153{
1154 if (type_ != tokenType::COMPOUND)
1155 {
1156 parseError("compound");
1157 }
1158 return static_cast<Type&>
1159 (
1161 (
1162 *data_.compoundPtr
1163 )
1164 );
1165}
1166
1167
1170{
1171 return transferCompoundToken(&is);
1172}
1173
1174
1175template<class Type>
1176inline Type& Foam::token::transferCompoundToken(const Istream& is)
1177{
1178 return static_cast<Type&>
1179 (
1181 (
1183 )
1184 );
1185}
1186
1187
1188template<class Type>
1190{
1191 // Does not cover all possibilities perfectly, but should handle
1192 // most of the common ones (bool, label, scalar, vector lists).
1193 // Something like List<edge> will not be quite correct if we rely
1194 // on nComponents
1195
1196 typedef typename Type::value_type valueType;
1197
1198 if constexpr (std::is_same_v<bool, valueType>)
1199 {
1200 // List<bool>
1202 }
1203 else if constexpr (is_contiguous_label<valueType>::value)
1204 {
1205 // List<label>, List<labelVector> etc
1206 if constexpr (sizeof(Foam::label) == sizeof(int32_t))
1207 {
1209 }
1210 else
1211 {
1213 }
1214 }
1215 else if constexpr (is_contiguous_scalar<valueType>::value)
1216 {
1217 // List<scalar>, List<vector>, List<tensor> etc
1218 if constexpr (sizeof(Foam::scalar) == sizeof(float))
1219 {
1221 }
1222 else
1223 {
1225 }
1226 }
1227 else if constexpr (std::is_same_v<char, valueType>)
1228 {
1229 // List<char>
1231 }
1232 else
1233 {
1234 // Do not handle List<word> or List<string> at the moment
1235 // since filling non-contiguous data is probably not desirable
1237 }
1238}
1239
1240
1241// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1242
1243inline void Foam::token::operator=(const token& tok)
1244{
1245 if (this == &tok)
1246 {
1247 return; // Self-assignment is a no-op
1248 }
1249
1250 reset();
1251
1252 type_ = tok.type_;
1253 data_ = tok.data_; // bit-wise copy of union content
1254 line_ = tok.line_;
1255
1256 // Fundamental: values already handled by bit-wise copy
1257 // Pointer: duplicate content or increase refCount
1258
1259 switch (type_)
1260 {
1261 // token::isWord()
1262 case tokenType::WORD:
1263 case tokenType::DIRECTIVE:
1264 {
1265 data_.wordPtr = new word(*tok.data_.wordPtr);
1266 }
1267 break;
1268
1269 // token::isString()
1270 case tokenType::STRING:
1271 case tokenType::EXPRESSION:
1272 case tokenType::VARIABLE:
1273 case tokenType::VERBATIM:
1274 case tokenType::CHAR_DATA:
1275 {
1276 data_.stringPtr = new string(*tok.data_.stringPtr);
1277 }
1278 break;
1279
1280 case tokenType::COMPOUND:
1281 {
1282 // Identical pointers, but increase the refCount
1283 data_.compoundPtr = tok.data_.compoundPtr;
1284 data_.compoundPtr->refCount::operator++();
1285 }
1286 break;
1288 default:
1289 break;
1290 }
1291}
1292
1293
1294inline void Foam::token::operator=(token&& tok)
1295{
1296 if (this == &tok)
1297 {
1298 return; // Self-assignment is a no-op
1299 }
1301 reset();
1302 line_ = 0;
1303 swap(tok);
1304}
1305
1307inline void Foam::token::operator=(const punctuationToken p)
1308{
1310}
1311
1312
1313inline void Foam::token::operator=(const int32_t val)
1315 reset();
1316 type_ = tokenType::INTEGER_32;
1317 data_.int32Val = val;
1318}
1319
1320
1321inline void Foam::token::operator=(const int64_t val)
1323 reset();
1324 type_ = tokenType::INTEGER_64;
1325 data_.int64Val = val;
1326}
1327
1328
1329inline void Foam::token::operator=(const uint32_t val)
1331 reset();
1333 data_.uint32Val = val;
1334}
1335
1336
1337inline void Foam::token::operator=(const uint64_t val)
1339 reset();
1341 data_.uint64Val = val;
1342}
1343
1344
1345inline void Foam::token::operator=(const float val)
1347 reset();
1348 type_ = tokenType::FLOAT;
1349 data_.floatVal = val;
1350}
1351
1352
1353inline void Foam::token::operator=(const double val)
1355 reset();
1356 type_ = tokenType::DOUBLE;
1357 data_.doubleVal = val;
1358}
1359
1360
1361inline void Foam::token::operator=(const word& w)
1363 reset();
1364 type_ = tokenType::WORD;
1365 data_.wordPtr = new word(w);
1366}
1367
1368
1369inline void Foam::token::operator=(const string& str)
1371 reset();
1372 type_ = tokenType::STRING;
1373 data_.stringPtr = new string(str);
1374}
1375
1376
1377inline void Foam::token::operator=(word&& w)
1379 reset();
1380 type_ = tokenType::WORD;
1381 data_.wordPtr = new word(std::move(w));
1382}
1383
1384
1385inline void Foam::token::operator=(string&& s)
1387 reset();
1388 type_ = tokenType::STRING;
1389 data_.stringPtr = new string(std::move(s));
1390}
1391
1392
1395 reset();
1396 type_ = tokenType::COMPOUND;
1397 data_.compoundPtr = ptr;
1398}
1399
1400
1403 reset();
1404 type_ = tokenType::COMPOUND;
1405 data_.compoundPtr = ptr.release();
1406}
1407
1408
1409inline bool Foam::token::operator==(const token& tok) const
1410{
1411 if (type_ != tok.type_)
1412 {
1413 return false;
1414 }
1415
1416 switch (type_)
1417 {
1418 case tokenType::UNDEFINED:
1419 return true;
1420
1421 case tokenType::BOOL:
1422 return data_.flagVal == tok.data_.flagVal;
1423
1424 case tokenType::FLAG:
1425 return data_.flagVal == tok.data_.flagVal;
1426
1427 case tokenType::PUNCTUATION:
1428 return data_.punctuationVal == tok.data_.punctuationVal;
1429
1430 case tokenType::INTEGER_32 :
1431 return data_.int32Val == tok.data_.int32Val;
1432
1433 case tokenType::INTEGER_64 :
1434 return data_.int64Val == tok.data_.int64Val;
1435
1436 case tokenType::UNSIGNED_INTEGER_32 :
1437 return data_.uint64Val == tok.data_.uint64Val;
1438
1439 case tokenType::UNSIGNED_INTEGER_64 :
1440 return data_.uint64Val == tok.data_.uint64Val;
1441
1442 case tokenType::FLOAT:
1443 return equal(data_.floatVal, tok.data_.floatVal);
1444
1445 case tokenType::DOUBLE:
1446 return equal(data_.doubleVal, tok.data_.doubleVal);
1447
1448 // token::isWord()
1449 case tokenType::WORD:
1450 case tokenType::DIRECTIVE:
1451 return *data_.wordPtr == *tok.data_.wordPtr;
1452
1453 // token::isString()
1454 case tokenType::STRING:
1455 case tokenType::EXPRESSION:
1456 case tokenType::VARIABLE:
1457 case tokenType::VERBATIM:
1458 case tokenType::CHAR_DATA:
1459 return *data_.stringPtr == *tok.data_.stringPtr;
1460
1461 case tokenType::COMPOUND:
1462 return data_.compoundPtr == tok.data_.compoundPtr;
1463
1464 case tokenType::ERROR:
1465 return true;
1466 }
1467
1468 return false;
1469}
1470
1472inline bool Foam::token::operator==(const punctuationToken p) const noexcept
1473{
1474 return isPunctuation(p);
1475}
1476
1477
1478inline bool Foam::token::operator==(const std::string& s) const
1479{
1480 return
1481 (
1483 ? s == *data_.wordPtr
1484 : isString() && s == *data_.stringPtr
1485 );
1486}
1487
1488
1489inline bool Foam::token::operator==(const int32_t val) const noexcept
1490{
1491 return
1493 type_ == tokenType::INTEGER_32
1494 && data_.int32Val == val
1495 );
1496}
1497
1498
1499inline bool Foam::token::operator==(const int64_t val) const noexcept
1500{
1501 return
1503 type_ == tokenType::INTEGER_64
1504 && data_.int64Val == val
1505 );
1506}
1507
1508
1509inline bool Foam::token::operator==(const uint32_t val) const noexcept
1510{
1511 return
1514 && data_.uint32Val == val
1515 );
1516}
1517
1518
1519inline bool Foam::token::operator==(const uint64_t val) const noexcept
1520{
1521 return
1524 && data_.uint64Val == val
1525 );
1526}
1527
1528
1529inline bool Foam::token::operator==(const float val) const noexcept
1530{
1531 return
1533 type_ == tokenType::FLOAT
1534 && equal(data_.floatVal, val)
1535 );
1536}
1537
1538
1539inline bool Foam::token::operator==(const double val) const noexcept
1540{
1541 return
1542 (
1543 type_ == tokenType::DOUBLE
1544 && equal(data_.doubleVal, val)
1545 );
1546}
1547
1548
1549// ************************************************************************* //
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition Istream.H:60
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
A class for handling character strings derived from std::string.
Definition string.H:76
static const string null
An empty string.
Definition string.H:203
virtual tokenType typeCode() const
The token type (if any) corresponding to the contained component type (LABEL, FLOAT,...
Definition tokenI.H:1182
Abstract base class for complex tokens.
Definition token.H:192
A token holds an item read from Istream.
Definition token.H:70
bool isIntType() const noexcept
Token is (int32 | int64 | uint32 | uint64).
Definition tokenI.H:696
bool isNumber() const noexcept
Token is (signed/unsigned) integer type, FLOAT or DOUBLE.
Definition tokenI.H:992
void swap(token &tok) noexcept
Swap token contents: type, data, line-number.
Definition tokenI.H:463
tokenType
Enumeration defining the types of token.
Definition token.H:81
@ ERROR
Token error encountered.
Definition token.H:83
@ DOUBLE
double (double-precision) type
Definition token.H:94
@ FLAG
stream flag (1-byte bitmask)
Definition token.H:86
@ WORD
Foam::word.
Definition token.H:97
@ UNSIGNED_INTEGER_32
uint32 type
Definition token.H:91
@ EXPRESSION
Definition token.H:104
@ UNDEFINED
An undefined token-type.
Definition token.H:82
@ COMPOUND
Compound type such as List<label> etc.
Definition token.H:99
@ CHAR_DATA
String-variant: plain character content.
Definition token.H:110
@ INTEGER_64
int64 type
Definition token.H:90
@ FLOAT
float (single-precision) type
Definition token.H:93
@ DIRECTIVE
Definition token.H:101
@ BOOL
boolean type
Definition token.H:88
@ UNSIGNED_INTEGER_64
uint64 type
Definition token.H:92
@ INTEGER_32
int32 type
Definition token.H:89
@ STRING
Foam::string (usually double-quoted).
Definition token.H:98
@ PUNCTUATION
single character punctuation
Definition token.H:87
label lineNumber() const noexcept
The line number for the token.
Definition tokenI.H:570
bool isBool() const noexcept
Token is BOOL.
Definition tokenI.H:602
bool isSeparator() const noexcept
Token is PUNCTUATION and isseparator.
Definition tokenI.H:666
bool isPunctuation() const noexcept
Token is PUNCTUATION.
Definition tokenI.H:650
bool isExpression() const noexcept
Token is EXPRESSION (string variant).
Definition tokenI.H:1046
word name() const
Return the name of the current token type.
Definition tokenI.H:476
compound & refCompoundToken()
Return reference to compound token. Fatal if the wrong type. No checks for released or pending states...
Definition tokenI.H:1134
bool is_int64() const noexcept
Token is INTEGER_64 or is convertible to one.
Definition tokenI.H:753
punctuationToken
Standard punctuation tokens (a character).
Definition token.H:140
@ DIVIDE
Divide [isseparator].
Definition token.H:160
@ BEGIN_BLOCK
Begin block [isseparator].
Definition token.H:178
@ BEGIN_SQR
Begin dimensions [isseparator].
Definition token.H:176
@ COLON
Colon [isseparator].
Definition token.H:146
@ END_BLOCK
End block [isseparator].
Definition token.H:179
@ ASSIGN
Assignment/equals [isseparator].
Definition token.H:156
@ END_STATEMENT
End entry [isseparator].
Definition token.H:173
@ NULL_TOKEN
Nul character.
Definition token.H:141
@ BEGIN_LIST
Begin list [isseparator].
Definition token.H:174
@ PLUS
Addition [isseparator].
Definition token.H:157
@ END_LIST
End list [isseparator].
Definition token.H:175
@ END_SQR
End dimensions [isseparator].
Definition token.H:177
@ MULTIPLY
Multiply [isseparator].
Definition token.H:159
@ COMMA
Comma [isseparator].
Definition token.H:148
float floatToken() const
Return float value.
Definition tokenI.H:923
bool isLabel() const noexcept
Integral token is convertible to Foam::label.
Definition tokenI.H:843
const string & stringToken() const
Return const reference to the string contents.
Definition tokenI.H:1076
bool is_int32() const noexcept
Token is INTEGER_32 or is convertible to one.
Definition tokenI.H:722
punctuationToken pToken() const
Return punctuation character.
Definition tokenI.H:676
bool operator==(const token &tok) const
Definition tokenI.H:1402
bool good() const noexcept
True if token is not UNDEFINED or ERROR.
Definition tokenI.H:584
void setBad()
Clear token and set to be ERROR.
Definition tokenI.H:456
label labelToken() const
Return integer type as label value or Error.
Definition tokenI.H:869
bool isDouble() const noexcept
Token is DOUBLE.
Definition tokenI.H:944
static bool isseparator(int c) noexcept
True if the character is a punctuation separator (eg, in ISstream).
Definition tokenI.H:81
bool isString() const noexcept
Token is string-variant (STRING, EXPRESSION, VARIABLE, VERBATIM, CHAR_DATA).
Definition tokenI.H:1040
@ NO_FLAG
No flags.
Definition token.H:130
constexpr token() noexcept
Default construct, initialized to an UNDEFINED token.
Definition tokenI.H:160
bool boolToken() const
Return boolean token value.
Definition tokenI.H:608
bool is_uint32() const noexcept
Token is UNSIGNED_INTEGER_32 or is convertible to one.
Definition tokenI.H:781
bool isULabel() const noexcept
Integral token is convertible to Foam::uLabel.
Definition tokenI.H:856
bool isScalar() const noexcept
Token is FLOAT or DOUBLE.
Definition tokenI.H:971
double doubleToken() const
Return double value.
Definition tokenI.H:950
const compound & compoundToken() const
Const reference to compound token. Fatal if the wrong type.
Definition tokenI.H:1124
bool isDirective() const noexcept
Token is DIRECTIVE (word variant).
Definition tokenI.H:1016
uint32_t uint32Token() const
Return int32 value, convert from other integer type or Error.
Definition tokenI.H:798
bool isFlag() const noexcept
Token is FLAG.
Definition tokenI.H:632
uLabel uLabelToken() const
Return integer type as uLabel value or Error.
Definition tokenI.H:875
bool setType(const tokenType tokType) noexcept
Change the token type, for similar types.
Definition tokenI.H:488
int flagToken() const
Return flag bitmask value.
Definition tokenI.H:638
bool undefined() const noexcept
Token is UNDEFINED.
Definition tokenI.H:590
bool is_uint64() const noexcept
Token is UNSIGNED_INTEGER_64 or is convertible to one.
Definition tokenI.H:812
tokenType type() const noexcept
Return the token type.
Definition tokenI.H:482
bool isQuotedString() const noexcept
Token is (quoted) STRING (string variant).
Definition tokenI.H:1034
compound & transferCompoundToken(const Istream *is=nullptr)
Return reference to compound and mark internally as released.
Definition token.C:157
bool isCompound() const noexcept
Token is COMPOUND.
Definition tokenI.H:1096
int64_t int64Token() const
Return int64 value, convert from other integer type or Error.
Definition tokenI.H:767
bool error() const noexcept
Token is ERROR.
Definition tokenI.H:596
bool isFloat() const noexcept
Token is FLOAT.
Definition tokenI.H:917
bool isStringType() const noexcept
Token is word-variant or string-variant (WORD, DIRECTIVE, STRING, EXPRESSION, VARIABLE,...
Definition tokenI.H:1070
bool isVariable() const noexcept
Token is VARIABLE (string variant).
Definition tokenI.H:1052
void reset()
Reset token to UNDEFINED and clear any allocated storage.
Definition tokenI.H:412
int32_t int32Token() const
Return int32 value, convert from other integer type or Error.
Definition tokenI.H:739
bool isCharData() const noexcept
Token is CHAR_DATA (string variant).
Definition tokenI.H:1064
const word & wordToken() const
Return const reference to the word contents.
Definition tokenI.H:1022
bool isWord() const noexcept
Token is word-variant (WORD, DIRECTIVE).
Definition tokenI.H:1004
scalar scalarToken() const
Return float or double value.
Definition tokenI.H:981
uint64_t uint64Token() const
Return int64 value, convert from other integer type or Error.
Definition tokenI.H:829
bool isVerbatim() const noexcept
Token is VERBATIM string (string variant).
Definition tokenI.H:1058
~token()
Destructor.
Definition tokenI.H:404
static token boolean(bool on) noexcept
Create a bool token.
Definition tokenI.H:26
static token flag(int bitmask) noexcept
Create a token with stream flags, no sanity check.
Definition tokenI.H:36
void operator=(const token &tok)
Copy assign.
Definition tokenI.H:1236
scalar number() const
Return label, float or double value.
Definition tokenI.H:998
A class for handling words, derived from Foam::string.
Definition word.H:66
static const word null
An empty word.
Definition word.H:84
volScalarField & p
limits reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL))
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
bool equal(const T &a, const T &b)
Compare two values for equality.
Definition label.H:180
Type & dynamicCast(U &obj)
A dynamic_cast (for references) that generates FatalError on failed casts.
Definition typeInfo.H:124
const direction noexcept
Definition scalarImpl.H:265
A template class to specify if a data type is composed solely of Foam::label elements.
Definition contiguous.H:82
A template class to specify if a data type is composed solely of Foam::scalar elements.
Definition contiguous.H:87