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> 47 #include <type_traits> 48 #include <unordered_map> 49 #include <unordered_set> 91 match(
const std::string &test_string)
const = 0;
133 virtual std::unique_ptr<PatternBase>
158 std::unique_ptr<PatternBase>
219 const int upper_bound = max_int_value);
226 match(
const std::string &test_string)
const override;
241 virtual std::unique_ptr<PatternBase>
242 clone()
const override;
249 static std::unique_ptr<Integer>
315 const double upper_bound = max_double_value);
322 match(
const std::string &test_string)
const override;
337 virtual std::unique_ptr<PatternBase>
338 clone()
const override;
347 static std::unique_ptr<Double>
396 match(
const std::string &test_string)
const override;
411 virtual std::unique_ptr<PatternBase>
412 clone()
const override;
426 static std::unique_ptr<Selection>
427 create(
const std::string &description);
469 const unsigned int min_elements = 0,
470 const unsigned int max_elements = max_int_value,
471 const std::string &separator =
",");
478 get_separator()
const;
484 get_base_pattern()
const;
496 match(
const std::string &test_string)
const override;
510 virtual std::unique_ptr<PatternBase>
511 clone()
const override;
518 static std::unique_ptr<List>
539 <<
"The values " << arg1 <<
" and " << arg2
540 <<
" do not form a valid range.");
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 =
":");
619 match(
const std::string &test_string)
const override;
633 virtual std::unique_ptr<PatternBase>
634 clone()
const override;
641 static std::unique_ptr<Map>
655 get_key_pattern()
const;
661 get_value_pattern()
const;
667 get_separator()
const;
673 get_key_value_separator()
const;
686 <<
"The values " << arg1 <<
" and " << arg2
687 <<
" do not form a valid range.");
782 Tuple(
const std::vector<std::unique_ptr<PatternBase>> &patterns,
783 const std::string & separator =
":");
790 Tuple(
const std::vector<std::unique_ptr<PatternBase>> &patterns,
791 const char * separator);
801 template <
class... PatternTypes>
802 Tuple(
const std::string &separator,
const PatternTypes &... patterns);
811 template <
class... PatternTypes>
812 Tuple(
const char *separator,
const PatternTypes &... patterns);
820 Tuple(
const Patterns &... patterns);
825 Tuple(
const Tuple &other);
832 match(
const std::string &test_string)
const override;
846 virtual std::unique_ptr<PatternBase>
847 clone()
const override;
854 static std::unique_ptr<Tuple>
855 create(
const std::string &description);
868 get_pattern(
const unsigned int i)
const;
874 get_separator()
const;
880 std::vector<std::unique_ptr<PatternBase>>
patterns;
917 match(
const std::string &test_string)
const override;
932 virtual std::unique_ptr<PatternBase>
933 clone()
const override;
940 static std::unique_ptr<MultipleSelection>
941 create(
const std::string &description);
961 <<
"A comma was found at position " << arg1
962 <<
" of your input string, but commas are not allowed here.");
1001 virtual std::unique_ptr<PatternBase>
1002 clone()
const override;
1009 static std::unique_ptr<Bool>
1010 create(
const std::string &description);
1036 match(
const std::string &test_string)
const override;
1050 virtual std::unique_ptr<PatternBase>
1051 clone()
const override;
1058 static std::unique_ptr<Anything>
1059 create(
const std::string &description);
1113 match(
const std::string &test_string)
const override;
1127 virtual std::unique_ptr<PatternBase>
1128 clone()
const override;
1140 static std::unique_ptr<FileName>
1176 match(
const std::string &test_string)
const override;
1190 virtual std::unique_ptr<PatternBase>
1191 clone()
const override;
1198 static std::unique_ptr<DirectoryName>
1199 create(
const std::string &description);
1298 template <
class T,
class Enable =
void>
1310 static std::unique_ptr<Patterns::PatternBase>
1311 to_pattern() =
delete;
1361 template <
typename T>
1390 template <
typename T>
1405 <<
"The string " << arg1 <<
" does not match the pattern \"" 1415 template <
class... PatternTypes>
1418 Tuple(
std::string(separator), ps...)
1423 template <
class... PatternTypes>
1425 : separator(separator)
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)
1439 template <
class... PatternTypes>
1475 template <
class T,
class Enable =
void>
1478 static constexpr
int list_rank = 0;
1479 static constexpr
int map_rank = 0;
1486 typename
std::enable_if<std::is_arithmetic<T>::value>::type>
1488 template <
typename Dummy = T>
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
1495 return std::make_unique<Patterns::Bool>();
1498 template <
typename Dummy = T>
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
1506 return std::make_unique<Patterns::Integer>(
1510 template <
typename Dummy = T>
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
1518 return std::make_unique<Patterns::Double>(
1526 std::stringstream str;
1527 if (std::is_same<T, unsigned char>::value ||
1528 std::is_same<T, signed char>::value || std::is_same<T, char>::value)
1529 str << static_cast<int>(value);
1530 else if (std::is_same<T, bool>::value)
1531 str << (static_cast<bool>(value) ?
"true" :
"false");
1544 if (std::is_same<T, bool>::value)
1545 value = (s ==
"true");
1548 std::istringstream is(s);
1549 if (std::is_same<T, unsigned char>::value ||
1550 std::is_same<T, signed char>::value ||
1551 std::is_same<T, char>::value)
1569 ExcMessage(
"Failed to convert from \"" + s +
"\" to the type \"" +
1570 boost::core::demangle(
typeid(
T).name()) +
"\""));
1579 {
",",
";",
"|",
"%"}};
1581 {
":",
"=",
"@",
"#"}};
1584 template <
typename T>
1587 template <
typename T, std::
size_t N>
1590 template <
typename... Args>
1593 template <
typename... Args>
1596 template <
typename... Args>
1599 template <
typename... Args>
1602 template <
typename... Args>
1605 template <
typename... Args>
1608 template <
typename... Args>
1613 template <
typename T>
1616 template <
class Key,
class T,
class Compare,
class Allocator>
1620 template <
class Key,
class T,
class Compare,
class Allocator>
1624 template <
class Key,
class T,
class Hash,
class KeyEqual,
class Allocator>
1626 std::unordered_map<Key, T, Hash, KeyEqual, Allocator>> : std::true_type
1628 template <
class Key,
class T,
class Hash,
class KeyEqual,
class Allocator>
1630 std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>>
1637 template <
typename T>
1640 static constexpr
bool const value =
1644 template <
typename T>
1647 static constexpr
bool const value =
1661 template <
class T1,
class T2,
class... Types>
1676 template <
class T1,
class T2,
class... Types>
1687 typename
std::enable_if<is_list_compatible<T>::value>::type>
1689 static constexpr
int list_rank =
1691 static constexpr
int map_rank =
1699 typename
std::enable_if<is_map_compatible<T>::value>::type>
1701 static constexpr
int list_rank =
1702 max_list_rank<typename T::key_type, typename T::mapped_type>() + 1;
1703 static constexpr
int map_rank =
1704 max_map_rank<typename T::key_type, typename T::mapped_type>() + 1;
1708 template <
int rank,
int dim,
class Number>
1715 template <
int dim,
class Number>
1720 template <
class Number>
1731 static constexpr
int list_rank = 1;
1732 static constexpr
int map_rank = 0;
1739 static constexpr
int list_rank = 1;
1740 static constexpr
int map_rank = 0;
1744 template <
class Key,
class Value>
1747 static constexpr
int list_rank =
1749 static constexpr
int map_rank =
1754 template <
class... Types>
1765 typename
std::enable_if<is_list_compatible<T>::value>::type>
1767 static std::unique_ptr<Patterns::PatternBase>
1771 "Cannot use this class for non List-compatible types.");
1772 return std::make_unique<Patterns::List>(
1787 ExcMessage(
"I need a List pattern to convert a " 1788 "string to a List type."));
1789 auto base_p = p->get_base_pattern().clone();
1790 std::vector<std::string> vec(t.size());
1793 t.cbegin(), t.cend(), vec.begin(), [&base_p](
const auto &entry) {
1800 for (
unsigned int i = 1; i < vec.size(); ++i)
1801 s += p->get_separator() +
" " + vec[i];
1815 ExcMessage(
"I need a List pattern to convert a string " 1816 "to a List type."));
1818 auto base_p = p->get_base_pattern().clone();
1822 for (
const auto &str : v)
1833 typename
std::enable_if<is_map_compatible<T>::value>::type>
1835 static std::unique_ptr<Patterns::PatternBase>
1839 "Cannot use this class for non List-compatible types.");
1841 "Cannot use this class for non Map-compatible types.");
1842 return std::make_unique<Patterns::Map>(
1859 ExcMessage(
"I need a Map pattern to convert a string to " 1860 "a Map compatible type."));
1861 auto key_p = p->get_key_pattern().clone();
1862 auto val_p = p->get_value_pattern().clone();
1863 std::vector<std::string> vec(t.size());
1866 for (
const auto &ti : t)
1869 p->get_key_value_separator() +
1875 for (
unsigned int i = 1; i < vec.size(); ++i)
1876 s += p->get_separator() +
" " + vec[i];
1890 ExcMessage(
"I need a Map pattern to convert a " 1891 "string to a Map compatible type."));
1893 auto key_p = p->get_key_pattern().clone();
1894 auto val_p = p->get_value_pattern().clone();
1898 for (
const auto &str : v)
1903 t.insert(std::make_pair(
1913 template <
int rank,
int dim,
class Number>
1917 static std::unique_ptr<Patterns::PatternBase>
1921 "Cannot use this class for non List-compatible types.");
1922 return std::make_unique<Patterns::List>(
1937 ExcMessage(
"I need a List pattern to convert a string " 1938 "to a List compatible type."));
1939 auto base_p = p->get_base_pattern().clone();
1940 std::vector<std::string> vec(dim);
1942 for (
unsigned int i = 0; i < dim; ++i)
1948 for (
unsigned int i = 1; i < vec.size(); ++i)
1949 s += p->get_separator() +
" " + vec[i];
1963 ExcMessage(
"I need a List pattern to convert a string " 1964 "to a List compatible type."));
1966 auto base_p = p->get_base_pattern().clone();
1971 for (
const auto &str : v)
1979 template <
int dim,
class Number>
1984 static std::unique_ptr<Patterns::PatternBase>
2011 using T = std::unique_ptr<FunctionParser<dim>>;
2013 static std::unique_ptr<Patterns::PatternBase>
2017 "Cannot use this class for non List-compatible types.");
2019 return std::make_unique<Patterns::List>(
2034 ExcMessage(
"I need a List pattern to convert a string " 2035 "to a List compatible type."));
2037 const auto &expressions = t->get_expressions();
2038 if (expressions.size() == 0)
2039 return std::string();
2041 std::string s = expressions[0];
2042 for (
unsigned int i = 1; i < expressions.size(); ++i)
2043 s = s + p->get_separator() + expressions[i];
2057 ExcMessage(
"I need a List pattern to convert a string " 2058 "to a List compatible type."));
2060 const auto expressions =
2063 T t = std::make_unique<FunctionParser<dim>>(expressions.size());
2064 const std::string var =
2067 t->initialize(var, expressions, constants,
true);
2078 static std::unique_ptr<Patterns::PatternBase>
2089 std::vector<bool> mask(t.
size());
2090 for (
unsigned int i = 0; i < t.
size(); ++i)
2106 template <
class Number>
2109 using T = std::complex<Number>;
2111 static std::unique_ptr<Patterns::PatternBase>
2115 "Cannot use this class for non List-compatible types.");
2116 return std::make_unique<Patterns::List>(
2131 ExcMessage(
"I need a List pattern to convert a string " 2132 "to a List compatible type."));
2134 auto base_p = p->get_base_pattern().clone();
2137 p->get_separator() +
" " +
2155 ExcMessage(
"I need a List pattern to convert a string " 2156 "to a List compatible type."));
2158 auto base_p = p->get_base_pattern().clone();
2172 using T = std::string;
2174 static std::unique_ptr<Patterns::PatternBase>
2177 return std::make_unique<Patterns::Anything>();
2199 template <
class Key,
class Value>
2202 using T = std::pair<Key, Value>;
2204 static std::unique_ptr<Patterns::PatternBase>
2208 "Cannot use this class for non Map-compatible types.");
2209 return std::make_unique<Patterns::Tuple>(
2220 std::tuple<Key, Value> m(t);
2230 std::tuple<Key, Value> m;
2232 return std::make_pair(std::get<0>(m), std::get<1>(m));
2237 template <
class... Args>
2240 using T = std::tuple<Args...>;
2242 static std::unique_ptr<Patterns::PatternBase>
2246 "Cannot use this class for non tuple-compatible types.");
2247 return std::make_unique<Patterns::Tuple>(
2259 ExcMessage(
"I need a Tuple pattern to convert a tuple " 2264 for (
unsigned int i = 0; i < string_array.size(); ++i)
2265 str += (i ?
" " + p->get_separator() +
" " :
"") + string_array[i];
2278 ExcMessage(
"I need a Tuple pattern to convert a string " 2279 "to a tuple type."));
2287 template <std::size_t...
U>
2288 static std::array<std::string, std::tuple_size<T>::value>
2291 std::index_sequence<U...>)
2293 std::array<std::string, std::tuple_size<T>::value> a = {
2299 static std::array<std::string, std::tuple_size<T>::value>
2303 t, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2306 template <std::size_t...
U>
2310 std::index_sequence<U...>)
2312 return std::make_tuple(
2322 s, pattern, std::make_index_sequence<std::tuple_size<T>::value>{});
2327 template <
typename T>
2335 template <
typename T>
Iterator lower_bound(Iterator first, Iterator last, const T &val)
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)
#define DeclException2(Exception2, type1, type2, outsequence)
#define AssertDimension(dim1, dim2)
std::string escape(const std::string &input, const PatternBase::OutputStyle style)
static const char * description_init
static const char * description_init
const PatternBase & get_pattern(const unsigned int i) const
const std::string separator
const std::string separator
std::unique_ptr< PatternBase > pattern
static const unsigned int max_int_value
virtual std::unique_ptr< PatternBase > clone() const =0
static const char * description_init
static const int max_int_value
#define AssertThrow(cond, exc)
const unsigned int max_elements
static const char * description_init
static ::ExceptionBase & ExcNoMatch(std::string arg1, std::string arg2)
static const int min_int_value
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
static std::string default_variable_names()
static const char * description_init
static ::ExceptionBase & ExcMessage(std::string arg1)
static const char * description_init
static const char * description_init
#define DeclException1(Exception1, type1, outsequence)
std::vector< std::unique_ptr< PatternBase > > patterns
virtual std::size_t memory_consumption() const
static const char * description_init
static const char * description_init
std::unique_ptr< PatternBase > key_pattern
#define DEAL_II_NAMESPACE_CLOSE
virtual ~PatternBase()=default
unsigned int size() const
static const double min_double_value
std::unique_ptr< PatternBase > pattern_factory(const std::string &description)
static const char * description_init
virtual bool match(const std::string &test_string) const =0
static const char * description_init
__global__ void set(Number *val, const Number s, const size_type N)
static const double max_double_value
virtual std::string description(const OutputStyle style=Machine) const =0
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
#define DEAL_II_NAMESPACE_OPEN
std::map< std::string, double > ConstMap
Tuple(const std::vector< std::unique_ptr< PatternBase >> &patterns, const std::string &separator=":")
const unsigned int min_elements
static const unsigned int max_int_value
std::unique_ptr< PatternBase > value_pattern
const std::string separator
const std::string key_value_separator
const unsigned int max_elements
T max(const T &t, const MPI_Comm &mpi_communicator)
const unsigned int min_elements