Reference documentation for deal.II version Git 3041c91f43 2021-03-05 14:58:09 +0100
\(\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.h
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 #ifndef dealii_patterns_h
17 #define dealii_patterns_h
18 
19 
20 #include <deal.II/base/config.h>
21 
23 #include <deal.II/base/point.h>
26 #include <deal.II/base/utilities.h>
27 
29 
31 #include <boost/archive/basic_archive.hpp>
32 #include <boost/core/demangle.hpp>
33 #include <boost/property_tree/ptree_fwd.hpp>
34 #include <boost/property_tree/ptree_serialization.hpp>
35 #include <boost/serialization/split_member.hpp>
37 
38 #include <algorithm>
39 #include <array>
40 #include <deque>
41 #include <list>
42 #include <map>
43 #include <memory>
44 #include <set>
45 #include <sstream>
46 #include <string>
47 #include <type_traits>
48 #include <unordered_map>
49 #include <unordered_set>
50 #include <utility>
51 #include <vector>
52 
54 
55 // forward declarations for interfaces and friendship
56 #ifndef DOXYGEN
57 class LogStream;
59 template <int dim>
60 class FunctionParser;
61 #endif
62 
71 namespace Patterns
72 {
80  {
81  public:
85  virtual ~PatternBase() = default;
86 
90  virtual bool
91  match(const std::string &test_string) const = 0;
92 
99  {
116  };
117 
121  virtual std::string
122  description(const OutputStyle style = Machine) const = 0;
123 
133  virtual std::unique_ptr<PatternBase>
134  clone() const = 0;
135 
151  virtual std::size_t
152  memory_consumption() const;
153  };
154 
158  std::unique_ptr<PatternBase>
159  pattern_factory(const std::string &description);
160 
161  namespace internal
162  {
168  std::string
169  escape(const std::string &input, const PatternBase::OutputStyle style);
170 
171  } // namespace internal
172 
189  class Integer : public PatternBase
190  {
191  public:
197  static const int min_int_value;
198 
204  static const int max_int_value;
205 
218  Integer(const int lower_bound = min_int_value,
219  const int upper_bound = max_int_value);
220 
225  virtual bool
226  match(const std::string &test_string) const override;
227 
233  virtual std::string
234  description(const OutputStyle style = Machine) const override;
235 
241  virtual std::unique_ptr<PatternBase>
242  clone() const override;
243 
249  static std::unique_ptr<Integer>
250  create(const std::string &description);
251 
252  private:
259  const int lower_bound;
260 
267  const int upper_bound;
268 
272  static const char *description_init;
273  };
274 
292  class Double : public PatternBase
293  {
294  public:
299  static const double min_double_value;
300 
305  static const double max_double_value;
306 
314  Double(const double lower_bound = min_double_value,
315  const double upper_bound = max_double_value);
316 
321  virtual bool
322  match(const std::string &test_string) const override;
323 
329  virtual std::string
330  description(const OutputStyle style = Machine) const override;
331 
337  virtual std::unique_ptr<PatternBase>
338  clone() const override;
339 
347  static std::unique_ptr<Double>
348  create(const std::string &description);
349 
350  private:
357  const double lower_bound;
358 
365  const double upper_bound;
366 
370  static const char *description_init;
371  };
372 
382  class Selection : public PatternBase
383  {
384  public:
389  Selection(const std::string &seq);
390 
395  virtual bool
396  match(const std::string &test_string) const override;
397 
403  virtual std::string
404  description(const OutputStyle style = Machine) const override;
405 
411  virtual std::unique_ptr<PatternBase>
412  clone() const override;
413 
418  std::size_t
419  memory_consumption() const override;
420 
426  static std::unique_ptr<Selection>
427  create(const std::string &description);
428 
429  private:
434  std::string sequence;
435 
439  static const char *description_init;
440  };
441 
442 
450  class List : public PatternBase
451  {
452  public:
458  static const unsigned int max_int_value;
459 
468  List(const PatternBase &base_pattern,
469  const unsigned int min_elements = 0,
470  const unsigned int max_elements = max_int_value,
471  const std::string &separator = ",");
472 
473 
477  const std::string &
478  get_separator() const;
479 
483  const PatternBase &
484  get_base_pattern() const;
485 
489  List(const List &other);
490 
495  virtual bool
496  match(const std::string &test_string) const override;
497 
502  virtual std::string
503  description(const OutputStyle style = Machine) const override;
504 
510  virtual std::unique_ptr<PatternBase>
511  clone() const override;
512 
518  static std::unique_ptr<List>
519  create(const std::string &description);
520 
525  std::size_t
526  memory_consumption() const override;
527 
536  DeclException2(ExcInvalidRange,
537  int,
538  int,
539  << "The values " << arg1 << " and " << arg2
540  << " do not form a valid range.");
542  private:
546  std::unique_ptr<PatternBase> pattern;
547 
551  const unsigned int min_elements;
552 
556  const unsigned int max_elements;
557 
561  const std::string separator;
562 
566  static const char *description_init;
567  };
568 
569 
584  class Map : public PatternBase
585  {
586  public:
592  static const unsigned int max_int_value;
593 
602  Map(const PatternBase &key_pattern,
603  const PatternBase &value_pattern,
604  const unsigned int min_elements = 0,
605  const unsigned int max_elements = max_int_value,
606  const std::string &separator = ",",
607  const std::string &key_value_separator = ":");
608 
612  Map(const Map &other);
613 
618  virtual bool
619  match(const std::string &test_string) const override;
620 
625  virtual std::string
626  description(const OutputStyle style = Machine) const override;
627 
633  virtual std::unique_ptr<PatternBase>
634  clone() const override;
635 
641  static std::unique_ptr<Map>
642  create(const std::string &description);
643 
648  std::size_t
649  memory_consumption() const override;
650 
654  const PatternBase &
655  get_key_pattern() const;
656 
660  const PatternBase &
661  get_value_pattern() const;
662 
666  const std::string &
667  get_separator() const;
668 
672  const std::string &
673  get_key_value_separator() const;
674 
683  DeclException2(ExcInvalidRange,
684  int,
685  int,
686  << "The values " << arg1 << " and " << arg2
687  << " do not form a valid range.");
689  private:
694  std::unique_ptr<PatternBase> key_pattern;
695  std::unique_ptr<PatternBase> value_pattern;
696 
700  const unsigned int min_elements;
701 
705  const unsigned int max_elements;
706 
710  const std::string separator;
711 
712 
716  const std::string key_value_separator;
717 
721  static const char *description_init;
722  };
723 
724 
725 
771  class Tuple : public PatternBase
772  {
773  public:
782  Tuple(const std::vector<std::unique_ptr<PatternBase>> &patterns,
783  const std::string & separator = ":");
784 
790  Tuple(const std::vector<std::unique_ptr<PatternBase>> &patterns,
791  const char * separator);
792 
793 
801  template <class... PatternTypes>
802  Tuple(const std::string &separator, const PatternTypes &... patterns);
803 
811  template <class... PatternTypes>
812  Tuple(const char *separator, const PatternTypes &... patterns);
813 
819  template <typename... Patterns>
820  Tuple(const Patterns &... patterns);
821 
825  Tuple(const Tuple &other);
826 
831  virtual bool
832  match(const std::string &test_string) const override;
833 
838  virtual std::string
839  description(const OutputStyle style = Machine) const override;
840 
846  virtual std::unique_ptr<PatternBase>
847  clone() const override;
848 
854  static std::unique_ptr<Tuple>
855  create(const std::string &description);
856 
861  std::size_t
862  memory_consumption() const override;
863 
867  const PatternBase &
868  get_pattern(const unsigned int i) const;
869 
873  const std::string &
874  get_separator() const;
875 
876  private:
880  std::vector<std::unique_ptr<PatternBase>> patterns;
881 
885  const std::string separator;
886 
890  static const char *description_init;
891  };
892 
893 
905  {
906  public:
910  MultipleSelection(const std::string &seq);
911 
916  virtual bool
917  match(const std::string &test_string) const override;
918 
924  virtual std::string
925  description(const OutputStyle style = Machine) const override;
926 
932  virtual std::unique_ptr<PatternBase>
933  clone() const override;
934 
940  static std::unique_ptr<MultipleSelection>
941  create(const std::string &description);
942 
947  std::size_t
948  memory_consumption() const override;
949 
959  ExcCommasNotAllowed,
960  int,
961  << "A comma was found at position " << arg1
962  << " of your input string, but commas are not allowed here.");
964  private:
969  std::string sequence;
970 
974  static const char *description_init;
975  };
976 
981  class Bool : public Selection
982  {
983  public:
987  Bool();
988 
993  virtual std::string
994  description(const OutputStyle style = Machine) const override;
995 
1001  virtual std::unique_ptr<PatternBase>
1002  clone() const override;
1003 
1009  static std::unique_ptr<Bool>
1010  create(const std::string &description);
1011 
1012  private:
1016  static const char *description_init;
1017  };
1018 
1022  class Anything : public PatternBase
1023  {
1024  public:
1029  Anything() = default;
1030 
1035  virtual bool
1036  match(const std::string &test_string) const override;
1037 
1042  virtual std::string
1043  description(const OutputStyle style = Machine) const override;
1044 
1050  virtual std::unique_ptr<PatternBase>
1051  clone() const override;
1052 
1058  static std::unique_ptr<Anything>
1059  create(const std::string &description);
1060 
1061  private:
1065  static const char *description_init;
1066  };
1067 
1068 
1083  class FileName : public PatternBase
1084  {
1085  public:
1091  {
1095  input = 0,
1099  output = 1
1100  };
1101 
1106  FileName(const FileType type = input);
1107 
1112  virtual bool
1113  match(const std::string &test_string) const override;
1114 
1119  virtual std::string
1120  description(const OutputStyle style = Machine) const override;
1121 
1127  virtual std::unique_ptr<PatternBase>
1128  clone() const override;
1129 
1134 
1140  static std::unique_ptr<FileName>
1141  create(const std::string &description);
1142 
1143  private:
1147  static const char *description_init;
1148  };
1149 
1150 
1164  {
1165  public:
1169  DirectoryName() = default;
1170 
1175  virtual bool
1176  match(const std::string &test_string) const override;
1177 
1182  virtual std::string
1183  description(const OutputStyle style = Machine) const override;
1184 
1190  virtual std::unique_ptr<PatternBase>
1191  clone() const override;
1192 
1198  static std::unique_ptr<DirectoryName>
1199  create(const std::string &description);
1200 
1201  private:
1205  static const char *description_init;
1206  };
1207 
1208 
1287  namespace Tools
1288  {
1298  template <class T, class Enable = void>
1299  struct Convert
1300  {
1310  static std::unique_ptr<Patterns::PatternBase>
1311  to_pattern() = delete;
1312 
1323  static std::string
1324  to_string(const T & s,
1326  delete;
1327 
1337  static T
1338  to_value(const std::string & s,
1340  delete;
1341  };
1342 
1361  template <typename T>
1362  std::string
1363  to_string(const T &t);
1364 
1390  template <typename T>
1391  void
1392  to_value(const std::string &s, T &t);
1393 
1403  std::string,
1404  std::string,
1405  << "The string " << arg1 << " does not match the pattern \""
1406  << arg2 << "\"");
1408  } // namespace Tools
1409 } // namespace Patterns
1410 
1411 
1412 // ---------------------- inline and template functions --------------------
1413 namespace Patterns
1414 {
1415  template <class... PatternTypes>
1416  Tuple::Tuple(const char *separator, const PatternTypes &... ps)
1417  : // forward to the version with std::string argument
1418  Tuple(std::string(separator), ps...)
1419  {}
1420 
1421 
1422 
1423  template <class... PatternTypes>
1424  Tuple::Tuple(const std::string &separator, const PatternTypes &... ps)
1425  : separator(separator)
1426  {
1428  "Not all of the input arguments of this function "
1429  "are derived from PatternBase");
1430  static_assert(sizeof...(ps) > 0,
1431  "The number of PatternTypes must be greater than zero!");
1432  const auto pattern_pointers = {(static_cast<const PatternBase *>(&ps))...};
1433  for (const auto p : pattern_pointers)
1434  patterns.push_back(p->clone());
1435  }
1436 
1437 
1438 
1439  template <class... PatternTypes>
1440  Tuple::Tuple(const PatternTypes &... ps)
1441  : // forward to the version with the separator argument
1442  Tuple(std::string(":"), ps...)
1443  {}
1444 
1445 
1446 
1447  namespace Tools
1448  {
1449  namespace internal
1450  {
1475  template <class T, class Enable = void>
1476  struct RankInfo
1477  {
1478  static constexpr int list_rank = 0;
1479  static constexpr int map_rank = 0;
1480  };
1481  } // namespace internal
1482 
1483  // Arithmetic types
1484  template <class T>
1485  struct Convert<T,
1486  typename std::enable_if<std::is_arithmetic<T>::value>::type>
1487  {
1488  template <typename Dummy = T>
1489  static
1490  typename std::enable_if<std::is_same<Dummy, T>::value &&
1491  std::is_same<T, bool>::value,
1492  std::unique_ptr<Patterns::PatternBase>>::type
1494  {
1495  return std::make_unique<Patterns::Bool>();
1496  }
1497 
1498  template <typename Dummy = T>
1499  static
1500  typename std::enable_if<std::is_same<Dummy, T>::value &&
1501  !std::is_same<T, bool>::value &&
1502  std::is_integral<T>::value,
1503  std::unique_ptr<Patterns::PatternBase>>::type
1505  {
1506  return std::make_unique<Patterns::Integer>(
1507  std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
1508  }
1509 
1510  template <typename Dummy = T>
1511  static
1512  typename std::enable_if<std::is_same<Dummy, T>::value &&
1513  !std::is_same<T, bool>::value &&
1514  std::is_floating_point<T>::value,
1515  std::unique_ptr<Patterns::PatternBase>>::type
1517  {
1518  return std::make_unique<Patterns::Double>(
1519  std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
1520  }
1521 
1522  static std::string
1523  to_string(const T & value,
1525  {
1526  std::stringstream str;
1527  if (std::is_same<T, unsigned char>::value ||
1528  std::is_same<T, signed char>::value || std::is_same<T, char>::value)
1529  str << static_cast<int>(value);
1530  else if (std::is_same<T, bool>::value)
1531  str << (static_cast<bool>(value) ? "true" : "false");
1532  else
1533  str << value;
1534  AssertThrow(p.match(str.str()), ExcNoMatch(str.str(), p.description()));
1535  return str.str();
1536  }
1537 
1538  static T
1539  to_value(const std::string & s,
1541  {
1542  AssertThrow(p.match(s), ExcNoMatch(s, p.description()));
1543  T value;
1544  if (std::is_same<T, bool>::value)
1545  value = (s == "true");
1546  else
1547  {
1548  std::istringstream is(s);
1549  if (std::is_same<T, unsigned char>::value ||
1550  std::is_same<T, signed char>::value ||
1551  std::is_same<T, char>::value)
1552  {
1553  int i;
1554  is >> i;
1555  value = i;
1556  }
1557  else
1558  is >> value;
1559 
1560  // If someone passes "123 abc" to the function, the method yields an
1561  // integer 123 alright, but the space terminates the read from the
1562  // string although there is more to come. This case, however, is
1563  // checked for in the call p->match(s) at the beginning of this
1564  // function, and would throw earlier. Here it is safe to assume that
1565  // if we didn't fail the conversion with the operator >>, then we
1566  // are good to go.
1567  AssertThrow(
1568  !is.fail(),
1569  ExcMessage("Failed to convert from \"" + s + "\" to the type \"" +
1570  boost::core::demangle(typeid(T).name()) + "\""));
1571  }
1572  return value;
1573  }
1574  };
1575 
1576  namespace internal
1577  {
1578  constexpr std::array<const char *, 4> default_list_separator{
1579  {",", ";", "|", "%"}};
1580  constexpr std::array<const char *, 4> default_map_separator{
1581  {":", "=", "@", "#"}};
1582 
1583  // specialize a type for all of the STL containers and maps
1584  template <typename T>
1585  struct is_list_compatible : std::false_type
1586  {};
1587  template <typename T, std::size_t N>
1588  struct is_list_compatible<std::array<T, N>> : std::true_type
1589  {};
1590  template <typename... Args>
1591  struct is_list_compatible<std::vector<Args...>> : std::true_type
1592  {};
1593  template <typename... Args>
1594  struct is_list_compatible<std::deque<Args...>> : std::true_type
1595  {};
1596  template <typename... Args>
1597  struct is_list_compatible<std::list<Args...>> : std::true_type
1598  {};
1599  template <typename... Args>
1600  struct is_list_compatible<std::set<Args...>> : std::true_type
1601  {};
1602  template <typename... Args>
1603  struct is_list_compatible<std::multiset<Args...>> : std::true_type
1604  {};
1605  template <typename... Args>
1606  struct is_list_compatible<std::unordered_set<Args...>> : std::true_type
1607  {};
1608  template <typename... Args>
1609  struct is_list_compatible<std::unordered_multiset<Args...>>
1610  : std::true_type
1611  {};
1612 
1613  template <typename T>
1614  struct is_map_compatible : std::false_type
1615  {};
1616  template <class Key, class T, class Compare, class Allocator>
1617  struct is_map_compatible<std::map<Key, T, Compare, Allocator>>
1618  : std::true_type
1619  {};
1620  template <class Key, class T, class Compare, class Allocator>
1621  struct is_map_compatible<std::multimap<Key, T, Compare, Allocator>>
1622  : std::true_type
1623  {};
1624  template <class Key, class T, class Hash, class KeyEqual, class Allocator>
1626  std::unordered_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type
1627  {};
1628  template <class Key, class T, class Hash, class KeyEqual, class Allocator>
1630  std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>>
1631  : std::true_type
1632  {};
1633  } // namespace internal
1634 
1635  // type trait to use the implementation type traits as well as decay the
1636  // type
1637  template <typename T>
1639  {
1640  static constexpr bool const value =
1642  };
1643 
1644  template <typename T>
1646  {
1647  static constexpr bool const value =
1649  };
1650 
1651  namespace internal
1652  {
1653  // Helper function for list_rank
1654  template <class T>
1655  constexpr int
1657  {
1658  return RankInfo<T>::list_rank;
1659  }
1660 
1661  template <class T1, class T2, class... Types>
1662  constexpr int
1664  {
1665  return std::max(RankInfo<T1>::list_rank, max_list_rank<T2, Types...>());
1666  }
1667 
1668  // Helper function for map_rank
1669  template <class T>
1670  constexpr int
1672  {
1673  return RankInfo<T>::map_rank;
1674  }
1675 
1676  template <class T1, class T2, class... Types>
1677  constexpr int
1679  {
1680  return std::max(RankInfo<T1>::map_rank, max_map_rank<T2, Types...>());
1681  }
1682 
1683  // Rank of vector types
1684  template <class T>
1685  struct RankInfo<
1686  T,
1687  typename std::enable_if<is_list_compatible<T>::value>::type>
1688  {
1689  static constexpr int list_rank =
1691  static constexpr int map_rank =
1693  };
1694 
1695  // Rank of map types
1696  template <class T>
1697  struct RankInfo<
1698  T,
1699  typename std::enable_if<is_map_compatible<T>::value>::type>
1700  {
1701  static constexpr int list_rank =
1702  max_list_rank<typename T::key_type, typename T::mapped_type>() + 1;
1703  static constexpr int map_rank =
1704  max_map_rank<typename T::key_type, typename T::mapped_type>() + 1;
1705  };
1706 
1707  // Rank of Tensor types
1708  template <int rank, int dim, class Number>
1709  struct RankInfo<Tensor<rank, dim, Number>>
1710  {
1711  static constexpr int list_rank = rank + RankInfo<Number>::list_rank;
1712  static constexpr int map_rank = RankInfo<Number>::map_rank;
1713  };
1714 
1715  template <int dim, class Number>
1716  struct RankInfo<Point<dim, Number>> : RankInfo<Tensor<1, dim, Number>>
1717  {};
1718 
1719  // Rank of complex types
1720  template <class Number>
1721  struct RankInfo<std::complex<Number>>
1722  {
1723  static constexpr int list_rank = RankInfo<Number>::list_rank + 1;
1724  static constexpr int map_rank = RankInfo<Number>::map_rank;
1725  };
1726 
1727  // Rank of FunctionParser
1728  template <int dim>
1729  struct RankInfo<std::unique_ptr<FunctionParser<dim>>>
1730  {
1731  static constexpr int list_rank = 1;
1732  static constexpr int map_rank = 0;
1733  };
1734 
1735  // Rank of ComponentMask
1736  template <>
1738  {
1739  static constexpr int list_rank = 1;
1740  static constexpr int map_rank = 0;
1741  };
1742 
1743  // Rank of std::pair
1744  template <class Key, class Value>
1745  struct RankInfo<std::pair<Key, Value>>
1746  {
1747  static constexpr int list_rank =
1749  static constexpr int map_rank =
1751  };
1752 
1753 
1754  template <class... Types>
1755  struct RankInfo<std::tuple<Types...>>
1756  {
1757  static constexpr int list_rank = max_list_rank<Types...>();
1758  static constexpr int map_rank = max_map_rank<Types...>() + 1;
1759  };
1760  } // namespace internal
1761 
1762  // stl containers
1763  template <class T>
1764  struct Convert<T,
1765  typename std::enable_if<is_list_compatible<T>::value>::type>
1766  {
1767  static std::unique_ptr<Patterns::PatternBase>
1769  {
1770  static_assert(internal::RankInfo<T>::list_rank > 0,
1771  "Cannot use this class for non List-compatible types.");
1772  return std::make_unique<Patterns::List>(
1774  0,
1777  1]);
1778  }
1779 
1780  static std::string
1782  const T & t,
1783  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
1784  {
1785  auto p = dynamic_cast<const Patterns::List *>(&pattern);
1786  AssertThrow(p,
1787  ExcMessage("I need a List pattern to convert a "
1788  "string to a List type."));
1789  auto base_p = p->get_base_pattern().clone();
1790  std::vector<std::string> vec(t.size());
1791 
1793  t.cbegin(), t.cend(), vec.begin(), [&base_p](const auto &entry) {
1794  return Convert<typename T::value_type>::to_string(entry, *base_p);
1795  });
1796 
1797  std::string s;
1798  if (vec.size() > 0)
1799  s = vec[0];
1800  for (unsigned int i = 1; i < vec.size(); ++i)
1801  s += p->get_separator() + " " + vec[i];
1802 
1803  AssertThrow(pattern.match(s), ExcNoMatch(s, p->description()));
1804  return s;
1805  }
1806 
1807  static T
1808  to_value(const std::string & s,
1809  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
1810  {
1811  AssertThrow(pattern.match(s), ExcNoMatch(s, pattern.description()));
1812 
1813  auto p = dynamic_cast<const Patterns::List *>(&pattern);
1814  AssertThrow(p,
1815  ExcMessage("I need a List pattern to convert a string "
1816  "to a List type."));
1817 
1818  auto base_p = p->get_base_pattern().clone();
1819  T t;
1820 
1821  auto v = Utilities::split_string_list(s, p->get_separator());
1822  for (const auto &str : v)
1823  t.insert(t.end(),
1825 
1826  return t;
1827  }
1828  };
1829 
1830  // stl maps
1831  template <class T>
1832  struct Convert<T,
1833  typename std::enable_if<is_map_compatible<T>::value>::type>
1834  {
1835  static std::unique_ptr<Patterns::PatternBase>
1837  {
1838  static_assert(internal::RankInfo<T>::list_rank > 0,
1839  "Cannot use this class for non List-compatible types.");
1840  static_assert(internal::RankInfo<T>::map_rank > 0,
1841  "Cannot use this class for non Map-compatible types.");
1842  return std::make_unique<Patterns::Map>(
1845  0,
1848  1],
1850  }
1851 
1852  static std::string
1854  const T & t,
1855  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
1856  {
1857  auto p = dynamic_cast<const Patterns::Map *>(&pattern);
1858  AssertThrow(p,
1859  ExcMessage("I need a Map pattern to convert a string to "
1860  "a Map compatible type."));
1861  auto key_p = p->get_key_pattern().clone();
1862  auto val_p = p->get_value_pattern().clone();
1863  std::vector<std::string> vec(t.size());
1864 
1865  unsigned int i = 0;
1866  for (const auto &ti : t)
1867  vec[i++] =
1868  Convert<typename T::key_type>::to_string(ti.first, *key_p) +
1869  p->get_key_value_separator() +
1871 
1872  std::string s;
1873  if (vec.size() > 0)
1874  s = vec[0];
1875  for (unsigned int i = 1; i < vec.size(); ++i)
1876  s += p->get_separator() + " " + vec[i];
1877 
1878  AssertThrow(p->match(s), ExcNoMatch(s, p->description()));
1879  return s;
1880  }
1881 
1882  static T
1883  to_value(const std::string & s,
1884  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
1885  {
1886  AssertThrow(pattern.match(s), ExcNoMatch(s, pattern.description()));
1887 
1888  auto p = dynamic_cast<const Patterns::Map *>(&pattern);
1889  AssertThrow(p,
1890  ExcMessage("I need a Map pattern to convert a "
1891  "string to a Map compatible type."));
1892 
1893  auto key_p = p->get_key_pattern().clone();
1894  auto val_p = p->get_value_pattern().clone();
1895  T t;
1896 
1897  auto v = Utilities::split_string_list(s, p->get_separator());
1898  for (const auto &str : v)
1899  {
1900  auto key_val =
1901  Utilities::split_string_list(str, p->get_key_value_separator());
1902  AssertDimension(key_val.size(), 2);
1903  t.insert(std::make_pair(
1904  Convert<typename T::key_type>::to_value(key_val[0], *key_p),
1906  }
1907 
1908  return t;
1909  }
1910  };
1911 
1912  // Tensors
1913  template <int rank, int dim, class Number>
1914  struct Convert<Tensor<rank, dim, Number>>
1915  {
1917  static std::unique_ptr<Patterns::PatternBase>
1919  {
1920  static_assert(internal::RankInfo<T>::list_rank > 0,
1921  "Cannot use this class for non List-compatible types.");
1922  return std::make_unique<Patterns::List>(
1924  dim,
1925  dim,
1927  1]);
1928  }
1929 
1930  static std::string
1932  const T & t,
1933  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
1934  {
1935  auto p = dynamic_cast<const Patterns::List *>(&pattern);
1936  AssertThrow(p,
1937  ExcMessage("I need a List pattern to convert a string "
1938  "to a List compatible type."));
1939  auto base_p = p->get_base_pattern().clone();
1940  std::vector<std::string> vec(dim);
1941 
1942  for (unsigned int i = 0; i < dim; ++i)
1943  vec[i] = Convert<typename T::value_type>::to_string(t[i], *base_p);
1944 
1945  std::string s;
1946  if (vec.size() > 0)
1947  s = vec[0];
1948  for (unsigned int i = 1; i < vec.size(); ++i)
1949  s += p->get_separator() + " " + vec[i];
1950 
1951  AssertThrow(p->match(s), ExcNoMatch(s, p->description()));
1952  return s;
1953  }
1954 
1955  static T
1956  to_value(const std::string & s,
1957  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
1958  {
1959  AssertThrow(pattern.match(s), ExcNoMatch(s, pattern.description()));
1960 
1961  auto p = dynamic_cast<const Patterns::List *>(&pattern);
1962  AssertThrow(p,
1963  ExcMessage("I need a List pattern to convert a string "
1964  "to a List compatible type."));
1965 
1966  auto base_p = p->get_base_pattern().clone();
1967  T t;
1968 
1969  auto v = Utilities::split_string_list(s, p->get_separator());
1970  unsigned int i = 0;
1971  for (const auto &str : v)
1972  t[i++] = Convert<typename T::value_type>::to_value(str, *base_p);
1973 
1974  return t;
1975  }
1976  };
1977 
1978  // Points
1979  template <int dim, class Number>
1980  struct Convert<Point<dim, Number>>
1981  {
1983 
1984  static std::unique_ptr<Patterns::PatternBase>
1986  {
1987  return Convert<Tensor<1, dim, Number>>::to_pattern();
1988  }
1989 
1990  static std::string
1992  const T & t,
1993  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
1994  {
1996  Tensor<1, dim, Number>(t), pattern);
1997  }
1998 
1999  static T
2000  to_value(const std::string & s,
2001  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2002  {
2003  return T(Convert<Tensor<1, dim, Number>>::to_value(s, pattern));
2004  }
2005  };
2006 
2007  // Functions::FunctionParser
2008  template <int dim>
2009  struct Convert<std::unique_ptr<FunctionParser<dim>>>
2010  {
2011  using T = std::unique_ptr<FunctionParser<dim>>;
2012 
2013  static std::unique_ptr<Patterns::PatternBase>
2015  {
2016  static_assert(internal::RankInfo<T>::list_rank > 0,
2017  "Cannot use this class for non List-compatible types.");
2018 
2019  return std::make_unique<Patterns::List>(
2021  1,
2024  1]);
2025  }
2026 
2027  static std::string
2029  const T & t,
2030  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2031  {
2032  auto p = dynamic_cast<const Patterns::List *>(&pattern);
2033  AssertThrow(p,
2034  ExcMessage("I need a List pattern to convert a string "
2035  "to a List compatible type."));
2036 
2037  const auto &expressions = t->get_expressions();
2038  if (expressions.size() == 0)
2039  return std::string();
2040 
2041  std::string s = expressions[0];
2042  for (unsigned int i = 1; i < expressions.size(); ++i)
2043  s = s + p->get_separator() + expressions[i];
2044 
2045  AssertThrow(pattern.match(s), ExcNoMatch(s, p->description()));
2046  return s;
2047  }
2048 
2049  static T
2050  to_value(const std::string & s,
2051  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2052  {
2053  AssertThrow(pattern.match(s), ExcNoMatch(s, pattern.description()));
2054 
2055  auto p = dynamic_cast<const Patterns::List *>(&pattern);
2056  AssertThrow(p,
2057  ExcMessage("I need a List pattern to convert a string "
2058  "to a List compatible type."));
2059 
2060  const auto expressions =
2061  Utilities::split_string_list(s, p->get_separator());
2062 
2063  T t = std::make_unique<FunctionParser<dim>>(expressions.size());
2064  const std::string var =
2066  const typename FunctionParser<dim>::ConstMap constants;
2067  t->initialize(var, expressions, constants, true);
2068  return t;
2069  }
2070  };
2071 
2072  // ComponentMask
2073  template <>
2075  {
2076  using T = ComponentMask;
2077 
2078  static std::unique_ptr<Patterns::PatternBase>
2080  {
2081  return Convert<std::vector<bool>>::to_pattern();
2082  }
2083 
2084  static std::string
2086  const T & t,
2087  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2088  {
2089  std::vector<bool> mask(t.size());
2090  for (unsigned int i = 0; i < t.size(); ++i)
2091  mask[i] = t[i];
2092 
2093  return Convert<std::vector<bool>>::to_string(mask, pattern);
2094  }
2095 
2096  static T
2097  to_value(const std::string & s,
2098  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2099  {
2100  const auto mask = Convert<std::vector<bool>>::to_value(s, pattern);
2101  return ComponentMask(mask);
2102  }
2103  };
2104 
2105  // Complex numbers
2106  template <class Number>
2107  struct Convert<std::complex<Number>>
2108  {
2109  using T = std::complex<Number>;
2110 
2111  static std::unique_ptr<Patterns::PatternBase>
2113  {
2114  static_assert(internal::RankInfo<T>::list_rank > 0,
2115  "Cannot use this class for non List-compatible types.");
2116  return std::make_unique<Patterns::List>(
2118  2,
2119  2,
2121  1]);
2122  }
2123 
2124  static std::string
2126  const T & t,
2127  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2128  {
2129  auto p = dynamic_cast<const Patterns::List *>(&pattern);
2130  AssertThrow(p,
2131  ExcMessage("I need a List pattern to convert a string "
2132  "to a List compatible type."));
2133 
2134  auto base_p = p->get_base_pattern().clone();
2135  std::string s =
2136  Convert<typename T::value_type>::to_string(t.real(), *base_p) +
2137  p->get_separator() + " " +
2138  Convert<typename T::value_type>::to_string(t.imag(), *base_p);
2139 
2140  AssertThrow(pattern.match(s), ExcNoMatch(s, p->description()));
2141  return s;
2142  }
2143 
2147  static T
2148  to_value(const std::string & s,
2149  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2150  {
2151  AssertThrow(pattern.match(s), ExcNoMatch(s, pattern.description()));
2152 
2153  auto p = dynamic_cast<const Patterns::List *>(&pattern);
2154  AssertThrow(p,
2155  ExcMessage("I need a List pattern to convert a string "
2156  "to a List compatible type."));
2157 
2158  auto base_p = p->get_base_pattern().clone();
2159 
2160  auto v = Utilities::split_string_list(s, p->get_separator());
2161  AssertDimension(v.size(), 2);
2164  return t;
2165  }
2166  };
2167 
2168  // Strings
2169  template <>
2170  struct Convert<std::string>
2171  {
2172  using T = std::string;
2173 
2174  static std::unique_ptr<Patterns::PatternBase>
2176  {
2177  return std::make_unique<Patterns::Anything>();
2178  }
2179 
2180  static std::string
2182  const T & t,
2183  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2184  {
2185  AssertThrow(pattern.match(t), ExcNoMatch(t, pattern.description()));
2186  return t;
2187  }
2188 
2189  static T
2190  to_value(const std::string & s,
2191  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2192  {
2193  AssertThrow(pattern.match(s), ExcNoMatch(s, pattern.description()));
2194  return s;
2195  }
2196  };
2197 
2198  // Pairs
2199  template <class Key, class Value>
2200  struct Convert<std::pair<Key, Value>>
2201  {
2202  using T = std::pair<Key, Value>;
2203 
2204  static std::unique_ptr<Patterns::PatternBase>
2206  {
2207  static_assert(internal::RankInfo<T>::map_rank > 0,
2208  "Cannot use this class for non Map-compatible types.");
2209  return std::make_unique<Patterns::Tuple>(
2213  }
2214 
2215  static std::string
2217  const T & t,
2218  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2219  {
2220  std::tuple<Key, Value> m(t);
2221  std::string s = Convert<decltype(m)>::to_string(m, pattern);
2222  AssertThrow(pattern.match(s), ExcNoMatch(s, pattern.description()));
2223  return s;
2224  }
2225 
2226  static T
2227  to_value(const std::string & s,
2228  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2229  {
2230  std::tuple<Key, Value> m;
2231  m = Convert<decltype(m)>::to_value(s, pattern);
2232  return std::make_pair(std::get<0>(m), std::get<1>(m));
2233  }
2234  };
2235 
2236  // Tuples
2237  template <class... Args>
2238  struct Convert<std::tuple<Args...>>
2239  {
2240  using T = std::tuple<Args...>;
2241 
2242  static std::unique_ptr<Patterns::PatternBase>
2244  {
2245  static_assert(internal::RankInfo<T>::map_rank > 0,
2246  "Cannot use this class for non tuple-compatible types.");
2247  return std::make_unique<Patterns::Tuple>(
2250  }
2251 
2252  static std::string
2254  const T & t,
2255  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2256  {
2257  auto p = dynamic_cast<const Patterns::Tuple *>(&pattern);
2258  AssertThrow(p,
2259  ExcMessage("I need a Tuple pattern to convert a tuple "
2260  "to a string."));
2261 
2262  const auto string_array = Convert<T>::to_string_internal_2(t, *p);
2263  std::string str;
2264  for (unsigned int i = 0; i < string_array.size(); ++i)
2265  str += (i ? " " + p->get_separator() + " " : "") + string_array[i];
2266  AssertThrow(p->match(str), ExcNoMatch(str, p->description()));
2267  return str;
2268  }
2269 
2270  static T
2271  to_value(const std::string & s,
2272  const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
2273  {
2274  AssertThrow(pattern.match(s), ExcNoMatch(s, pattern.description()));
2275 
2276  auto p = dynamic_cast<const Patterns::Tuple *>(&pattern);
2277  AssertThrow(p,
2278  ExcMessage("I need a Tuple pattern to convert a string "
2279  "to a tuple type."));
2280 
2281  auto v = Utilities::split_string_list(s, p->get_separator());
2282 
2283  return Convert<T>::to_value_internal_2(v, *p);
2284  }
2285 
2286  private:
2287  template <std::size_t... U>
2288  static std::array<std::string, std::tuple_size<T>::value>
2290  const Patterns::Tuple &pattern,
2291  std::index_sequence<U...>)
2292  {
2293  std::array<std::string, std::tuple_size<T>::value> a = {
2295  std::get<U>(t), pattern.get_pattern(U))...}};
2296  return a;
2297  }
2298 
2299  static std::array<std::string, std::tuple_size<T>::value>
2300  to_string_internal_2(const T &t, const Patterns::Tuple &pattern)
2301  {
2303  t, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2304  }
2305 
2306  template <std::size_t... U>
2307  static T
2308  to_value_internal_1(const std::vector<std::string> &s,
2309  const Patterns::Tuple & pattern,
2310  std::index_sequence<U...>)
2311  {
2312  return std::make_tuple(
2313  Convert<typename std::tuple_element<U, T>::type>::to_value(
2314  s[U], pattern.get_pattern(U))...);
2315  }
2316 
2317  static T
2318  to_value_internal_2(const std::vector<std::string> &s,
2319  const Patterns::Tuple & pattern)
2320  {
2322  s, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2323  }
2324  };
2325 
2326  // Utility function with default Pattern
2327  template <typename T>
2328  std::string
2329  to_string(const T &t)
2330  {
2331  return Convert<T>::to_string(t);
2332  }
2333 
2334  // Utility function with default Pattern
2335  template <typename T>
2336  void
2337  to_value(const std::string &s, T &t)
2338  {
2339  t = Convert<T>::to_value(s);
2340  }
2341  } // namespace Tools
2342 } // namespace Patterns
2343 
2344 
2346 
2347 #endif
static std::string to_string(const T &t, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2181
Iterator lower_bound(Iterator first, Iterator last, const T &val)
Definition: utilities.h:1111
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
Definition: utilities.cc:704
void transform(const InputIterator &begin_in, const InputIterator &end_in, OutputIterator out, const Predicate &predicate, const unsigned int grainsize)
Definition: parallel.h:213
static T to_value(const std::string &s, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2097
static T to_value(const std::string &s, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:1883
static std::string to_string(const T &t, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2253
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:538
static T to_value(const std::string &s, const Patterns::PatternBase &p= *Convert< T >::to_pattern())
Definition: patterns.h:1539
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1623
std::string escape(const std::string &input, const PatternBase::OutputStyle style)
Definition: patterns.cc:55
void to_value(const std::string &s, T &t)
Definition: patterns.h:2337
std::string sequence
Definition: patterns.h:434
const double upper_bound
Definition: patterns.h:365
static const char * description_init
Definition: patterns.h:370
static const char * description_init
Definition: patterns.h:1147
static T to_value(const std::string &s, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2000
static std::string to_string(const T &t, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:1991
const PatternBase & get_pattern(const unsigned int i) const
Definition: patterns.cc:1223
static T to_value(const std::string &s, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:1808
static T to_value(const std::string &s, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2050
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:1918
const std::string separator
Definition: patterns.h:885
const std::string separator
Definition: patterns.h:710
std::unique_ptr< PatternBase > pattern
Definition: patterns.h:546
static const unsigned int max_int_value
Definition: patterns.h:592
virtual std::unique_ptr< PatternBase > clone() const =0
static const char * description_init
Definition: patterns.h:721
static std::string to_string(const T &t, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2125
static T to_value(const std::string &s, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2148
static std::string to_string(const T &t, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:1931
STL namespace.
static const char U
static std::array< std::string, std::tuple_size< T >::value > to_string_internal_1(const T &t, const Patterns::Tuple &pattern, std::index_sequence< U... >)
Definition: patterns.h:2289
static const int max_int_value
Definition: patterns.h:204
#define AssertThrow(cond, exc)
Definition: exceptions.h:1576
static std::string to_string(const T &t, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:1853
constexpr std::array< const char *, 4 > default_list_separator
Definition: patterns.h:1578
const unsigned int max_elements
Definition: patterns.h:705
static const char * description_init
Definition: patterns.h:974
static ::ExceptionBase & ExcNoMatch(std::string arg1, std::string arg2)
Definition: point.h:110
FileType file_type
Definition: patterns.h:1133
static const int min_int_value
Definition: patterns.h:197
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition: config.h:407
static std::string default_variable_names()
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:1985
static T to_value_internal_1(const std::vector< std::string > &s, const Patterns::Tuple &pattern, std::index_sequence< U... >)
Definition: patterns.h:2308
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2243
const double lower_bound
Definition: patterns.h:357
static const char * description_init
Definition: patterns.h:566
static ::ExceptionBase & ExcMessage(std::string arg1)
static const char * description_init
Definition: patterns.h:1016
static const char * description_init
Definition: patterns.h:439
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:515
constexpr int max_list_rank()
Definition: patterns.h:1663
static const char T
static std::string to_string(const T &value, const Patterns::PatternBase &p= *Convert< T >::to_pattern())
Definition: patterns.h:1523
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2079
std::vector< std::unique_ptr< PatternBase > > patterns
Definition: patterns.h:880
static std::enable_if< std::is_same< Dummy, T >::value &&!std::is_same< T, bool >::value &&std::is_floating_point< T >::value, std::unique_ptr< Patterns::PatternBase > >::type to_pattern()
Definition: patterns.h:1516
virtual std::size_t memory_consumption() const
Definition: patterns.cc:192
static const char * description_init
Definition: patterns.h:272
static const char * description_init
Definition: patterns.h:890
std::unique_ptr< PatternBase > key_pattern
Definition: patterns.h:694
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:394
virtual ~PatternBase()=default
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2175
static std::string to_string(const T &t, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2028
std::string to_string(const T &t)
Definition: patterns.h:2329
unsigned int size() const
static const double min_double_value
Definition: patterns.h:299
std::unique_ptr< PatternBase > pattern_factory(const std::string &description)
Definition: patterns.cc:140
static const char * description_init
Definition: patterns.h:1205
static std::enable_if< std::is_same< Dummy, T >::value &&!std::is_same< T, bool >::value &&std::is_integral< T >::value, std::unique_ptr< Patterns::PatternBase > >::type to_pattern()
Definition: patterns.h:1504
static std::string to_string(const T &t, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:1781
virtual bool match(const std::string &test_string) const =0
static std::string to_string(const T &t, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2085
static T to_value_internal_2(const std::vector< std::string > &s, const Patterns::Tuple &pattern)
Definition: patterns.h:2318
static const char * description_init
Definition: patterns.h:1065
constexpr int max_map_rank()
Definition: patterns.h:1678
static std::string to_string(const T &t, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2216
__global__ void set(Number *val, const Number s, const size_type N)
static std::enable_if< std::is_same< Dummy, T >::value &&std::is_same< T, bool >::value, std::unique_ptr< Patterns::PatternBase > >::type to_pattern()
Definition: patterns.h:1493
static const double max_double_value
Definition: patterns.h:305
virtual std::string description(const OutputStyle style=Machine) const =0
Definition: tensor.h:449
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition: config.h:444
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:393
static T to_value(const std::string &s, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2227
std::map< std::string, double > ConstMap
const int upper_bound
Definition: patterns.h:267
static std::array< std::string, std::tuple_size< T >::value > to_string_internal_2(const T &t, const Patterns::Tuple &pattern)
Definition: patterns.h:2300
constexpr std::array< const char *, 4 > default_map_separator
Definition: patterns.h:1580
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2112
Tuple(const std::vector< std::unique_ptr< PatternBase >> &patterns, const std::string &separator=":")
Definition: patterns.cc:1057
const unsigned int min_elements
Definition: patterns.h:700
static const unsigned int max_int_value
Definition: patterns.h:458
static T to_value(const std::string &s, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:1956
static T to_value(const std::string &s, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2271
const int lower_bound
Definition: patterns.h:259
std::unique_ptr< PatternBase > value_pattern
Definition: patterns.h:695
static T to_value(const std::string &s, const Patterns::PatternBase &pattern= *Convert< T >::to_pattern())
Definition: patterns.h:2190
const std::string separator
Definition: patterns.h:561
const std::string key_value_separator
Definition: patterns.h:716
const unsigned int max_elements
Definition: patterns.h:556
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2205
T max(const T &t, const MPI_Comm &mpi_communicator)
const unsigned int min_elements
Definition: patterns.h:551
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2014