Reference documentation for deal.II version Git cd4d0b9268 2020-11-30 14:25:08 -0500
\(\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,
1325  const std::unique_ptr<Patterns::PatternBase> &p =
1326  Convert<T>::to_pattern()) = delete;
1327 
1337  static T
1338  to_value(const std::string & s,
1339  const std::unique_ptr<Patterns::PatternBase> &p =
1340  Convert<T>::to_pattern()) = 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,
1524  const std::unique_ptr<Patterns::PatternBase> &p =
1526  {
1527  std::stringstream str;
1528  if (std::is_same<T, unsigned char>::value ||
1529  std::is_same<T, signed char>::value || std::is_same<T, char>::value)
1530  str << static_cast<int>(value);
1531  else if (std::is_same<T, bool>::value)
1532  str << (static_cast<bool>(value) ? "true" : "false");
1533  else
1534  str << value;
1535  AssertThrow(p->match(str.str()),
1536  ExcNoMatch(str.str(), p->description()));
1537  return str.str();
1538  }
1539 
1540  static T
1541  to_value(const std::string & s,
1542  const std::unique_ptr<Patterns::PatternBase> &p =
1544  {
1545  AssertThrow(p->match(s), ExcNoMatch(s, p->description()));
1546  T value;
1547  if (std::is_same<T, bool>::value)
1548  value = (s == "true");
1549  else
1550  {
1551  std::istringstream is(s);
1552  if (std::is_same<T, unsigned char>::value ||
1553  std::is_same<T, signed char>::value ||
1554  std::is_same<T, char>::value)
1555  {
1556  int i;
1557  is >> i;
1558  value = i;
1559  }
1560  else
1561  is >> value;
1562 
1563  // If someone passes "123 abc" to the function, the method yields an
1564  // integer 123 alright, but the space terminates the read from the
1565  // string although there is more to come. This case, however, is
1566  // checked for in the call p->match(s) at the beginning of this
1567  // function, and would throw earlier. Here it is safe to assume that
1568  // if we didn't fail the conversion with the operator >>, then we
1569  // are good to go.
1570  AssertThrow(
1571  !is.fail(),
1572  ExcMessage("Failed to convert from \"" + s + "\" to the type \"" +
1573  boost::core::demangle(typeid(T).name()) + "\""));
1574  }
1575  return value;
1576  }
1577  };
1578 
1579  namespace internal
1580  {
1581  constexpr std::array<const char *, 4> default_list_separator{
1582  {",", ";", "|", "%"}};
1583  constexpr std::array<const char *, 4> default_map_separator{
1584  {":", "=", "@", "#"}};
1585 
1586  // specialize a type for all of the STL containers and maps
1587  template <typename T>
1588  struct is_list_compatible : std::false_type
1589  {};
1590  template <typename T, std::size_t N>
1591  struct is_list_compatible<std::array<T, N>> : std::true_type
1592  {};
1593  template <typename... Args>
1594  struct is_list_compatible<std::vector<Args...>> : std::true_type
1595  {};
1596  template <typename... Args>
1597  struct is_list_compatible<std::deque<Args...>> : std::true_type
1598  {};
1599  template <typename... Args>
1600  struct is_list_compatible<std::list<Args...>> : std::true_type
1601  {};
1602  template <typename... Args>
1603  struct is_list_compatible<std::set<Args...>> : std::true_type
1604  {};
1605  template <typename... Args>
1606  struct is_list_compatible<std::multiset<Args...>> : std::true_type
1607  {};
1608  template <typename... Args>
1609  struct is_list_compatible<std::unordered_set<Args...>> : std::true_type
1610  {};
1611  template <typename... Args>
1612  struct is_list_compatible<std::unordered_multiset<Args...>>
1613  : std::true_type
1614  {};
1615 
1616  template <typename T>
1617  struct is_map_compatible : std::false_type
1618  {};
1619  template <class Key, class T, class Compare, class Allocator>
1620  struct is_map_compatible<std::map<Key, T, Compare, Allocator>>
1621  : std::true_type
1622  {};
1623  template <class Key, class T, class Compare, class Allocator>
1624  struct is_map_compatible<std::multimap<Key, T, Compare, Allocator>>
1625  : std::true_type
1626  {};
1627  template <class Key, class T, class Hash, class KeyEqual, class Allocator>
1629  std::unordered_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type
1630  {};
1631  template <class Key, class T, class Hash, class KeyEqual, class Allocator>
1633  std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>>
1634  : std::true_type
1635  {};
1636  } // namespace internal
1637 
1638  // type trait to use the implementation type traits as well as decay the
1639  // type
1640  template <typename T>
1642  {
1643  static constexpr bool const value =
1645  };
1646 
1647  template <typename T>
1649  {
1650  static constexpr bool const value =
1652  };
1653 
1654  namespace internal
1655  {
1656  // Helper function for list_rank
1657  template <class T>
1658  constexpr int
1660  {
1661  return RankInfo<T>::list_rank;
1662  }
1663 
1664  template <class T1, class T2, class... Types>
1665  constexpr int
1667  {
1668  return std::max(RankInfo<T1>::list_rank, max_list_rank<T2, Types...>());
1669  }
1670 
1671  // Helper function for map_rank
1672  template <class T>
1673  constexpr int
1675  {
1676  return RankInfo<T>::map_rank;
1677  }
1678 
1679  template <class T1, class T2, class... Types>
1680  constexpr int
1682  {
1683  return std::max(RankInfo<T1>::map_rank, max_map_rank<T2, Types...>());
1684  }
1685 
1686  // Rank of vector types
1687  template <class T>
1688  struct RankInfo<
1689  T,
1690  typename std::enable_if<is_list_compatible<T>::value>::type>
1691  {
1692  static constexpr int list_rank =
1694  static constexpr int map_rank =
1696  };
1697 
1698  // Rank of map types
1699  template <class T>
1700  struct RankInfo<
1701  T,
1702  typename std::enable_if<is_map_compatible<T>::value>::type>
1703  {
1704  static constexpr int list_rank =
1705  max_list_rank<typename T::key_type, typename T::mapped_type>() + 1;
1706  static constexpr int map_rank =
1707  max_map_rank<typename T::key_type, typename T::mapped_type>() + 1;
1708  };
1709 
1710  // Rank of Tensor types
1711  template <int rank, int dim, class Number>
1712  struct RankInfo<Tensor<rank, dim, Number>>
1713  {
1714  static constexpr int list_rank = rank + RankInfo<Number>::list_rank;
1715  static constexpr int map_rank = RankInfo<Number>::map_rank;
1716  };
1717 
1718  template <int dim, class Number>
1719  struct RankInfo<Point<dim, Number>> : RankInfo<Tensor<1, dim, Number>>
1720  {};
1721 
1722  // Rank of complex types
1723  template <class Number>
1724  struct RankInfo<std::complex<Number>>
1725  {
1726  static constexpr int list_rank = RankInfo<Number>::list_rank + 1;
1727  static constexpr int map_rank = RankInfo<Number>::map_rank;
1728  };
1729 
1730  // Rank of FunctionParser
1731  template <int dim>
1732  struct RankInfo<std::unique_ptr<FunctionParser<dim>>>
1733  {
1734  static constexpr int list_rank = 1;
1735  static constexpr int map_rank = 0;
1736  };
1737 
1738  // Rank of ComponentMask
1739  template <>
1741  {
1742  static constexpr int list_rank = 1;
1743  static constexpr int map_rank = 0;
1744  };
1745 
1746  // Rank of std::pair
1747  template <class Key, class Value>
1748  struct RankInfo<std::pair<Key, Value>>
1749  {
1750  static constexpr int list_rank =
1752  static constexpr int map_rank =
1754  };
1755 
1756 
1757  template <class... Types>
1758  struct RankInfo<std::tuple<Types...>>
1759  {
1760  static constexpr int list_rank = max_list_rank<Types...>();
1761  static constexpr int map_rank = max_map_rank<Types...>() + 1;
1762  };
1763  } // namespace internal
1764 
1765  // stl containers
1766  template <class T>
1767  struct Convert<T,
1768  typename std::enable_if<is_list_compatible<T>::value>::type>
1769  {
1770  static std::unique_ptr<Patterns::PatternBase>
1772  {
1773  static_assert(internal::RankInfo<T>::list_rank > 0,
1774  "Cannot use this class for non List-compatible types.");
1775  return std::make_unique<Patterns::List>(
1777  0,
1780  1]);
1781  }
1782 
1783  static std::string
1784  to_string(const T & t,
1785  const std::unique_ptr<Patterns::PatternBase> &pattern =
1787  {
1788  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
1789  AssertThrow(p,
1790  ExcMessage("I need a List pattern to convert a "
1791  "string to a List type."));
1792  auto base_p = p->get_base_pattern().clone();
1793  std::vector<std::string> vec(t.size());
1794 
1796  t.cbegin(), t.cend(), vec.begin(), [&base_p](const auto &entry) {
1797  return Convert<typename T::value_type>::to_string(entry, base_p);
1798  });
1799 
1800  std::string s;
1801  if (vec.size() > 0)
1802  s = vec[0];
1803  for (unsigned int i = 1; i < vec.size(); ++i)
1804  s += p->get_separator() + " " + vec[i];
1805 
1806  AssertThrow(pattern->match(s), ExcNoMatch(s, p->description()));
1807  return s;
1808  }
1809 
1810  static T
1811  to_value(const std::string & s,
1812  const std::unique_ptr<Patterns::PatternBase> &pattern =
1814  {
1815  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
1816 
1817  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
1818  AssertThrow(p,
1819  ExcMessage("I need a List pattern to convert a string "
1820  "to a List type."));
1821 
1822  auto base_p = p->get_base_pattern().clone();
1823  T t;
1824 
1825  auto v = Utilities::split_string_list(s, p->get_separator());
1826  for (const auto &str : v)
1827  t.insert(t.end(),
1829 
1830  return t;
1831  }
1832  };
1833 
1834  // stl maps
1835  template <class T>
1836  struct Convert<T,
1837  typename std::enable_if<is_map_compatible<T>::value>::type>
1838  {
1839  static std::unique_ptr<Patterns::PatternBase>
1841  {
1842  static_assert(internal::RankInfo<T>::list_rank > 0,
1843  "Cannot use this class for non List-compatible types.");
1844  static_assert(internal::RankInfo<T>::map_rank > 0,
1845  "Cannot use this class for non Map-compatible types.");
1846  return std::make_unique<Patterns::Map>(
1849  0,
1852  1],
1854  }
1855 
1856  static std::string
1857  to_string(const T & t,
1858  const std::unique_ptr<Patterns::PatternBase> &pattern =
1860  {
1861  auto p = dynamic_cast<const Patterns::Map *>(pattern.get());
1862  AssertThrow(p,
1863  ExcMessage("I need a Map pattern to convert a string to "
1864  "a Map compatible type."));
1865  auto key_p = p->get_key_pattern().clone();
1866  auto val_p = p->get_value_pattern().clone();
1867  std::vector<std::string> vec(t.size());
1868 
1869  unsigned int i = 0;
1870  for (const auto &ti : t)
1871  vec[i++] =
1872  Convert<typename T::key_type>::to_string(ti.first, key_p) +
1873  p->get_key_value_separator() +
1875 
1876  std::string s;
1877  if (vec.size() > 0)
1878  s = vec[0];
1879  for (unsigned int i = 1; i < vec.size(); ++i)
1880  s += p->get_separator() + " " + vec[i];
1881 
1882  AssertThrow(p->match(s), ExcNoMatch(s, p->description()));
1883  return s;
1884  }
1885 
1886  static T
1887  to_value(const std::string & s,
1888  const std::unique_ptr<Patterns::PatternBase> &pattern =
1890  {
1891  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
1892 
1893  auto p = dynamic_cast<const Patterns::Map *>(pattern.get());
1894  AssertThrow(p,
1895  ExcMessage("I need a Map pattern to convert a "
1896  "string to a Map compatible type."));
1897 
1898  auto key_p = p->get_key_pattern().clone();
1899  auto val_p = p->get_value_pattern().clone();
1900  T t;
1901 
1902  auto v = Utilities::split_string_list(s, p->get_separator());
1903  for (const auto &str : v)
1904  {
1905  auto key_val =
1906  Utilities::split_string_list(str, p->get_key_value_separator());
1907  AssertDimension(key_val.size(), 2);
1908  t.insert(std::make_pair(
1909  Convert<typename T::key_type>::to_value(key_val[0], key_p),
1911  }
1912 
1913  return t;
1914  }
1915  };
1916 
1917  // Tensors
1918  template <int rank, int dim, class Number>
1919  struct Convert<Tensor<rank, dim, Number>>
1920  {
1922  static std::unique_ptr<Patterns::PatternBase>
1924  {
1925  static_assert(internal::RankInfo<T>::list_rank > 0,
1926  "Cannot use this class for non List-compatible types.");
1927  return std::make_unique<Patterns::List>(
1929  dim,
1930  dim,
1932  1]);
1933  }
1934 
1935  static std::string
1936  to_string(const T & t,
1937  const std::unique_ptr<Patterns::PatternBase> &pattern =
1939  {
1940  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
1941  AssertThrow(p,
1942  ExcMessage("I need a List pattern to convert a string "
1943  "to a List compatible type."));
1944  auto base_p = p->get_base_pattern().clone();
1945  std::vector<std::string> vec(dim);
1946 
1947  for (unsigned int i = 0; i < dim; ++i)
1948  vec[i] = Convert<typename T::value_type>::to_string(t[i], base_p);
1949 
1950  std::string s;
1951  if (vec.size() > 0)
1952  s = vec[0];
1953  for (unsigned int i = 1; i < vec.size(); ++i)
1954  s += p->get_separator() + " " + vec[i];
1955 
1956  AssertThrow(p->match(s), ExcNoMatch(s, p->description()));
1957  return s;
1958  }
1959 
1960  static T
1961  to_value(const std::string & s,
1962  const std::unique_ptr<Patterns::PatternBase> &pattern =
1964  {
1965  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
1966 
1967  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
1968  AssertThrow(p,
1969  ExcMessage("I need a List pattern to convert a string "
1970  "to a List compatible type."));
1971 
1972  auto base_p = p->get_base_pattern().clone();
1973  T t;
1974 
1975  auto v = Utilities::split_string_list(s, p->get_separator());
1976  unsigned int i = 0;
1977  for (const auto &str : v)
1978  t[i++] = Convert<typename T::value_type>::to_value(str, base_p);
1979 
1980  return t;
1981  }
1982  };
1983 
1984  // Points
1985  template <int dim, class Number>
1986  struct Convert<Point<dim, Number>>
1987  {
1989 
1990  static std::unique_ptr<Patterns::PatternBase>
1992  {
1993  return Convert<Tensor<1, dim, Number>>::to_pattern();
1994  }
1995 
1996  static std::string
1997  to_string(const T & t,
1998  const std::unique_ptr<Patterns::PatternBase> &pattern =
2000  {
2002  Tensor<1, dim, Number>(t), pattern);
2003  }
2004 
2005  static T
2006  to_value(const std::string & s,
2007  const std::unique_ptr<Patterns::PatternBase> &pattern =
2009  {
2010  return T(Convert<Tensor<1, dim, Number>>::to_value(s, pattern));
2011  }
2012  };
2013 
2014  // Functions::FunctionParser
2015  template <int dim>
2016  struct Convert<std::unique_ptr<FunctionParser<dim>>>
2017  {
2018  using T = std::unique_ptr<FunctionParser<dim>>;
2019 
2020  static std::unique_ptr<Patterns::PatternBase>
2022  {
2023  static_assert(internal::RankInfo<T>::list_rank > 0,
2024  "Cannot use this class for non List-compatible types.");
2025 
2026  return std::make_unique<Patterns::List>(
2028  1,
2031  1]);
2032  }
2033 
2034  static std::string
2035  to_string(const T & t,
2036  const std::unique_ptr<Patterns::PatternBase> &pattern =
2038  {
2039  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2040  AssertThrow(p,
2041  ExcMessage("I need a List pattern to convert a string "
2042  "to a List compatible type."));
2043 
2044  const auto &expressions = t->get_expressions();
2045  if (expressions.size() == 0)
2046  return std::string();
2047 
2048  std::string s = expressions[0];
2049  for (unsigned int i = 1; i < expressions.size(); ++i)
2050  s = s + p->get_separator() + expressions[i];
2051 
2052  AssertThrow(pattern->match(s), ExcNoMatch(s, p->description()));
2053  return s;
2054  }
2055 
2056  static T
2057  to_value(const std::string & s,
2058  const std::unique_ptr<Patterns::PatternBase> &pattern =
2060  {
2061  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2062 
2063  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2064  AssertThrow(p,
2065  ExcMessage("I need a List pattern to convert a string "
2066  "to a List compatible type."));
2067 
2068  const auto expressions =
2069  Utilities::split_string_list(s, p->get_separator());
2070 
2071  T t = std::make_unique<FunctionParser<dim>>(expressions.size());
2072  const std::string var =
2074  const typename FunctionParser<dim>::ConstMap constants;
2075  t->initialize(var, expressions, constants, true);
2076  return t;
2077  }
2078  };
2079 
2080  // ComponentMask
2081  template <>
2083  {
2084  using T = ComponentMask;
2085 
2086  static std::unique_ptr<Patterns::PatternBase>
2088  {
2089  return Convert<std::vector<bool>>::to_pattern();
2090  }
2091 
2092  static std::string
2093  to_string(const T & t,
2094  const std::unique_ptr<Patterns::PatternBase> &pattern =
2096  {
2097  std::vector<bool> mask(t.size());
2098  for (unsigned int i = 0; i < t.size(); ++i)
2099  mask[i] = t[i];
2100 
2101  return Convert<std::vector<bool>>::to_string(mask, pattern);
2102  }
2103 
2104  static T
2105  to_value(const std::string & s,
2106  const std::unique_ptr<Patterns::PatternBase> &pattern =
2108  {
2109  const auto mask = Convert<std::vector<bool>>::to_value(s, pattern);
2110  return ComponentMask(mask);
2111  }
2112  };
2113 
2114  // Complex numbers
2115  template <class Number>
2116  struct Convert<std::complex<Number>>
2117  {
2118  using T = std::complex<Number>;
2119 
2120  static std::unique_ptr<Patterns::PatternBase>
2122  {
2123  static_assert(internal::RankInfo<T>::list_rank > 0,
2124  "Cannot use this class for non List-compatible types.");
2125  return std::make_unique<Patterns::List>(
2127  2,
2128  2,
2130  1]);
2131  }
2132 
2133  static std::string
2134  to_string(const T & t,
2135  const std::unique_ptr<Patterns::PatternBase> &pattern =
2137  {
2138  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2139  AssertThrow(p,
2140  ExcMessage("I need a List pattern to convert a string "
2141  "to a List compatible type."));
2142 
2143  auto base_p = p->get_base_pattern().clone();
2144  std::string s =
2145  Convert<typename T::value_type>::to_string(t.real(), base_p) +
2146  p->get_separator() + " " +
2148 
2149  AssertThrow(pattern->match(s), ExcNoMatch(s, p->description()));
2150  return s;
2151  }
2152 
2156  static T
2157  to_value(const std::string & s,
2158  const std::unique_ptr<Patterns::PatternBase> &pattern =
2160  {
2161  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2162 
2163  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2164  AssertThrow(p,
2165  ExcMessage("I need a List pattern to convert a string "
2166  "to a List compatible type."));
2167 
2168  auto base_p = p->get_base_pattern().clone();
2169 
2170  auto v = Utilities::split_string_list(s, p->get_separator());
2171  AssertDimension(v.size(), 2);
2174  return t;
2175  }
2176  };
2177 
2178  // Strings
2179  template <>
2180  struct Convert<std::string>
2181  {
2182  using T = std::string;
2183 
2184  static std::unique_ptr<Patterns::PatternBase>
2186  {
2187  return std::make_unique<Patterns::Anything>();
2188  }
2189 
2190  static std::string
2191  to_string(const T & t,
2192  const std::unique_ptr<Patterns::PatternBase> &pattern =
2194  {
2195  AssertThrow(pattern->match(t), ExcNoMatch(t, pattern->description()));
2196  return t;
2197  }
2198 
2199  static T
2200  to_value(const std::string & s,
2201  const std::unique_ptr<Patterns::PatternBase> &pattern =
2203  {
2204  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2205  return s;
2206  }
2207  };
2208 
2209  // Pairs
2210  template <class Key, class Value>
2211  struct Convert<std::pair<Key, Value>>
2212  {
2213  using T = std::pair<Key, Value>;
2214 
2215  static std::unique_ptr<Patterns::PatternBase>
2217  {
2218  static_assert(internal::RankInfo<T>::map_rank > 0,
2219  "Cannot use this class for non Map-compatible types.");
2220  return std::make_unique<Patterns::Tuple>(
2224  }
2225 
2226  static std::string
2227  to_string(const T & t,
2228  const std::unique_ptr<Patterns::PatternBase> &pattern =
2230  {
2231  std::tuple<Key, Value> m(t);
2232  std::string s = Convert<decltype(m)>::to_string(m, pattern);
2233  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2234  return s;
2235  }
2236 
2237  static T
2238  to_value(const std::string & s,
2239  const std::unique_ptr<Patterns::PatternBase> &pattern =
2241  {
2242  std::tuple<Key, Value> m;
2243  m = Convert<decltype(m)>::to_value(s, pattern);
2244  return std::make_pair(std::get<0>(m), std::get<1>(m));
2245  }
2246  };
2247 
2248  // Tuples
2249  template <class... Args>
2250  struct Convert<std::tuple<Args...>>
2251  {
2252  using T = std::tuple<Args...>;
2253 
2254  static std::unique_ptr<Patterns::PatternBase>
2256  {
2257  static_assert(internal::RankInfo<T>::map_rank > 0,
2258  "Cannot use this class for non tuple-compatible types.");
2259  return std::make_unique<Patterns::Tuple>(
2262  }
2263 
2264  static std::string
2265  to_string(const T & t,
2266  const std::unique_ptr<Patterns::PatternBase> &pattern =
2268  {
2269  auto p = dynamic_cast<const Patterns::Tuple *>(pattern.get());
2270  AssertThrow(p,
2271  ExcMessage("I need a Tuple pattern to convert a tuple "
2272  "to a string."));
2273 
2274  const auto string_array = Convert<T>::to_string_internal_2(t, *p);
2275  std::string str;
2276  for (unsigned int i = 0; i < string_array.size(); ++i)
2277  str += (i ? " " + p->get_separator() + " " : "") + string_array[i];
2278  AssertThrow(p->match(str), ExcNoMatch(str, p->description()));
2279  return str;
2280  }
2281 
2282  static T
2283  to_value(const std::string & s,
2284  const std::unique_ptr<Patterns::PatternBase> &pattern =
2286  {
2287  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2288 
2289  auto p = dynamic_cast<const Patterns::Tuple *>(pattern.get());
2290  AssertThrow(p,
2291  ExcMessage("I need a Tuple pattern to convert a string "
2292  "to a tuple type."));
2293 
2294  auto v = Utilities::split_string_list(s, p->get_separator());
2295 
2296  return Convert<T>::to_value_internal_2(v, *p);
2297  }
2298 
2299  private:
2300  template <std::size_t... U>
2301  static std::array<std::string, std::tuple_size<T>::value>
2303  const Patterns::Tuple &pattern,
2304  std::index_sequence<U...>)
2305  {
2306  std::array<std::string, std::tuple_size<T>::value> a = {
2308  std::get<U>(t), pattern.get_pattern(U).clone())...}};
2309  return a;
2310  }
2311 
2312  static std::array<std::string, std::tuple_size<T>::value>
2313  to_string_internal_2(const T &t, const Patterns::Tuple &pattern)
2314  {
2316  t, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2317  }
2318 
2319  template <std::size_t... U>
2320  static T
2321  to_value_internal_1(const std::vector<std::string> &s,
2322  const Patterns::Tuple & pattern,
2323  std::index_sequence<U...>)
2324  {
2325  return std::make_tuple(
2326  Convert<typename std::tuple_element<U, T>::type>::to_value(
2327  s[U], pattern.get_pattern(U).clone())...);
2328  }
2329 
2330  static T
2331  to_value_internal_2(const std::vector<std::string> &s,
2332  const Patterns::Tuple & pattern)
2333  {
2335  s, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2336  }
2337  };
2338 
2339  // Utility function with default Pattern
2340  template <typename T>
2341  std::string
2342  to_string(const T &t)
2343  {
2344  return Convert<T>::to_string(t);
2345  }
2346 
2347  // Utility function with default Pattern
2348  template <typename T>
2349  void
2350  to_value(const std::string &s, T &t)
2351  {
2352  t = Convert<T>::to_value(s);
2353  }
2354  } // namespace Tools
2355 } // namespace Patterns
2356 
2357 
2359 
2360 #endif
Iterator lower_bound(Iterator first, Iterator last, const T &val)
Definition: utilities.h:1075
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
Definition: utilities.cc:705
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 std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2200
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:538
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1623
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1961
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:2350
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 T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2238
static const char * description_init
Definition: patterns.h:1147
const PatternBase & get_pattern(const unsigned int i) const
Definition: patterns.cc:1223
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:1923
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &p=Convert< T >::to_pattern())
Definition: patterns.h:1541
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 T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2283
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 T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2006
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2057
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:2302
static const int max_int_value
Definition: patterns.h:204
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2093
#define AssertThrow(cond, exc)
Definition: exceptions.h:1576
constexpr std::array< const char *, 4 > default_list_separator
Definition: patterns.h:1581
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
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2134
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition: config.h:385
static std::string default_variable_names()
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:1991
static T to_value_internal_1(const std::vector< std::string > &s, const Patterns::Tuple &pattern, std::index_sequence< U... >)
Definition: patterns.h:2321
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2255
const double lower_bound
Definition: patterns.h:357
static const char * description_init
Definition: patterns.h:566
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:2105
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:1666
static const char T
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2087
std::vector< std::unique_ptr< PatternBase > > patterns
Definition: patterns.h:880
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2227
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:372
virtual ~PatternBase()=default
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2185
static std::string to_string(const T &value, const std::unique_ptr< Patterns::PatternBase > &p=Convert< T >::to_pattern())
Definition: patterns.h:1523
std::string to_string(const T &t)
Definition: patterns.h:2342
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
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:1811
static T to_value_internal_2(const std::vector< std::string > &s, const Patterns::Tuple &pattern)
Definition: patterns.h:2331
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2157
static const char * description_init
Definition: patterns.h:1065
constexpr int max_map_rank()
Definition: patterns.h:1681
__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
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1784
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2035
virtual std::string description(const OutputStyle style=Machine) const =0
Definition: tensor.h:448
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition: config.h:422
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:371
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:1887
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:2313
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2191
constexpr std::array< const char *, 4 > default_map_separator
Definition: patterns.h:1583
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2121
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:2265
const unsigned int min_elements
Definition: patterns.h:700
static const unsigned int max_int_value
Definition: patterns.h:458
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1997
const int lower_bound
Definition: patterns.h:259
std::unique_ptr< PatternBase > value_pattern
Definition: patterns.h:695
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:2216
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1857
T max(const T &t, const MPI_Comm &mpi_communicator)
const unsigned int min_elements
Definition: patterns.h:551
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1936
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2021