16 #ifndef dealii_patterns_h
17 #define dealii_patterns_h
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>
48 #include <type_traits>
49 #include <unordered_map>
50 #include <unordered_set>
92 match(
const std::string &test_string)
const = 0;
134 virtual std::unique_ptr<PatternBase>
159 std::unique_ptr<PatternBase>
227 match(
const std::string &test_string)
const override;
242 virtual std::unique_ptr<PatternBase>
243 clone()
const override;
250 static std::unique_ptr<Integer>
323 match(
const std::string &test_string)
const override;
338 virtual std::unique_ptr<PatternBase>
339 clone()
const override;
348 static std::unique_ptr<Double>
397 match(
const std::string &test_string)
const override;
412 virtual std::unique_ptr<PatternBase>
413 clone()
const override;
427 static std::unique_ptr<Selection>
497 match(
const std::string &test_string)
const override;
511 virtual std::unique_ptr<PatternBase>
512 clone()
const override;
519 static std::unique_ptr<List>
540 <<
"The values " << arg1 <<
" and " << arg2
541 <<
" do not form a valid range.");
620 match(
const std::string &test_string)
const override;
634 virtual std::unique_ptr<PatternBase>
635 clone()
const override;
642 static std::unique_ptr<Map>
687 <<
"The values " << arg1 <<
" and " << arg2
688 <<
" do not form a valid range.");
783 Tuple(
const std::vector<std::unique_ptr<PatternBase>> &
patterns,
791 Tuple(
const std::vector<std::unique_ptr<PatternBase>> &
patterns,
802 template <
class... PatternTypes>
812 template <
class... PatternTypes>
833 match(
const std::string &test_string)
const override;
847 virtual std::unique_ptr<PatternBase>
848 clone()
const override;
855 static std::unique_ptr<Tuple>
881 std::vector<std::unique_ptr<PatternBase>>
patterns;
918 match(
const std::string &test_string)
const override;
933 virtual std::unique_ptr<PatternBase>
934 clone()
const override;
941 static std::unique_ptr<MultipleSelection>
962 <<
"A comma was found at position " << arg1
963 <<
" of your input string, but commas are not allowed here.");
1002 virtual std::unique_ptr<PatternBase>
1003 clone()
const override;
1010 static std::unique_ptr<Bool>
1037 match(
const std::string &test_string)
const override;
1051 virtual std::unique_ptr<PatternBase>
1052 clone()
const override;
1059 static std::unique_ptr<Anything>
1114 match(
const std::string &test_string)
const override;
1128 virtual std::unique_ptr<PatternBase>
1129 clone()
const override;
1141 static std::unique_ptr<FileName>
1177 match(
const std::string &test_string)
const override;
1191 virtual std::unique_ptr<PatternBase>
1192 clone()
const override;
1199 static std::unique_ptr<DirectoryName>
1299 template <
class T,
class Enable =
void>
1311 static std::unique_ptr<Patterns::PatternBase>
1362 template <
typename T>
1391 template <
typename T>
1406 <<
"The string \"" << arg1
1407 <<
"\" does not match the pattern \"" << arg2 <<
"\"");
1416 template <
class... PatternTypes>
1419 Tuple(std::string(separator), ps...)
1424 template <
class... PatternTypes>
1426 : separator(separator)
1429 "Not all of the input arguments of this function "
1430 "are derived from PatternBase");
1431 static_assert(
sizeof...(ps) > 0,
1432 "The number of PatternTypes must be greater than zero!");
1433 const auto pattern_pointers = {(
static_cast<const PatternBase *
>(&ps))...};
1434 for (
const auto p : pattern_pointers)
1440 template <
class... PatternTypes>
1443 Tuple(std::string(
":"), ps...)
1476 template <
class T,
class Enable =
void>
1486 struct Convert<
T, std::enable_if_t<std::is_arithmetic<T>::value>>
1488 template <
typename Dummy = T>
1489 static std::enable_if_t<std::is_same<Dummy, T>::value &&
1490 std::is_same<T, bool>::value,
1491 std::unique_ptr<Patterns::PatternBase>>
1494 return std::make_unique<Patterns::Bool>();
1497 template <
typename Dummy = T>
1498 static std::enable_if_t<std::is_same<Dummy, T>::value &&
1499 !std::is_same<T, bool>::value &&
1500 std::is_integral<T>::value,
1501 std::unique_ptr<Patterns::PatternBase>>
1504 return std::make_unique<Patterns::Integer>(
1508 template <
typename Dummy = T>
1509 static std::enable_if_t<std::is_same<Dummy, T>::value &&
1510 !std::is_same<T, bool>::value &&
1511 std::is_floating_point<T>::value,
1512 std::unique_ptr<Patterns::PatternBase>>
1515 return std::make_unique<Patterns::Double>(
1523 std::stringstream str;
1524 if (std::is_same<T, unsigned char>::value ||
1525 std::is_same<T, signed char>::value || std::is_same<T, char>::value)
1526 str << static_cast<int>(value);
1527 else if (std::is_same<T, bool>::value)
1528 str << (static_cast<bool>(value) ?
"true" :
"false");
1541 if (std::is_same<T, bool>::value)
1542 value = (s ==
"true");
1545 std::istringstream is(s);
1546 if (std::is_same<T, unsigned char>::value ||
1547 std::is_same<T, signed char>::value ||
1548 std::is_same<T, char>::value)
1566 ExcMessage(
"Failed to convert from \"" + s +
"\" to the type \"" +
1567 boost::core::demangle(
typeid(
T).name()) +
"\""));
1576 {
",",
";",
"|",
"%"}};
1578 {
":",
"=",
"@",
"#"}};
1581 template <
typename T>
1584 template <
typename... Args>
1587 template <
typename... Args>
1590 template <
typename... Args>
1593 template <
typename... Args>
1596 template <
typename... Args>
1599 template <
typename... Args>
1602 template <
typename... Args>
1607 template <
typename T>
1610 template <
class Key,
class T,
class Compare,
class Allocator>
1614 template <
class Key,
class T,
class Compare,
class Allocator>
1618 template <
class Key,
class T,
class Hash,
class KeyEqual,
class Allocator>
1620 std::unordered_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type
1622 template <
class Key,
class T,
class Hash,
class KeyEqual,
class Allocator>
1624 std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>>
1631 template <
typename T>
1638 template <
typename T>
1655 template <
class T1,
class T2,
class... Types>
1670 template <
class T1,
class T2,
class... Types>
1679 struct RankInfo<
T, std::enable_if_t<is_list_compatible<T>::value>>
1689 struct RankInfo<
T, std::enable_if_t<is_map_compatible<T>::value>>
1692 max_list_rank<typename T::key_type, typename T::mapped_type>() + 1;
1694 max_map_rank<typename T::key_type, typename T::mapped_type>() + 1;
1698 template <
int rank,
int dim,
class Number>
1705 template <
int dim,
class Number>
1710 template <
class Number>
1734 template <
class Key,
class Value>
1744 template <
class... Types>
1752 template <
class T, std::
size_t N>
1762 struct Convert<
T, std::enable_if_t<is_list_compatible<T>::value>>
1764 static std::unique_ptr<Patterns::PatternBase>
1768 "Cannot use this class for non List-compatible types.");
1769 return std::make_unique<Patterns::List>(
1784 ExcMessage(
"I need a List pattern to convert a "
1785 "string to a List type."));
1786 auto base_p = p->get_base_pattern().clone();
1787 std::vector<std::string> vec(t.size());
1790 t.cbegin(), t.cend(), vec.begin(), [&base_p](
const auto &entry) {
1791 return Convert<typename T::value_type>::to_string(entry, *base_p);
1797 for (
unsigned int i = 1; i < vec.size(); ++i)
1798 s += p->get_separator() +
" " + vec[i];
1812 ExcMessage(
"I need a List pattern to convert a string "
1813 "to a List type."));
1815 auto base_p = p->get_base_pattern().clone();
1819 for (
const auto &str : v)
1829 struct Convert<
T, std::enable_if_t<is_map_compatible<T>::value>>
1831 static std::unique_ptr<Patterns::PatternBase>
1835 "Cannot use this class for non List-compatible types.");
1837 "Cannot use this class for non Map-compatible types.");
1838 return std::make_unique<Patterns::Map>(
1855 ExcMessage(
"I need a Map pattern to convert a string to "
1856 "a Map compatible type."));
1857 auto key_p = p->get_key_pattern().clone();
1858 auto val_p = p->get_value_pattern().clone();
1859 std::vector<std::string> vec(t.size());
1862 for (
const auto &ti : t)
1865 p->get_key_value_separator() +
1871 for (
unsigned int i = 1; i < vec.size(); ++i)
1872 s += p->get_separator() +
" " + vec[i];
1886 ExcMessage(
"I need a Map pattern to convert a "
1887 "string to a Map compatible type."));
1889 auto key_p = p->get_key_pattern().clone();
1890 auto val_p = p->get_value_pattern().clone();
1894 for (
const auto &str : v)
1899 t.insert(std::make_pair(
1909 template <
class ValueType, std::
size_t N>
1912 using T = std::array<ValueType, N>;
1914 static std::unique_ptr<Patterns::PatternBase>
1918 "Cannot use this class for non List-compatible types.");
1919 return std::make_unique<Patterns::List>(
1934 ExcMessage(
"I need a List pattern to convert a "
1935 "string to a std::array."));
1936 auto base_p = p->get_base_pattern().clone();
1937 std::vector<std::string> vec(t.size());
1940 t.cbegin(), t.cend(), vec.begin(), [&base_p](
const auto &entry) {
1941 return Convert<typename T::value_type>::to_string(entry, *base_p);
1947 for (
unsigned int i = 1; i < vec.size(); ++i)
1948 s += p->get_separator() +
" " + vec[i];
1962 ExcMessage(
"I need a List pattern to convert a string "
1963 "to a std::array."));
1965 auto base_p = p->get_base_pattern().clone();
1970 for (
unsigned int i = 0; i <
N; ++i)
1977 template <
int rank,
int dim,
class Number>
1981 static std::unique_ptr<Patterns::PatternBase>
1985 "Cannot use this class for non List-compatible types.");
1986 return std::make_unique<Patterns::List>(
2001 ExcMessage(
"I need a List pattern to convert a string "
2002 "to a List compatible type."));
2003 auto base_p = p->get_base_pattern().clone();
2004 std::vector<std::string> vec(dim);
2006 for (
unsigned int i = 0; i < dim; ++i)
2012 for (
unsigned int i = 1; i < vec.size(); ++i)
2013 s += p->get_separator() +
" " + vec[i];
2027 ExcMessage(
"I need a List pattern to convert a string "
2028 "to a List compatible type."));
2030 auto base_p = p->get_base_pattern().clone();
2035 for (
const auto &str : v)
2043 template <
int dim,
class Number>
2048 static std::unique_ptr<Patterns::PatternBase>
2073 struct Convert<std::unique_ptr<FunctionParser<dim>>>
2075 using T = std::unique_ptr<FunctionParser<dim>>;
2077 static std::unique_ptr<Patterns::PatternBase>
2081 "Cannot use this class for non List-compatible types.");
2083 return std::make_unique<Patterns::List>(
2098 ExcMessage(
"I need a List pattern to convert a string "
2099 "to a List compatible type."));
2101 const auto &expressions = t->get_expressions();
2102 if (expressions.size() == 0)
2103 return std::string();
2105 std::string s = expressions[0];
2106 for (
unsigned int i = 1; i < expressions.size(); ++i)
2107 s = s + p->get_separator() + expressions[i];
2121 ExcMessage(
"I need a List pattern to convert a string "
2122 "to a List compatible type."));
2124 const auto expressions =
2127 T t = std::make_unique<FunctionParser<dim>>(expressions.size());
2128 const std::string var =
2131 t->initialize(var, expressions, constants,
true);
2142 static std::unique_ptr<Patterns::PatternBase>
2153 std::vector<bool> mask(t.
size());
2154 for (
unsigned int i = 0; i < t.
size(); ++i)
2170 template <
class Number>
2173 using T = std::complex<Number>;
2175 static std::unique_ptr<Patterns::PatternBase>
2179 "Cannot use this class for non List-compatible types.");
2180 return std::make_unique<Patterns::List>(
2195 ExcMessage(
"I need a List pattern to convert a string "
2196 "to a List compatible type."));
2198 auto base_p = p->get_base_pattern().clone();
2201 p->get_separator() +
" " +
2219 ExcMessage(
"I need a List pattern to convert a string "
2220 "to a List compatible type."));
2222 auto base_p = p->get_base_pattern().clone();
2236 using T = std::string;
2238 static std::unique_ptr<Patterns::PatternBase>
2241 return std::make_unique<Patterns::Anything>();
2263 template <
class Key,
class Value>
2266 using T = std::pair<Key, Value>;
2268 static std::unique_ptr<Patterns::PatternBase>
2272 "Cannot use this class for non Map-compatible types.");
2273 return std::make_unique<Patterns::Tuple>(
2284 std::tuple<Key, Value> m(t);
2294 std::tuple<Key, Value> m;
2296 return std::make_pair(std::get<0>(m), std::get<1>(m));
2301 template <
class... Args>
2304 using T = std::tuple<Args...>;
2306 static std::unique_ptr<Patterns::PatternBase>
2310 "Cannot use this class for non tuple-compatible types.");
2311 return std::make_unique<Patterns::Tuple>(
2323 ExcMessage(
"I need a Tuple pattern to convert a tuple "
2328 for (
unsigned int i = 0; i < string_array.size(); ++i)
2330 (i != 0u ?
" " + p->get_separator() +
" " :
"") + string_array[i];
2343 ExcMessage(
"I need a Tuple pattern to convert a string "
2344 "to a tuple type."));
2352 template <std::size_t...
U>
2353 static std::array<std::string, std::tuple_size<T>::value>
2356 std::index_sequence<U...>)
2358 std::array<std::string, std::tuple_size<T>::value> a = {
2364 static std::array<std::string, std::tuple_size<T>::value>
2368 t, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2371 template <std::size_t...
U>
2375 std::index_sequence<U...>)
2377 return std::make_tuple(
2387 s, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2392 template <
typename T>
2400 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::string description(const OutputStyle style=Machine) const =0
virtual std::unique_ptr< PatternBase > clone() 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
Tuple(const std::vector< std::unique_ptr< PatternBase >> &patterns, const std::string &separator=":")
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
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_DISABLE_EXTRA_DIAGNOSTICS
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
__global__ void set(Number *val, const Number s, const size_type N)
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 & ExcInvalidRange(int arg1, int arg2)
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=",")
void transform(const InputIterator &begin_in, const InputIterator &end_in, OutputIterator out, const Predicate &predicate, const unsigned int grainsize)