16#ifndef dealii_patterns_h
17#define dealii_patterns_h
30#include <boost/archive/basic_archive.hpp>
31#include <boost/core/demangle.hpp>
32#include <boost/property_tree/ptree_fwd.hpp>
33#include <boost/property_tree/ptree_serialization.hpp>
34#include <boost/serialization/split_member.hpp>
47#include <unordered_map>
48#include <unordered_set>
90 match(
const std::string &test_string)
const = 0;
132 virtual std::unique_ptr<PatternBase>
157 std::unique_ptr<PatternBase>
225 match(
const std::string &test_string)
const override;
240 virtual std::unique_ptr<PatternBase>
241 clone()
const override;
248 static std::unique_ptr<Integer>
321 match(
const std::string &test_string)
const override;
336 virtual std::unique_ptr<PatternBase>
337 clone()
const override;
346 static std::unique_ptr<Double>
395 match(
const std::string &test_string)
const override;
410 virtual std::unique_ptr<PatternBase>
411 clone()
const override;
425 static std::unique_ptr<Selection>
495 match(
const std::string &test_string)
const override;
509 virtual std::unique_ptr<PatternBase>
510 clone()
const override;
517 static std::unique_ptr<List>
538 <<
"The values " << arg1 <<
" and " << arg2
539 <<
" do not form a valid range.");
618 match(
const std::string &test_string)
const override;
632 virtual std::unique_ptr<PatternBase>
633 clone()
const override;
640 static std::unique_ptr<Map>
685 <<
"The values " << arg1 <<
" and " << arg2
686 <<
" do not form a valid range.");
781 Tuple(
const std::vector<std::unique_ptr<PatternBase>> &
patterns,
789 Tuple(
const std::vector<std::unique_ptr<PatternBase>> &
patterns,
800 template <
class... PatternTypes>
810 template <
class... PatternTypes>
831 match(
const std::string &test_string)
const override;
845 virtual std::unique_ptr<PatternBase>
846 clone()
const override;
853 static std::unique_ptr<Tuple>
879 std::vector<std::unique_ptr<PatternBase>>
patterns;
916 match(
const std::string &test_string)
const override;
931 virtual std::unique_ptr<PatternBase>
932 clone()
const override;
939 static std::unique_ptr<MultipleSelection>
960 <<
"A comma was found at position " << arg1
961 <<
" of your input string, but commas are not allowed here.");
1000 virtual std::unique_ptr<PatternBase>
1001 clone()
const override;
1008 static std::unique_ptr<Bool>
1035 match(
const std::string &test_string)
const override;
1049 virtual std::unique_ptr<PatternBase>
1050 clone()
const override;
1057 static std::unique_ptr<Anything>
1112 match(
const std::string &test_string)
const override;
1126 virtual std::unique_ptr<PatternBase>
1127 clone()
const override;
1139 static std::unique_ptr<FileName>
1175 match(
const std::string &test_string)
const override;
1189 virtual std::unique_ptr<PatternBase>
1190 clone()
const override;
1197 static std::unique_ptr<DirectoryName>
1297 template <
class T,
class Enable =
void>
1309 static std::unique_ptr<Patterns::PatternBase>
1360 template <
typename T>
1389 template <
typename T>
1391 to_value(
const std::string &s, T &t);
1404 <<
"The string \"" << arg1
1405 <<
"\" does not match the pattern \"" << arg2 <<
"\"");
1414 template <
class... PatternTypes>
1417 Tuple(
std::string(separator), ps...)
1422 template <
class... PatternTypes>
1424 : separator(separator)
1427 "Not all of the input arguments of this function "
1428 "are derived from PatternBase");
1429 static_assert(
sizeof...(ps) > 0,
1430 "The number of PatternTypes must be greater than zero!");
1431 const auto pattern_pointers = {(
static_cast<const PatternBase *
>(&ps))...};
1432 for (
const auto p : pattern_pointers)
1438 template <
class... PatternTypes>
1474 template <
class T,
class Enable =
void>
1484 struct Convert<T,
std::enable_if_t<std::is_arithmetic<T>::value>>
1486 template <
typename Dummy = T>
1487 static std::enable_if_t<std::is_same<Dummy, T>::value &&
1488 std::is_same<T, bool>::value,
1489 std::unique_ptr<Patterns::PatternBase>>
1492 return std::make_unique<Patterns::Bool>();
1495 template <
typename Dummy = T>
1496 static std::enable_if_t<std::is_same<Dummy, T>::value &&
1497 !std::is_same<T, bool>::value &&
1498 std::is_integral<T>::value,
1499 std::unique_ptr<Patterns::PatternBase>>
1502 return std::make_unique<Patterns::Integer>(
1503 std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
1506 template <
typename Dummy = T>
1507 static std::enable_if_t<std::is_same<Dummy, T>::value &&
1508 !std::is_same<T, bool>::value &&
1509 std::is_floating_point<T>::value,
1510 std::unique_ptr<Patterns::PatternBase>>
1513 return std::make_unique<Patterns::Double>(
1514 std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
1521 std::stringstream str;
1522 if (std::is_same<T, unsigned char>::value ||
1523 std::is_same<T, signed char>::value || std::is_same<T, char>::value)
1524 str << static_cast<int>(value);
1525 else if (std::is_same<T, bool>::value)
1526 str << (static_cast<bool>(value) ?
"true" :
"false");
1539 if (std::is_same<T, bool>::value)
1540 value = (s ==
"true");
1543 std::istringstream is(s);
1544 if (std::is_same<T, unsigned char>::value ||
1545 std::is_same<T, signed char>::value ||
1546 std::is_same<T, char>::value)
1564 ExcMessage(
"Failed to convert from \"" + s +
"\" to the type \"" +
1565 boost::core::demangle(
typeid(T).name()) +
"\""));
1574 {
",",
";",
"|",
"%"}};
1576 {
":",
"=",
"@",
"#"}};
1579 template <
typename T>
1582 template <
typename... Args>
1585 template <
typename... Args>
1588 template <
typename... Args>
1591 template <
typename... Args>
1594 template <
typename... Args>
1597 template <
typename... Args>
1600 template <
typename... Args>
1605 template <
typename T>
1608 template <
class Key,
class T,
class Compare,
class Allocator>
1612 template <
class Key,
class T,
class Compare,
class Allocator>
1616 template <
class Key,
class T,
class Hash,
class KeyEqual,
class Allocator>
1618 std::unordered_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type
1620 template <
class Key,
class T,
class Hash,
class KeyEqual,
class Allocator>
1622 std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>>
1629 template <
typename T>
1636 template <
typename T>
1653 template <
class T1,
class T2,
class... Types>
1668 template <
class T1,
class T2,
class... Types>
1690 max_list_rank<typename T::key_type, typename T::mapped_type>() + 1;
1692 max_map_rank<typename T::key_type, typename T::mapped_type>() + 1;
1696 template <
int rank,
int dim,
class Number>
1703 template <
int dim,
class Number>
1708 template <
class Number>
1732 template <
class Key,
class Value>
1742 template <
class... Types>
1750 template <
class T, std::
size_t N>
1760 struct Convert<T,
std::enable_if_t<is_list_compatible<T>::value>>
1762 static std::unique_ptr<Patterns::PatternBase>
1766 "Cannot use this class for non List-compatible types.");
1767 return std::make_unique<Patterns::List>(
1770 std::numeric_limits<unsigned int>::max(),
1782 ExcMessage(
"I need a List pattern to convert a "
1783 "string to a List type."));
1784 auto base_p = p->get_base_pattern().clone();
1785 std::vector<std::string> vec(t.size());
1788 t.cbegin(), t.cend(), vec.begin(), [&base_p](
const auto &entry) {
1789 return Convert<typename T::value_type>::to_string(entry, *base_p);
1795 for (
unsigned int i = 1; i < vec.size(); ++i)
1796 s += p->get_separator() +
" " + vec[i];
1810 ExcMessage(
"I need a List pattern to convert a string "
1811 "to a List type."));
1813 auto base_p = p->get_base_pattern().clone();
1817 for (
const auto &str : v)
1829 static std::unique_ptr<Patterns::PatternBase>
1833 "Cannot use this class for non List-compatible types.");
1835 "Cannot use this class for non Map-compatible types.");
1836 return std::make_unique<Patterns::Map>(
1840 std::numeric_limits<unsigned int>::max(),
1853 ExcMessage(
"I need a Map pattern to convert a string to "
1854 "a Map compatible type."));
1855 auto key_p = p->get_key_pattern().clone();
1856 auto val_p = p->get_value_pattern().clone();
1857 std::vector<std::string> vec(t.size());
1860 for (
const auto &ti : t)
1863 p->get_key_value_separator() +
1869 for (
unsigned int i = 1; i < vec.size(); ++i)
1870 s += p->get_separator() +
" " + vec[i];
1884 ExcMessage(
"I need a Map pattern to convert a "
1885 "string to a Map compatible type."));
1887 auto key_p = p->get_key_pattern().clone();
1888 auto val_p = p->get_value_pattern().clone();
1892 for (
const auto &str : v)
1897 t.insert(std::make_pair(
1907 template <
class ValueType, std::
size_t N>
1910 using T = std::array<ValueType, N>;
1912 static std::unique_ptr<Patterns::PatternBase>
1916 "Cannot use this class for non List-compatible types.");
1917 return std::make_unique<Patterns::List>(
1932 ExcMessage(
"I need a List pattern to convert a "
1933 "string to a std::array."));
1934 auto base_p = p->get_base_pattern().clone();
1935 std::vector<std::string> vec(t.size());
1938 t.cbegin(), t.cend(), vec.begin(), [&base_p](
const auto &entry) {
1939 return Convert<typename T::value_type>::to_string(entry, *base_p);
1945 for (
unsigned int i = 1; i < vec.size(); ++i)
1946 s += p->get_separator() +
" " + vec[i];
1960 ExcMessage(
"I need a List pattern to convert a string "
1961 "to a std::array."));
1963 auto base_p = p->get_base_pattern().clone();
1968 for (
unsigned int i = 0; i < N; ++i)
1975 template <
int rank,
int dim,
class Number>
1979 static std::unique_ptr<Patterns::PatternBase>
1983 "Cannot use this class for non List-compatible types.");
1984 return std::make_unique<Patterns::List>(
1999 ExcMessage(
"I need a List pattern to convert a string "
2000 "to a List compatible type."));
2001 auto base_p = p->get_base_pattern().clone();
2002 std::vector<std::string> vec(dim);
2004 for (
unsigned int i = 0; i < dim; ++i)
2010 for (
unsigned int i = 1; i < vec.size(); ++i)
2011 s += p->get_separator() +
" " + vec[i];
2025 ExcMessage(
"I need a List pattern to convert a string "
2026 "to a List compatible type."));
2028 auto base_p = p->get_base_pattern().clone();
2033 for (
const auto &str : v)
2041 template <
int dim,
class Number>
2046 static std::unique_ptr<Patterns::PatternBase>
2073 using T = std::unique_ptr<FunctionParser<dim>>;
2075 static std::unique_ptr<Patterns::PatternBase>
2079 "Cannot use this class for non List-compatible types.");
2081 return std::make_unique<Patterns::List>(
2096 ExcMessage(
"I need a List pattern to convert a string "
2097 "to a List compatible type."));
2099 const auto &expressions = t->get_expressions();
2100 if (expressions.size() == 0)
2101 return std::string();
2103 std::string s = expressions[0];
2104 for (
unsigned int i = 1; i < expressions.size(); ++i)
2105 s = s + p->get_separator() + expressions[i];
2119 ExcMessage(
"I need a List pattern to convert a string "
2120 "to a List compatible type."));
2122 const auto expressions =
2125 T t = std::make_unique<FunctionParser<dim>>(expressions.size());
2126 const std::string var =
2129 t->initialize(var, expressions, constants,
true);
2140 static std::unique_ptr<Patterns::PatternBase>
2151 std::vector<bool> mask(t.
size());
2152 for (
unsigned int i = 0; i < t.
size(); ++i)
2168 template <
class Number>
2171 using T = std::complex<Number>;
2173 static std::unique_ptr<Patterns::PatternBase>
2177 "Cannot use this class for non List-compatible types.");
2178 return std::make_unique<Patterns::List>(
2193 ExcMessage(
"I need a List pattern to convert a string "
2194 "to a List compatible type."));
2196 auto base_p = p->get_base_pattern().clone();
2199 p->get_separator() +
" " +
2217 ExcMessage(
"I need a List pattern to convert a string "
2218 "to a List compatible type."));
2220 auto base_p = p->get_base_pattern().clone();
2234 using T = std::string;
2236 static std::unique_ptr<Patterns::PatternBase>
2239 return std::make_unique<Patterns::Anything>();
2261 template <
class Key,
class Value>
2264 using T = std::pair<Key, Value>;
2266 static std::unique_ptr<Patterns::PatternBase>
2270 "Cannot use this class for non Map-compatible types.");
2271 return std::make_unique<Patterns::Tuple>(
2282 std::tuple<Key, Value> m(t);
2292 std::tuple<Key, Value> m;
2294 return std::make_pair(std::get<0>(m), std::get<1>(m));
2299 template <
class... Args>
2302 using T = std::tuple<Args...>;
2304 static std::unique_ptr<Patterns::PatternBase>
2308 "Cannot use this class for non tuple-compatible types.");
2309 return std::make_unique<Patterns::Tuple>(
2321 ExcMessage(
"I need a Tuple pattern to convert a tuple "
2326 for (
unsigned int i = 0; i < string_array.size(); ++i)
2328 (i != 0u ?
" " + p->get_separator() +
" " :
"") + string_array[i];
2341 ExcMessage(
"I need a Tuple pattern to convert a string "
2342 "to a tuple type."));
2350 template <std::size_t... U>
2351 static std::array<std::string, std::tuple_size<T>::value>
2354 std::index_sequence<U...>)
2356 std::array<std::string, std::tuple_size<T>::value> a = {
2362 static std::array<std::string, std::tuple_size<T>::value>
2366 t, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2369 template <std::size_t... U>
2373 std::index_sequence<U...>)
2375 return std::make_tuple(
2385 s, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2390 template <
typename T>
2398 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
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
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
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
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
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
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
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 > &)