Reference documentation for deal.II version 9.2.0
\(\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>
29 #include <deal.II/base/utilities.h>
30 
32 
34 #include <boost/archive/basic_archive.hpp>
35 #include <boost/core/demangle.hpp>
36 #include <boost/property_tree/ptree_fwd.hpp>
37 #include <boost/property_tree/ptree_serialization.hpp>
38 #include <boost/serialization/split_member.hpp>
40 
41 #include <array>
42 #include <deque>
43 #include <list>
44 #include <map>
45 #include <set>
46 #include <sstream>
47 #include <string>
48 #include <type_traits>
49 #include <unordered_map>
50 #include <unordered_set>
51 #include <utility>
52 #include <vector>
53 
55 
56 // forward declarations for interfaces and friendship
57 #ifndef DOXYGEN
58 class LogStream;
60 template <int dim>
61 class FunctionParser;
62 #endif
63 
72 namespace Patterns
73 {
81  {
82  public:
86  virtual ~PatternBase() = default;
87 
91  virtual bool
92  match(const std::string &test_string) const = 0;
93 
100  {
117  };
118 
122  virtual std::string
123  description(const OutputStyle style = Machine) const = 0;
124 
134  virtual std::unique_ptr<PatternBase>
135  clone() const = 0;
136 
152  virtual std::size_t
153  memory_consumption() const;
154  };
155 
159  std::unique_ptr<PatternBase>
160  pattern_factory(const std::string &description);
161 
162  namespace internal
163  {
169  std::string
170  escape(const std::string &input, const PatternBase::OutputStyle style);
171 
172  } // namespace internal
173 
190  class Integer : public PatternBase
191  {
192  public:
198  static const int min_int_value;
199 
205  static const int max_int_value;
206 
219  Integer(const int lower_bound = min_int_value,
220  const int upper_bound = max_int_value);
221 
226  virtual bool
227  match(const std::string &test_string) const override;
228 
234  virtual std::string
235  description(const OutputStyle style = Machine) const override;
236 
242  virtual std::unique_ptr<PatternBase>
243  clone() const override;
244 
250  static std::unique_ptr<Integer>
251  create(const std::string &description);
252 
253  private:
260  const int lower_bound;
261 
268  const int upper_bound;
269 
273  static const char *description_init;
274  };
275 
293  class Double : public PatternBase
294  {
295  public:
300  static const double min_double_value;
301 
306  static const double max_double_value;
307 
315  Double(const double lower_bound = min_double_value,
316  const double upper_bound = max_double_value);
317 
322  virtual bool
323  match(const std::string &test_string) const override;
324 
330  virtual std::string
331  description(const OutputStyle style = Machine) const override;
332 
338  virtual std::unique_ptr<PatternBase>
339  clone() const override;
340 
348  static std::unique_ptr<Double>
349  create(const std::string &description);
350 
351  private:
358  const double lower_bound;
359 
366  const double upper_bound;
367 
371  static const char *description_init;
372  };
373 
383  class Selection : public PatternBase
384  {
385  public:
390  Selection(const std::string &seq);
391 
396  virtual bool
397  match(const std::string &test_string) const override;
398 
404  virtual std::string
405  description(const OutputStyle style = Machine) const override;
406 
412  virtual std::unique_ptr<PatternBase>
413  clone() const override;
414 
419  std::size_t
420  memory_consumption() const override;
421 
427  static std::unique_ptr<Selection>
428  create(const std::string &description);
429 
430  private:
435  std::string sequence;
436 
440  static const char *description_init;
441  };
442 
443 
451  class List : public PatternBase
452  {
453  public:
459  static const unsigned int max_int_value;
460 
469  List(const PatternBase &base_pattern,
470  const unsigned int min_elements = 0,
471  const unsigned int max_elements = max_int_value,
472  const std::string &separator = ",");
473 
474 
478  const std::string &
479  get_separator() const;
480 
484  const PatternBase &
485  get_base_pattern() const;
486 
490  List(const List &other);
491 
496  virtual bool
497  match(const std::string &test_string) const override;
498 
503  virtual std::string
504  description(const OutputStyle style = Machine) const override;
505 
511  virtual std::unique_ptr<PatternBase>
512  clone() const override;
513 
519  static std::unique_ptr<List>
520  create(const std::string &description);
521 
526  std::size_t
527  memory_consumption() const override;
528 
537  DeclException2(ExcInvalidRange,
538  int,
539  int,
540  << "The values " << arg1 << " and " << arg2
541  << " do not form a valid range.");
543  private:
547  std::unique_ptr<PatternBase> pattern;
548 
552  const unsigned int min_elements;
553 
557  const unsigned int max_elements;
558 
562  const std::string separator;
563 
567  static const char *description_init;
568  };
569 
570 
585  class Map : public PatternBase
586  {
587  public:
593  static const unsigned int max_int_value;
594 
603  Map(const PatternBase &key_pattern,
604  const PatternBase &value_pattern,
605  const unsigned int min_elements = 0,
606  const unsigned int max_elements = max_int_value,
607  const std::string &separator = ",",
608  const std::string &key_value_separator = ":");
609 
613  Map(const Map &other);
614 
619  virtual bool
620  match(const std::string &test_string) const override;
621 
626  virtual std::string
627  description(const OutputStyle style = Machine) const override;
628 
634  virtual std::unique_ptr<PatternBase>
635  clone() const override;
636 
642  static std::unique_ptr<Map>
643  create(const std::string &description);
644 
649  std::size_t
650  memory_consumption() const override;
651 
655  const PatternBase &
656  get_key_pattern() const;
657 
661  const PatternBase &
662  get_value_pattern() const;
663 
667  const std::string &
668  get_separator() const;
669 
673  const std::string &
674  get_key_value_separator() const;
675 
684  DeclException2(ExcInvalidRange,
685  int,
686  int,
687  << "The values " << arg1 << " and " << arg2
688  << " do not form a valid range.");
690  private:
695  std::unique_ptr<PatternBase> key_pattern;
696  std::unique_ptr<PatternBase> value_pattern;
697 
701  const unsigned int min_elements;
702 
706  const unsigned int max_elements;
707 
711  const std::string separator;
712 
713 
717  const std::string key_value_separator;
718 
722  static const char *description_init;
723  };
724 
725 
726 
774  class Tuple : public PatternBase
775  {
776  public:
785  Tuple(const std::vector<std::unique_ptr<PatternBase>> &patterns,
786  const std::string & separator = ":");
787 
793  Tuple(const std::vector<std::unique_ptr<PatternBase>> &patterns,
794  const char * separator);
795 
796 
804  template <class... PatternTypes>
805  Tuple(const std::string &separator, const PatternTypes &... patterns);
806 
814  template <class... PatternTypes>
815  Tuple(const char *separator, const PatternTypes &... patterns);
816 
822  template <typename... Patterns>
823  Tuple(const Patterns &... patterns);
824 
828  Tuple(const Tuple &other);
829 
834  virtual bool
835  match(const std::string &test_string) const override;
836 
841  virtual std::string
842  description(const OutputStyle style = Machine) const override;
843 
849  virtual std::unique_ptr<PatternBase>
850  clone() const override;
851 
857  static std::unique_ptr<Tuple>
858  create(const std::string &description);
859 
864  std::size_t
865  memory_consumption() const override;
866 
870  const PatternBase &
871  get_pattern(const unsigned int i) const;
872 
876  const std::string &
877  get_separator() const;
878 
879  private:
883  std::vector<std::unique_ptr<PatternBase>> patterns;
884 
888  const std::string separator;
889 
893  static const char *description_init;
894  };
895 
896 
908  {
909  public:
913  MultipleSelection(const std::string &seq);
914 
919  virtual bool
920  match(const std::string &test_string) const override;
921 
927  virtual std::string
928  description(const OutputStyle style = Machine) const override;
929 
935  virtual std::unique_ptr<PatternBase>
936  clone() const override;
937 
943  static std::unique_ptr<MultipleSelection>
944  create(const std::string &description);
945 
950  std::size_t
951  memory_consumption() const override;
952 
962  ExcCommasNotAllowed,
963  int,
964  << "A comma was found at position " << arg1
965  << " of your input string, but commas are not allowed here.");
967  private:
972  std::string sequence;
973 
977  static const char *description_init;
978  };
979 
984  class Bool : public Selection
985  {
986  public:
990  Bool();
991 
996  virtual std::string
997  description(const OutputStyle style = Machine) const override;
998 
1004  virtual std::unique_ptr<PatternBase>
1005  clone() const override;
1006 
1012  static std::unique_ptr<Bool>
1013  create(const std::string &description);
1014 
1015  private:
1019  static const char *description_init;
1020  };
1021 
1025  class Anything : public PatternBase
1026  {
1027  public:
1032  Anything() = default;
1033 
1038  virtual bool
1039  match(const std::string &test_string) const override;
1040 
1045  virtual std::string
1046  description(const OutputStyle style = Machine) const override;
1047 
1053  virtual std::unique_ptr<PatternBase>
1054  clone() const override;
1055 
1061  static std::unique_ptr<Anything>
1062  create(const std::string &description);
1063 
1064  private:
1068  static const char *description_init;
1069  };
1070 
1071 
1086  class FileName : public PatternBase
1087  {
1088  public:
1094  {
1098  input = 0,
1102  output = 1
1103  };
1104 
1109  FileName(const FileType type = input);
1110 
1115  virtual bool
1116  match(const std::string &test_string) const override;
1117 
1122  virtual std::string
1123  description(const OutputStyle style = Machine) const override;
1124 
1130  virtual std::unique_ptr<PatternBase>
1131  clone() const override;
1132 
1137 
1143  static std::unique_ptr<FileName>
1144  create(const std::string &description);
1145 
1146  private:
1150  static const char *description_init;
1151  };
1152 
1153 
1167  {
1168  public:
1172  DirectoryName() = default;
1173 
1178  virtual bool
1179  match(const std::string &test_string) const override;
1180 
1185  virtual std::string
1186  description(const OutputStyle style = Machine) const override;
1187 
1193  virtual std::unique_ptr<PatternBase>
1194  clone() const override;
1195 
1201  static std::unique_ptr<DirectoryName>
1202  create(const std::string &description);
1203 
1204  private:
1208  static const char *description_init;
1209  };
1210 
1211 
1291  namespace Tools
1292  {
1304  template <class T, class Enable = void>
1305  struct Convert
1306  {
1316  static std::unique_ptr<Patterns::PatternBase>
1317  to_pattern() = delete;
1318 
1329  static std::string
1330  to_string(const T & s,
1331  const std::unique_ptr<Patterns::PatternBase> &p =
1332  Convert<T>::to_pattern()) = delete;
1333 
1343  static T
1344  to_value(const std::string & s,
1345  const std::unique_ptr<Patterns::PatternBase> &p =
1346  Convert<T>::to_pattern()) = delete;
1347  };
1348 
1369  template <typename T>
1370  std::string
1371  to_string(const T &t);
1372 
1400  template <typename T>
1401  void
1402  to_value(const std::string &s, T &t);
1403 
1413  std::string,
1414  std::string,
1415  << "The string " << arg1 << " does not match the pattern \""
1416  << arg2 << "\"");
1418  } // namespace Tools
1419 } // namespace Patterns
1420 
1421 
1422 // ---------------------- inline and template functions --------------------
1423 namespace Patterns
1424 {
1425  template <class... PatternTypes>
1426  Tuple::Tuple(const char *separator, const PatternTypes &... ps)
1427  : // forward to the version with std::string argument
1428  Tuple(std::string(separator), ps...)
1429  {}
1430 
1431 
1432 
1433  template <class... PatternTypes>
1434  Tuple::Tuple(const std::string &separator, const PatternTypes &... ps)
1435  : separator(separator)
1436  {
1438  "Not all of the input arguments of this function "
1439  "are derived from PatternBase");
1440  static_assert(sizeof...(ps) > 0,
1441  "The number of PatternTypes must be greater than zero!");
1442  const auto pattern_pointers = {(static_cast<const PatternBase *>(&ps))...};
1443  for (const auto p : pattern_pointers)
1444  patterns.push_back(p->clone());
1445  }
1446 
1447 
1448 
1449  template <class... PatternTypes>
1450  Tuple::Tuple(const PatternTypes &... ps)
1451  : // forward to the version with the separator argument
1452  Tuple(std::string(":"), ps...)
1453  {}
1454 
1455 
1456 
1457  namespace Tools
1458  {
1459  namespace internal
1460  {
1487  template <class T, class Enable = void>
1488  struct RankInfo
1489  {
1490  static constexpr int list_rank = 0;
1491  static constexpr int map_rank = 0;
1492  };
1493  } // namespace internal
1494 
1495  // Arithmetic types
1496  template <class T>
1497  struct Convert<T,
1498  typename std::enable_if<std::is_arithmetic<T>::value>::type>
1499  {
1500  template <typename Dummy = T>
1501  static
1504  std::unique_ptr<Patterns::PatternBase>>::type
1506  {
1507  return std_cxx14::make_unique<Patterns::Bool>();
1508  }
1509 
1510  template <typename Dummy = T>
1511  static
1513  !std::is_same<T, bool>::value &&
1515  std::unique_ptr<Patterns::PatternBase>>::type
1517  {
1518  return std_cxx14::make_unique<Patterns::Integer>(
1519  std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
1520  }
1521 
1522  template <typename Dummy = T>
1523  static
1525  !std::is_same<T, bool>::value &&
1527  std::unique_ptr<Patterns::PatternBase>>::type
1529  {
1530  return std_cxx14::make_unique<Patterns::Double>(
1531  std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
1532  }
1533 
1534  static std::string
1535  to_string(const T & value,
1536  const std::unique_ptr<Patterns::PatternBase> &p =
1538  {
1539  std::stringstream str;
1542  str << static_cast<int>(value);
1543  else if (std::is_same<T, bool>::value)
1544  str << (static_cast<bool>(value) ? "true" : "false");
1545  else
1546  str << value;
1547  AssertThrow(p->match(str.str()),
1548  ExcNoMatch(str.str(), p->description()));
1549  return str.str();
1550  }
1551 
1552  static T
1553  to_value(const std::string & s,
1554  const std::unique_ptr<Patterns::PatternBase> &p =
1556  {
1557  AssertThrow(p->match(s), ExcNoMatch(s, p->description()));
1558  T value;
1559  if (std::is_same<T, bool>::value)
1560  value = (s == "true");
1561  else
1562  {
1563  std::istringstream is(s);
1567  {
1568  int i;
1569  is >> i;
1570  value = i;
1571  }
1572  else
1573  is >> value;
1574 
1575  // If someone passes "123 abc" to the function, the method yields an
1576  // integer 123 alright, but the space terminates the read from the
1577  // string although there is more to come. This case, however, is
1578  // checked for in the call p->match(s) at the beginning of this
1579  // function, and would throw earlier. Here it is safe to assume that
1580  // if we didn't fail the conversion with the operator >>, then we
1581  // are good to go.
1582  AssertThrow(
1583  !is.fail(),
1584  ExcMessage("Failed to convert from \"" + s + "\" to the type \"" +
1585  boost::core::demangle(typeid(T).name()) + "\""));
1586  }
1587  return value;
1588  }
1589  };
1590 
1591  namespace internal
1592  {
1593  constexpr std::array<const char *, 4> default_list_separator{
1594  {",", ";", "|", "%"}};
1595  constexpr std::array<const char *, 4> default_map_separator{
1596  {":", "=", "@", "#"}};
1597 
1598  // specialize a type for all of the STL containers and maps
1599  template <typename T>
1600  struct is_list_compatible : std::false_type
1601  {};
1602  template <typename T, std::size_t N>
1603  struct is_list_compatible<std::array<T, N>> : std::true_type
1604  {};
1605  template <typename... Args>
1606  struct is_list_compatible<std::vector<Args...>> : std::true_type
1607  {};
1608  template <typename... Args>
1609  struct is_list_compatible<std::deque<Args...>> : std::true_type
1610  {};
1611  template <typename... Args>
1612  struct is_list_compatible<std::list<Args...>> : std::true_type
1613  {};
1614  template <typename... Args>
1615  struct is_list_compatible<std::set<Args...>> : std::true_type
1616  {};
1617  template <typename... Args>
1618  struct is_list_compatible<std::multiset<Args...>> : std::true_type
1619  {};
1620  template <typename... Args>
1621  struct is_list_compatible<std::unordered_set<Args...>> : std::true_type
1622  {};
1623  template <typename... Args>
1624  struct is_list_compatible<std::unordered_multiset<Args...>>
1625  : std::true_type
1626  {};
1627 
1628  template <typename T>
1629  struct is_map_compatible : std::false_type
1630  {};
1631  template <class Key, class T, class Compare, class Allocator>
1632  struct is_map_compatible<std::map<Key, T, Compare, Allocator>>
1633  : std::true_type
1634  {};
1635  template <class Key, class T, class Compare, class Allocator>
1636  struct is_map_compatible<std::multimap<Key, T, Compare, Allocator>>
1637  : std::true_type
1638  {};
1639  template <class Key, class T, class Hash, class KeyEqual, class Allocator>
1641  std::unordered_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type
1642  {};
1643  template <class Key, class T, class Hash, class KeyEqual, class Allocator>
1645  std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>>
1646  : std::true_type
1647  {};
1648  } // namespace internal
1649 
1650  // type trait to use the implementation type traits as well as decay the
1651  // type
1652  template <typename T>
1654  {
1655  static constexpr bool const value =
1657  };
1658 
1659  template <typename T>
1661  {
1662  static constexpr bool const value =
1664  };
1665 
1666  namespace internal
1667  {
1668  // Helper function for list_rank
1669  template <class T>
1670  constexpr int
1672  {
1673  return RankInfo<T>::list_rank;
1674  }
1675 
1676  template <class T1, class T2, class... Types>
1677  constexpr int
1679  {
1681  max_list_rank<T2, Types...>());
1682  }
1683 
1684  // Helper function for map_rank
1685  template <class T>
1686  constexpr int
1688  {
1689  return RankInfo<T>::map_rank;
1690  }
1691 
1692  template <class T1, class T2, class... Types>
1693  constexpr int
1695  {
1697  max_map_rank<T2, Types...>());
1698  }
1699 
1700  // Rank of vector types
1701  template <class T>
1702  struct RankInfo<
1703  T,
1704  typename std::enable_if<is_list_compatible<T>::value>::type>
1705  {
1706  static constexpr int list_rank =
1708  static constexpr int map_rank =
1710  };
1711 
1712  // Rank of map types
1713  template <class T>
1714  struct RankInfo<
1715  T,
1716  typename std::enable_if<is_map_compatible<T>::value>::type>
1717  {
1718  static constexpr int list_rank =
1719  max_list_rank<typename T::key_type, typename T::mapped_type>() + 1;
1720  static constexpr int map_rank =
1721  max_map_rank<typename T::key_type, typename T::mapped_type>() + 1;
1722  };
1723 
1724  // Rank of Tensor types
1725  template <int rank, int dim, class Number>
1726  struct RankInfo<Tensor<rank, dim, Number>>
1727  {
1728  static constexpr int list_rank = rank + RankInfo<Number>::list_rank;
1729  static constexpr int map_rank = RankInfo<Number>::map_rank;
1730  };
1731 
1732  template <int dim, class Number>
1733  struct RankInfo<Point<dim, Number>> : RankInfo<Tensor<1, dim, Number>>
1734  {};
1735 
1736  // Rank of complex types
1737  template <class Number>
1738  struct RankInfo<std::complex<Number>>
1739  {
1740  static constexpr int list_rank = RankInfo<Number>::list_rank + 1;
1741  static constexpr int map_rank = RankInfo<Number>::map_rank;
1742  };
1743 
1744  // Rank of FunctionParser
1745  template <int dim>
1746  struct RankInfo<std::unique_ptr<FunctionParser<dim>>>
1747  {
1748  static constexpr int list_rank = 1;
1749  static constexpr int map_rank = 0;
1750  };
1751 
1752  // Rank of ComponentMask
1753  template <>
1755  {
1756  static constexpr int list_rank = 1;
1757  static constexpr int map_rank = 0;
1758  };
1759 
1760  // Rank of std::pair
1761  template <class Key, class Value>
1762  struct RankInfo<std::pair<Key, Value>>
1763  {
1764  static constexpr int list_rank =
1766  static constexpr int map_rank =
1768  1;
1769  };
1770 
1771 
1772  template <class... Types>
1773  struct RankInfo<std::tuple<Types...>>
1774  {
1775  static constexpr int list_rank = max_list_rank<Types...>();
1776  static constexpr int map_rank = max_map_rank<Types...>() + 1;
1777  };
1778  } // namespace internal
1779 
1780  // stl containers
1781  template <class T>
1782  struct Convert<T,
1783  typename std::enable_if<is_list_compatible<T>::value>::type>
1784  {
1785  static std::unique_ptr<Patterns::PatternBase>
1787  {
1788  static_assert(internal::RankInfo<T>::list_rank > 0,
1789  "Cannot use this class for non List-compatible types.");
1790  return std_cxx14::make_unique<Patterns::List>(
1792  0,
1795  1]);
1796  }
1797 
1798  static std::string
1799  to_string(const T & t,
1800  const std::unique_ptr<Patterns::PatternBase> &pattern =
1802  {
1803  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
1804  AssertThrow(p,
1805  ExcMessage("I need a List pattern to convert a "
1806  "string to a List type."));
1807  auto base_p = p->get_base_pattern().clone();
1808  std::vector<std::string> vec(t.size());
1809 
1810  unsigned int i = 0;
1811  for (const auto &entry : t)
1812  vec[i++] = Convert<typename T::value_type>::to_string(entry, base_p);
1813 
1814  std::string s;
1815  if (vec.size() > 0)
1816  s = vec[0];
1817  for (unsigned int i = 1; i < vec.size(); ++i)
1818  s += p->get_separator() + " " + vec[i];
1819 
1820  AssertThrow(pattern->match(s), ExcNoMatch(s, p->description()));
1821  return s;
1822  }
1823 
1824  static T
1825  to_value(const std::string & s,
1826  const std::unique_ptr<Patterns::PatternBase> &pattern =
1828  {
1829  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
1830 
1831  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
1832  AssertThrow(p,
1833  ExcMessage("I need a List pattern to convert a string "
1834  "to a List type."));
1835 
1836  auto base_p = p->get_base_pattern().clone();
1837  T t;
1838 
1839  auto v = Utilities::split_string_list(s, p->get_separator());
1840  for (const auto &str : v)
1841  t.insert(t.end(),
1843 
1844  return t;
1845  }
1846  };
1847 
1848  // stl maps
1849  template <class T>
1850  struct Convert<T,
1851  typename std::enable_if<is_map_compatible<T>::value>::type>
1852  {
1853  static std::unique_ptr<Patterns::PatternBase>
1855  {
1856  static_assert(internal::RankInfo<T>::list_rank > 0,
1857  "Cannot use this class for non List-compatible types.");
1858  static_assert(internal::RankInfo<T>::map_rank > 0,
1859  "Cannot use this class for non Map-compatible types.");
1860  return std_cxx14::make_unique<Patterns::Map>(
1863  0,
1866  1],
1868  }
1869 
1870  static std::string
1871  to_string(const T & t,
1872  const std::unique_ptr<Patterns::PatternBase> &pattern =
1874  {
1875  auto p = dynamic_cast<const Patterns::Map *>(pattern.get());
1876  AssertThrow(p,
1877  ExcMessage("I need a Map pattern to convert a string to "
1878  "a Map compatible type."));
1879  auto key_p = p->get_key_pattern().clone();
1880  auto val_p = p->get_value_pattern().clone();
1881  std::vector<std::string> vec(t.size());
1882 
1883  unsigned int i = 0;
1884  for (const auto &ti : t)
1885  vec[i++] =
1886  Convert<typename T::key_type>::to_string(ti.first, key_p) +
1887  p->get_key_value_separator() +
1889 
1890  std::string s;
1891  if (vec.size() > 0)
1892  s = vec[0];
1893  for (unsigned int i = 1; i < vec.size(); ++i)
1894  s += p->get_separator() + " " + vec[i];
1895 
1896  AssertThrow(p->match(s), ExcNoMatch(s, p->description()));
1897  return s;
1898  }
1899 
1900  static T
1901  to_value(const std::string & s,
1902  const std::unique_ptr<Patterns::PatternBase> &pattern =
1904  {
1905  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
1906 
1907  auto p = dynamic_cast<const Patterns::Map *>(pattern.get());
1908  AssertThrow(p,
1909  ExcMessage("I need a Map pattern to convert a "
1910  "string to a Map compatible type."));
1911 
1912  auto key_p = p->get_key_pattern().clone();
1913  auto val_p = p->get_value_pattern().clone();
1914  T t;
1915 
1916  auto v = Utilities::split_string_list(s, p->get_separator());
1917  for (const auto &str : v)
1918  {
1919  auto key_val =
1920  Utilities::split_string_list(str, p->get_key_value_separator());
1921  AssertDimension(key_val.size(), 2);
1922  t.insert(std::make_pair(
1923  Convert<typename T::key_type>::to_value(key_val[0], key_p),
1925  }
1926 
1927  return t;
1928  }
1929  };
1930 
1931  // Tensors
1932  template <int rank, int dim, class Number>
1933  struct Convert<Tensor<rank, dim, Number>>
1934  {
1936  static std::unique_ptr<Patterns::PatternBase>
1938  {
1939  static_assert(internal::RankInfo<T>::list_rank > 0,
1940  "Cannot use this class for non List-compatible types.");
1941  return std_cxx14::make_unique<Patterns::List>(
1943  dim,
1944  dim,
1946  1]);
1947  }
1948 
1949  static std::string
1950  to_string(const T & t,
1951  const std::unique_ptr<Patterns::PatternBase> &pattern =
1953  {
1954  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
1955  AssertThrow(p,
1956  ExcMessage("I need a List pattern to convert a string "
1957  "to a List compatible type."));
1958  auto base_p = p->get_base_pattern().clone();
1959  std::vector<std::string> vec(dim);
1960 
1961  for (unsigned int i = 0; i < dim; ++i)
1962  vec[i] = Convert<typename T::value_type>::to_string(t[i], base_p);
1963 
1964  std::string s;
1965  if (vec.size() > 0)
1966  s = vec[0];
1967  for (unsigned int i = 1; i < vec.size(); ++i)
1968  s += p->get_separator() + " " + vec[i];
1969 
1970  AssertThrow(p->match(s), ExcNoMatch(s, p->description()));
1971  return s;
1972  }
1973 
1974  static T
1975  to_value(const std::string & s,
1976  const std::unique_ptr<Patterns::PatternBase> &pattern =
1978  {
1979  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
1980 
1981  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
1982  AssertThrow(p,
1983  ExcMessage("I need a List pattern to convert a string "
1984  "to a List compatible type."));
1985 
1986  auto base_p = p->get_base_pattern().clone();
1987  T t;
1988 
1989  auto v = Utilities::split_string_list(s, p->get_separator());
1990  unsigned int i = 0;
1991  for (const auto &str : v)
1992  t[i++] = Convert<typename T::value_type>::to_value(str, base_p);
1993 
1994  return t;
1995  }
1996  };
1997 
1998  // Points
1999  template <int dim, class Number>
2000  struct Convert<Point<dim, Number>>
2001  {
2003 
2004  static std::unique_ptr<Patterns::PatternBase>
2006  {
2007  return Convert<Tensor<1, dim, Number>>::to_pattern();
2008  }
2009 
2010  static std::string
2011  to_string(const T & t,
2012  const std::unique_ptr<Patterns::PatternBase> &pattern =
2014  {
2016  Tensor<1, dim, Number>(t), pattern);
2017  }
2018 
2019  static T
2020  to_value(const std::string & s,
2021  const std::unique_ptr<Patterns::PatternBase> &pattern =
2023  {
2024  return T(Convert<Tensor<1, dim, Number>>::to_value(s, pattern));
2025  }
2026  };
2027 
2028  // Functions::FunctionParser
2029  template <int dim>
2030  struct Convert<std::unique_ptr<FunctionParser<dim>>>
2031  {
2032  using T = std::unique_ptr<FunctionParser<dim>>;
2033 
2034  static std::unique_ptr<Patterns::PatternBase>
2036  {
2037  static_assert(internal::RankInfo<T>::list_rank > 0,
2038  "Cannot use this class for non List-compatible types.");
2039 
2040  return std_cxx14::make_unique<Patterns::List>(
2042  1,
2045  1]);
2046  }
2047 
2048  static std::string
2049  to_string(const T & t,
2050  const std::unique_ptr<Patterns::PatternBase> &pattern =
2052  {
2053  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2054  AssertThrow(p,
2055  ExcMessage("I need a List pattern to convert a string "
2056  "to a List compatible type."));
2057 
2058  const auto &expressions = t->get_expressions();
2059  if (expressions.size() == 0)
2060  return std::string();
2061 
2062  std::string s = expressions[0];
2063  for (unsigned int i = 1; i < expressions.size(); ++i)
2064  s = s + p->get_separator() + expressions[i];
2065 
2066  AssertThrow(pattern->match(s), ExcNoMatch(s, p->description()));
2067  return s;
2068  }
2069 
2070  static T
2071  to_value(const std::string & s,
2072  const std::unique_ptr<Patterns::PatternBase> &pattern =
2074  {
2075  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2076 
2077  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2078  AssertThrow(p,
2079  ExcMessage("I need a List pattern to convert a string "
2080  "to a List compatible type."));
2081 
2082  const auto expressions =
2083  Utilities::split_string_list(s, p->get_separator());
2084 
2085  T t = std_cxx14::make_unique<FunctionParser<dim>>(expressions.size());
2086  const std::string var =
2088  const typename FunctionParser<dim>::ConstMap constants;
2089  t->initialize(var, expressions, constants, true);
2090  return t;
2091  }
2092  };
2093 
2094  // ComponentMask
2095  template <>
2097  {
2098  using T = ComponentMask;
2099 
2100  static std::unique_ptr<Patterns::PatternBase>
2102  {
2103  return Convert<std::vector<bool>>::to_pattern();
2104  }
2105 
2106  static std::string
2107  to_string(const T & t,
2108  const std::unique_ptr<Patterns::PatternBase> &pattern =
2110  {
2111  std::vector<bool> mask(t.size());
2112  for (unsigned int i = 0; i < t.size(); ++i)
2113  mask[i] = t[i];
2114 
2115  return Convert<std::vector<bool>>::to_string(mask, pattern);
2116  }
2117 
2118  static T
2119  to_value(const std::string & s,
2120  const std::unique_ptr<Patterns::PatternBase> &pattern =
2122  {
2123  const auto mask = Convert<std::vector<bool>>::to_value(s, pattern);
2124  return ComponentMask(mask);
2125  }
2126  };
2127 
2128  // Complex numbers
2129  template <class Number>
2130  struct Convert<std::complex<Number>>
2131  {
2132  using T = std::complex<Number>;
2133 
2134  static std::unique_ptr<Patterns::PatternBase>
2136  {
2137  static_assert(internal::RankInfo<T>::list_rank > 0,
2138  "Cannot use this class for non List-compatible types.");
2139  return std_cxx14::make_unique<Patterns::List>(
2141  2,
2142  2,
2144  1]);
2145  }
2146 
2147  static std::string
2148  to_string(const T & t,
2149  const std::unique_ptr<Patterns::PatternBase> &pattern =
2151  {
2152  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2153  AssertThrow(p,
2154  ExcMessage("I need a List pattern to convert a string "
2155  "to a List compatible type."));
2156 
2157  auto base_p = p->get_base_pattern().clone();
2158  std::string s =
2159  Convert<typename T::value_type>::to_string(t.real(), base_p) +
2160  p->get_separator() + " " +
2162 
2163  AssertThrow(pattern->match(s), ExcNoMatch(s, p->description()));
2164  return s;
2165  }
2166 
2170  static T
2171  to_value(const std::string & s,
2172  const std::unique_ptr<Patterns::PatternBase> &pattern =
2174  {
2175  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2176 
2177  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2178  AssertThrow(p,
2179  ExcMessage("I need a List pattern to convert a string "
2180  "to a List compatible type."));
2181 
2182  auto base_p = p->get_base_pattern().clone();
2183 
2184  auto v = Utilities::split_string_list(s, p->get_separator());
2185  AssertDimension(v.size(), 2);
2188  return t;
2189  }
2190  };
2191 
2192  // Strings
2193  template <>
2194  struct Convert<std::string>
2195  {
2196  using T = std::string;
2197 
2198  static std::unique_ptr<Patterns::PatternBase>
2200  {
2201  return std_cxx14::make_unique<Patterns::Anything>();
2202  }
2203 
2204  static std::string
2205  to_string(const T & t,
2206  const std::unique_ptr<Patterns::PatternBase> &pattern =
2208  {
2209  AssertThrow(pattern->match(t), ExcNoMatch(t, pattern->description()));
2210  return t;
2211  }
2212 
2213  static T
2214  to_value(const std::string & s,
2215  const std::unique_ptr<Patterns::PatternBase> &pattern =
2217  {
2218  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2219  return s;
2220  }
2221  };
2222 
2223  // Pairs
2224  template <class Key, class Value>
2225  struct Convert<std::pair<Key, Value>>
2226  {
2227  using T = std::pair<Key, Value>;
2228 
2229  static std::unique_ptr<Patterns::PatternBase>
2231  {
2232  static_assert(internal::RankInfo<T>::map_rank > 0,
2233  "Cannot use this class for non Map-compatible types.");
2234  return std_cxx14::make_unique<Patterns::Tuple>(
2238  }
2239 
2240  static std::string
2241  to_string(const T & t,
2242  const std::unique_ptr<Patterns::PatternBase> &pattern =
2244  {
2245  std::tuple<Key, Value> m(t);
2246  std::string s = Convert<decltype(m)>::to_string(m, pattern);
2247  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2248  return s;
2249  }
2250 
2251  static T
2252  to_value(const std::string & s,
2253  const std::unique_ptr<Patterns::PatternBase> &pattern =
2255  {
2256  std::tuple<Key, Value> m;
2257  m = Convert<decltype(m)>::to_value(s, pattern);
2258  return std::make_pair(std::get<0>(m), std::get<1>(m));
2259  }
2260  };
2261 
2262  // Tuples
2263  template <class... Args>
2264  struct Convert<std::tuple<Args...>>
2265  {
2266  using T = std::tuple<Args...>;
2267 
2268  static std::unique_ptr<Patterns::PatternBase>
2270  {
2271  static_assert(internal::RankInfo<T>::map_rank > 0,
2272  "Cannot use this class for non tuple-compatible types.");
2273  return std_cxx14::make_unique<Patterns::Tuple>(
2276  }
2277 
2278  static std::string
2279  to_string(const T & t,
2280  const std::unique_ptr<Patterns::PatternBase> &pattern =
2282  {
2283  auto p = dynamic_cast<const Patterns::Tuple *>(pattern.get());
2284  AssertThrow(p,
2285  ExcMessage("I need a Tuple pattern to convert a tuple "
2286  "to a string."));
2287 
2288  const auto string_array = Convert<T>::to_string_internal_2(t, *p);
2289  std::string str;
2290  for (unsigned int i = 0; i < string_array.size(); ++i)
2291  str += (i ? " " + p->get_separator() + " " : "") + string_array[i];
2292  AssertThrow(p->match(str), ExcNoMatch(str, p->description()));
2293  return str;
2294  }
2295 
2296  static T
2297  to_value(const std::string & s,
2298  const std::unique_ptr<Patterns::PatternBase> &pattern =
2300  {
2301  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2302 
2303  auto p = dynamic_cast<const Patterns::Tuple *>(pattern.get());
2304  AssertThrow(p,
2305  ExcMessage("I need a Tuple pattern to convert a string "
2306  "to a tuple type."));
2307 
2308  auto v = Utilities::split_string_list(s, p->get_separator());
2309 
2310  return Convert<T>::to_value_internal_2(v, *p);
2311  }
2312 
2313  private:
2314  template <std::size_t... U>
2317  const Patterns::Tuple &pattern,
2318  std_cxx14::index_sequence<U...>)
2319  {
2322  std::get<U>(t), pattern.get_pattern(U).clone())...}};
2323  return a;
2324  }
2325 
2327  to_string_internal_2(const T &t, const Patterns::Tuple &pattern)
2328  {
2330  t,
2331  pattern,
2332  std_cxx14::make_index_sequence<std::tuple_size<T>::value>{});
2333  }
2334 
2335  template <std::size_t... U>
2336  static T
2337  to_value_internal_1(const std::vector<std::string> &s,
2338  const Patterns::Tuple & pattern,
2339  std_cxx14::index_sequence<U...>)
2340  {
2341  return std::make_tuple(
2342  Convert<typename std::tuple_element<U, T>::type>::to_value(
2343  s[U], pattern.get_pattern(U).clone())...);
2344  }
2345 
2346  static T
2347  to_value_internal_2(const std::vector<std::string> &s,
2348  const Patterns::Tuple & pattern)
2349  {
2351  s,
2352  pattern,
2353  std_cxx14::make_index_sequence<std::tuple_size<T>::value>{});
2354  }
2355  };
2356 
2357  // Utility function with default Pattern
2358  template <typename T>
2359  std::string
2360  to_string(const T &t)
2361  {
2362  return Convert<T>::to_string(t);
2363  }
2364 
2365  // Utility function with default Pattern
2366  template <typename T>
2367  void
2368  to_value(const std::string &s, T &t)
2369  {
2370  t = Convert<T>::to_value(s);
2371  }
2372  } // namespace Tools
2373 } // namespace Patterns
2374 
2375 
2377 
2378 #endif
Iterator lower_bound(Iterator first, Iterator last, const T &val)
Definition: utilities.h:1102
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
Definition: utilities.cc:705
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2214
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:541
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1579
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1975
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:2368
std::string sequence
Definition: patterns.h:435
const double upper_bound
Definition: patterns.h:366
static const char * description_init
Definition: patterns.h:371
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2252
static const char * description_init
Definition: patterns.h:1150
const PatternBase & get_pattern(const unsigned int i) const
Definition: patterns.cc:1223
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:1937
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &p=Convert< T >::to_pattern())
Definition: patterns.h:1553
const std::string separator
Definition: patterns.h:888
const std::string separator
Definition: patterns.h:711
std::unique_ptr< PatternBase > pattern
Definition: patterns.h:547
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2297
static const unsigned int max_int_value
Definition: patterns.h:593
virtual std::unique_ptr< PatternBase > clone() const =0
static const char * description_init
Definition: patterns.h:722
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2020
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2071
static T to_value_internal_1(const std::vector< std::string > &s, const Patterns::Tuple &pattern, std_cxx14::index_sequence< U... >)
Definition: patterns.h:2337
STL namespace.
static const char U
static const int max_int_value
Definition: patterns.h:205
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2107
#define AssertThrow(cond, exc)
Definition: exceptions.h:1531
constexpr std::array< const char *, 4 > default_list_separator
Definition: patterns.h:1593
const unsigned int max_elements
Definition: patterns.h:706
static const char * description_init
Definition: patterns.h:977
static ::ExceptionBase & ExcNoMatch(std::string arg1, std::string arg2)
Definition: point.h:111
FileType file_type
Definition: patterns.h:1136
static const int min_int_value
Definition: patterns.h:198
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2148
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition: config.h:372
static std::string default_variable_names()
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2005
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2269
const double lower_bound
Definition: patterns.h:358
static const char * description_init
Definition: patterns.h:567
static ::ExceptionBase & ExcMessage(std::string arg1)
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2119
static const char * description_init
Definition: patterns.h:1019
static const char * description_init
Definition: patterns.h:440
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:518
constexpr int max_list_rank()
Definition: patterns.h:1678
static const char T
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2101
std::vector< std::unique_ptr< PatternBase > > patterns
Definition: patterns.h:883
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2241
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:1528
virtual std::size_t memory_consumption() const
Definition: patterns.cc:192
static const char * description_init
Definition: patterns.h:273
static const char * description_init
Definition: patterns.h:893
std::unique_ptr< PatternBase > key_pattern
Definition: patterns.h:695
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:359
virtual ~PatternBase()=default
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2199
static std::string to_string(const T &value, const std::unique_ptr< Patterns::PatternBase > &p=Convert< T >::to_pattern())
Definition: patterns.h:1535
std::string to_string(const T &t)
Definition: patterns.h:2360
unsigned int size() const
static const double min_double_value
Definition: patterns.h:300
std::unique_ptr< PatternBase > pattern_factory(const std::string &description)
Definition: patterns.cc:140
static const char * description_init
Definition: patterns.h:1208
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:1516
virtual bool match(const std::string &test_string) const =0
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1825
static T to_value_internal_2(const std::vector< std::string > &s, const Patterns::Tuple &pattern)
Definition: patterns.h:2347
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2171
static const char * description_init
Definition: patterns.h:1068
constexpr int max_map_rank()
Definition: patterns.h:1694
__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:1505
static std::array< std::string, std::tuple_size< T >::value > to_string_internal_1(const T &t, const Patterns::Tuple &pattern, std_cxx14::index_sequence< U... >)
Definition: patterns.h:2316
static const double max_double_value
Definition: patterns.h:306
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1799
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2049
virtual std::string description(const OutputStyle style=Machine) const =0
Definition: tensor.h:450
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition: config.h:409
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:358
std::map< std::string, double > ConstMap
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1901
const int upper_bound
Definition: patterns.h:268
static std::array< std::string, std::tuple_size< T >::value > to_string_internal_2(const T &t, const Patterns::Tuple &pattern)
Definition: patterns.h:2327
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2205
constexpr std::array< const char *, 4 > default_map_separator
Definition: patterns.h:1595
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2135
Tuple(const std::vector< std::unique_ptr< PatternBase >> &patterns, const std::string &separator=":")
Definition: patterns.cc:1057
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2279
const unsigned int min_elements
Definition: patterns.h:701
static const unsigned int max_int_value
Definition: patterns.h:459
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2011
const int lower_bound
Definition: patterns.h:260
std::unique_ptr< PatternBase > value_pattern
Definition: patterns.h:696
static const bool value
const std::string separator
Definition: patterns.h:562
const std::string key_value_separator
Definition: patterns.h:717
const unsigned int max_elements
Definition: patterns.h:557
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2230
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1871
T max(const T &t, const MPI_Comm &mpi_communicator)
const unsigned int min_elements
Definition: patterns.h:552
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1950
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2035