Reference documentation for deal.II version 9.3.3
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
patterns.cc
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 1998 - 2020 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
16
22
24#define BOOST_BIND_GLOBAL_PLACEHOLDERS
25#include <boost/io/ios_state.hpp>
26#include <boost/property_tree/json_parser.hpp>
27#include <boost/property_tree/ptree.hpp>
28#include <boost/property_tree/xml_parser.hpp>
29#undef BOOST_BIND_GLOBAL_PLACEHOLDERS
31
32#include <algorithm>
33#include <cctype>
34#include <cstdlib>
35#include <cstring>
36#include <fstream>
37#include <iomanip>
38#include <iostream>
39#include <limits>
40#include <sstream>
41
42
44
45
46
47// TODO[WB]: various functions here could be simplified by using namespace
48// Utilities
49
50namespace Patterns
51{
52 namespace internal
53 {
54 std::string
55 escape(const std::string &input, const PatternBase::OutputStyle style)
56 {
57 switch (style)
58 {
61 return input;
63 {
64 std::string u;
65 u.reserve(input.size());
66 for (const auto c : input)
67 {
68 switch (c)
69 {
70 case '#':
71 case '@f$':
72 case '%':
73 case '&':
74 case '_':
75 case '{':
76 case '}':
77 // simple escaping:
78 u.push_back('\\');
79 u.push_back(c);
80 break;
81
82 case '\\':
83 u.append("\\textbackslash{}");
84 break;
85
86 case '^':
87 u.append("\\^{}");
88 break;
89
90 case '~':
91 u.append("\\~{}");
92 break;
93
94 default:
95 // all other chars are just copied:
96 u.push_back(c);
97 }
98 }
99 return u;
100 }
101 default:
102 Assert(false, ExcNotImplemented());
103 }
104 return "";
105 }
106
107 } // namespace internal
108
109
110 namespace
111 {
118 bool
119 has_only_whitespace(std::istream &in)
120 {
121 while (in)
122 {
123 char c;
124
125 // skip if we've reached the end of
126 // the line
127 if (!(in >> c))
128 break;
129
130 if ((c != ' ') && (c != '\t'))
131 return false;
132 }
133 return true;
134 }
135 } // namespace
136
137
138
139 std::unique_ptr<PatternBase>
140 pattern_factory(const std::string &description)
141 {
142 std::unique_ptr<PatternBase> p;
143
144 p = Integer::create(description);
145 if (p != nullptr)
146 return p;
147
148 p = Double::create(description);
149 if (p != nullptr)
150 return p;
151
152 p = Selection::create(description);
153 if (p != nullptr)
154 return p;
155
156 p = List::create(description);
157 if (p != nullptr)
158 return p;
159
160 p = Map::create(description);
161 if (p != nullptr)
162 return p;
163
164 p = MultipleSelection::create(description);
165 if (p != nullptr)
166 return p;
167
168 p = Bool::create(description);
169 if (p != nullptr)
170 return p;
171
172 p = Anything::create(description);
173 if (p != nullptr)
174 return p;
175
176 p = FileName::create(description);
177 if (p != nullptr)
178 return p;
179
180 p = DirectoryName::create(description);
181 if (p != nullptr)
182 return p;
183
184 Assert(false, ExcNotImplemented());
185
186 return p;
187 }
188
189
190
191 std::size_t
193 {
194 if (dynamic_cast<const Integer *>(this) != nullptr)
195 return sizeof(Integer);
196 else if (dynamic_cast<const Double *>(this) != nullptr)
197 return sizeof(Double);
198 else if (dynamic_cast<const Bool *>(this) != nullptr)
199 return sizeof(Bool);
200 else if (dynamic_cast<const Anything *>(this) != nullptr)
201 return sizeof(Anything);
202 else
203 return sizeof(*this) + 32;
204 }
205
206
207
210
211 const char *Integer::description_init = "[Integer";
212
213 Integer::Integer(const int lower_bound, const int upper_bound)
215 , upper_bound(upper_bound)
216 {}
217
218
219
220 bool
221 Integer::match(const std::string &test_string) const
222 {
223 std::istringstream str(test_string);
224
225 int i;
226 if (!(str >> i))
227 return false;
228
229 if (!has_only_whitespace(str))
230 return false;
231 // check whether valid bounds
232 // were specified, and if so
233 // enforce their values
235 return ((lower_bound <= i) && (upper_bound >= i));
236 else
237 return true;
238 }
239
240
241
242 std::string
244 {
245 switch (style)
246 {
247 case Machine:
248 {
249 // check whether valid bounds
250 // were specified, and if so
251 // output their values
253 {
254 std::ostringstream description;
255
256 description << description_init << " range " << lower_bound
257 << "..." << upper_bound << " (inclusive)]";
258 return description.str();
259 }
260 else
261 // if no bounds were given, then
262 // return generic string
263 return "[Integer]";
264 }
265 case Text:
266 {
268 {
269 std::ostringstream description;
270
271 description << "An integer n such that " << lower_bound
272 << " <= n <= " << upper_bound;
273
274 return description.str();
275 }
276 else
277 return "An integer";
278 }
279 case LaTeX:
280 {
282 {
283 std::ostringstream description;
284
285 description << "An integer @f$n@f$ such that @f$" << lower_bound
286 << "\\leq n \\leq " << upper_bound << "@f$";
287
288 return description.str();
289 }
290 else
291 return "An integer";
292 }
293 default:
295 }
296 // Should never occur without an exception, but prevent compiler from
297 // complaining
298 return "";
299 }
300
301
302
303 std::unique_ptr<PatternBase>
305 {
306 return std::unique_ptr<PatternBase>(new Integer(lower_bound, upper_bound));
307 }
308
309
310
311 std::unique_ptr<Integer>
312 Integer::create(const std::string &description)
313 {
314 if (description.compare(0,
315 std::strlen(description_init),
316 description_init) == 0)
317 {
318 std::istringstream is(description);
319
320 if (is.str().size() > strlen(description_init) + 1)
321 {
322 // TODO: verify that description matches the pattern "^\[Integer
323 // range \d+\.\.\.\d+\]@f$"
325
326 is.ignore(strlen(description_init) + strlen(" range "));
327
328 if (!(is >> lower_bound))
329 return std::make_unique<Integer>();
330
331 is.ignore(strlen("..."));
332
333 if (!(is >> upper_bound))
334 return std::make_unique<Integer>();
335
336 return std::make_unique<Integer>(lower_bound, upper_bound);
337 }
338 else
339 return std::make_unique<Integer>();
340 }
341 else
342 return std::unique_ptr<Integer>();
343 }
344
345
346
349
350 const char *Double::description_init = "[Double";
351
352 Double::Double(const double lower_bound, const double upper_bound)
354 , upper_bound(upper_bound)
355 {}
356
357
358
359 bool
360 Double::match(const std::string &test_string) const
361 {
362 std::istringstream str(test_string);
363
364 double d;
365 str >> d;
366 if (str.fail())
367 return false;
368
369 if (!has_only_whitespace(str))
370 return false;
371 // check whether valid bounds
372 // were specified, and if so
373 // enforce their values
375 return ((lower_bound <= d) && (upper_bound >= d));
376 else
377 return true;
378 }
379
380
381
382 std::string
384 {
385 switch (style)
386 {
387 case Machine:
388 {
389 std::ostringstream description;
390
392 {
393 // bounds are valid
395 // We really want to compare with ==, but -Wfloat-equal would
396 // create a warning here, so work around it.
397 if (0 == std::memcmp(&lower_bound,
399 sizeof(lower_bound)))
400 description << "-MAX_DOUBLE";
401 else
403 description << "...";
404 if (0 == std::memcmp(&upper_bound,
406 sizeof(upper_bound)))
407 description << "MAX_DOUBLE";
408 else
410 description << " (inclusive)]";
411 return description.str();
412 }
413 else
414 {
415 // invalid bounds, assume unbounded double:
417 return description.str();
418 }
419 }
420 case Text:
421 {
423 {
424 std::ostringstream description;
425
426 description << "A floating point number v such that ";
427 if (0 == std::memcmp(&lower_bound,
429 sizeof(lower_bound)))
430 description << "-MAX_DOUBLE";
431 else
433 description << " <= v <= ";
434 if (0 == std::memcmp(&upper_bound,
436 sizeof(upper_bound)))
437 description << "MAX_DOUBLE";
438 else
440
441 return description.str();
442 }
443 else
444 return "A floating point number";
445 }
446 case LaTeX:
447 {
449 {
450 std::ostringstream description;
451
452 description << "A floating point number @f$v@f$ such that @f$";
453 if (0 == std::memcmp(&lower_bound,
455 sizeof(lower_bound)))
456 description << "-\\text{MAX\\_DOUBLE}";
457 else
459 description << " \\leq v \\leq ";
460 if (0 == std::memcmp(&upper_bound,
462 sizeof(upper_bound)))
463 description << "\\text{MAX\\_DOUBLE}";
464 else
466 description << "@f$";
467
468 return description.str();
469 }
470 else
471 return "A floating point number";
472 }
473 default:
475 }
476 // Should never occur without an exception, but prevent compiler from
477 // complaining
478 return "";
479 }
480
481
482 std::unique_ptr<PatternBase>
484 {
485 return std::unique_ptr<PatternBase>(new Double(lower_bound, upper_bound));
486 }
487
488
489
490 std::unique_ptr<Double>
491 Double::create(const std::string &description)
492 {
493 const std::string description_init_str = description_init;
494 if (description.compare(0,
495 description_init_str.size(),
496 description_init_str) != 0)
497 return std::unique_ptr<Double>();
498 if (*description.rbegin() != ']')
499 return std::unique_ptr<Double>();
500
501 std::string temp = description.substr(description_init_str.size());
502 if (temp == "]")
503 return std::make_unique<Double>(1.0,
504 -1.0); // return an invalid range
505
506 if (temp.find("...") != std::string::npos)
507 temp.replace(temp.find("..."), 3, " ");
508
510
511 std::istringstream is(temp);
512 if (0 == temp.compare(0, std::strlen(" -MAX_DOUBLE"), " -MAX_DOUBLE"))
513 is.ignore(std::strlen(" -MAX_DOUBLE"));
514 else
515 {
516 // parse lower bound and give up if not a double
517 if (!(is >> lower_bound))
518 return std::unique_ptr<Double>();
519 }
520
521 // ignore failure here and assume we got MAX_DOUBLE as upper bound:
522 is >> upper_bound;
523 if (is.fail())
525
526 return std::make_unique<Double>(lower_bound, upper_bound);
527 }
528
529
530
531 const char *Selection::description_init = "[Selection";
532
533
534 Selection::Selection(const std::string &seq)
535 : sequence(seq)
536 {
537 while (sequence.find(" |") != std::string::npos)
538 sequence.replace(sequence.find(" |"), 2, "|");
539 while (sequence.find("| ") != std::string::npos)
540 sequence.replace(sequence.find("| "), 2, "|");
541 }
542
543
544
545 bool
546 Selection::match(const std::string &test_string) const
547 {
548 std::string tmp(sequence);
549
550 // remove whitespace at beginning
551 while ((tmp.length() != 0) && (std::isspace(tmp[0])))
552 tmp.erase(0, 1);
553
554 // check the different possibilities
555 while (tmp.find('|') != std::string::npos)
556 {
557 if (test_string == std::string(tmp, 0, tmp.find('|')))
558 return true;
559
560 tmp.erase(0, tmp.find('|') + 1);
561 }
562
563 // remove whitespace at the end
564 while ((tmp.length() != 0) && (std::isspace(*(tmp.end() - 1))))
565 tmp.erase(tmp.end() - 1);
566
567 // check last choice, not finished by |
568 if (test_string == tmp)
569 return true;
570
571 // not found
572 return false;
573 }
574
575
576
577 std::string
579 {
580 switch (style)
581 {
582 case Machine:
583 {
584 std::ostringstream description;
585
586 description << description_init << " " << sequence << " ]";
587
588 return description.str();
589 }
590 case Text:
591 case LaTeX:
592 {
593 std::ostringstream description;
594
595 description << "Any one of "
598 style);
599
600 return description.str();
601 }
602 default:
604 }
605 // Should never occur without an exception, but prevent compiler from
606 // complaining
607 return "";
608 }
609
610
611
612 std::unique_ptr<PatternBase>
614 {
615 return std::unique_ptr<PatternBase>(new Selection(sequence));
616 }
617
618
619 std::size_t
621 {
622 return (sizeof(PatternBase) +
624 }
625
626
627
628 std::unique_ptr<Selection>
629 Selection::create(const std::string &description)
630 {
631 if (description.compare(0,
632 std::strlen(description_init),
633 description_init) == 0)
634 {
635 std::string sequence(description);
636
637 sequence.erase(0, std::strlen(description_init) + 1);
638 sequence.erase(sequence.length() - 2, 2);
639
640 return std::make_unique<Selection>(sequence);
641 }
642 else
643 return std::unique_ptr<Selection>();
644 }
645
646
647
648 const unsigned int List::max_int_value =
650
651 const char *List::description_init = "[List";
652
653
655 const unsigned int min_elements,
656 const unsigned int max_elements,
657 const std::string &separator)
658 : pattern(p.clone())
659 , min_elements(min_elements)
660 , max_elements(max_elements)
661 , separator(separator)
662 {
665 Assert(separator.size() > 0,
666 ExcMessage("The separator must have a non-zero length."));
667 }
668
669
670
671 List::List(const List &other)
672 : pattern(other.pattern->clone())
673 , min_elements(other.min_elements)
674 , max_elements(other.max_elements)
675 , separator(other.separator)
676 {}
677
678
679 const std::string &
681 {
682 return separator;
683 }
684
685
686
687 const PatternBase &
689 {
690 return *pattern;
691 }
692
693
694
695 bool
696 List::match(const std::string &test_string_list) const
697 {
698 const std::vector<std::string> split_list =
699 Utilities::split_string_list(test_string_list, separator);
700
701 if ((split_list.size() < min_elements) ||
702 (split_list.size() > max_elements))
703 return false;
704
705 // check the different possibilities
706 for (const std::string &string : split_list)
707 if (pattern->match(string) == false)
708 return false;
709
710 return true;
711 }
712
713
714
715 std::string
717 {
718 switch (style)
719 {
720 case Machine:
721 {
722 std::ostringstream description;
723
724 description << description_init << " of <"
725 << pattern->description(style) << ">"
726 << " of length " << min_elements << "..."
727 << max_elements << " (inclusive)";
728 if (separator != ",")
729 description << " separated by <" << separator << ">";
730 description << "]";
731
732 return description.str();
733 }
734 case Text:
735 case LaTeX:
736 {
737 std::ostringstream description;
738
739 description << "A list of " << min_elements << " to "
740 << max_elements << " elements ";
741 if (separator != ",")
742 description << "separated by <"
743 << internal::escape(separator, style) << "> ";
744 description << "where each element is ["
745 << pattern->description(style) << "]";
746
747 return description.str();
748 }
749 default:
751 }
752 // Should never occur without an exception, but prevent compiler from
753 // complaining
754 return "";
755 }
756
757
758
759 std::unique_ptr<PatternBase>
761 {
762 return std::unique_ptr<PatternBase>(
764 }
765
766
767 std::size_t
769 {
770 return (sizeof(*this) + MemoryConsumption::memory_consumption(*pattern) +
772 }
773
774
775
776 std::unique_ptr<List>
777 List::create(const std::string &description)
778 {
779 if (description.compare(0,
780 std::strlen(description_init),
781 description_init) == 0)
782 {
783 unsigned int min_elements = 0, max_elements = 0;
784
785 std::istringstream is(description);
786 is.ignore(strlen(description_init) + strlen(" of <"));
787
788 std::string str;
789 std::getline(is, str, '>');
790
791 std::unique_ptr<PatternBase> base_pattern(pattern_factory(str));
792
793 is.ignore(strlen(" of length "));
794 if (!(is >> min_elements))
795 return std::make_unique<List>(*base_pattern);
796
797 is.ignore(strlen("..."));
798 if (!(is >> max_elements))
799 return std::make_unique<List>(*base_pattern, min_elements);
800
801 is.ignore(strlen(" (inclusive) separated by <"));
802 std::string separator;
803 if (!is.eof())
804 std::getline(is, separator, '>');
805 else
806 separator = ",";
807
808 return std::make_unique<List>(*base_pattern,
811 separator);
812 }
813 else
814 return std::unique_ptr<List>();
815 }
816
817
818
819 const unsigned int Map::max_int_value =
821
822 const char *Map::description_init = "[Map";
823
824
825 Map::Map(const PatternBase &p_key,
826 const PatternBase &p_value,
827 const unsigned int min_elements,
828 const unsigned int max_elements,
829 const std::string &separator,
830 const std::string &key_value_separator)
831 : key_pattern(p_key.clone())
832 , value_pattern(p_value.clone())
833 , min_elements(min_elements)
834 , max_elements(max_elements)
835 , separator(separator)
836 , key_value_separator(key_value_separator)
837 {
840 Assert(separator.size() > 0,
841 ExcMessage("The separator must have a non-zero length."));
842 Assert(key_value_separator.size() > 0,
843 ExcMessage("The key_value_separator must have a non-zero length."));
846 "The separator can not be the same of the key_value_separator "
847 "since that is used as the separator between the two elements "
848 "of <key:value> pairs"));
849 }
850
851
852
853 Map::Map(const Map &other)
854 : key_pattern(other.key_pattern->clone())
855 , value_pattern(other.value_pattern->clone())
856 , min_elements(other.min_elements)
857 , max_elements(other.max_elements)
858 , separator(other.separator)
859 , key_value_separator(other.key_value_separator)
860 {}
861
862
863
864 bool
865 Map::match(const std::string &test_string_list) const
866 {
867 std::vector<std::string> split_list =
868 Utilities::split_string_list(test_string_list, separator);
869 if ((split_list.size() < min_elements) ||
870 (split_list.size() > max_elements))
871 return false;
872
873 for (const auto &key_value_pair : split_list)
874 {
875 std::vector<std::string> pair =
877
878 // Check that we have in fact two matches
879 if (pair.size() != 2)
880 return false;
881
882 // then verify that the patterns are satisfied
883 if (key_pattern->match(pair[0]) == false)
884 return false;
885 if (value_pattern->match(pair[1]) == false)
886 return false;
887 }
888
889 return true;
890 }
891
892
893
894 std::string
895 Map::description(const OutputStyle style) const
896 {
897 switch (style)
898 {
899 case Machine:
900 {
901 std::ostringstream description;
902
903 description << description_init << " of <"
904 << key_pattern->description(style) << ">"
905 << key_value_separator << "<"
906 << value_pattern->description(style) << ">"
907 << " of length " << min_elements << "..."
908 << max_elements << " (inclusive)";
909 if (separator != ",")
910 description << " separated by <" << separator << ">";
911 description << "]";
912
913 return description.str();
914 }
915 case Text:
916 case LaTeX:
917 {
918 std::ostringstream description;
919
920 description << "A key"
922 << "value map of " << min_elements << " to "
923 << max_elements << " elements ";
924 if (separator != ",")
925 description << " separated by <"
926 << internal::escape(separator, style) << "> ";
927 description << " where each key is ["
928 << key_pattern->description(style) << "]"
929 << " and each value is ["
930 << value_pattern->description(style) << "]";
931
932 return description.str();
933 }
934 default:
936 }
937 // Should never occur without an exception, but prevent compiler from
938 // complaining
939 return "";
940 }
941
942
943
944 std::unique_ptr<PatternBase>
946 {
947 return std::unique_ptr<PatternBase>(new Map(*key_pattern,
951 separator,
953 }
954
955
956 std::size_t
958 {
959 return (sizeof(*this) +
964 }
965
966
967
968 std::unique_ptr<Map>
969 Map::create(const std::string &description)
970 {
971 if (description.compare(0,
972 std::strlen(description_init),
973 description_init) == 0)
974 {
975 unsigned int min_elements = 0, max_elements = 0;
976
977 std::istringstream is(description);
978 is.ignore(strlen(description_init) + strlen(" of <"));
979
980 std::string key;
981 std::getline(is, key, '>');
982
983 std::string key_value_separator;
984 std::getline(is, key_value_separator, '<');
985
986 // split 'str' into key and value
987 std::string value;
988 std::getline(is, value, '>');
989
990 std::unique_ptr<PatternBase> key_pattern(pattern_factory(key));
991 std::unique_ptr<PatternBase> value_pattern(pattern_factory(value));
992
993 is.ignore(strlen(" of length "));
994 if (!(is >> min_elements))
995 return std::make_unique<Map>(*key_pattern, *value_pattern);
996
997 is.ignore(strlen("..."));
998 if (!(is >> max_elements))
999 return std::make_unique<Map>(*key_pattern,
1001 min_elements);
1002
1003 is.ignore(strlen(" (inclusive) separated by <"));
1004 std::string separator;
1005 if (!is.eof())
1006 std::getline(is, separator, '>');
1007 else
1008 separator = ",";
1009
1010 return std::make_unique<Map>(*key_pattern,
1014 separator,
1016 }
1017 else
1018 return std::unique_ptr<Map>();
1019 }
1020
1021
1022
1023 const PatternBase &
1025 {
1026 return *key_pattern;
1027 }
1028
1029
1030
1031 const PatternBase &
1033 {
1034 return *value_pattern;
1035 }
1036
1037
1038
1039 const std::string &
1041 {
1042 return separator;
1043 }
1044
1045
1046 const std::string &
1048 {
1049 return key_value_separator;
1050 }
1051
1052
1053
1054 const char *Tuple::description_init = "[Tuple";
1055
1056
1057 Tuple::Tuple(const std::vector<std::unique_ptr<PatternBase>> &ps,
1058 const std::string & separator)
1059 : separator(separator)
1060 {
1061 Assert(ps.size() > 0,
1062 ExcMessage("The Patterns list must have a non-zero length."));
1063 Assert(separator.size() > 0,
1064 ExcMessage("The separator must have a non-zero length."));
1065 patterns.resize(ps.size());
1066 for (unsigned int i = 0; i < ps.size(); ++i)
1067 patterns[i] = ps[i]->clone();
1068 }
1069
1070
1071
1072 Tuple::Tuple(const std::vector<std::unique_ptr<PatternBase>> &ps,
1073 const char * separator)
1074 : Tuple(ps, std::string(separator))
1075 {}
1076
1077
1078
1079 Tuple::Tuple(const Tuple &other)
1080 : separator(other.separator)
1081 {
1082 patterns.resize(other.patterns.size());
1083 for (unsigned int i = 0; i < other.patterns.size(); ++i)
1084 patterns[i] = other.patterns[i]->clone();
1085 }
1086
1087
1088
1089 bool
1090 Tuple::match(const std::string &test_string_list) const
1091 {
1092 std::vector<std::string> split_list =
1093 Utilities::split_string_list(test_string_list, separator);
1094 if (split_list.size() != patterns.size())
1095 return false;
1096
1097 for (unsigned int i = 0; i < patterns.size(); ++i)
1098 {
1099 if (patterns[i]->match(split_list[i]) == false)
1100 return false;
1101 }
1102
1103 return true;
1104 }
1105
1106
1107
1108 std::string
1110 {
1111 switch (style)
1112 {
1113 case Machine:
1114 {
1115 std::ostringstream description;
1116
1117 description << description_init << " of <" << patterns.size()
1118 << "> elements <" << patterns[0]->description(style)
1119 << ">";
1120 for (unsigned int i = 1; i < patterns.size(); ++i)
1121 description << ", <" << patterns[i]->description(style) << ">";
1122
1123 if (separator != ":")
1124 description << " separated by <" << separator << ">";
1125 description << "]";
1126
1127 return description.str();
1128 }
1129 case Text:
1130 case LaTeX:
1131 {
1132 std::ostringstream description;
1133
1134 description << "A Tuple of " << patterns.size() << " elements ";
1135 if (separator != ":")
1136 description << " separated by <"
1137 << internal::escape(separator, style) << "> ";
1138 description << " where each element is ["
1139 << patterns[0]->description(style) << "]";
1140 for (unsigned int i = 1; i < patterns.size(); ++i)
1141 {
1142 description << internal::escape(separator, style) << "["
1143 << patterns[i]->description(style) << "]";
1144 }
1145 return description.str();
1146 }
1147
1148 default:
1150 }
1151 // Should never occur without an exception, but prevent compiler from
1152 // complaining
1153 return "";
1154 }
1155
1156
1157
1158 std::unique_ptr<PatternBase>
1160 {
1161 return std::unique_ptr<PatternBase>(new Tuple(patterns, separator));
1162 }
1163
1164
1165 std::size_t
1167 {
1168 return (sizeof(*this) + MemoryConsumption::memory_consumption(patterns) +
1170 }
1171
1172
1173
1174 std::unique_ptr<Tuple>
1175 Tuple::create(const std::string &description)
1176 {
1177 if (description.compare(0,
1178 std::strlen(description_init),
1179 description_init) == 0)
1180 {
1181 std::vector<std::unique_ptr<PatternBase>> patterns;
1182
1183 std::istringstream is(description);
1184 is.ignore(strlen(description_init) + strlen(" of <"));
1185
1186 std::string len;
1187 std::getline(is, len, '>');
1188 const unsigned int n_elements = Utilities::string_to_int(len);
1189 Assert(n_elements > 0,
1190 ExcMessage("Provide at least 1 element in the tuple."));
1191 patterns.resize(n_elements);
1192
1193 is.ignore(strlen(" elements <"));
1194
1195 std::string element;
1196 std::getline(is, element, '>');
1197 patterns[0] = pattern_factory(element);
1198
1199 for (unsigned int i = 1; i < n_elements; ++i)
1200 {
1201 is.ignore(strlen(", <"));
1202 std::getline(is, element, '>');
1203 patterns[i] = pattern_factory(element);
1204 }
1205
1206 is.ignore(strlen(" separated by <"));
1207
1208 std::string separator;
1209 if (!is.eof())
1210 std::getline(is, separator, '>');
1211 else
1212 separator = ":";
1213
1214 return std::make_unique<Tuple>(patterns, separator);
1215 }
1216 else
1217 return std::unique_ptr<Tuple>();
1218 }
1219
1220
1221
1222 const PatternBase &
1223 Tuple::get_pattern(const unsigned int i) const
1224 {
1225 return *patterns[i];
1226 }
1227
1228
1229
1230 const std::string &
1232 {
1233 return separator;
1234 }
1235
1236
1237
1238 const char *MultipleSelection::description_init = "[MultipleSelection";
1239
1240
1242 {
1243 Assert(seq.find(',') == std::string::npos,
1244 ExcCommasNotAllowed(seq.find(',')));
1245
1246 sequence = seq;
1247 while (sequence.find(" |") != std::string::npos)
1248 sequence.replace(sequence.find(" |"), 2, "|");
1249 while (sequence.find("| ") != std::string::npos)
1250 sequence.replace(sequence.find("| "), 2, "|");
1251 }
1252
1253
1254
1255 bool
1256 MultipleSelection::match(const std::string &test_string_list) const
1257 {
1258 std::string tmp = test_string_list;
1259 std::vector<std::string> split_names;
1260
1261 // first split the input list
1262 while (tmp.length() != 0)
1263 {
1264 std::string name;
1265 name = tmp;
1266
1267 if (name.find(',') != std::string::npos)
1268 {
1269 name.erase(name.find(','), std::string::npos);
1270 tmp.erase(0, tmp.find(',') + 1);
1271 }
1272 else
1273 tmp = "";
1274
1275 while ((name.length() != 0) && (std::isspace(name[0])))
1276 name.erase(0, 1);
1277 while (std::isspace(name[name.length() - 1]))
1278 name.erase(name.length() - 1, 1);
1279
1280 split_names.push_back(name);
1281 }
1282
1283
1284 // check the different possibilities
1285 for (const auto &test_string : split_names)
1286 {
1287 bool string_found = false;
1288
1289 tmp = sequence;
1290 while (tmp.find('|') != std::string::npos)
1291 {
1292 if (test_string == std::string(tmp, 0, tmp.find('|')))
1293 {
1294 // string found, quit
1295 // loop. don't change
1296 // tmp, since we don't
1297 // need it anymore.
1298 string_found = true;
1299 break;
1300 }
1301
1302 tmp.erase(0, tmp.find('|') + 1);
1303 }
1304 // check last choice, not finished by |
1305 if (!string_found)
1306 if (test_string == tmp)
1307 string_found = true;
1308
1309 if (!string_found)
1310 return false;
1311 }
1312
1313 return true;
1314 }
1315
1316
1317
1318 std::string
1320 {
1321 switch (style)
1322 {
1323 case Machine:
1324 {
1325 std::ostringstream description;
1326
1327 description << description_init << " " << sequence << " ]";
1328
1329 return description.str();
1330 }
1331 case Text:
1332 case LaTeX:
1333 {
1334 std::ostringstream description;
1335
1336 description << "A comma-separated list of any of "
1339 style);
1340
1341 return description.str();
1342 }
1343 default:
1345 }
1346 // Should never occur without an exception, but prevent compiler from
1347 // complaining
1348 return "";
1349 }
1350
1351
1352
1353 std::unique_ptr<PatternBase>
1355 {
1356 return std::unique_ptr<PatternBase>(new MultipleSelection(sequence));
1357 }
1358
1359
1360 std::size_t
1362 {
1363 return (sizeof(PatternBase) +
1365 }
1366
1367
1368
1369 std::unique_ptr<MultipleSelection>
1370 MultipleSelection::create(const std::string &description)
1371 {
1372 if (description.compare(0,
1373 std::strlen(description_init),
1374 description_init) == 0)
1375 {
1376 std::string sequence(description);
1377
1378 sequence.erase(0, std::strlen(description_init) + 1);
1379 sequence.erase(sequence.length() - 2, 2);
1380
1381 return std::make_unique<MultipleSelection>(sequence);
1382 }
1383 else
1384 return std::unique_ptr<MultipleSelection>();
1385 }
1386
1387
1388
1389 const char *Bool::description_init = "[Bool";
1390
1391
1393 : Selection("true|false")
1394 {}
1395
1396
1397
1398 std::string
1400 {
1401 switch (style)
1402 {
1403 case Machine:
1404 {
1405 std::ostringstream description;
1406
1407 description << description_init << "]";
1408
1409 return description.str();
1410 }
1411 case Text:
1412 case LaTeX:
1413 {
1414 return "A boolean value (true or false)";
1415 }
1416 default:
1418 }
1419 // Should never occur without an exception, but prevent compiler from
1420 // complaining
1421 return "";
1422 }
1423
1424
1425
1426 std::unique_ptr<PatternBase>
1428 {
1429 return std::unique_ptr<PatternBase>(new Bool());
1430 }
1431
1432
1433
1434 std::unique_ptr<Bool>
1435 Bool::create(const std::string &description)
1436 {
1437 if (description.compare(0,
1438 std::strlen(description_init),
1439 description_init) == 0)
1440 return std::make_unique<Bool>();
1441 else
1442 return std::unique_ptr<Bool>();
1443 }
1444
1445
1446
1447 const char *Anything::description_init = "[Anything";
1448
1449
1450
1451 bool
1452 Anything::match(const std::string &) const
1453 {
1454 return true;
1455 }
1456
1457
1458
1459 std::string
1461 {
1462 switch (style)
1463 {
1464 case Machine:
1465 {
1466 std::ostringstream description;
1467
1468 description << description_init << "]";
1469
1470 return description.str();
1471 }
1472 case Text:
1473 case LaTeX:
1474 {
1475 return "Any string";
1476 }
1477 default:
1479 }
1480 // Should never occur without an exception, but prevent compiler from
1481 // complaining
1482 return "";
1483 }
1484
1485
1486
1487 std::unique_ptr<PatternBase>
1489 {
1490 return std::unique_ptr<PatternBase>(new Anything());
1491 }
1492
1493
1494
1495 std::unique_ptr<Anything>
1496 Anything::create(const std::string &description)
1497 {
1498 if (description.compare(0,
1499 std::strlen(description_init),
1500 description_init) == 0)
1501 return std::make_unique<Anything>();
1502 else
1503 return std::unique_ptr<Anything>();
1504 }
1505
1506
1507
1508 const char *FileName::description_init = "[FileName";
1509
1510
1512 : file_type(type)
1513 {}
1514
1515
1516
1517 bool
1518 FileName::match(const std::string &) const
1519 {
1520 return true;
1521 }
1522
1523
1524
1525 std::string
1527 {
1528 switch (style)
1529 {
1530 case Machine:
1531 {
1532 std::ostringstream description;
1533
1535
1536 if (file_type == input)
1537 description << " (Type: input)]";
1538 else
1539 description << " (Type: output)]";
1540
1541 return description.str();
1542 }
1543 case Text:
1544 case LaTeX:
1545 {
1546 if (file_type == input)
1547 return "an input filename";
1548 else
1549 return "an output filename";
1550 }
1551 default:
1553 }
1554 // Should never occur without an exception, but prevent compiler from
1555 // complaining
1556 return "";
1557 }
1558
1559
1560
1561 std::unique_ptr<PatternBase>
1563 {
1564 return std::unique_ptr<PatternBase>(new FileName(file_type));
1565 }
1566
1567
1568
1569 std::unique_ptr<FileName>
1570 FileName::create(const std::string &description)
1571 {
1572 if (description.compare(0,
1573 std::strlen(description_init),
1574 description_init) == 0)
1575 {
1576 std::istringstream is(description);
1577 std::string file_type;
1578 FileType type;
1579
1580 is.ignore(strlen(description_init) + strlen(" (Type:"));
1581
1582 is >> file_type;
1583
1584 if (file_type == "input)]")
1585 type = input;
1586 else
1587 type = output;
1588
1589 return std::make_unique<FileName>(type);
1590 }
1591 else
1592 return std::unique_ptr<FileName>();
1593 }
1594
1595
1596
1597 const char *DirectoryName::description_init = "[DirectoryName";
1598
1599
1600
1601 bool
1602 DirectoryName::match(const std::string &) const
1603 {
1604 return true;
1605 }
1606
1607
1608
1609 std::string
1611 {
1612 switch (style)
1613 {
1614 case Machine:
1615 {
1616 std::ostringstream description;
1617
1618 description << description_init << "]";
1619
1620 return description.str();
1621 }
1622 case Text:
1623 case LaTeX:
1624 {
1625 return "A directory name";
1626 }
1627 default:
1629 }
1630 // Should never occur without an exception, but prevent compiler from
1631 // complaining
1632 return "";
1633 }
1634
1635
1636
1637 std::unique_ptr<PatternBase>
1639 {
1640 return std::unique_ptr<PatternBase>(new DirectoryName());
1641 }
1642
1643
1644
1645 std::unique_ptr<DirectoryName>
1646 DirectoryName::create(const std::string &description)
1647 {
1648 if (description.compare(0,
1649 std::strlen(description_init),
1650 description_init) == 0)
1651 return std::make_unique<DirectoryName>();
1652 else
1653 return std::unique_ptr<DirectoryName>();
1654 }
1655
1656} // end namespace Patterns
1657
static std::unique_ptr< Double > create(const std::string &description)
Definition: patterns.cc:491
static const char * description_init
Definition: patterns.h:370
virtual std::unique_ptr< PatternBase > clone() const override
Definition: patterns.cc:483
Double(const double lower_bound=min_double_value, const double upper_bound=max_double_value)
Definition: patterns.cc:352
const double lower_bound
Definition: patterns.h:357
const double upper_bound
Definition: patterns.h:365
static const double max_double_value
Definition: patterns.h:305
static const double min_double_value
Definition: patterns.h:299
virtual std::string description(const OutputStyle style=Machine) const override
Definition: patterns.cc:383
virtual bool match(const std::string &test_string) const override
Definition: patterns.cc:360
static std::unique_ptr< Integer > create(const std::string &description)
Definition: patterns.cc:312
static const char * description_init
Definition: patterns.h:272
const int upper_bound
Definition: patterns.h:267
virtual std::unique_ptr< PatternBase > clone() const override
Definition: patterns.cc:304
Integer(const int lower_bound=min_int_value, const int upper_bound=max_int_value)
Definition: patterns.cc:213
const int lower_bound
Definition: patterns.h:259
static const int min_int_value
Definition: patterns.h:197
virtual std::string description(const OutputStyle style=Machine) const override
Definition: patterns.cc:243
virtual bool match(const std::string &test_string) const override
Definition: patterns.cc:221
static const int max_int_value
Definition: patterns.h:204
std::size_t memory_consumption() const override
Definition: patterns.cc:768
static std::unique_ptr< List > create(const std::string &description)
Definition: patterns.cc:777
virtual std::string description(const OutputStyle style=Machine) const override
Definition: patterns.cc:716
const PatternBase & get_base_pattern() const
Definition: patterns.cc:688
virtual bool match(const std::string &test_string) const override
Definition: patterns.cc:696
const std::string & get_separator() const
Definition: patterns.cc:680
List(const PatternBase &base_pattern, const unsigned int min_elements=0, const unsigned int max_elements=max_int_value, const std::string &separator=",")
Definition: patterns.cc:654
static const unsigned int max_int_value
Definition: patterns.h:458
virtual std::unique_ptr< PatternBase > clone() const override
Definition: patterns.cc:760
virtual std::size_t memory_consumption() const
Definition: patterns.cc:192
static const char * description_init
Definition: patterns.h:439
virtual std::string description(const OutputStyle style=Machine) const override
Definition: patterns.cc:578
virtual std::unique_ptr< PatternBase > clone() const override
Definition: patterns.cc:613
virtual bool match(const std::string &test_string) const override
Definition: patterns.cc:546
static std::unique_ptr< Selection > create(const std::string &description)
Definition: patterns.cc:629
std::size_t memory_consumption() const override
Definition: patterns.cc:620
Selection(const std::string &seq)
Definition: patterns.cc:534
std::string sequence
Definition: patterns.h:434
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:402
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition: config.h:416
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:403
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition: config.h:454
virtual std::string description(const OutputStyle style=Machine) const override
Definition: patterns.cc:1399
virtual bool match(const std::string &test_string) const override
Definition: patterns.cc:1090
FileType file_type
Definition: patterns.h:1133
virtual std::unique_ptr< PatternBase > clone() const override
Definition: patterns.cc:1638
std::size_t memory_consumption() const override
Definition: patterns.cc:1166
static std::unique_ptr< Anything > create(const std::string &description)
Definition: patterns.cc:1496
static std::unique_ptr< Tuple > create(const std::string &description)
Definition: patterns.cc:1175
const unsigned int max_elements
Definition: patterns.h:556
static ::ExceptionBase & ExcInvalidRange(int arg1, int arg2)
static std::unique_ptr< Map > create(const std::string &description)
Definition: patterns.cc:969
static ::ExceptionBase & ExcInvalidRange(int arg1, int arg2)
virtual bool match(const std::string &test_string) const override
Definition: patterns.cc:1518
static const char * description_init
Definition: patterns.h:566
const unsigned int min_elements
Definition: patterns.h:551
std::unique_ptr< PatternBase > value_pattern
Definition: patterns.h:695
std::vector< std::unique_ptr< PatternBase > > patterns
Definition: patterns.h:880
const unsigned int min_elements
Definition: patterns.h:700
static const char * description_init
Definition: patterns.h:1016
const PatternBase & get_key_pattern() const
Definition: patterns.cc:1024
virtual bool match(const std::string &test_string) const override
Definition: patterns.cc:865
std::unique_ptr< PatternBase > pattern
Definition: patterns.h:546
MultipleSelection(const std::string &seq)
Definition: patterns.cc:1241
virtual bool match(const std::string &test_string) const override
Definition: patterns.cc:1452
const std::string separator
Definition: patterns.h:561
Map(const PatternBase &key_pattern, const PatternBase &value_pattern, const unsigned int min_elements=0, const unsigned int max_elements=max_int_value, const std::string &separator=",", const std::string &key_value_separator=":")
Definition: patterns.cc:825
const unsigned int max_elements
Definition: patterns.h:705
FileName(const FileType type=input)
Definition: patterns.cc:1511
static ::ExceptionBase & ExcNotImplemented()
virtual std::unique_ptr< PatternBase > clone() const override
Definition: patterns.cc:1159
static const char * description_init
Definition: patterns.h:1147
static const char * description_init
Definition: patterns.h:1205
static std::unique_ptr< MultipleSelection > create(const std::string &description)
Definition: patterns.cc:1370
virtual bool match(const std::string &test_string) const override
Definition: patterns.cc:1256
#define Assert(cond, exc)
Definition: exceptions.h:1465
virtual std::unique_ptr< PatternBase > clone() const override
Definition: patterns.cc:1427
const std::string separator
Definition: patterns.h:885
virtual std::unique_ptr< PatternBase > clone() const override
Definition: patterns.cc:1562
virtual std::unique_ptr< PatternBase > clone() const override
Definition: patterns.cc:1354
virtual std::string description(const OutputStyle style=Machine) const override
Definition: patterns.cc:1610
virtual std::unique_ptr< PatternBase > clone() const override
Definition: patterns.cc:945
static const char * description_init
Definition: patterns.h:890
static const char * description_init
Definition: patterns.h:974
static std::unique_ptr< FileName > create(const std::string &description)
Definition: patterns.cc:1570
static const char * description_init
Definition: patterns.h:1065
const PatternBase & get_value_pattern() const
Definition: patterns.cc:1032
std::size_t memory_consumption() const override
Definition: patterns.cc:1361
static std::unique_ptr< Bool > create(const std::string &description)
Definition: patterns.cc:1435
const std::string & get_separator() const
Definition: patterns.cc:1040
virtual std::string description(const OutputStyle style=Machine) const override
Definition: patterns.cc:1460
Tuple(const std::vector< std::unique_ptr< PatternBase > > &patterns, const std::string &separator=":")
Definition: patterns.cc:1057
const std::string & get_separator() const
Definition: patterns.cc:1231
virtual std::string description(const OutputStyle style=Machine) const override
Definition: patterns.cc:895
virtual std::string description(const OutputStyle style=Machine) const override
Definition: patterns.cc:1319
static std::unique_ptr< DirectoryName > create(const std::string &description)
Definition: patterns.cc:1646
static const unsigned int max_int_value
Definition: patterns.h:592
std::unique_ptr< PatternBase > key_pattern
Definition: patterns.h:694
virtual std::string description(const OutputStyle style=Machine) const override
Definition: patterns.cc:1526
virtual bool match(const std::string &test_string) const override
Definition: patterns.cc:1602
const std::string separator
Definition: patterns.h:710
const PatternBase & get_pattern(const unsigned int i) const
Definition: patterns.cc:1223
std::size_t memory_consumption() const override
Definition: patterns.cc:957
static ::ExceptionBase & ExcCommasNotAllowed(int arg1)
static const char * description_init
Definition: patterns.h:721
virtual std::unique_ptr< PatternBase > clone() const override
Definition: patterns.cc:1488
virtual std::string description(const OutputStyle style=Machine) const override
Definition: patterns.cc:1109
const std::string & get_key_value_separator() const
Definition: patterns.cc:1047
static ::ExceptionBase & ExcMessage(std::string arg1)
const std::string key_value_separator
Definition: patterns.h:716
#define AssertThrow(cond, exc)
Definition: exceptions.h:1575
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
std::string escape(const std::string &input, const PatternBase::OutputStyle style)
Definition: patterns.cc:55
std::unique_ptr< PatternBase > pattern_factory(const std::string &description)
Definition: patterns.cc:140
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
Definition: utilities.cc:704
std::string replace_in_string(const std::string &input, const std::string &from, const std::string &to)
Definition: utilities.cc:512
Iterator lower_bound(Iterator first, Iterator last, const T &val)
Definition: utilities.h:1111
int string_to_int(const std::string &s)
Definition: utilities.cc:608
STL namespace.