NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
stringfunchandler.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 NumeRe: Framework fuer Numerische Rechnungen
3 Copyright (C) 2019 Erik Haenel et al.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17******************************************************************************/
18
19#include "stringfunchandler.hpp"
20#include "../../kernel.hpp"
21#include "../structures.hpp"
22#define DEFAULT_NUM_ARG INT_MIN
23// define the "End of transmission block" as string separator
24#define NEWSTRING (char)23
25
26using namespace std;
27
28string removeQuotationMarks(const string& sString);
29string addQuotationMarks(const string& sString);
30
31namespace NumeRe
32{
43 string StringFuncHandler::addMaskedStrings(const string& sString)
44 {
45 if (sString.find('"') == string::npos && sString.find(NEWSTRING) == string::npos && sString.back() != '\\')
46 return sString;
47 string sRet = sString;
48
49 // Go through the complete string without the first
50 // and the last character
51 for (size_t i = 1; i < sRet.length() - 1; i++)
52 {
53 // Escape backslashes
54 if (sRet[i] == '\\' && sRet[i + 1] != '"' && sRet[i + 1] != ' ')
55 {
56 sRet.insert(i + 1, " ");
57 i++;
58 }
59
60 // Escape quotation marks
61 if (sRet[i] == '"' && sRet[i - 1] != '\\' && sRet[i + 1] != NEWSTRING && sRet.find('"', i + 1) != string::npos)
62 {
63 sRet.insert(i, "\\");
64 i++;
65 }
66
67 // Replace the new string character with a comma
68 if (sRet[i] == NEWSTRING)
69 {
70 sRet[i] = ',';
71 if (sRet[i + 1] == '"')
72 i++;
73 }
74
75 // Escape tab and newlines
76 //if (sRet[i] == '\t')
77 // sRet.replace(i, 1, "\\t");
78 //if (sRet[i] == '\n')
79 // sRet.replace(i, 1, "\\n");
80 }
81 return sRet;
82 }
83
84
104 void StringFuncHandler::evalFunction(std::string& sLine, const std::string& sFuncName, StringFuncHandle funcHandle)
105 {
106 size_t nStartPosition = 0;
107 size_t nEndPosition = 0;
108
109 // While the function signature can be found
110 while ((nStartPosition = findNextFunction(sFuncName, sLine, nStartPosition, nEndPosition)) != string::npos)
111 {
112 // Extract the argument of the current found function and process it
113 StringView sFunctionArgument = getFunctionArgumentList(sFuncName, sLine, nStartPosition, nEndPosition);
114 std::vector<s_vect> vReturnValues;
115 StringFuncArgs stringArgs;
116 stringArgs.opt = &NumeReKernel::getInstance()->getSettings();
117 bool bLogicalOnly = false;
118
119 // Create function argument vector variables
120 s_vect sStringArg1, sStringArg2, sStringArg3;
121 n_vect nIntArg1, nIntArg2;
122 d_vect dValArg;
123 size_t nMaxArgs = 0;
124
125 // Apply the parser as specified by the function signature. After that call the corresponding
126 // string function with the returned arguments as many times as it's needed
127 if (funcHandle.fType >= PARSER_INT && funcHandle.fType < PARSER_DOUBLE)
128 nMaxArgs = argumentParser(sFunctionArgument, nIntArg1);
129 else if (funcHandle.fType >= PARSER_DOUBLE && funcHandle.fType < PARSER_STRING)
130 nMaxArgs = argumentParser(sFunctionArgument, dValArg, nIntArg1);
131 else if (funcHandle.fType >= PARSER_STRING && funcHandle.fType < PARSER_STRING_DOUBLE)
132 {
133 if (sFuncName == "to_string(" && !isStringExpression(sFunctionArgument.to_string()))
134 {
135 sStringArg1.push_generic(sFunctionArgument.to_string());
136 nMaxArgs = 1;
137 }
138 else
139 nMaxArgs = argumentParser(sFunctionArgument, sStringArg1, bLogicalOnly);
140
141 if (!nMaxArgs)
143
144 // These five multiargument functions are also defined for numerical values.
145 // If the return value for the current functions arguments is an only logical
146 // value, ignore the current function call
147 if (bLogicalOnly
148 && (sFuncName == "min(" || sFuncName == "max(" || sFuncName == "cnt(" || sFuncName == "num(" || sFuncName == "sum("))
149 {
150 nStartPosition++;
151 continue;
152 }
153 }
154 else if (funcHandle.fType >= PARSER_STRING_DOUBLE && funcHandle.fType < PARSER_STRING_INT_INT)
155 nMaxArgs = argumentParser(sFunctionArgument, sStringArg1, dValArg);
156 else if (funcHandle.fType >= PARSER_STRING_INT_INT && funcHandle.fType < PARSER_STRING_INT_INT_STRING)
157 nMaxArgs = argumentParser(sFunctionArgument, sStringArg1, nIntArg1, nIntArg2);
158 else if (funcHandle.fType >= PARSER_STRING_INT_INT_STRING && funcHandle.fType < PARSER_STRING_STRING_INT_INT)
159 nMaxArgs = argumentParser(sFunctionArgument, sStringArg1, nIntArg1, nIntArg2, sStringArg2);
161 nMaxArgs = argumentParser(sFunctionArgument, sStringArg1, sStringArg2, nIntArg1, nIntArg2);
162 else if (funcHandle.fType >= PARSER_STRING_STRING_STRING_INT_INT)
163 nMaxArgs = argumentParser(sFunctionArgument, sStringArg1, sStringArg2, sStringArg3, nIntArg1, nIntArg2);
164
165 // Ensure that at least a single argument is available
166 if (!nMaxArgs && funcHandle.fType != NOARGS)
168
169 // Evaluate the function calls
170 if (funcHandle.bTakesMultiArguments)
171 {
172 if (funcHandle.fType >= PARSER_INT && funcHandle.fType < PARSER_STRING)
173 {
174 stringArgs.nMultiArg = nIntArg1;
175 vReturnValues.push_back(funcHandle.fHandle(stringArgs));
176 }
177 else
178 {
179 nMaxArgs = max(max(max(max(sStringArg2.size(), sStringArg3.size()), nIntArg1.size()), nIntArg2.size()), 1u);
180
181 if (nMaxArgs < 500)
182 vReturnValues = callMultiFunction(funcHandle, sStringArg1, sStringArg2, sStringArg3, nIntArg1, nIntArg2, dValArg, nMaxArgs);
183 else
184 vReturnValues = callMultiFunctionParallel(funcHandle, sStringArg1, sStringArg2, sStringArg3, nIntArg1, nIntArg2, dValArg, nMaxArgs);
185 }
186 }
187 else
188 {
189 if (nMaxArgs < 500)
190 vReturnValues = callFunction(funcHandle, sStringArg1, sStringArg2, sStringArg3, nIntArg1, nIntArg2, dValArg, nMaxArgs);
191 else
192 vReturnValues = callFunctionParallel(funcHandle, sStringArg1, sStringArg2, sStringArg3, nIntArg1, nIntArg2, dValArg, nMaxArgs);
193 }
194
195 // Create a string vector variable for the function output
196 std::string sFuncReturnValue = createStringVectorVar(expandStringVectorComponents(vReturnValues));
197
198 // replace the function with the return value
199 sLine.replace(nStartPosition, nEndPosition + 1 - nStartPosition, sFuncReturnValue);
200
201 nStartPosition++;
202 }
203 }
204
205
221 {
225 std::string sFuncArgument = __sFuncArgument.to_string();
226 value_type* v = 0;
227 int nReturn = 0;
228
229 // If the current function argument contains strings,
230 // parse it correspondingly
231 if (isStringExpression(sFuncArgument) || _data.containsClusters(sFuncArgument))
232 {
233 // Call the string parser core
234 StringResult strRes = eval(sFuncArgument, "", true);
235
236 // If already numerical value are available, use them directly
237 if (strRes.vNumericalValues.size())
238 {
239 for (size_t i = 0; i < strRes.vNumericalValues.size(); i++)
240 nArg.push_back(intCast(strRes.vNumericalValues[i]));
241
242 return nArg.size();
243 }
244
245 // Evaluate the returned strings numerically
246 for (size_t i = 0; i < strRes.vResult.size(); i++)
247 {
248 _parser.SetExpr(strRes.vResult[i]);
249 v = _parser.Eval(nReturn);
250
251 for (int n = 0; n < nReturn; n++)
252 nArg.push_back(intCast(v[n]));
253 }
254
255 return nArg.size();
256 }
257 else if (_data.containsTablesOrClusters(sFuncArgument))
258 {
259 getDataElements(sFuncArgument, _parser, _data, _option, false);
260 }
261
262 // Set the expression and evaluate it
263 _parser.SetExpr(sFuncArgument);
264 v = _parser.Eval(nReturn);
265
266 for (int i = 0; i < nReturn; i++)
267 {
268 nArg.push_back(intCast(v[i]));
269 }
270
271 return (size_t)nReturn;
272 }
273
274
290 {
294 std::string sFuncArgument = __sFuncArgument.to_string();
295 value_type* v = 0;
296 int nReturn = 0;
297
298 // If the current function argument contains strings,
299 // parse it correspondingly
300 if (isStringExpression(sFuncArgument) || _data.containsClusters(sFuncArgument))
301 {
302 // Call the string parser core
303 StringResult strRes = eval(sFuncArgument, "", true);
304
305 // If already numerical value are available, use them directly
306 if (strRes.vNumericalValues.size())
307 {
308 dArg = strRes.vNumericalValues;
309
310 return dArg.size();
311 }
312
313 // Evaluate the returned strings numerically
314 for (size_t i = 0; i < strRes.vResult.size(); i++)
315 {
316 _parser.SetExpr(strRes.vResult[i]);
317 v = _parser.Eval(nReturn);
318 dArg.insert(dArg.end(), v, v+nReturn);
319 }
320
321 return dArg.size();
322 }
323 else if (_data.containsTablesOrClusters(sFuncArgument))
324 {
325 getDataElements(sFuncArgument, _parser, _data, _option, false);
326 }
327
328 // Set the expression and evaluate it
329 _parser.SetExpr(sFuncArgument);
330 v = _parser.Eval(nReturn);
331 dArg.insert(dArg.end(), v, v+nReturn);
332
333 return (size_t)nReturn;
334 }
335
336
353 size_t StringFuncHandler::argumentParser(StringView __sFuncArgument, d_vect& dArg, n_vect& nArg)
354 {
355 size_t nMaxLength = 0;
356
357 // Get the single arguments
358 StringView sDouble = getNextViewedArgument(__sFuncArgument);
359 StringView sNumVal = getNextViewedArgument(__sFuncArgument);
360
361 // Handle the arguments using the basic functions
362 // and store the highest number of return values
363 nMaxLength = argumentParser(sDouble, dArg);
364
365 if (!nMaxLength)
366 return 0;
367
368 if (sNumVal.length())
369 {
370 size_t nReturn = argumentParser(sNumVal, nArg);
371
372 if (!nReturn)
373 return 0;
374
375 if (nMaxLength < nReturn)
376 nMaxLength = nReturn;
377 }
378
379 return nMaxLength;
380 }
381
382
398 size_t StringFuncHandler::argumentParser(StringView __sFuncArgument, s_vect& sArg, bool& bLogicalOnly)
399 {
403 std::string sFuncArgument = __sFuncArgument.to_string();
404
405 // If the current function argument contains strings,
406 // parse it correspondingly
407 if (isStringExpression(sFuncArgument) || _data.containsClusters(sFuncArgument))
408 {
409 // Call the string parser core
410 StringResult strRes = eval(sFuncArgument, "", true);
411
412 // Use the returned values as function arguments
413 sArg = strRes.vResult;
414
415 bLogicalOnly = strRes.bOnlyLogicals;
416 return strRes.vResult.size();
417 }
418 else if (_data.containsTablesOrClusters(sFuncArgument))
419 {
420 getDataElements(sFuncArgument, _parser, _data, _option, 0);
421
422 if (isStringExpression(sFuncArgument))
423 {
424 // Call the string parser core
425 StringResult strRes = eval(sFuncArgument, "", true);
426
427 // Use the returned values as function arguments
428 sArg = strRes.vResult;
429
430 bLogicalOnly = strRes.bOnlyLogicals;
431 return strRes.vResult.size();
432 }
433 }
434
435 // Expand the passed argument, if needed and
436 // distribute it to the components of the argument vector
437 if (sFuncArgument.find('{') != string::npos || sFuncArgument.find(',') != string::npos)
438 {
439 convertVectorToExpression(sFuncArgument, _option);
440
441 // As long as the function argument has a length,
442 // get the next argument and store it in the vector
443 while (sFuncArgument.length())
444 sArg.push_generic(removeQuotationMarks(getNextArgument(sFuncArgument, true)));
445 }
446 else
447 sArg.push_generic(removeQuotationMarks(sFuncArgument));
448
449 // Declare argument as numerical only
450 bLogicalOnly = true;
451
452 return sArg.size();
453 }
454
455
467 size_t StringFuncHandler::argumentParser(StringView __sFuncArgument, s_vect& sArg1, d_vect& dArg1)
468 {
469 size_t nMaxLength = 0;
470 bool bLogicalOnly = false;
471
472 // Get the single arguments
473 StringView sString = getNextViewedArgument(__sFuncArgument);
474 StringView sNumVal = getNextViewedArgument(__sFuncArgument);
475
476 // Handle the arguments using the basic functions
477 // and store the highets number of return values
478 nMaxLength = argumentParser(sString, sArg1, bLogicalOnly);
479
480 if (!nMaxLength)
481 return 0;
482
483 if (sNumVal.length())
484 {
485 size_t nReturn = argumentParser(sNumVal, dArg1);
486
487 if (!nReturn)
488 return 0;
489
490 if (nMaxLength < nReturn)
491 nMaxLength = nReturn;
492 }
493
494 return nMaxLength;
495 }
496
497
510 size_t StringFuncHandler::argumentParser(StringView __sFuncArgument, s_vect& sArg1, n_vect& nArg1, n_vect& nArg2)
511 {
512 size_t nMaxLength = 0;
513 bool bLogicalOnly = false;
514
515 // Get the single arguments
516 StringView sString = getNextViewedArgument(__sFuncArgument);
517 StringView sNumVal1 = getNextViewedArgument(__sFuncArgument);
518 StringView sNumVal2 = getNextViewedArgument(__sFuncArgument);
519
520 // Handle the arguments using the basic functions
521 // and store the highets number of return values
522 nMaxLength = argumentParser(sString, sArg1, bLogicalOnly);
523
524 if (!nMaxLength)
525 return 0;
526
527 if (sNumVal1.length())
528 {
529 size_t nReturn = argumentParser(sNumVal1, nArg1);
530
531 if (!nReturn)
532 return 0;
533
534 if (nMaxLength < nReturn)
535 nMaxLength = nReturn;
536 }
537 else
538 return nMaxLength;
539
540 if (sNumVal2.length())
541 {
542 size_t nReturn = argumentParser(sNumVal2, nArg2);
543
544 if (!nReturn)
545 return 0;
546
547 if (nMaxLength < nReturn)
548 nMaxLength = nReturn;
549 }
550
551 return nMaxLength;
552 }
553
554
570 size_t StringFuncHandler::argumentParser(StringView __sFuncArgument, s_vect& sArg1, n_vect& nArg1, n_vect& nArg2, s_vect& sArg2)
571 {
572 size_t nMaxLength = 0;
573 bool bLogicalOnly = false;
574
575 // Get the single arguments
576 StringView sString1 = getNextViewedArgument(__sFuncArgument);
577 StringView sNumVal1 = getNextViewedArgument(__sFuncArgument);
578 StringView sNumVal2 = getNextViewedArgument(__sFuncArgument);
579 StringView sString2 = getNextViewedArgument(__sFuncArgument);
580
581 // Handle the arguments using the basic functions
582 // and store the highets number of return values
583 nMaxLength = argumentParser(sString1, sArg1, bLogicalOnly);
584
585 if (!nMaxLength)
586 return 0;
587
588 if (sNumVal1.length())
589 {
590 size_t nReturn = argumentParser(sNumVal1, nArg1);
591
592 if (!nReturn)
593 return 0;
594
595 if (nMaxLength < nReturn)
596 nMaxLength = nReturn;
597 }
598 else
599 return nMaxLength;
600
601 if (sNumVal2.length())
602 {
603 size_t nReturn = argumentParser(sNumVal2, nArg2);
604
605 if (!nReturn)
606 return 0;
607
608 if (nMaxLength < nReturn)
609 nMaxLength = nReturn;
610 }
611 else
612 return nMaxLength;
613
614 if (sString2.length())
615 {
616 size_t nReturn = argumentParser(sString2, sArg2, bLogicalOnly);
617
618 if (!nReturn)
619 return 0;
620
621 if (nMaxLength < nReturn)
622 nMaxLength = nReturn;
623 }
624
625 return nMaxLength;
626 }
627
628
643 size_t StringFuncHandler::argumentParser(StringView __sFuncArgument, s_vect& sArg1, s_vect& sArg2, n_vect& nArg1, n_vect& nArg2)
644 {
645 size_t nMaxLength = 0;
646 bool bLogicalOnly = false;
647
648 // Get the single arguments
649 StringView sString1 = getNextViewedArgument(__sFuncArgument);
650 StringView sString2 = getNextViewedArgument(__sFuncArgument);
651 StringView sNumVal1 = getNextViewedArgument(__sFuncArgument);
652 StringView sNumVal2 = getNextViewedArgument(__sFuncArgument);
653
654 // Handle the arguments using the basic functions
655 // and store the highets number of return values
656 nMaxLength = argumentParser(sString1, sArg1, bLogicalOnly);
657
658 if (!nMaxLength)
659 return 0;
660
661 if (sString2.length())
662 {
663 size_t nReturn = argumentParser(sString2, sArg2, bLogicalOnly);
664
665 if (!nReturn)
666 return 0;
667
668 if (nMaxLength < nReturn)
669 nMaxLength = nReturn;
670 }
671 else
672 return nMaxLength;
673
674 if (sNumVal1.length())
675 {
676 size_t nReturn = argumentParser(sNumVal1, nArg1);
677
678 if (!nReturn)
679 return 0;
680
681 if (nMaxLength < nReturn)
682 nMaxLength = nReturn;
683 }
684 else
685 return nMaxLength;
686
687 if (sNumVal2.length())
688 {
689 size_t nReturn = argumentParser(sNumVal2, nArg2);
690
691 if (!nReturn)
692 return 0;
693
694 if (nMaxLength < nReturn)
695 nMaxLength = nReturn;
696 }
697
698 return nMaxLength;
699 }
700
701
717 size_t StringFuncHandler::argumentParser(StringView __sFuncArgument, s_vect& sArg1, s_vect& sArg2, s_vect& sArg3, n_vect& nArg1, n_vect& nArg2)
718 {
719 size_t nMaxLength = 0;
720 bool bLogicalOnly = false;
721
722 // Get the single arguments
723 StringView sString1 = getNextViewedArgument(__sFuncArgument);
724 StringView sString2 = getNextViewedArgument(__sFuncArgument);
725 StringView sString3 = getNextViewedArgument(__sFuncArgument);
726 StringView sNumVal1 = getNextViewedArgument(__sFuncArgument);
727 StringView sNumVal2 = getNextViewedArgument(__sFuncArgument);
728
729 // Handle the arguments using the basic functions
730 // and store the highets number of return values
731 nMaxLength = argumentParser(sString1, sArg1, bLogicalOnly);
732
733 if (!nMaxLength)
734 return 0;
735
736 if (sString2.length())
737 {
738 size_t nReturn = argumentParser(sString2, sArg2, bLogicalOnly);
739
740 if (!nReturn)
741 return 0;
742
743 if (nMaxLength < nReturn)
744 nMaxLength = nReturn;
745 }
746 else
747 return nMaxLength;
748
749 if (sString3.length())
750 {
751 size_t nReturn = argumentParser(sString3, sArg3, bLogicalOnly);
752
753 if (!nReturn)
754 return 0;
755
756 if (nMaxLength < nReturn)
757 nMaxLength = nReturn;
758 }
759 else
760 return nMaxLength;
761
762 if (sNumVal1.length())
763 {
764 size_t nReturn = argumentParser(sNumVal1, nArg1);
765
766 if (!nReturn)
767 return 0;
768
769 if (nMaxLength < nReturn)
770 nMaxLength = nReturn;
771 }
772 else
773 return nMaxLength;
774
775 if (sNumVal2.length())
776 {
777 size_t nReturn = argumentParser(sNumVal2, nArg2);
778
779 if (!nReturn)
780 return 0;
781
782 if (nMaxLength < nReturn)
783 nMaxLength = nReturn;
784 }
785
786 return nMaxLength;
787 }
788
789
806 std::vector<s_vect> StringFuncHandler::callFunction(StringFuncHandle funcHandle, s_vect& sStringArg1, s_vect& sStringArg2, s_vect& sStringArg3, n_vect& nIntArg1, n_vect& nIntArg2, d_vect& dValArg, size_t nMaxArgs)
807 {
808 StringFuncArgs stringArgs;
809 stringArgs.opt = &NumeReKernel::getInstance()->getSettings();
810
811 // Shortcut for empty function arguments
812 if (!nMaxArgs)
813 return std::vector<s_vect>(1, funcHandle.fHandle(stringArgs));
814
815 std::vector<s_vect> vReturnValues(nMaxArgs);
816
817 for (size_t i = 0; i < nMaxArgs; i++)
818 {
819 stringArgs.sArg1 = sStringArg1.getArg(i);
820 stringArgs.sArg2 = sStringArg2.getArg(i);
821 stringArgs.sArg3 = sStringArg3.getArg(i);
822
823 if (i < nIntArg1.size())
824 stringArgs.nArg1 = nIntArg1[i];
825 else if (nIntArg1.size() == 1)
826 stringArgs.nArg1 = nIntArg1[0];
827 else
828 stringArgs.nArg1 = DEFAULT_NUM_ARG;
829
830 if (i < nIntArg2.size())
831 stringArgs.nArg2 = nIntArg2[i];
832 else if (nIntArg2.size() == 1)
833 stringArgs.nArg2 = nIntArg2[0];
834 else
835 stringArgs.nArg2 = DEFAULT_NUM_ARG;
836
837 if (i < dValArg.size())
838 stringArgs.dArg1 = dValArg[i];
839 else if (dValArg.size() == 1)
840 stringArgs.dArg1 = dValArg[0];
841 else
842 stringArgs.dArg1 = 0.0;
843
844 vReturnValues[i] = funcHandle.fHandle(stringArgs);
845 }
846
847 return vReturnValues;
848 }
849
850
867 std::vector<s_vect> StringFuncHandler::callFunctionParallel(StringFuncHandle funcHandle, s_vect& sStringArg1, s_vect& sStringArg2, s_vect& sStringArg3, n_vect& nIntArg1, n_vect& nIntArg2, d_vect& dValArg, size_t nMaxArgs)
868 {
869 std::vector<s_vect> vReturnValues(nMaxArgs);
870
871 StringFuncArgs stringArgs;
872 stringArgs.opt = &NumeReKernel::getInstance()->getSettings();
873
874 #pragma omp parallel for firstprivate(stringArgs)
875 for (size_t i = 0; i < nMaxArgs; i++)
876 {
877 stringArgs.sArg1 = sStringArg1.getArg(i);
878 stringArgs.sArg2 = sStringArg2.getArg(i);
879 stringArgs.sArg3 = sStringArg3.getArg(i);
880
881 if (i < nIntArg1.size())
882 stringArgs.nArg1 = nIntArg1[i];
883 else if (nIntArg1.size() == 1)
884 stringArgs.nArg1 = nIntArg1[0];
885 else
886 stringArgs.nArg1 = DEFAULT_NUM_ARG;
887
888 if (i < nIntArg2.size())
889 stringArgs.nArg2 = nIntArg2[i];
890 else if (nIntArg2.size() == 1)
891 stringArgs.nArg2 = nIntArg2[0];
892 else
893 stringArgs.nArg2 = DEFAULT_NUM_ARG;
894
895 if (i < dValArg.size())
896 stringArgs.dArg1 = dValArg[i];
897 else if (dValArg.size() == 1)
898 stringArgs.dArg1 = dValArg[0];
899 else
900 stringArgs.dArg1 = 0.0;
901
902 vReturnValues[i] = funcHandle.fHandle(stringArgs);
903 }
904
905 return vReturnValues;
906 }
907
908
926 std::vector<s_vect> StringFuncHandler::callMultiFunction(StringFuncHandle funcHandle, s_vect& sStringArg1, s_vect& sStringArg2, s_vect& sStringArg3, n_vect& nIntArg1, n_vect& nIntArg2, d_vect& dValArg, size_t nMaxArgs)
927 {
928 std::vector<s_vect> vReturnValues(nMaxArgs);
929
930 StringFuncArgs stringArgs;
931 stringArgs.opt = &NumeReKernel::getInstance()->getSettings();
932 stringArgs.sMultiArg = sStringArg1;
933
934 for (size_t i = 0; i < nMaxArgs; i++)
935 {
936 stringArgs.sArg2 = sStringArg2.getArg(i);
937 stringArgs.sArg3 = sStringArg3.getArg(i);
938
939 if (i < nIntArg1.size())
940 stringArgs.nArg1 = nIntArg1[i];
941 else if (nIntArg1.size() == 1)
942 stringArgs.nArg1 = nIntArg1[0];
943 else
944 stringArgs.nArg1 = DEFAULT_NUM_ARG;
945
946 if (i < nIntArg2.size())
947 stringArgs.nArg2 = nIntArg2[i];
948 else if (nIntArg2.size() == 1)
949 stringArgs.nArg2 = nIntArg2[0];
950 else
951 stringArgs.nArg2 = DEFAULT_NUM_ARG;
952
953 if (i < dValArg.size())
954 stringArgs.dArg1 = dValArg[i];
955 else if (dValArg.size() == 1)
956 stringArgs.dArg1 = dValArg[0];
957 else
958 stringArgs.dArg1 = 0.0;
959
960 vReturnValues[i] = funcHandle.fHandle(stringArgs);
961 }
962
963 return vReturnValues;
964 }
965
966
984 std::vector<s_vect> StringFuncHandler::callMultiFunctionParallel(StringFuncHandle funcHandle, s_vect& sStringArg1, s_vect& sStringArg2, s_vect& sStringArg3, n_vect& nIntArg1, n_vect& nIntArg2, d_vect& dValArg, size_t nMaxArgs)
985 {
986 std::vector<s_vect> vReturnValues(nMaxArgs);
987
988 StringFuncArgs stringArgs;
989 stringArgs.opt = &NumeReKernel::getInstance()->getSettings();
990 stringArgs.sMultiArg = sStringArg1;
991
992 #pragma omp parallel for firstprivate(stringArgs)
993 for (size_t i = 0; i < nMaxArgs; i++)
994 {
995 stringArgs.sArg2 = sStringArg2.getArg(i);
996 stringArgs.sArg3 = sStringArg3.getArg(i);
997
998 if (i < nIntArg1.size())
999 stringArgs.nArg1 = nIntArg1[i];
1000 else if (nIntArg1.size() == 1)
1001 stringArgs.nArg1 = nIntArg1[0];
1002 else
1003 stringArgs.nArg1 = DEFAULT_NUM_ARG;
1004
1005 if (i < nIntArg2.size())
1006 stringArgs.nArg2 = nIntArg2[i];
1007 else if (nIntArg2.size() == 1)
1008 stringArgs.nArg2 = nIntArg2[0];
1009 else
1010 stringArgs.nArg2 = DEFAULT_NUM_ARG;
1011
1012 if (i < dValArg.size())
1013 stringArgs.dArg1 = dValArg[i];
1014 else if (dValArg.size() == 1)
1015 stringArgs.dArg1 = dValArg[0];
1016 else
1017 stringArgs.dArg1 = 0.0;
1018
1019 vReturnValues[i] = funcHandle.fHandle(stringArgs);
1020 }
1021
1022 return vReturnValues;
1023 }
1024
1025
1037 {
1041 size_t nStartPosition = 0;
1042 size_t nEndPosition;
1043
1044 // str string_cast(EXPR)
1045 while ((nStartPosition = findNextFunction("string_cast(", sLine, nStartPosition, nEndPosition)) != string::npos)
1046 {
1047 string sToString = getFunctionArgumentList("string_cast(", sLine, nStartPosition, nEndPosition).to_string();
1048
1049 if (sToString.find('"') != string::npos || sToString.find('#') != string::npos)
1050 {
1051 StringResult strRes = eval(sToString, "");
1052
1053 if (!strRes.vResult.size())
1055
1056 sToString = createStringVectorVar(strRes.vResult);
1057 }
1058 else
1059 sToString = "\"" + sToString + "\"";
1060
1061 sLine = sLine.substr(0, nStartPosition) + sToString + sLine.substr(nEndPosition + 1);
1062
1063 nStartPosition++;
1064 }
1065
1066 nStartPosition = 0;
1067 // cmd to_cmd(str)
1068 while ((nStartPosition = findNextFunction("to_cmd(", sLine, nStartPosition, nEndPosition)) != string::npos)
1069 {
1070 string sCmdString = getFunctionArgumentList("to_cmd(", sLine, nStartPosition, nEndPosition).to_string();
1071 StripSpaces(sCmdString);
1072
1073 if (isStringExpression(sCmdString))
1074 {
1075 StringResult strRes = eval(sCmdString, "");
1076
1077 if (!strRes.vResult.size())
1079
1080 // use only the first one
1081 sCmdString = strRes.vResult.front();
1082 }
1083
1084 // Because the result might be a constructed table, we
1085 // disable the access caching for this expression
1086 _parser.DisableAccessCaching();
1087
1088 sLine = sLine.substr(0, nStartPosition) + removeQuotationMarks(sCmdString) + sLine.substr(nEndPosition + 1);
1089 nStartPosition++;
1090 }
1091
1092 nStartPosition = 0;
1093 // val to_value(str)
1094 while ((nStartPosition = findNextFunction("to_value(", sLine, nStartPosition, nEndPosition)) != string::npos)
1095 {
1096 string sToValue = getFunctionArgumentList("to_value(", sLine, nStartPosition, nEndPosition).to_string();
1097 StripSpaces(sToValue);
1098
1099 if (isStringExpression(sToValue))
1100 {
1101 StringResult strRes = eval(sToValue, "");
1102
1103 if (!strRes.vResult.size())
1105
1106 vector<string> vToValueResults;
1107
1108 // Remove all quotation marks from the results TODO: Split the equations
1109 for (size_t i = 0; i < strRes.vResult.size(); i++)
1110 {
1111 std::string sComponent = strRes.vResult[i].to_string();
1112
1113 while (sComponent.length())
1114 {
1115 vToValueResults.push_back(getNextArgument(sComponent, true));
1116 }
1117 }
1118
1119 // Create a new string vector variable
1120 sToValue = createStringVectorVar(vToValueResults);
1121 }
1122
1123 // Because the result might be a constructed table, we
1124 // disable the access caching for this expression
1125 _parser.DisableAccessCaching();
1126
1127 sLine = sLine.substr(0, nStartPosition) + sToValue + sLine.substr(nEndPosition + 1);
1128 nStartPosition++;
1129 }
1130
1131 nStartPosition = 0;
1132 // log is_string(EXPR)
1133 while ((nStartPosition = findNextFunction("is_string(", sLine, nStartPosition, nEndPosition)) != string::npos)
1134 {
1135 string sArgument = getFunctionArgumentList("is_string(", sLine, nStartPosition, nEndPosition).to_string();
1136
1137 // check for data sets in the evaluation of the `valtostr()` arguments
1138 if (!isStringExpression(sArgument) && _data.containsTablesOrClusters(sArgument))
1139 getDataElements(sArgument, _parser, _data, _option);
1140
1141 if (!isStringExpression(sArgument))
1142 {
1143 int nResults = 0;
1144 _parser.SetExpr(sArgument);
1145 _parser.Eval(nResults);
1146 std::vector<std::string> vIsString(nResults, "false");
1147 sArgument = createStringVectorVar(vIsString);
1148 }
1149 else
1150 {
1151 StringResult strRes = eval(sArgument, "");
1152
1153 if (!strRes.vResult.size())
1155
1156 std::vector<std::string> vIsString;
1157
1158 for (size_t i = 0; i < strRes.vResult.size(); i++)
1159 {
1160 vIsString.push_back(strRes.vResult.is_string(i) ? "true" : "false");
1161 }
1162
1163 sArgument = createStringVectorVar(vIsString);
1164 }
1165
1166 sLine = sLine.substr(0, nStartPosition) + sArgument + sLine.substr(nEndPosition + 1);
1167 nStartPosition += sArgument.length();
1168 }
1169
1170 nStartPosition = 0;
1171 // {val} = getindices(str, [val])
1172 while ((nStartPosition = findNextFunction("getindices(", sLine, nStartPosition, nEndPosition)) != string::npos)
1173 {
1174 string _sObject = getFunctionArgumentList("getindices(", sLine, nStartPosition, nEndPosition).to_string();
1175 StringResult strRes = eval(_sObject, "");
1176
1177 if (!strRes.vResult.size())
1179
1180 // use only first one
1181 _sObject = strRes.vResult[0].to_string();
1182 int nType = 0;
1183
1184 if (strRes.vResult.size() > 1)
1185 {
1186 std::string sType = strRes.vResult[1].to_string();
1187
1188 if (sType.length())
1189 {
1190 StripSpaces(_sObject);
1191
1192 if (isStringExpression(sType))
1193 {
1194 StringResult res = eval(sType, "");
1195
1196 if (!res.vResult.size())
1198
1199 sType = res.vResult[0].to_string();
1200 }
1201
1202 _parser.SetExpr(sType);
1203 nType = intCast(_parser.Eval());
1204
1205 if (nType < -1 || nType > 2)
1206 nType = 0;
1207 }
1208 }
1209
1210 // Because the object might be a constructed table, we
1211 // disable the access caching for this expression
1212 _parser.DisableAccessCaching();
1213
1214 DataAccessParser _accessParser(_sObject);
1215
1216 if (!_accessParser.getDataObject().length() || !isValidIndexSet(_accessParser.getIndices()))
1217 {
1218 sLine = sLine.substr(0, nStartPosition) + "nan" + sLine.substr(nEndPosition + 1);
1219 nStartPosition++;
1220 continue;
1221 }
1222
1223 if (nType > -1)
1224 {
1225 if (nType == 2 && _accessParser.getIndices().row.isOpenEnd())
1226 _accessParser.getIndices().row.setRange(_accessParser.getIndices().row.front(),
1227 _accessParser.getIndices().row.front() + 1);
1228 else if (nType == 1 && _accessParser.getIndices().col.isOpenEnd())
1229 _accessParser.getIndices().col.setRange(_accessParser.getIndices().col.front(),
1230 _accessParser.getIndices().col.front() + 1);
1231
1232 if (_accessParser.isCluster())
1233 {
1234 if (_accessParser.getIndices().row.isOpenEnd())
1235 _accessParser.getIndices().row.setRange(0, _data.getCluster(_accessParser.getDataObject()).size()-1);
1236
1237 if (_accessParser.getIndices().col.isOpenEnd())
1238 _accessParser.getIndices().col.back() = VectorIndex::INVALID;
1239 }
1240 else if (_accessParser.getDataObject() == "string")
1241 {
1242 if (_accessParser.getIndices().row.isOpenEnd())
1243 {
1244 if (_accessParser.getIndices().col.size() == 1)
1245 {
1246 if (_data.getStringElements(_accessParser.getIndices().col.front()))
1247 _accessParser.getIndices().row.setRange(0, _data.getStringElements(_accessParser.getIndices().col.front())-1);
1248 else
1249 _accessParser.getIndices().row.setRange(0, 0);
1250 }
1251 else
1252 {
1253 if (_data.getStringElements())
1254 _accessParser.getIndices().row.setRange(0, _data.getStringElements()-1);
1255 else
1256 _accessParser.getIndices().row.setRange(0, 0);
1257 }
1258 }
1259
1260 if (_accessParser.getIndices().col.isOpenEnd())
1261 _accessParser.getIndices().col.setRange(0, _data.getStringCols()-1);
1262 }
1263 else
1264 {
1265 if (_accessParser.getIndices().row.isOpenEnd())
1266 _accessParser.getIndices().row.setRange(0, _data.getLines(_accessParser.getDataObject(), false)-1);
1267
1268 if (_accessParser.getIndices().col.isOpenEnd())
1269 _accessParser.getIndices().col.setRange(0, _data.getCols(_accessParser.getDataObject(), false)-1);
1270 }
1271 }
1272
1273 _accessParser.getIndices().row.linearize();
1274 _accessParser.getIndices().col.linearize();
1275
1276 vector<mu::value_type> vIndices;
1277 vIndices.push_back(_accessParser.getIndices().row.front() + 1);
1278 vIndices.push_back(_accessParser.getIndices().row.last() + 1);
1279 vIndices.push_back(_accessParser.getIndices().col.front() + 1);
1280 vIndices.push_back(_accessParser.getIndices().col.last() + 1);
1281 _parser.SetVectorVar("_~indices[" + replaceToVectorname(_sObject) + "]", vIndices);
1282 sLine = sLine.substr(0, nStartPosition) + "_~indices[" + replaceToVectorname(_sObject) + "]" + sLine.substr(nEndPosition + 1);
1283
1284 nStartPosition++;
1285 }
1286
1287 nStartPosition = 0;
1288 // log = is_data(EXPR)
1289 while ((nStartPosition = findNextFunction("is_data(", sLine, nStartPosition, nEndPosition)) != string::npos)
1290 {
1291 string sData = getFunctionArgumentList("is_data(", sLine, nStartPosition, nEndPosition).to_string();
1292
1293 if (isStringExpression(sData))
1294 {
1295 StringResult strRes = eval(sData, "");
1296
1297 if (!strRes.vResult.size())
1299
1300 // use only first one
1301 sData = strRes.vResult[0].to_string();
1302 }
1303
1304 StripSpaces(sData);
1305
1306 if (_data.isTable(sData) || _data.isCluster(sData))
1307 sLine = sLine.substr(0, nStartPosition) + "true" + sLine.substr(nEndPosition + 1);
1308 else
1309 sLine = sLine.substr(0, nStartPosition) + "false" + sLine.substr(nEndPosition + 1);
1310
1311 nStartPosition++;
1312 }
1313
1314 nStartPosition = 0;
1315 // log = is_table(EXPR)
1316 while ((nStartPosition = findNextFunction("is_table(", sLine, nStartPosition, nEndPosition)) != string::npos)
1317 {
1318 string sData = getFunctionArgumentList("is_table(", sLine, nStartPosition, nEndPosition).to_string();
1319
1320 if (isStringExpression(sData))
1321 {
1322 StringResult strRes = eval(sData, "");
1323
1324 if (!strRes.vResult.size())
1326
1327 // use only first one
1328 sData = strRes.vResult[0].to_string();
1329 }
1330
1331 StripSpaces(sData);
1332
1333 if (_data.isTable(sData))
1334 sLine = sLine.substr(0, nStartPosition) + "true" + sLine.substr(nEndPosition + 1);
1335 else
1336 sLine = sLine.substr(0, nStartPosition) + "false" + sLine.substr(nEndPosition + 1);
1337
1338 nStartPosition++;
1339 }
1340
1341 nStartPosition = 0;
1342 // log = is_cluster(EXPR)
1343 while ((nStartPosition = findNextFunction("is_cluster(", sLine, nStartPosition, nEndPosition)) != string::npos)
1344 {
1345 string sData = getFunctionArgumentList("is_cluster(", sLine, nStartPosition, nEndPosition).to_string();
1346
1347 if (isStringExpression(sData))
1348 {
1349 StringResult strRes = eval(sData, "");
1350
1351 if (!strRes.vResult.size())
1353
1354 // use only first one
1355 sData = strRes.vResult[0].to_string();
1356 }
1357
1358 StripSpaces(sData);
1359
1360 if (_data.isCluster(sData))
1361 sLine = sLine.substr(0, nStartPosition) + "true" + sLine.substr(nEndPosition + 1);
1362 else
1363 sLine = sLine.substr(0, nStartPosition) + "false" + sLine.substr(nEndPosition + 1);
1364
1365 nStartPosition++;
1366 }
1367
1368 nStartPosition = 0;
1369 // {var} = findcolumn("data","header")
1370 while ((nStartPosition = findNextFunction("findcolumn(", sLine, nStartPosition, nEndPosition)) != string::npos)
1371 {
1372 string sData = getFunctionArgumentList("findcolumn(", sLine, nStartPosition, nEndPosition).to_string();
1373 string sHeadline;
1374
1375 if (isStringExpression(sData))
1376 {
1377 StringResult strRes = eval(sData, "");
1378
1379 if (!strRes.vResult.size())
1381
1382 // use only first one
1383 sData = strRes.vResult[0].to_string();
1384 sHeadline = strRes.vResult[1].to_string();
1385 }
1386
1387 if (!sHeadline.length())
1389
1390 StripSpaces(sData);
1391 StripSpaces(sHeadline);
1392
1393 if (_data.isTable(sData))
1394 {
1395 sData.erase(sData.find("("));
1396 string sResult;
1397
1398 for (long long int i = 0; i < _data.getCols(sData, false); i++)
1399 {
1400 if (_data.getHeadLineElement(i, sData) == sHeadline)
1401 {
1402 if (sResult.length())
1403 sResult += ", ";
1404
1405 sResult += toString(i + 1);
1406 }
1407 }
1408
1409 if (!sResult.length())
1410 sResult = "nan";
1411
1412 if (sResult.find(',') != string::npos)
1413 sResult = "{" + sResult + "}";
1414
1415 sLine = sLine.substr(0, nStartPosition) + sResult + sLine.substr(nEndPosition + 1);
1416 }
1417 else
1418 sLine = sLine.substr(0, nStartPosition) + "nan" + sLine.substr(nEndPosition + 1);
1419
1420 nStartPosition++;
1421 }
1422
1423 nStartPosition = 0;
1424 // str = valtostr(EXPR, [str])
1425 while ((nStartPosition = findNextFunction("valtostr(", sLine, nStartPosition, nEndPosition)) != string::npos)
1426 {
1427 string sToString = getFunctionArgumentList("valtostr(", sLine, nStartPosition, nEndPosition).to_string();
1428 string sExpr = getNextArgument(sToString, true);
1429 string sChar = "";
1430 std::vector<mu::value_type> vCounts;
1431
1432 if (sToString.length())
1433 {
1434 sChar = getNextArgument(sToString, true);
1435
1436 if (isStringExpression(sChar))
1437 {
1438 StringResult strRes = eval(sChar, "");
1439
1440 if (!strRes.vResult.size())
1442
1443 // use only first one
1444 sChar = strRes.vResult[0].to_string();
1445 }
1446
1447 string sCnt = getNextArgument(sToString, true);
1448
1449 if (sCnt.length())
1450 {
1451 if (_data.containsTablesOrClusters(sCnt))
1452 getDataElements(sCnt, _parser, _data, _option);
1453
1454 _parser.SetExpr(sCnt);
1455 int nCount;
1456 value_type* v;
1457 v = _parser.Eval(nCount);
1458 vCounts.assign(v, v+nCount);
1459 }
1460 }
1461
1462 // check for data sets in the evaluation of the `valtostr()` arguments
1463 if (!isStringExpression(sExpr) && _data.containsTablesOrClusters(sExpr))
1464 getDataElements(sExpr, _parser, _data, _option);
1465
1466 if (!isStringExpression(sExpr))
1467 {
1468 int nResults = 0;
1469 value_type* v = 0;
1470 _parser.SetExpr(sExpr);
1471 v = _parser.Eval(nResults);
1472 vector<string> vToString;
1473 string sElement = "";
1474 size_t nLen = 0;
1475
1476 for (int n = 0; n < nResults; n++)
1477 {
1478 sElement = printValue(v[n]);
1479
1480 if (n < (int)vCounts.size())
1481 nLen = intCast(fabs(vCounts[n]));
1482
1483 while (sElement.length() < nLen && sChar.length())
1484 sElement.insert(0, sChar);
1485
1486 vToString.push_back("\"" + sElement + "\"");
1487 }
1488
1489 sToString = createStringVectorVar(vToString);
1490 }
1491 else
1492 {
1493 StringResult strRes = eval(sExpr, "");
1494 size_t nLen = 0;
1495
1496 if (!strRes.vResult.size())
1498
1499 for (size_t i = 0; i < strRes.vResult.size(); i++)
1500 {
1501 if (i < vCounts.size())
1502 nLen = intCast(fabs(vCounts[i]));
1503
1504 while (strRes.vResult[i].length() < nLen && sChar.length())
1505 strRes.vResult.getRef(i).insert(strRes.vResult.is_string(i) ? 1 : 0, sChar);
1506
1507 // add quotation marks, if they are missing
1508 strRes.vResult.convert_to_string(i);
1509 }
1510
1511 sToString = createStringVectorVar(strRes.vResult);
1512 }
1513
1514 sLine = sLine.substr(0, nStartPosition) + sToString + sLine.substr(nEndPosition + 1);
1515
1516 nStartPosition++;
1517 }
1518
1519 return sLine;
1520 }
1521
1522
1535 {
1536 for (auto iter = m_mStringFuncs.begin(); iter != m_mStringFuncs.end(); ++iter)
1537 {
1538 // Found an occurence -> call the string function handler
1539 if (sLine.find(iter->first + "(") != string::npos)
1540 {
1541 evalFunction(sLine, iter->first + "(", iter->second);
1542
1543 if (sLine.find('(') == string::npos)
1544 break;
1545 }
1546 }
1547
1548 return sLine;
1549 }
1550
1551
1561 void StringFuncHandler::declareStringFuncs(const map<string,StringFuncHandle>& mStringFuncs)
1562 {
1563 if (!m_mStringFuncs.size())
1564 m_mStringFuncs = mStringFuncs;
1565 }
1566
1567
1581 size_t StringFuncHandler::findNextFunction(const string& sFunc, StringView sLine, size_t nStartPos, size_t& nEndPosition, bool searchForMethods)
1582 {
1583 // Search for occurences of the passed function
1584 while ((nStartPos = sLine.find(sFunc, nStartPos)) != string::npos)
1585 {
1586 // Ignore false positives
1587 if ((nStartPos && !(isDelimiter(sLine[nStartPos-1]) || sLine[nStartPos-1] == '~'))
1588 || isInQuotes(sLine, nStartPos, true))
1589 {
1590 nStartPos++;
1591 continue;
1592 }
1593
1594 // Find the matching parenthesis
1595 if ((nEndPosition = getMatchingParenthesis(sLine.subview(nStartPos + sFunc.length() - 1))) == std::string::npos)
1596 throw SyntaxError(SyntaxError::UNMATCHED_PARENTHESIS, sLine.to_string(), nStartPos + sFunc.length() - 1);
1597
1598 // Update the end position and return the
1599 // starting position
1600 nEndPosition += nStartPos + sFunc.length() - 1;
1601
1602 // Catch method calls
1603 if (searchForMethods && nEndPosition+1 < sLine.length() && sLine[nEndPosition+1] == '.')
1604 {
1605 for (size_t i = nEndPosition+1; i < sLine.length(); i++)
1606 {
1607 if (sLine[i] == '(' || sLine[i] == '{')
1608 i += getMatchingParenthesis(sLine.subview(i));
1609 else if (sLine[i] == ')' || sLine[i] == '}')
1610 {
1611 // This block will only get activated, if we find an unmatched
1612 // closing paranthesis, which can happen with methods, that
1613 // don't need parentheses
1614 nEndPosition = i-1;
1615 break;
1616 }
1617
1618 if (isDelimiter(sLine[i]) || i+1 == sLine.length())
1619 {
1620 nEndPosition = i;
1621 break;
1622 }
1623 }
1624 }
1625
1626 return nStartPos;
1627 }
1628
1629 // Return string::npos, if nothing was found
1630 return string::npos;
1631 }
1632
1633
1646 StringView StringFuncHandler::getFunctionArgumentList(const std::string& sFunc, StringView sLine, size_t nStartPosition, size_t nEndPosition)
1647 {
1648 return sLine.subview(nStartPosition + sFunc.length(),
1649 nEndPosition - nStartPosition - sFunc.length());
1650 }
1651
1652
1662 {
1663 // Is one of the components zero, then try to find an
1664 // integer optimisation
1665 if (value.imag() == 0.0)
1666 {
1667 if (fabs(rint(value.real()) - value.real()) < 1e-14 && fabs(value.real()) >= 1.0)
1668 return toString(intCast(value.real()));
1669 }
1670 else if (value.real() == 0.0)
1671 {
1672 if (fabs(rint(value.imag()) - value.imag()) < 1e-14 && fabs(value.imag()) >= 1.0)
1673 return toString(intCast(value.imag())) + "i";
1674 }
1675
1676 // Otherwise do not optimize due to the fact that the
1677 // precision will get halved in this case
1678 return toString(value, NumeReKernel::getInstance()->getSettings().getPrecision());
1679 }
1680
1681}
1682
This class is defined to abstrahize the determination of the correct data object and the calculation ...
Definition: dataaccess.hpp:38
Indices & getIndices()
Returns a reference to the stored indices.
Definition: dataaccess.cpp:196
bool isCluster() const
Determines, whether the data access references a cluster.
Definition: dataaccess.cpp:209
std::string & getDataObject()
Returns a reference to the data object identifier.
Definition: dataaccess.cpp:170
This class represents the central memory managing instance. It will handle all tables and clusters,...
int getLines(StringView sTable, bool _bFull=false) const
bool isTable(const std::string &sTable) const
This member function returns, whether the passed table name corresponds to a known table.
std::string getHeadLineElement(int _i, const std::string &_sTable) const
bool containsTablesOrClusters(const std::string &sCmdLine)
This member function evaluates, whether the passed command line contains tables or clusters.
int getCols(StringView sTable, bool _bFull=false) const
size_t size() const
This member function returns the size of the internal memory buffer as items.
Definition: cluster.cpp:356
bool containsClusters(const std::string &sCmdLine) const
This member function detects, whether any cluster is used in the current expression.
Definition: cluster.cpp:1989
Cluster & getCluster(StringView sCluster)
This member function returns a reference to the cluster indicated by the passed cluster identifier.
Definition: cluster.cpp:2077
bool isCluster(StringView sCluster) const
This member function returns true, if the passed cluster identifier can be found in the internal map.
Definition: cluster.cpp:2041
std::string applyStringFuncs(std::string sLine)
This member function searches for an occurence of a known string function in the passed command line ...
std::string applySpecialStringFuncs(std::string sLine)
This member function applies special string functions in the expression, which cannot be implemented ...
size_t findNextFunction(const std::string &sFunc, StringView sLine, size_t nStartPos, size_t &nEndPosition, bool searchForMethods=false)
Finds the position of the next function occurence in the passed string including the position of the ...
virtual bool isStringExpression(const std::string &sExpression)=0
virtual StringResult eval(std::string &sLine, std::string sCache, bool bParseNumericals=true)=0
std::vector< s_vect > callMultiFunction(StringFuncHandle, s_vect &, s_vect &, s_vect &, n_vect &, n_vect &, d_vect &, size_t)
Calls the selected string function accepting multiple values as first argument using the passed strin...
void evalFunction(std::string &sLine, const std::string &sFuncName, StringFuncHandle)
This member function evaluates the passed call sequence to the string function.
StringView getFunctionArgumentList(const std::string &sFunc, StringView sLine, size_t nStartPosition, size_t nEndPosition)
Returns the contents of the argument parentheses of the function starting at nStartPosition.
std::vector< s_vect > callFunctionParallel(StringFuncHandle, s_vect &, s_vect &, s_vect &, n_vect &, n_vect &, d_vect &, size_t)
Calls the selected string function using the passed string function arguments parallel using OpenMP.
std::string addMaskedStrings(const std::string &sString)
This member function adds escape characters into the passed string and transforms the newstring chara...
void declareStringFuncs(const std::map< std::string, StringFuncHandle > &mStringFuncs)
This member function is used to fill the internal map of declared string functions with the data of t...
size_t argumentParser(StringView, n_vect &)
This member function is the string function argument parser for numerical arguments.
std::vector< s_vect > callFunction(StringFuncHandle, s_vect &, s_vect &, s_vect &, n_vect &, n_vect &, d_vect &, size_t)
Calls the selected string function using the passed string function arguments sequentially.
std::map< std::string, StringFuncHandle > m_mStringFuncs
std::vector< s_vect > callMultiFunctionParallel(StringFuncHandle, s_vect &, s_vect &, s_vect &, n_vect &, n_vect &, d_vect &, size_t)
Calls the selected string function accepting multiple values as first argument using the passed strin...
std::string printValue(const mu::value_type &value)
Prints a value to a string respecting possible integer optimizations.
StringVector expandStringVectorComponents(std::vector< StringVector > &vStringVector)
This member function expands the internal multi-expressions in the veector into separate components b...
std::string createStringVectorVar(const std::vector< std::string > &vStringVector)
This member function is used to create a string vector variable.
static NumeReKernel * getInstance()
This static member function returns a a pointer to the singleton instance of the kernel.
Definition: kernel.hpp:221
mu::Parser & getParser()
Definition: kernel.hpp:281
MemoryManager & getMemoryManager()
Definition: kernel.hpp:263
Settings & getSettings()
Definition: kernel.hpp:296
This class manages the setting values of the internal (kernel) settings of this application.
Definition: settings.hpp:663
unsigned int getStringCols() const
unsigned int getStringElements(unsigned int nCol=std::string::npos) const
This class is an extension to the std::vector<std::string> to provide the vector-like functionalities...
void push_back(const std::string &sStr)
Append a string to the end of this vector. Will be stored as local string.
std::string & getRef(size_t i)
Return a reference to the i-th element in this string.
void convert_to_string(size_t i, size_t minChars=0)
Convert the i-th element to a string.
void push_generic(const std::string &sStr)
Append a generic string value to the end of this vector. Depending on the existence of surrounding qu...
bool is_string(size_t i) const
Check whether the i-th element represents a string or a numeric value.
StringArg getArg(size_t i) const
Create a StringArg instance from the i-th or the 1st element, if this vector is a singleton.
std::string to_string() const
This member function returns a copy of the viewed section of the string (via std::string::substr)....
size_t find(const std::string &findstr, size_t pos=0) const
Wrapper member function for std::string::find()
size_t length() const
This member function simply returns the length of the viewed section.
This class is the immutable (const) version of a string view. It can be constructed from a MutableStr...
StringView subview(size_t pos=0, size_t len=std::string::npos) const
This member function creates a new StringView class instance using the selected position and length a...
Common exception class for all exceptions thrown in NumeRe.
Definition: error.hpp:32
@ UNMATCHED_PARENTHESIS
Definition: error.hpp:224
@ STRING_ERROR
Definition: error.hpp:209
static size_t invalid_position
Definition: error.hpp:235
void linearize()
This member function linearizes the contents of a vector-described index set. The vectorial informati...
Definition: structures.hpp:276
int last() const
This member function returns the last index value, which can be reached by the values stored internal...
Definition: structures.hpp:693
size_t size() const
This member function returns the size of the indices stored in this class.
Definition: structures.hpp:314
bool isOpenEnd() const
This member function determines, whether the internal index set has an open end.
Definition: structures.hpp:614
void setRange(int nMin, int nMax)
This member function can be used to force the indices stored internally to be in a defined interval....
Definition: structures.hpp:712
int & back()
This member function returns a reference to the final index value stored internally.
Definition: structures.hpp:653
int & front()
This member function returns a reference to the first index value stored internally.
Definition: structures.hpp:640
void SetExpr(StringView a_sExpr)
Set the expression. Triggers first time calculation thus the creation of the bytecode and scanning of...
value_type Eval()
Single-value wrapper around the vectorized overload of this member function.
void DisableAccessCaching()
Disable the data access caching for this position.
void SetVectorVar(const std::string &sVarName, const std::vector< mu::value_type > &vVar, bool bAddVectorType=false)
This member function copies the passed vector into the internal storage referencing it with the passe...
Mathematical expressions parser.
Definition: muParser.h:51
string getDataElements(string &sLine, Parser &_parser, MemoryManager &_data, const Settings &_option, int options)
Searches the passed string for calls to any table or cluster and replaces them with internal vectors ...
Definition: dataaccess.cpp:276
bool isValidIndexSet(const Indices &_idx)
Definition: dataaccess.hpp:81
unsigned int getMatchingParenthesis(const StringView &)
Returns the position of the closing parenthesis.
Definition: tools.cpp:414
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:251
value_type rint(value_type v)
void convertVectorToExpression(string &sLine, const Settings &_option)
This function replaces vector expressions with their corresponding multi- expression equation.
#define max(a, b)
Definition: resampler.cpp:30
void StripSpaces(std::string &)
Removes leading and trailing white spaces and tabulator characters.
std::vector< long long int > n_vect
Simple abbreviation.
@ PARSER_STRING_INT_INT_STRING
@ PARSER_STRING_STRING_STRING_INT_INT
@ PARSER_STRING_STRING_INT_INT
@ PARSER_STRING_INT_INT
@ PARSER_STRING_DOUBLE
std::vector< mu::value_type > d_vect
Simple abbreviation.
#define NEWSTRING
string addQuotationMarks(const string &sString)
This function simply adds the surrounding quotation marks.
#define DEFAULT_NUM_ARG
string removeQuotationMarks(const string &sString)
This function simply removes the surrounding quotation marks.
std::string getNextArgument(std::string &sArgList, bool bCut)
Definition: tools.cpp:2294
VectorIndex col
VectorIndex row
This structure combines all string function's arguments into a single structure to align all string f...
const Settings * opt
This structure defines the internal string function signature. It contains the pointer to the actual ...
FunctionSignatureType fType
This structure contains all possible return values of the central string parser in single combined st...
std::vector< mu::value_type > vNumericalValues
long long int intCast(const std::complex< double > &)
Casts the real part of the complex number to an integer and avoids rounding errors.
Definition: tools.cpp:1824
std::string toString(int)
Converts an integer to a string without the Settings bloat.
string replaceToVectorname(const string &sExpression)
This function replaces a data access expression (i.e. the contents of the object argument parentheses...
Definition: tools.cpp:3108
bool isInQuotes(StringView sExpr, unsigned int nPos, bool bIgnoreVarParser)
Checks, whether the position in the passed expression is part of a string literal.
Definition: tools.cpp:1672
StringView getNextViewedArgument(StringView &sView)
Definition: tools.cpp:2327
bool isDelimiter(char c)
This function determines, if the passed character is a delimiter character.
Definition: tools.cpp:1852