15#ifndef dealii_patterns_h
16#define dealii_patterns_h
29#include <boost/archive/basic_archive.hpp>
30#include <boost/core/demangle.hpp>
31#include <boost/property_tree/ptree_fwd.hpp>
32#include <boost/property_tree/ptree_serialization.hpp>
33#include <boost/serialization/split_member.hpp>
46#include <unordered_map>
47#include <unordered_set>
89 match(
const std::string &test_string)
const = 0;
131 virtual std::unique_ptr<PatternBase>
156 std::unique_ptr<PatternBase>
224 match(
const std::string &test_string)
const override;
239 virtual std::unique_ptr<PatternBase>
240 clone()
const override;
247 static std::unique_ptr<Integer>
320 match(
const std::string &test_string)
const override;
335 virtual std::unique_ptr<PatternBase>
336 clone()
const override;
345 static std::unique_ptr<Double>
394 match(
const std::string &test_string)
const override;
409 virtual std::unique_ptr<PatternBase>
410 clone()
const override;
424 static std::unique_ptr<Selection>
494 match(
const std::string &test_string)
const override;
508 virtual std::unique_ptr<PatternBase>
509 clone()
const override;
516 static std::unique_ptr<List>
537 <<
"The values " << arg1 <<
" and " << arg2
538 <<
" do not form a valid range.");
617 match(
const std::string &test_string)
const override;
631 virtual std::unique_ptr<PatternBase>
632 clone()
const override;
639 static std::unique_ptr<Map>
684 <<
"The values " << arg1 <<
" and " << arg2
685 <<
" do not form a valid range.");
780 Tuple(
const std::vector<std::unique_ptr<PatternBase>> &
patterns,
788 Tuple(
const std::vector<std::unique_ptr<PatternBase>> &
patterns,
799 template <
class... PatternTypes>
809 template <
class... PatternTypes>
830 match(
const std::string &test_string)
const override;
844 virtual std::unique_ptr<PatternBase>
845 clone()
const override;
852 static std::unique_ptr<Tuple>
878 std::vector<std::unique_ptr<PatternBase>>
patterns;
915 match(
const std::string &test_string)
const override;
930 virtual std::unique_ptr<PatternBase>
931 clone()
const override;
938 static std::unique_ptr<MultipleSelection>
959 <<
"A comma was found at position " << arg1
960 <<
" of your input string, but commas are not allowed here.");
999 virtual std::unique_ptr<PatternBase>
1000 clone()
const override;
1007 static std::unique_ptr<Bool>
1034 match(
const std::string &test_string)
const override;
1048 virtual std::unique_ptr<PatternBase>
1049 clone()
const override;
1056 static std::unique_ptr<Anything>
1111 match(
const std::string &test_string)
const override;
1125 virtual std::unique_ptr<PatternBase>
1126 clone()
const override;
1138 static std::unique_ptr<FileName>
1174 match(
const std::string &test_string)
const override;
1188 virtual std::unique_ptr<PatternBase>
1189 clone()
const override;
1196 static std::unique_ptr<DirectoryName>
1296 template <
class T,
class Enable =
void>
1308 static std::unique_ptr<Patterns::PatternBase>
1359 template <
typename T>
1388 template <
typename T>
1390 to_value(
const std::string &s, T &t);
1403 <<
"The string \"" << arg1
1404 <<
"\" does not match the pattern \"" << arg2 <<
"\"");
1413 template <
class... PatternTypes>
1416 Tuple(
std::string(separator), ps...)
1421 template <
class... PatternTypes>
1423 : separator(separator)
1426 "Not all of the input arguments of this function "
1427 "are derived from PatternBase");
1428 static_assert(
sizeof...(ps) > 0,
1429 "The number of PatternTypes must be greater than zero!");
1430 const auto pattern_pointers = {(
static_cast<const PatternBase *
>(&ps))...};
1431 for (
const auto p : pattern_pointers)
1437 template <
class... PatternTypes>
1473 template <
class T,
class Enable =
void>
1485 template <
typename Dummy = T>
1486 static std::enable_if_t<std::is_same_v<Dummy, T> &&
1487 std::is_same_v<T, bool>,
1488 std::unique_ptr<Patterns::PatternBase>>
1491 return std::make_unique<Patterns::Bool>();
1494 template <
typename Dummy = T>
1495 static std::enable_if_t<std::is_same_v<Dummy, T> &&
1496 !std::is_same_v<T, bool> &&
1497 std::is_integral_v<T>,
1498 std::unique_ptr<Patterns::PatternBase>>
1501 return std::make_unique<Patterns::Integer>(
1502 std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
1505 template <
typename Dummy = T>
1506 static std::enable_if_t<std::is_same_v<Dummy, T> &&
1507 !std::is_same_v<T, bool> &&
1508 std::is_floating_point_v<T>,
1509 std::unique_ptr<Patterns::PatternBase>>
1512 return std::make_unique<Patterns::Double>(
1513 std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
1520 std::stringstream str;
1521 if (std::is_same_v<T, unsigned char> ||
1522 std::is_same_v<T, signed char> || std::is_same_v<T, char>)
1523 str << static_cast<int>(value);
1524 else if (std::is_same_v<T, bool>)
1525 str << (static_cast<bool>(value) ?
"true" :
"false");
1538 if (std::is_same_v<T, bool>)
1539 value = (s ==
"true");
1542 std::istringstream is(s);
1543 if (std::is_same_v<T, unsigned char> ||
1544 std::is_same_v<T, signed char> || std::is_same_v<T, char>)
1562 ExcMessage(
"Failed to convert from \"" + s +
"\" to the type \"" +
1563 boost::core::demangle(
typeid(T).name()) +
"\""));
1572 {
",",
";",
"|",
"%"}};
1574 {
":",
"=",
"@",
"#"}};
1577 template <
typename T>
1580 template <
typename... Args>
1583 template <
typename... Args>
1586 template <
typename... Args>
1589 template <
typename... Args>
1592 template <
typename... Args>
1595 template <
typename... Args>
1598 template <
typename... Args>
1603 template <
typename T>
1606 template <
class Key,
class T,
class Compare,
class Allocator>
1610 template <
class Key,
class T,
class Compare,
class Allocator>
1614 template <
class Key,
class T,
class Hash,
class KeyEqual,
class Allocator>
1616 std::unordered_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type
1618 template <
class Key,
class T,
class Hash,
class KeyEqual,
class Allocator>
1620 std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>>
1627 template <
typename T>
1634 template <
typename T>
1651 template <
class T1,
class T2,
class... Types>
1666 template <
class T1,
class T2,
class... Types>
1694 template <
int rank,
int dim,
class Number>
1701 template <
int dim,
class Number>
1706 template <
class Number>
1730 template <
class Key,
class Value>
1740 template <
class... Types>
1748 template <
class T, std::
size_t N>
1758 struct Convert<T,
std::enable_if_t<is_list_compatible<T>::value>>
1760 static std::unique_ptr<Patterns::PatternBase>
1764 "Cannot use this class for non List-compatible types.");
1765 return std::make_unique<Patterns::List>(
1768 std::numeric_limits<unsigned int>::max(),
1780 ExcMessage(
"I need a List pattern to convert a "
1781 "string to a List type."));
1782 auto base_p = p->get_base_pattern().clone();
1783 std::vector<std::string> vec(t.size());
1786 t.cbegin(), t.cend(), vec.begin(), [&base_p](
const auto &entry) {
1787 return Convert<typename T::value_type>::to_string(entry, *base_p);
1793 for (
unsigned int i = 1; i < vec.size(); ++i)
1794 s += p->get_separator() +
" " + vec[i];
1808 ExcMessage(
"I need a List pattern to convert a string "
1809 "to a List type."));
1811 auto base_p = p->get_base_pattern().clone();
1815 for (
const auto &str : v)
1827 static std::unique_ptr<Patterns::PatternBase>
1831 "Cannot use this class for non List-compatible types.");
1833 "Cannot use this class for non Map-compatible types.");
1834 return std::make_unique<Patterns::Map>(
1838 std::numeric_limits<unsigned int>::max(),
1849 const auto *p =
dynamic_cast<const Patterns::Map *
>(&pattern);
1851 ExcMessage(
"I need a Map pattern to convert a string to "
1852 "a Map compatible type."));
1853 auto key_p = p->get_key_pattern().clone();
1854 auto val_p = p->get_value_pattern().clone();
1855 std::vector<std::string> vec(t.size());
1858 for (
const auto &ti : t)
1861 p->get_key_value_separator() +
1867 for (
unsigned int i = 1; i < vec.size(); ++i)
1868 s += p->get_separator() +
" " + vec[i];
1880 const auto *p =
dynamic_cast<const Patterns::Map *
>(&pattern);
1882 ExcMessage(
"I need a Map pattern to convert a "
1883 "string to a Map compatible type."));
1885 auto key_p = p->get_key_pattern().clone();
1886 auto val_p = p->get_value_pattern().clone();
1890 for (
const auto &str : v)
1895 t.insert(std::make_pair(
1905 template <
typename ValueType, std::
size_t N>
1908 using T = std::array<ValueType, N>;
1910 static std::unique_ptr<Patterns::PatternBase>
1914 "Cannot use this class for non List-compatible types.");
1915 return std::make_unique<Patterns::List>(
1930 ExcMessage(
"I need a List pattern to convert a "
1931 "string to a std::array."));
1932 auto base_p = p->get_base_pattern().clone();
1933 std::vector<std::string> vec(t.size());
1936 t.cbegin(), t.cend(), vec.begin(), [&base_p](
const auto &entry) {
1937 return Convert<typename T::value_type>::to_string(entry, *base_p);
1943 for (
unsigned int i = 1; i < vec.size(); ++i)
1944 s += p->get_separator() +
" " + vec[i];
1958 ExcMessage(
"I need a List pattern to convert a string "
1959 "to a std::array."));
1961 auto base_p = p->get_base_pattern().clone();
1966 for (
unsigned int i = 0; i < N; ++i)
1973 template <
int rank,
int dim,
class Number>
1977 static std::unique_ptr<Patterns::PatternBase>
1981 "Cannot use this class for non List-compatible types.");
1982 return std::make_unique<Patterns::List>(
1997 ExcMessage(
"I need a List pattern to convert a string "
1998 "to a List compatible type."));
1999 auto base_p = p->get_base_pattern().clone();
2000 std::vector<std::string> vec(dim);
2002 for (
unsigned int i = 0; i < dim; ++i)
2008 for (
unsigned int i = 1; i < vec.size(); ++i)
2009 s += p->get_separator() +
" " + vec[i];
2023 ExcMessage(
"I need a List pattern to convert a string "
2024 "to a List compatible type."));
2026 auto base_p = p->get_base_pattern().clone();
2031 for (
const auto &str : v)
2039 template <
int dim,
class Number>
2044 static std::unique_ptr<Patterns::PatternBase>
2071 using T = std::unique_ptr<FunctionParser<dim>>;
2073 static std::unique_ptr<Patterns::PatternBase>
2077 "Cannot use this class for non List-compatible types.");
2079 return std::make_unique<Patterns::List>(
2094 ExcMessage(
"I need a List pattern to convert a string "
2095 "to a List compatible type."));
2097 const auto &expressions = t->get_expressions();
2098 if (expressions.empty())
2099 return std::string();
2101 std::string s = expressions[0];
2102 for (
unsigned int i = 1; i < expressions.size(); ++i)
2103 s = s + p->get_separator() + expressions[i];
2117 ExcMessage(
"I need a List pattern to convert a string "
2118 "to a List compatible type."));
2120 const auto expressions =
2123 T t = std::make_unique<FunctionParser<dim>>(expressions.size());
2124 const std::string var =
2127 t->initialize(var, expressions, constants,
true);
2138 static std::unique_ptr<Patterns::PatternBase>
2149 std::vector<bool> mask(t.
size());
2150 for (
unsigned int i = 0; i < t.
size(); ++i)
2166 template <
class Number>
2169 using T = std::complex<Number>;
2171 static std::unique_ptr<Patterns::PatternBase>
2175 "Cannot use this class for non List-compatible types.");
2176 return std::make_unique<Patterns::List>(
2191 ExcMessage(
"I need a List pattern to convert a string "
2192 "to a List compatible type."));
2194 auto base_p = p->get_base_pattern().clone();
2197 p->get_separator() +
" " +
2215 ExcMessage(
"I need a List pattern to convert a string "
2216 "to a List compatible type."));
2218 auto base_p = p->get_base_pattern().clone();
2232 using T = std::string;
2234 static std::unique_ptr<Patterns::PatternBase>
2237 return std::make_unique<Patterns::Anything>();
2259 template <
class Key,
class Value>
2262 using T = std::pair<Key, Value>;
2264 static std::unique_ptr<Patterns::PatternBase>
2268 "Cannot use this class for non Map-compatible types.");
2269 return std::make_unique<Patterns::Tuple>(
2280 std::tuple<Key, Value> m(t);
2290 std::tuple<Key, Value> m;
2292 return std::make_pair(std::get<0>(m), std::get<1>(m));
2297 template <
class... Args>
2300 using T = std::tuple<Args...>;
2302 static std::unique_ptr<Patterns::PatternBase>
2306 "Cannot use this class for non tuple-compatible types.");
2307 return std::make_unique<Patterns::Tuple>(
2319 ExcMessage(
"I need a Tuple pattern to convert a tuple "
2324 for (
unsigned int i = 0; i < string_array.size(); ++i)
2326 (i != 0u ?
" " + p->get_separator() +
" " :
"") + string_array[i];
2339 ExcMessage(
"I need a Tuple pattern to convert a string "
2340 "to a tuple type."));
2348 template <std::size_t... U>
2349 static std::array<std::string, std::tuple_size<T>::value>
2352 std::index_sequence<U...>)
2354 std::array<std::string, std::tuple_size<T>::value> a = {
2360 static std::array<std::string, std::tuple_size<T>::value>
2364 t, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2367 template <std::size_t... U>
2371 std::index_sequence<U...>)
2373 return std::make_tuple(
2383 s, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2388 template <
typename T>
2396 template <
typename T>
unsigned int size() const
std::map< std::string, double > ConstMap
static std::string default_variable_names()
static std::unique_ptr< Anything > create(const std::string &description)
virtual bool match(const std::string &test_string) const override
static const char * description_init
virtual std::string description(const OutputStyle style=Machine) const override
virtual std::unique_ptr< PatternBase > clone() const override
virtual std::string description(const OutputStyle style=Machine) const override
static const char * description_init
virtual std::unique_ptr< PatternBase > clone() const override
static std::unique_ptr< Bool > create(const std::string &description)
virtual std::unique_ptr< PatternBase > clone() const override
static const char * description_init
virtual std::string description(const OutputStyle style=Machine) const override
static std::unique_ptr< DirectoryName > create(const std::string &description)
virtual bool match(const std::string &test_string) const override
static std::unique_ptr< Double > create(const std::string &description)
static const char * description_init
virtual std::unique_ptr< PatternBase > clone() const override
Double(const double lower_bound=min_double_value, const double upper_bound=max_double_value)
static const double max_double_value
static const double min_double_value
virtual std::string description(const OutputStyle style=Machine) const override
virtual bool match(const std::string &test_string) const override
virtual bool match(const std::string &test_string) const override
FileName(const FileType type=input)
static const char * description_init
virtual std::unique_ptr< PatternBase > clone() const override
static std::unique_ptr< FileName > create(const std::string &description)
virtual std::string description(const OutputStyle style=Machine) const override
static std::unique_ptr< Integer > create(const std::string &description)
static const char * description_init
virtual std::unique_ptr< PatternBase > clone() const override
Integer(const int lower_bound=min_int_value, const int upper_bound=max_int_value)
static const int min_int_value
virtual std::string description(const OutputStyle style=Machine) const override
virtual bool match(const std::string &test_string) const override
static const int max_int_value
const unsigned int max_elements
static const char * description_init
const unsigned int min_elements
std::unique_ptr< PatternBase > pattern
const std::string separator
std::size_t memory_consumption() const override
static std::unique_ptr< List > create(const std::string &description)
virtual std::string description(const OutputStyle style=Machine) const override
const PatternBase & get_base_pattern() const
virtual bool match(const std::string &test_string) const override
const std::string & get_separator() const
List(const PatternBase &base_pattern, const unsigned int min_elements=0, const unsigned int max_elements=max_int_value, const std::string &separator=",")
static const unsigned int max_int_value
virtual std::unique_ptr< PatternBase > clone() const override
static std::unique_ptr< Map > create(const std::string &description)
std::unique_ptr< PatternBase > value_pattern
const unsigned int min_elements
const PatternBase & get_key_pattern() const
virtual bool match(const std::string &test_string) const override
Map(const PatternBase &key_pattern, const PatternBase &value_pattern, const unsigned int min_elements=0, const unsigned int max_elements=max_int_value, const std::string &separator=",", const std::string &key_value_separator=":")
const unsigned int max_elements
virtual std::unique_ptr< PatternBase > clone() const override
const PatternBase & get_value_pattern() const
const std::string & get_separator() const
virtual std::string description(const OutputStyle style=Machine) const override
static const unsigned int max_int_value
std::unique_ptr< PatternBase > key_pattern
const std::string separator
std::size_t memory_consumption() const override
static const char * description_init
const std::string & get_key_value_separator() const
const std::string key_value_separator
MultipleSelection(const std::string &seq)
static std::unique_ptr< MultipleSelection > create(const std::string &description)
virtual bool match(const std::string &test_string) const override
virtual std::unique_ptr< PatternBase > clone() const override
static const char * description_init
std::size_t memory_consumption() const override
virtual std::string description(const OutputStyle style=Machine) const override
virtual std::size_t memory_consumption() const
virtual std::unique_ptr< PatternBase > clone() const =0
virtual std::string description(const OutputStyle style=Machine) const =0
virtual bool match(const std::string &test_string) const =0
virtual ~PatternBase()=default
static const char * description_init
virtual std::string description(const OutputStyle style=Machine) const override
virtual std::unique_ptr< PatternBase > clone() const override
virtual bool match(const std::string &test_string) const override
static std::unique_ptr< Selection > create(const std::string &description)
std::size_t memory_consumption() const override
Selection(const std::string &seq)
virtual bool match(const std::string &test_string) const override
std::size_t memory_consumption() const override
static std::unique_ptr< Tuple > create(const std::string &description)
std::vector< std::unique_ptr< PatternBase > > patterns
virtual std::unique_ptr< PatternBase > clone() const override
Tuple(const Patterns &...patterns)
const std::string separator
static const char * description_init
Tuple(const std::vector< std::unique_ptr< PatternBase > > &patterns, const std::string &separator=":")
const std::string & get_separator() const
const PatternBase & get_pattern(const unsigned int i) const
virtual std::string description(const OutputStyle style=Machine) const override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcInvalidRange(int arg1, int arg2)
static ::ExceptionBase & ExcInvalidRange(int arg1, int arg2)
static ::ExceptionBase & ExcNoMatch(std::string arg1, std::string arg2)
#define DeclException2(Exception2, type1, type2, outsequence)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcCommasNotAllowed(int arg1)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::string escape(const std::string &input, const PatternBase::OutputStyle style)
std::unique_ptr< PatternBase > pattern_factory(const std::string &description)
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)