Reference documentation for deal.II version Git cd8b20072f 2020-09-24 16:28:23 -0400
\(\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 
1795  unsigned int i = 0;
1796  for (const auto &entry : t)
1797  vec[i++] = Convert<typename T::value_type>::to_string(entry, base_p);
1798 
1799  std::string s;
1800  if (vec.size() > 0)
1801  s = vec[0];
1802  for (unsigned int i = 1; i < vec.size(); ++i)
1803  s += p->get_separator() + " " + vec[i];
1804 
1805  AssertThrow(pattern->match(s), ExcNoMatch(s, p->description()));
1806  return s;
1807  }
1808 
1809  static T
1810  to_value(const std::string & s,
1811  const std::unique_ptr<Patterns::PatternBase> &pattern =
1813  {
1814  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
1815 
1816  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
1817  AssertThrow(p,
1818  ExcMessage("I need a List pattern to convert a string "
1819  "to a List type."));
1820 
1821  auto base_p = p->get_base_pattern().clone();
1822  T t;
1823 
1824  auto v = Utilities::split_string_list(s, p->get_separator());
1825  for (const auto &str : v)
1826  t.insert(t.end(),
1828 
1829  return t;
1830  }
1831  };
1832 
1833  // stl maps
1834  template <class T>
1835  struct Convert<T,
1836  typename std::enable_if<is_map_compatible<T>::value>::type>
1837  {
1838  static std::unique_ptr<Patterns::PatternBase>
1840  {
1841  static_assert(internal::RankInfo<T>::list_rank > 0,
1842  "Cannot use this class for non List-compatible types.");
1843  static_assert(internal::RankInfo<T>::map_rank > 0,
1844  "Cannot use this class for non Map-compatible types.");
1845  return std::make_unique<Patterns::Map>(
1848  0,
1851  1],
1853  }
1854 
1855  static std::string
1856  to_string(const T & t,
1857  const std::unique_ptr<Patterns::PatternBase> &pattern =
1859  {
1860  auto p = dynamic_cast<const Patterns::Map *>(pattern.get());
1861  AssertThrow(p,
1862  ExcMessage("I need a Map pattern to convert a string to "
1863  "a Map compatible type."));
1864  auto key_p = p->get_key_pattern().clone();
1865  auto val_p = p->get_value_pattern().clone();
1866  std::vector<std::string> vec(t.size());
1867 
1868  unsigned int i = 0;
1869  for (const auto &ti : t)
1870  vec[i++] =
1871  Convert<typename T::key_type>::to_string(ti.first, key_p) +
1872  p->get_key_value_separator() +
1874 
1875  std::string s;
1876  if (vec.size() > 0)
1877  s = vec[0];
1878  for (unsigned int i = 1; i < vec.size(); ++i)
1879  s += p->get_separator() + " " + vec[i];
1880 
1881  AssertThrow(p->match(s), ExcNoMatch(s, p->description()));
1882  return s;
1883  }
1884 
1885  static T
1886  to_value(const std::string & s,
1887  const std::unique_ptr<Patterns::PatternBase> &pattern =
1889  {
1890  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
1891 
1892  auto p = dynamic_cast<const Patterns::Map *>(pattern.get());
1893  AssertThrow(p,
1894  ExcMessage("I need a Map pattern to convert a "
1895  "string to a Map compatible type."));
1896 
1897  auto key_p = p->get_key_pattern().clone();
1898  auto val_p = p->get_value_pattern().clone();
1899  T t;
1900 
1901  auto v = Utilities::split_string_list(s, p->get_separator());
1902  for (const auto &str : v)
1903  {
1904  auto key_val =
1905  Utilities::split_string_list(str, p->get_key_value_separator());
1906  AssertDimension(key_val.size(), 2);
1907  t.insert(std::make_pair(
1908  Convert<typename T::key_type>::to_value(key_val[0], key_p),
1910  }
1911 
1912  return t;
1913  }
1914  };
1915 
1916  // Tensors
1917  template <int rank, int dim, class Number>
1918  struct Convert<Tensor<rank, dim, Number>>
1919  {
1921  static std::unique_ptr<Patterns::PatternBase>
1923  {
1924  static_assert(internal::RankInfo<T>::list_rank > 0,
1925  "Cannot use this class for non List-compatible types.");
1926  return std::make_unique<Patterns::List>(
1928  dim,
1929  dim,
1931  1]);
1932  }
1933 
1934  static std::string
1935  to_string(const T & t,
1936  const std::unique_ptr<Patterns::PatternBase> &pattern =
1938  {
1939  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
1940  AssertThrow(p,
1941  ExcMessage("I need a List pattern to convert a string "
1942  "to a List compatible type."));
1943  auto base_p = p->get_base_pattern().clone();
1944  std::vector<std::string> vec(dim);
1945 
1946  for (unsigned int i = 0; i < dim; ++i)
1947  vec[i] = Convert<typename T::value_type>::to_string(t[i], base_p);
1948 
1949  std::string s;
1950  if (vec.size() > 0)
1951  s = vec[0];
1952  for (unsigned int i = 1; i < vec.size(); ++i)
1953  s += p->get_separator() + " " + vec[i];
1954 
1955  AssertThrow(p->match(s), ExcNoMatch(s, p->description()));
1956  return s;
1957  }
1958 
1959  static T
1960  to_value(const std::string & s,
1961  const std::unique_ptr<Patterns::PatternBase> &pattern =
1963  {
1964  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
1965 
1966  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
1967  AssertThrow(p,
1968  ExcMessage("I need a List pattern to convert a string "
1969  "to a List compatible type."));
1970 
1971  auto base_p = p->get_base_pattern().clone();
1972  T t;
1973 
1974  auto v = Utilities::split_string_list(s, p->get_separator());
1975  unsigned int i = 0;
1976  for (const auto &str : v)
1977  t[i++] = Convert<typename T::value_type>::to_value(str, base_p);
1978 
1979  return t;
1980  }
1981  };
1982 
1983  // Points
1984  template <int dim, class Number>
1985  struct Convert<Point<dim, Number>>
1986  {
1988 
1989  static std::unique_ptr<Patterns::PatternBase>
1991  {
1992  return Convert<Tensor<1, dim, Number>>::to_pattern();
1993  }
1994 
1995  static std::string
1996  to_string(const T & t,
1997  const std::unique_ptr<Patterns::PatternBase> &pattern =
1999  {
2001  Tensor<1, dim, Number>(t), pattern);
2002  }
2003 
2004  static T
2005  to_value(const std::string & s,
2006  const std::unique_ptr<Patterns::PatternBase> &pattern =
2008  {
2009  return T(Convert<Tensor<1, dim, Number>>::to_value(s, pattern));
2010  }
2011  };
2012 
2013  // Functions::FunctionParser
2014  template <int dim>
2015  struct Convert<std::unique_ptr<FunctionParser<dim>>>
2016  {
2017  using T = std::unique_ptr<FunctionParser<dim>>;
2018 
2019  static std::unique_ptr<Patterns::PatternBase>
2021  {
2022  static_assert(internal::RankInfo<T>::list_rank > 0,
2023  "Cannot use this class for non List-compatible types.");
2024 
2025  return std::make_unique<Patterns::List>(
2027  1,
2030  1]);
2031  }
2032 
2033  static std::string
2034  to_string(const T & t,
2035  const std::unique_ptr<Patterns::PatternBase> &pattern =
2037  {
2038  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2039  AssertThrow(p,
2040  ExcMessage("I need a List pattern to convert a string "
2041  "to a List compatible type."));
2042 
2043  const auto &expressions = t->get_expressions();
2044  if (expressions.size() == 0)
2045  return std::string();
2046 
2047  std::string s = expressions[0];
2048  for (unsigned int i = 1; i < expressions.size(); ++i)
2049  s = s + p->get_separator() + expressions[i];
2050 
2051  AssertThrow(pattern->match(s), ExcNoMatch(s, p->description()));
2052  return s;
2053  }
2054 
2055  static T
2056  to_value(const std::string & s,
2057  const std::unique_ptr<Patterns::PatternBase> &pattern =
2059  {
2060  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2061 
2062  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2063  AssertThrow(p,
2064  ExcMessage("I need a List pattern to convert a string "
2065  "to a List compatible type."));
2066 
2067  const auto expressions =
2068  Utilities::split_string_list(s, p->get_separator());
2069 
2070  T t = std::make_unique<FunctionParser<dim>>(expressions.size());
2071  const std::string var =
2073  const typename FunctionParser<dim>::ConstMap constants;
2074  t->initialize(var, expressions, constants, true);
2075  return t;
2076  }
2077  };
2078 
2079  // ComponentMask
2080  template <>
2082  {
2083  using T = ComponentMask;
2084 
2085  static std::unique_ptr<Patterns::PatternBase>
2087  {
2088  return Convert<std::vector<bool>>::to_pattern();
2089  }
2090 
2091  static std::string
2092  to_string(const T & t,
2093  const std::unique_ptr<Patterns::PatternBase> &pattern =
2095  {
2096  std::vector<bool> mask(t.size());
2097  for (unsigned int i = 0; i < t.size(); ++i)
2098  mask[i] = t[i];
2099 
2100  return Convert<std::vector<bool>>::to_string(mask, pattern);
2101  }
2102 
2103  static T
2104  to_value(const std::string & s,
2105  const std::unique_ptr<Patterns::PatternBase> &pattern =
2107  {
2108  const auto mask = Convert<std::vector<bool>>::to_value(s, pattern);
2109  return ComponentMask(mask);
2110  }
2111  };
2112 
2113  // Complex numbers
2114  template <class Number>
2115  struct Convert<std::complex<Number>>
2116  {
2117  using T = std::complex<Number>;
2118 
2119  static std::unique_ptr<Patterns::PatternBase>
2121  {
2122  static_assert(internal::RankInfo<T>::list_rank > 0,
2123  "Cannot use this class for non List-compatible types.");
2124  return std::make_unique<Patterns::List>(
2126  2,
2127  2,
2129  1]);
2130  }
2131 
2132  static std::string
2133  to_string(const T & t,
2134  const std::unique_ptr<Patterns::PatternBase> &pattern =
2136  {
2137  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2138  AssertThrow(p,
2139  ExcMessage("I need a List pattern to convert a string "
2140  "to a List compatible type."));
2141 
2142  auto base_p = p->get_base_pattern().clone();
2143  std::string s =
2144  Convert<typename T::value_type>::to_string(t.real(), base_p) +
2145  p->get_separator() + " " +
2147 
2148  AssertThrow(pattern->match(s), ExcNoMatch(s, p->description()));
2149  return s;
2150  }
2151 
2155  static T
2156  to_value(const std::string & s,
2157  const std::unique_ptr<Patterns::PatternBase> &pattern =
2159  {
2160  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2161 
2162  auto p = dynamic_cast<const Patterns::List *>(pattern.get());
2163  AssertThrow(p,
2164  ExcMessage("I need a List pattern to convert a string "
2165  "to a List compatible type."));
2166 
2167  auto base_p = p->get_base_pattern().clone();
2168 
2169  auto v = Utilities::split_string_list(s, p->get_separator());
2170  AssertDimension(v.size(), 2);
2173  return t;
2174  }
2175  };
2176 
2177  // Strings
2178  template <>
2179  struct Convert<std::string>
2180  {
2181  using T = std::string;
2182 
2183  static std::unique_ptr<Patterns::PatternBase>
2185  {
2186  return std::make_unique<Patterns::Anything>();
2187  }
2188 
2189  static std::string
2190  to_string(const T & t,
2191  const std::unique_ptr<Patterns::PatternBase> &pattern =
2193  {
2194  AssertThrow(pattern->match(t), ExcNoMatch(t, pattern->description()));
2195  return t;
2196  }
2197 
2198  static T
2199  to_value(const std::string & s,
2200  const std::unique_ptr<Patterns::PatternBase> &pattern =
2202  {
2203  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2204  return s;
2205  }
2206  };
2207 
2208  // Pairs
2209  template <class Key, class Value>
2210  struct Convert<std::pair<Key, Value>>
2211  {
2212  using T = std::pair<Key, Value>;
2213 
2214  static std::unique_ptr<Patterns::PatternBase>
2216  {
2217  static_assert(internal::RankInfo<T>::map_rank > 0,
2218  "Cannot use this class for non Map-compatible types.");
2219  return std::make_unique<Patterns::Tuple>(
2223  }
2224 
2225  static std::string
2226  to_string(const T & t,
2227  const std::unique_ptr<Patterns::PatternBase> &pattern =
2229  {
2230  std::tuple<Key, Value> m(t);
2231  std::string s = Convert<decltype(m)>::to_string(m, pattern);
2232  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2233  return s;
2234  }
2235 
2236  static T
2237  to_value(const std::string & s,
2238  const std::unique_ptr<Patterns::PatternBase> &pattern =
2240  {
2241  std::tuple<Key, Value> m;
2242  m = Convert<decltype(m)>::to_value(s, pattern);
2243  return std::make_pair(std::get<0>(m), std::get<1>(m));
2244  }
2245  };
2246 
2247  // Tuples
2248  template <class... Args>
2249  struct Convert<std::tuple<Args...>>
2250  {
2251  using T = std::tuple<Args...>;
2252 
2253  static std::unique_ptr<Patterns::PatternBase>
2255  {
2256  static_assert(internal::RankInfo<T>::map_rank > 0,
2257  "Cannot use this class for non tuple-compatible types.");
2258  return std::make_unique<Patterns::Tuple>(
2261  }
2262 
2263  static std::string
2264  to_string(const T & t,
2265  const std::unique_ptr<Patterns::PatternBase> &pattern =
2267  {
2268  auto p = dynamic_cast<const Patterns::Tuple *>(pattern.get());
2269  AssertThrow(p,
2270  ExcMessage("I need a Tuple pattern to convert a tuple "
2271  "to a string."));
2272 
2273  const auto string_array = Convert<T>::to_string_internal_2(t, *p);
2274  std::string str;
2275  for (unsigned int i = 0; i < string_array.size(); ++i)
2276  str += (i ? " " + p->get_separator() + " " : "") + string_array[i];
2277  AssertThrow(p->match(str), ExcNoMatch(str, p->description()));
2278  return str;
2279  }
2280 
2281  static T
2282  to_value(const std::string & s,
2283  const std::unique_ptr<Patterns::PatternBase> &pattern =
2285  {
2286  AssertThrow(pattern->match(s), ExcNoMatch(s, pattern->description()));
2287 
2288  auto p = dynamic_cast<const Patterns::Tuple *>(pattern.get());
2289  AssertThrow(p,
2290  ExcMessage("I need a Tuple pattern to convert a string "
2291  "to a tuple type."));
2292 
2293  auto v = Utilities::split_string_list(s, p->get_separator());
2294 
2295  return Convert<T>::to_value_internal_2(v, *p);
2296  }
2297 
2298  private:
2299  template <std::size_t... U>
2300  static std::array<std::string, std::tuple_size<T>::value>
2302  const Patterns::Tuple &pattern,
2303  std::index_sequence<U...>)
2304  {
2305  std::array<std::string, std::tuple_size<T>::value> a = {
2307  std::get<U>(t), pattern.get_pattern(U).clone())...}};
2308  return a;
2309  }
2310 
2311  static std::array<std::string, std::tuple_size<T>::value>
2312  to_string_internal_2(const T &t, const Patterns::Tuple &pattern)
2313  {
2315  t, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2316  }
2317 
2318  template <std::size_t... U>
2319  static T
2320  to_value_internal_1(const std::vector<std::string> &s,
2321  const Patterns::Tuple & pattern,
2322  std::index_sequence<U...>)
2323  {
2324  return std::make_tuple(
2325  Convert<typename std::tuple_element<U, T>::type>::to_value(
2326  s[U], pattern.get_pattern(U).clone())...);
2327  }
2328 
2329  static T
2330  to_value_internal_2(const std::vector<std::string> &s,
2331  const Patterns::Tuple & pattern)
2332  {
2334  s, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2335  }
2336  };
2337 
2338  // Utility function with default Pattern
2339  template <typename T>
2340  std::string
2341  to_string(const T &t)
2342  {
2343  return Convert<T>::to_string(t);
2344  }
2345 
2346  // Utility function with default Pattern
2347  template <typename T>
2348  void
2349  to_value(const std::string &s, T &t)
2350  {
2351  t = Convert<T>::to_value(s);
2352  }
2353  } // namespace Tools
2354 } // namespace Patterns
2355 
2356 
2358 
2359 #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
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2199
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:538
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1568
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1960
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:2349
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:2237
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:1922
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:2282
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:2005
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2056
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:2301
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:2092
#define AssertThrow(cond, exc)
Definition: exceptions.h:1521
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:2133
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition: config.h:376
static std::string default_variable_names()
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:1990
static T to_value_internal_1(const std::vector< std::string > &s, const Patterns::Tuple &pattern, std::index_sequence< U... >)
Definition: patterns.h:2320
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2254
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:2104
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:2086
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:2226
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:363
virtual ~PatternBase()=default
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2184
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:2341
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:1810
static T to_value_internal_2(const std::vector< std::string > &s, const Patterns::Tuple &pattern)
Definition: patterns.h:2330
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2156
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:2034
virtual std::string description(const OutputStyle style=Machine) const =0
Definition: tensor.h:448
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition: config.h:413
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:362
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:1886
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:2312
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:2190
constexpr std::array< const char *, 4 > default_map_separator
Definition: patterns.h:1583
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2120
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:2264
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:1996
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:2215
static std::string to_string(const T &t, const std::unique_ptr< Patterns::PatternBase > &pattern=Convert< T >::to_pattern())
Definition: patterns.h:1856
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:1935
static std::unique_ptr< Patterns::PatternBase > to_pattern()
Definition: patterns.h:2020