VM2D  1.12
Vortex methods for 2D flows simulation
StreamParser.h
Go to the documentation of this file.
1 /*--------------------------------*- VMlib -*----------------*---------------*\
2 | ## ## ## ## ## ## ## | | Version 1.12 |
3 | ## ## ### ### ## ## | VMlib: VM2D/VM3D Library | 2024/01/14 |
4 | ## ## ## # ## ## ## #### | Open Source Code *----------------*
5 | #### ## ## ## ## ## ## | https://www.github.com/vortexmethods/VM2D |
6 | ## ## ## #### ### #### | https://www.github.com/vortexmethods/VM3D |
7 | |
8 | Copyright (C) 2017-2024 Ilia Marchevsky |
9 *-----------------------------------------------------------------------------*
10 | File name: StreamParser.h |
11 | Info: Source code of VMlib |
12 | |
13 | This file is part of VMlib. |
14 | VMLib 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 | VMlib 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 VMlib. If not, see <http://www.gnu.org/licenses/>. |
26 \*---------------------------------------------------------------------------*/
27 
28 
37 #ifndef STREAMPARSER_H
38 #define STREAMPARSER_H
39 
40 //#define VARNAME(var) #var
41 
42 #include <algorithm>
43 #include <sstream>
44 #include <unordered_map>
45 
46 #include "defs.h"
47 #include "AirfoilGeometry.h"
48 #include "Gpu2D.h"
49 
50 namespace VMlib
51 {
57  inline int is_match(const std::string& line_, const std::string& pattern_)
58  {
59 
60  const auto lineCStr = line_.c_str();
61  const auto patternCStr = pattern_.c_str();
62 
63  const char* line = &(lineCStr[0]);
64  const char* pattern = &(patternCStr[0]);
65 
66  // returns 1 (true) if there is a match
67  // returns 0 if the pattern is not whitin the line
68  int wildcard = 0;
69 
70  const char* last_pattern_start = 0;
71  const char* last_line_start = 0;
72  do
73  {
74  if (*pattern == *line)
75  {
76  if (wildcard == 1)
77  last_line_start = line + 1;
78 
79  line++;
80  pattern++;
81  wildcard = 0;
82  }
83  else if (*pattern == '?')
84  {
85  if (*(line) == '\0') // the line is ended but char was expected
86  return 0;
87  if (wildcard == 1)
88  last_line_start = line + 1;
89  line++;
90  pattern++;
91  wildcard = 0;
92  }
93  else if (*pattern == '*')
94  {
95  if (*(pattern + 1) == '\0')
96  return 1;
97 
98  last_pattern_start = pattern;
99  //last_line_start = line + 1;
100  wildcard = 1;
101 
102  pattern++;
103  }
104  else if (wildcard)
105  {
106  if (*line == *pattern)
107  {
108  wildcard = 0;
109  line++;
110  pattern++;
111  last_line_start = line + 1;
112  }
113  else
114  line++;
115  }
116  else
117  {
118  if ((*pattern) == '\0' && (*line) == '\0') // end of mask
119  return 1; // if the line also ends here then the pattern match
120  else
121  {
122  if (last_pattern_start != 0) // try to restart the mask on the rest
123  {
124  pattern = last_pattern_start;
125  line = last_line_start;
126  last_line_start = 0;
127  }
128  else
129  return 0;
130  }
131  }
132 
133  } while (*line);
134 
135  if (*pattern == '\0')
136  return 1;
137  else
138  return 0;
139  };
140 
141 
142 
143 
144 
152  {
153  private:
154 
156  mutable LogStream info;
157 
162  public:
163  std::unordered_map<std::string, std::vector<std::string>> database;
164  private:
169  std::unordered_map<std::string, std::vector<std::string>> defaults;
170 
175  std::unordered_map<std::string, std::vector<std::string>> vars;
176 
181  std::unordered_map<std::string, std::vector<std::string>> switchers;
182 
193  void ParseStream(
194  std::istream& stream,
195  std::unordered_map<std::string, std::vector<std::string>>& database,
196  std::vector<std::string> specificKey = {},
197  bool replaceVars = false,
198  char openBracket = '(', char closeBracket = ')'
199  );
200 
206  void ReplaceVarsInString(std::string& st);
207 
208 
209  public:
222  StreamParser(LogStream& infoStream, const std::string& label, std::istream& mainStream, std::istream& defaultsStream, std::istream& switchersStream, std::istream& varsStream, std::vector<std::string> specificKey = {});
223 
234  StreamParser(LogStream& infoStream, const std::string& label, std::istream& mainStream, std::istream& defaultsStream, std::vector<std::string> specificKey = {});
235 
246  StreamParser(LogStream& infoStream, const std::string& label, std::istream& mainStream, char openBracket = '{', char closeBracket = '}');
247 
250 
255  static std::string UpperCase(const std::string& line);
256 
264  static std::vector<std::string> StringToVector(std::string line, char openBracket = '(', char closeBracket = ')');
265 
271  static std::string VectorStringToString(const std::vector<std::string>& _vecString);
272 
280  static std::pair<std::string, std::string> SplitString(LogStream& info, std::string line, bool upcase = true);
281 
290  template <typename T>
291  void SetDefault(const std::string& name, T& res, const T* defValue, bool echoDefault) const
292  {
293  if (defValue != nullptr)
294  {
295  res = *defValue;
296  if (echoDefault)
297  info('i') << "parameter <" << name << " = " << res << "> set as default" << std::endl;
298  }
299  else
300  {
301  info('e') << "parameter " << name << " is not found" << std::endl;
302  exit(-1);
303  }
304  }
305 
314  bool get(const std::string& name, std::vector<Point2D>& res, const std::vector<Point2D>* defValue = nullptr, bool echoDefault = true) const
315  {
316  bool boolRes = false;
317 
318  res.resize(0);
319 
320  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
321 
322  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
323  if (is_match(search_ita->first, UpperCase(name)))
324  break;
325 
326  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
327  if (is_match(search_itb->first, UpperCase(name)))
328  break;
329 
330  //поиск ключа в базе и, если нет, то в базе умолчаний
331  //if (((search_it = database.find(UpperCase(name))) != database.end()) ||
332  // ((search_it = defaults.find(UpperCase(name))) != defaults.end()))
333  if (((search_it = search_ita) != database.end()) ||
334  ((search_it = search_itb) != defaults.end()))
335  {
336  for (size_t i = 0; i < (search_it->second).size(); ++i)
337  {
338  std::string s = (search_it->second)[i];
339 
340  Point2D elem;
341  size_t pos = s.find(',', 1);
342  std::stringstream(s.substr(1, pos - 1)) >> elem[0];
343  std::stringstream(s.substr(pos + 1, s.length() - pos - 2)) >> elem[1];
344  res.push_back(elem);
345  }
346  boolRes = true;
347  }
348  //else
349  // SetDefault(name, res, defValue, echoDefault);
350  return boolRes;
351  };
352 
353 
362  bool get(const std::string& name, std::vector<v3D>& res, const std::vector<v3D>* defValue = nullptr, bool echoDefault = true) const
363  {
364  bool boolRes = false;
365 
366  res.resize(0);
367  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
368 
369  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
370  if (is_match(search_ita->first, UpperCase(name)))
371  break;
372 
373  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
374  if (is_match(search_itb->first, UpperCase(name)))
375  break;
376 
377  //поиск ключа в базе и, если нет, то в базе умолчаний
378  //if (((search_it = database.find(UpperCase(name))) != database.end()) ||
379  // ((search_it = defaults.find(UpperCase(name))) != defaults.end()))
380  if (((search_it = search_ita) != database.end()) ||
381  ((search_it = search_itb) != defaults.end()))
382  {
383  for (size_t i = 0; i < (search_it->second).size(); ++i)
384  {
385  std::string s = (search_it->second)[i];
386 
387  v3D elem;
388  size_t pos1 = s.find(',', 1);
389  std::stringstream(s.substr(1, pos1 - 1)) >> elem[0];
390  size_t pos2 = s.find(',', pos1 + 1);
391  std::stringstream(s.substr(pos1 + 1, pos2 - pos1 - 1)) >> elem[1];
392  std::stringstream(s.substr(pos2 + 1, s.length() - pos2 - 2)) >> elem[2];
393  res.push_back(elem);
394  }
395  boolRes = true;
396  }
397  //else
398  // SetDefault(name, res, defValue, echoDefault);
399 
400  return boolRes;
401  };
402 
411  template<typename T, typename P>
412  bool get(const std::string& name, std::vector<std::pair<T,P>>& res, const std::vector<std::pair<T, P>>* defValue = nullptr, bool echoDefault = true) const
413  {
414  bool boolRes = false;
415 
416  res.resize(0);
417  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
418 
419  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
420  if (is_match(search_ita->first, UpperCase(name)))
421  break;
422 
423  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
424  if (is_match(search_itb->first, UpperCase(name)))
425  break;
426 
427  //поиск ключа в базе и, если нет, то в базе умолчаний
428  //if (((search_it = database.find(UpperCase(name))) != database.end()) ||
429  // ((search_it = defaults.find(UpperCase(name))) != defaults.end()))
430  if (((search_it = search_ita) != database.end()) ||
431  ((search_it = search_itb) != defaults.end()))
432  {
433  for (size_t i = 0; i < (search_it->second).size(); ++i)
434  {
435  std::string s = (search_it->second)[i];
436 
437  std::pair<T,P> elem;
438  size_t pos = s.find(',', 1);
439  std::stringstream(s.substr(1, pos - 1)) >> elem.first;
440  std::stringstream(s.substr(pos + 1, s.length() - pos - 2)) >> elem.second;
441  res.push_back(elem);
442  }
443  boolRes = true;
444  }
445  //else
446  // SetDefault(name, res, defValue, echoDefault);
447 
448  return boolRes;
449  };
450 
451 
460  template<typename T>
461  bool get(const std::string& name, std::vector<numvector<T,2>>& res, const std::vector<numvector<T, 2>>* defValue = nullptr, bool echoDefault = true) const
462  {
463  bool boolRes = false;
464 
465  res.resize(0);
466  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
467 
468  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
469  if (is_match(search_ita->first, UpperCase(name)))
470  break;
471 
472  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
473  if (is_match(search_itb->first, UpperCase(name)))
474  break;
475 
476  //поиск ключа в базе и, если нет, то в базе умолчаний
477  //if (((search_it = database.find(UpperCase(name))) != database.end()) ||
478  // ((search_it = defaults.find(UpperCase(name))) != defaults.end()))
479  if (((search_it = search_ita) != database.end()) ||
480  ((search_it = search_itb) != defaults.end()))
481  {
482  for (size_t i = 0; i < (search_it->second).size(); ++i)
483  {
484  std::string s = (search_it->second)[i];
485 
486  numvector<T, 2> elem;
487  size_t pos = s.find(',', 1);
488  std::stringstream(s.substr(1, pos - 1)) >> elem[0];
489  std::stringstream(s.substr(pos + 1, s.length() - pos - 2)) >> elem[1];
490  res.push_back(elem);
491  }
492  boolRes = true;
493  }
494  //else
495  // SetDefault(name, res, defValue, echoDefault);
496 
497  return boolRes;
498  };
499 
500 
509  bool get(const std::string& name, std::vector<Vortex2D/*, VM2D::MyAlloc<VMlib::Vortex2D>*/>& res, const std::vector<Vortex2D>* defValue = nullptr, bool echoDefault = true) const
510  {
511  bool boolRes = false;
512 
513  res.resize(0);
514  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
515 
516  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
517  if (is_match(search_ita->first, UpperCase(name)))
518  break;
519 
520  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
521  if (is_match(search_itb->first, UpperCase(name)))
522  break;
523 
524  //поиск ключа в базе и, если нет, то в базе умолчаний
525  //if (((search_it = database.find(UpperCase(name))) != database.end()) ||
526  // ((search_it = defaults.find(UpperCase(name))) != defaults.end()))
527  if (((search_it = search_ita) != database.end()) ||
528  ((search_it = search_itb) != defaults.end()))
529  {
530  for (size_t i = 0; i < (search_it->second).size(); ++i)
531  {
532  std::string s = (search_it->second)[i];
533 
534  Point2D r;
535  double g;
536  size_t pos1 = s.find(',', 1);
537  size_t pos2 = s.find(',', pos1 + 1);
538  std::stringstream(s.substr(1, pos1 - 1)) >> r[0];
539  std::stringstream(s.substr(pos1 + 1, pos2 - pos1 - 1)) >> r[1];
540  std::stringstream(s.substr(pos2 + 1, s.length() - pos2 - 2)) >> g;
541 
542  Vortex2D elem(r, g);
543 
544  res.push_back(elem);
545  }
546  boolRes = true;
547  }
548  //else
549  // SetDefault(name, res, defValue, echoDefault);
550 
551  return boolRes;
552  };
553 
554 
563  bool get(const std::string& name, std::vector<GeomPoint>& res, const std::vector<GeomPoint>* defValue = nullptr, bool echoDefault = true) const
564  {
565  bool boolRes = false;
566 
567  res.resize(0);
568  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
569 
570  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
571  if (is_match(search_ita->first, UpperCase(name)))
572  break;
573 
574  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
575  if (is_match(search_itb->first, UpperCase(name)))
576  break;
577 
578  //поиск ключа в базе и, если нет, то в базе умолчаний
579  //if (((search_it = database.find(UpperCase(name))) != database.end()) ||
580  // ((search_it = defaults.find(UpperCase(name))) != defaults.end()))
581  if (((search_it = search_ita) != database.end()) ||
582  ((search_it = search_itb) != defaults.end()))
583  {
584  for (size_t i = 0; i < (search_it->second).size(); ++i)
585  {
586  std::string s = (search_it->second)[i];
587 
588  Point2D r;
589  std::string type;
590  size_t pos1 = s.find(',', 1);
591  size_t pos2 = s.find(',', pos1 + 1);
592  std::stringstream(s.substr(1, pos1 - 1)) >> r[0];
593  std::stringstream(s.substr(pos1 + 1, pos2 - pos1 - 1)) >> r[1];
594  std::stringstream(s.substr(pos2 + 1, s.length() - pos2 - 2)) >> type;
595 
596  GeomPoint elem(r, type);
597 
598 
599  res.push_back(elem);
600  }
601  boolRes = true;
602  }
603  //else
604  // SetDefault(name, res, defValue, echoDefault);
605 
606 
607  return boolRes;
608  };
609 
610 
611 
612 
622  template <typename T>
623  bool get(const std::string& name, std::vector<T>& res, const std::vector<T>* defValue = nullptr, bool echoDefault = true) const
624  {
625  bool boolRes = false;
626 
627  res.resize(0);
628  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
629 
630  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
631  if (is_match(search_ita->first, UpperCase(name)))
632  break;
633 
634  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
635  if (is_match(search_itb->first, UpperCase(name)))
636  break;;
637 
638  //поиск ключа в базе и, если нет, то в базе умолчаний
639  //if (((search_it = database.find(UpperCase(name))) != database.end()) ||
640  // ((search_it = defaults.find(UpperCase(name))) != defaults.end()))
641  if (((search_it = search_ita) != database.end()) ||
642  ((search_it = search_itb) != defaults.end()))
643  {
644  for (size_t i = 0; i < (search_it->second).size(); ++i)
645  {
646  std::string s = (search_it->second)[i];
647 
648  std::stringstream ss(s);
649  T elem;
650  ss >> elem;
651  if (typeid(elem).name() == typeid(std::string("TestString")).name())
652  {
653  std::string* str = reinterpret_cast<std::string*>(&elem);
654  str->erase(remove(str->begin(), str->end(), '\"'), str->end());
655  }
656  res.push_back(elem);
657  }
658  boolRes = true;
659  }
660  else
661  SetDefault(name, res, defValue, echoDefault);
662 
663  return boolRes;
664  };
665 
666 
676  template <typename T>
677  bool get(const std::string& name, std::pair<std::string, T>& res, const std::pair<std::string, T>* defValue = nullptr, bool echoDefault = true) const
678  {
679  bool boolRes = false;
680 
681  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
682 
683  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
684  if (is_match(search_ita->first, UpperCase(name)))
685  break;
686 
687  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
688  if (is_match(search_itb->first, UpperCase(name)))
689  break;
690 
691  //поиск ключа в базе и, если нет, то в базе умолчаний
692  //if ((((search_it = database.find(UpperCase(name))) != database.end()) && ((search_it->second).size() > 0)) ||
693  // (((search_it = defaults.find(UpperCase(name))) != defaults.end()) && ((search_it->second).size() > 0)))
694  if ((((search_it = search_ita) != database.end()) && ((search_it->second).size() > 0)) ||
695  (((search_it = search_itb) != defaults.end()) && ((search_it->second).size() > 0)))
696  {
697  if ((search_it->second).size() == 1)
698  {
699  std::string s = (search_it->second)[0];
700  res.first = s;
701 
702  //проверка на значение-переключатель
703  if (((search_it = switchers.find(UpperCase(s))) != switchers.end()) && ((search_it->second).size() > 0))
704  s = search_it->second[0];
705 
706  std::stringstream ss(s);
707  T elem;
708  ss >> elem;
709  if (typeid(elem).name() == typeid(std::string("TestString")).name())
710  {
711  std::string* str = reinterpret_cast<std::string*>(&elem);
712  str->erase(remove(str->begin(), str->end(), '\"'), str->end());
713  }
714  res.second = elem;
715  boolRes = true;
716  }
717  else
718  {
719  info('e') << "parameter " << name << " is list (only scalar is available)" << std::endl;
720  exit(-1);
721  }
722  }
723  else
724  SetDefault(name, res, defValue, echoDefault);
725 
726  return boolRes;
727  };
728 
729 
730 
731 
741  template <typename T>
742  bool get(const std::string& name, T& res, const T* defValue = nullptr, bool echoDefault = true) const
743  {
744  bool boolRes = false;
745 
746  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
747 
748  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
749  if (is_match(search_ita->first, UpperCase(name)))
750  break;
751 
752  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
753  if (is_match(search_itb->first, UpperCase(name)))
754  break;
755 
756  //поиск ключа в базе и, если нет, то в базе умолчаний
757  //if ((((search_it = database.find(UpperCase(name))) != database.end()) && ((search_it->second).size() > 0)) ||
758  // (((search_it = defaults.find(UpperCase(name))) != defaults.end()) && ((search_it->second).size() > 0)))
759  if ((((search_it = search_ita) != database.end()) && ((search_it->second).size() > 0)) ||
760  (((search_it = search_itb) != defaults.end()) && ((search_it->second).size() > 0)))
761  {
762  if ((search_it->second).size() == 1)
763  {
764  std::string s = (search_it->second)[0];
765 
766  //проверка на значение-переключатель
767  if (((search_it = switchers.find(UpperCase(s))) != switchers.end()) && ((search_it->second).size() > 0))
768  s = search_it->second[0];
769 
770  std::stringstream ss(s);
771  T elem;
772  ss >> elem;
773  if (typeid(elem).name() == typeid(std::string("TestString")).name())
774  {
775  std::string* str = reinterpret_cast<std::string*>(&elem);
776  str->erase(remove(str->begin(), str->end(), '\"'), str->end());
777  }
778  res = elem;
779  boolRes = true;
780  }
781  else
782  {
783  info('e') << "parameter " << name << " is list (only scalar is available)" << std::endl;
784  exit(-1);
785  }
786  }
787  else
788  SetDefault(name, res, defValue, echoDefault);
789 
790  return boolRes;
791  };
792 
793 
794 
803  bool get(const std::string& name, Point2D& res, const Point2D* defValue = nullptr, bool echoDefault = true) const
804  {
805  bool boolRes = false;
806 
807  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
808 
809  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
810  if (is_match(search_ita->first, UpperCase(name)))
811  break;
812 
813  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
814  if (is_match(search_itb->first, UpperCase(name)))
815  break;
816 
817  //поиск ключа в базе и, если нет, то в базе умолчаний
818  //if (((search_it = database.find(UpperCase(name))) != database.end()) ||
819  // ((search_it = defaults.find(UpperCase(name))) != defaults.end()))
820  if (((search_it = search_ita) != database.end()) ||
821  ((search_it = search_itb) != defaults.end()))
822  {
823  if ((search_it->second).size() == res.size())
824  {
825  for (size_t i = 0; i < (search_it->second).size(); ++i)
826  {
827  std::string s = (search_it->second)[i];
828 
829  std::stringstream ss(s);
830  double elem;
831  ss >> elem;
832  res[i] = elem;
833  }
834  boolRes = true;
835  }
836  else
837  {
838  info('e') << "parameter " << name << " length differs from 2 (only Point2D is available)" << std::endl;
839  exit(-1);
840  }
841 
842  }
843  else
844  SetDefault(name, res, defValue, echoDefault);
845 
846  return boolRes;
847  }
848 
849 
858  bool get(const std::string& name, v3D& res, const v3D* defValue = nullptr, bool echoDefault = true) const
859  {
860  bool boolRes = false;
861 
862  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
863 
864  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
865  if (is_match(search_ita->first, UpperCase(name)))
866  break;
867 
868  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
869  if (is_match(search_itb->first, UpperCase(name)))
870  break;
871 
872  //поиск ключа в базе и, если нет, то в базе умолчаний
873  //if (((search_it = database.find(UpperCase(name))) != database.end()) ||
874  // ((search_it = defaults.find(UpperCase(name))) != defaults.end()))
875  if (((search_it = search_ita) != database.end()) ||
876  ((search_it = search_itb) != defaults.end()))
877  {
878  if ((search_it->second).size() == res.size())
879  {
880  for (size_t i = 0; i < (search_it->second).size(); ++i)
881  {
882  std::string s = (search_it->second)[i];
883 
884  std::stringstream ss(s);
885  double elem;
886  ss >> elem;
887  res[i] = elem;
888  }
889  boolRes = true;
890  }
891  else
892  {
893  info('e') << "parameter " << name << " length differs from 3 (only v3D is available)" << std::endl;
894  exit(-1);
895  }
896 
897  }
898  else
899  SetDefault(name, res, defValue, echoDefault);
900 
901  return boolRes;
902  }
903 
904 
913  bool get(const std::string& name, bool& res, const bool* defValue = nullptr, bool echoDefault = true) const
914  {
915  bool boolRes = false;
916 
917  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
918 
919  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
920  if (is_match(search_ita->first, UpperCase(name)))
921  break;
922 
923  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
924  if (is_match(search_itb->first, UpperCase(name)))
925  break;
926 
927  //поиск ключа в базе и, если нет, то в базе умолчаний
928  //if ((((search_it = database.find(UpperCase(name))) != database.end()) && ((search_it->second).size() > 0)) ||
929  // (((search_it = defaults.find(UpperCase(name))) != defaults.end()) && ((search_it->second).size() > 0)))
930  if ((((search_it = search_ita) != database.end()) && ((search_it->second).size() > 0)) ||
931  (((search_it = search_itb) != defaults.end()) && ((search_it->second).size() > 0)))
932  {
933  if ((search_it->second).size() == 1)
934  {
935  std::string s = (search_it->second)[0];
936 
937  //проверка на значение-переключатель
938  if (((search_it = switchers.find(UpperCase(s))) != switchers.end()) && ((search_it->second).size() > 0))
939  s = search_it->second[0];
940 
941  if ((UpperCase(s) == "FALSE") || (UpperCase(s) == "NO") || (s.c_str()[0] == '0'))
942  res = false;
943  else
944  res = true;
945 
946  boolRes = true;
947  }
948  else
949  {
950  info('e') << "parameter " << name << " is list (only scalar is available)" << std::endl;
951  exit(-1);
952  }
953  }
954  else
955  SetDefault(name, res, defValue, echoDefault);
956 
957  return boolRes;
958  };//get(...)
959 
960 
970  bool get(const std::string& name, std::pair<std::pair<std::string, int>, std::string>& res, const std::pair<std::pair<std::string, int>, std::string>* defValue = nullptr, bool echoDefault = true) const
971  {
972  bool boolRes = false;
973 
974  std::unordered_map<std::string, std::vector<std::string>>::const_iterator search_it, search_ita, search_itb;
975 
976  for (search_ita = database.begin(); search_ita != database.end(); ++search_ita)
977  if (is_match(search_ita->first, UpperCase(name)))
978  break;
979 
980  for (search_itb = defaults.begin(); search_itb != defaults.end(); ++search_itb)
981  if (is_match(search_itb->first, UpperCase(name)))
982  break;
983 
984  //поиск ключа в базе и, если нет, то в базе умолчаний
985  //if ((((search_it = database.find(UpperCase(name))) != database.end()) && ((search_it->second).size() > 0)) ||
986  // (((search_it = defaults.find(UpperCase(name))) != defaults.end()) && ((search_it->second).size() > 0)))
987  if ((((search_it = search_ita) != database.end()) && ((search_it->second).size() > 0)) ||
988  (((search_it = search_itb) != defaults.end()) && ((search_it->second).size() > 0)))
989  {
990  if ((search_it->second).size() == 1)
991  {
992  std::string s = (search_it->second)[0];
993 
994  size_t posBegin = s.find('(');
995  size_t posEnd = s.find(')');
996 
997  if ((posBegin != -1) && (posEnd == -1))
998  {
999  info('e') << "parameter " << name << " is given incorrectly" << std::endl;
1000  exit(-1);
1001  }
1002  else
1003  {
1004  std::string str1a, str1b, str2;
1005  str1a = s.substr(0, posBegin);
1006 
1007  if (((search_it = switchers.find(UpperCase(str1a))) != switchers.end()) && ((search_it->second).size() > 0))
1008  str1b = search_it->second[0];
1009  else
1010  str1b = "-1";
1011 
1012  std::stringstream ssStr1b;
1013  ssStr1b << str1b;
1014  int res1b;
1015  ssStr1b >> res1b;
1016 
1017  str2 = s.substr(posBegin + 1, posEnd - posBegin - 1);
1018 
1019  if ((posBegin == -1) && (posEnd == -1))
1020  res = { {str1a, res1b}, "" };
1021  else
1022  res = { {str1a, res1b}, str2 };
1023 
1024  boolRes = true;
1025  }
1026  }
1027  else
1028  {
1029  info('e') << "parameter " << name << " is list (only scalar is available)" << std::endl;
1030  exit(-1);
1031  }
1032  }
1033  else
1034  SetDefault(name, res, defValue, echoDefault);
1035 
1036  return boolRes;
1037  };
1038  };
1039 
1040 }//namespace VMlib
1041 
1042 #endif
Шаблонный класс, определяющий вектор фиксированной длины Фактически представляет собой массив...
Definition: numvector.h:95
void ReplaceVarsInString(std::string &st)
Замена переменных в строке их значениями
Класс, определяющий работу с потоком логов
Definition: LogStream.h:53
int is_match(const std::string &line_, const std::string &pattern_)
Функция сверки строки с шаблоном, который может содержать знаки * и ?
Definition: StreamParser.h:57
std::unordered_map< std::string, std::vector< std::string > > defaults
Данные считываемые из списка умолчаний
Definition: StreamParser.h:169
Описание базовых вспомогательных функций
LogStream info
Поток для вывода логов и сообщений об ошибках
Definition: StreamParser.h:156
void SetDefault(const std::string &name, T &res, const T *defValue, bool echoDefault) const
Установка значения параметра по умолчанию
Definition: StreamParser.h:291
static std::vector< std::string > StringToVector(std::string line, char openBracket= '(', char closeBracket= ')')
Pазбор строки, содержащей запятые, на отдельные строки
Класс, опеделяющий двумерный вектор
Definition: v3D.h:55
Класс, опеделяющий двумерный вектор
Definition: Point2D.h:75
static std::pair< std::string, std::string > SplitString(LogStream &info, std::string line, bool upcase=true)
Разбор строки на пару ключ-значение
std::unordered_map< std::string, std::vector< std::string > > database
Данные считываемые из основного файла-паспорта расчета
Definition: StreamParser.h:163
std::unordered_map< std::string, std::vector< std::string > > vars
Данные считываемые из параметров конкретной задачи
Definition: StreamParser.h:175
Класс, опеделяющий двумерный вихревой элемент
Definition: Vortex2D.h:51
StreamParser(LogStream &infoStream, const std::string &label, std::istream &mainStream, std::istream &defaultsStream, std::istream &switchersStream, std::istream &varsStream, std::vector< std::string > specificKey={})
Конструктор, принимающий четыре потока
static std::string VectorStringToString(const std::vector< std::string > &_vecString)
Объединение вектора (списка) из строк в одну строку
void ParseStream(std::istream &stream, std::unordered_map< std::string, std::vector< std::string >> &database, std::vector< std::string > specificKey={}, bool replaceVars=false, char openBracket= '(', char closeBracket= ')')
Парсинг заданного потока
Заголовочный файл с описанием класса Gpu.
Класс, позволяющий выполнять разбор файлов и строк с настройками и параметрами
Definition: StreamParser.h:151
std::unordered_map< std::string, std::vector< std::string > > switchers
Данные считываемые из перечня параметров-переключателей
Definition: StreamParser.h:181
~StreamParser()
Деструктор
Definition: StreamParser.h:249
static std::string UpperCase(const std::string &line)
Перевод строки в верхний регистр