23#define BOOST_BIND_GLOBAL_PLACEHOLDERS
24#include <boost/algorithm/string.hpp>
25#include <boost/io/ios_state.hpp>
26#include <boost/property_tree/json_parser.hpp>
27#include <boost/property_tree/ptree.hpp>
28#include <boost/property_tree/xml_parser.hpp>
29#undef BOOST_BIND_GLOBAL_PLACEHOLDERS
53 mangle(
const std::string &s)
65 for (
const char c : s)
68 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
76 static const char hex[16] = {
'0',
92 u.push_back(hex[
static_cast<unsigned char>(c) / 16]);
93 u.push_back(hex[
static_cast<unsigned char>(c) % 16]);
108 for (
unsigned int i = 0; i < s.size(); ++i)
114 ExcMessage(
"Trying to demangle an invalid string."));
224 u.push_back(
static_cast<char>(c));
240 return static_cast<bool>(p.get_optional<std::string>(
"value"));
251 return static_cast<bool>(p.get_optional<std::string>(
"alias"));
262 const std::vector<std::string> &subsection_path)
264 if (subsection_path.size() > 0)
266 std::string p =
mangle(subsection_path[0]);
267 for (
unsigned int i = 1; i < subsection_path.size(); ++i)
270 p +=
mangle(subsection_path[i]);
285 const char separator,
287 boost::property_tree::ptree & tree)
295 static auto compare =
296 [](
const std::pair<std::string, boost::property_tree::ptree> &a,
297 const std::pair<std::string, boost::property_tree::ptree> &
b) {
313 return a.first <
b.first;
342 boost::property_tree::ptree &
tree_out,
349 tree_out.put_child(p.first, p.second);
353 boost::property_tree::ptree
temp;
355 if (
const auto val = p.second.get_value_optional<std::string>())
356 temp.put_value<std::string>(*val);
380 "You have chosen either no or multiple style formats. You can choose "
381 "between: PRM, Description, LaTeX, XML, JSON."));
412 const std::vector<std::string> &
sub_path,
413 const std::string & name)
const
581 ExcMessage(
"Unknown input file name extension. Supported types "
582 "are .prm, .xml, and .json."));
610 const boost::property_tree::ptree &
source,
612 const char path_separator,
613 const std::vector<std::unique_ptr<const Patterns::PatternBase>> &patterns,
617 for (
const auto &p :
source)
620 if (p.second.empty())
637 else if (p.second.get_optional<std::string>(
"value"))
645 p.second.get<std::string>(
"value"));
653 prm.
set(
demangle(p.first), p.second.get<std::string>(
"value"));
660 else if (p.second.get_optional<std::string>(
"alias"))
708 if (p.second.get_optional<std::string>(
"value"))
711 const auto temp = p.second.get<std::string>(
"value");
715 p.second.put_value<std::string>(
temp);
717 else if (p.second.get_optional<std::string>(
"alias"))
748 "called \"ParameterHandler\"."));
757 <<
" top level elements while reading\n "
758 <<
" an XML format input file, but there should be"
759 <<
" exactly one top level element.\n"
760 <<
" The top level elements are:\n";
778 const boost::property_tree::ptree &
my_entries =
799 catch (
const std::exception &e)
804 "The provided JSON file is not valid. Boost aborted with the "
805 "following assert message: \n\n" +
806 std::string(e.what())));
820 entries = std::make_unique<boost::property_tree::ptree>();
850 static_cast<unsigned int>(
patterns.size() - 1));
861 "pattern_description",
874 const std::string & entry,
875 const std::function<
void(
const std::string &)> &
action,
920 ">, but the latter does not exist."));
928 ">, but the latter does not seem to be a "
929 "parameter declaration."));
939 ExcMessage(
"You are trying to declare an alias entry <" +
941 "> but a non-alias entry already exists in this "
942 "subsection (i.e., there is either a preexisting "
943 "further subsection, or a parameter entry, with "
944 "the same name as the alias)."));
949 "You are trying to declare an alias entry <" +
alias_name +
950 "> but an alias entry already exists in this "
951 "subsection and this existing alias references a "
952 "different parameter entry. Specifically, "
953 "you are trying to reference the entry <" +
955 "> whereas the existing alias references "
965 "deprecation_status",
977 boost::property_tree::ptree());
1000 const std::vector<std::string> &
sub_path)
const
1006 boost::optional<const boost::property_tree::ptree &>
subsection(
1024 if (boost::optional<std::string> value =
entries->get_optional<std::string>(
1042 if (boost::optional<std::string> value =
entries->get_optional<std::string>(
1067 ExcMessage(
"Can't convert the parameter value <" +
1089 "Can't convert the parameter value <" +
1093 "> to an integer."));
1110 ExcMessage(
"Can't convert the parameter value <" +
1113 "> to a double precision variable."));
1134 "Can't convert the parameter value <" +
1138 "> to a double precision variable."));
1150 AssertThrow((s ==
"true") || (s ==
"false") || (s ==
"yes") || (s ==
"no"),
1151 ExcMessage(
"Can't convert the parameter value <" +
1153 "> to a boolean."));
1154 if (s ==
"true" || s ==
"yes")
1169 AssertThrow((s ==
"true") || (s ==
"false") || (s ==
"yes") || (s ==
"no"),
1170 ExcMessage(
"Can't convert the parameter value <" +
1175 "> to a boolean."));
1176 if (s ==
"true" || s ==
"yes")
1206 "pattern_description")));
1217 if (
actions.size() >= index + 1)
1230 " in map entries_set_status."));
1248 std::ostringstream s;
1249 s << std::setprecision(16);
1262 std::ostringstream s;
1301 std::vector<std::string>(),
1357 out <<
"# Listing of Parameters" << std::endl
1358 <<
"# ---------------------" << std::endl;
1362 out <<
"\\subsection{Global parameters}" << std::endl;
1363 out <<
"\\label{parameters:global}" << std::endl;
1364 out << std::endl << std::endl;
1368 out <<
"Listing of Parameters:" << std::endl << std::endl;
1378 std::vector<std::string>(),
1415 const boost::property_tree::ptree &tree,
1419 std::ostream & out)
const
1449 p.second.get<std::string>(
"value").
size());
1457 const std::string value = p.second.get<std::string>(
"value");
1465 !p.second.get<std::string>(
"documentation").
empty())
1472 const std::vector<std::string>
doc_lines =
1474 p.second.get<std::string>(
"documentation"),
1491 value != p.second.get<std::string>(
"default_value"))
1496 << p.second.get<std::string>(
"default_value");
1504 auto escape = [](
const std::string &input) {
1513 [](
const boost::property_tree::ptree::value_type &p) {
1514 return is_parameter_node(p.second) ||
1515 is_alias_node(p.second);
1519 out <<
"\\begin{itemize}" <<
'\n';
1525 const std::string value = p.second.get<std::string>(
"value");
1528 out <<
"\\item {\\it Parameter name:} {\\tt "
1529 << escape(
demangle(p.first)) <<
"}\n"
1530 <<
"\\phantomsection";
1534 std::string
label =
"parameters:";
1540 label.append(p.first);
1543 if (
label.find(
"_20") != std::string::npos)
1547 out <<
"\\label{" <<
label <<
"}\n";
1551 out <<
"\\index[prmindex]{" << escape(
demangle(p.first))
1553 out <<
"\\index[prmindexfull]{";
1555 out << escape(
path) <<
"!";
1556 out << escape(
demangle(p.first)) <<
"}\n";
1559 out <<
"{\\it Value:} " << escape(value) <<
"\n\n"
1561 <<
"{\\it Default:} "
1562 << escape(p.second.get<std::string>(
"default_value"))
1569 !p.second.get<std::string>(
"documentation").
empty())
1570 out <<
"{\\it Description:} "
1571 << p.second.get<std::string>(
"documentation") <<
"\n\n"
1578 p.second.get<
unsigned int>(
"pattern");
1582 out <<
"{\\it Possible values:} " <<
desc_str <<
'\n';
1587 const std::string
alias = p.second.get<std::string>(
"alias");
1590 out <<
"\\item {\\it Parameter name:} {\\tt "
1591 << escape(
demangle(p.first)) <<
"}\n"
1592 <<
"\\phantomsection";
1596 std::string
label =
"parameters:";
1602 label.append(p.first);
1605 if (
label.find(
"_20") != std::string::npos)
1609 out <<
"\\label{" <<
label <<
"}\n";
1613 out <<
"\\index[prmindex]{" << escape(
demangle(p.first))
1615 out <<
"\\index[prmindexfull]{";
1617 out << escape(
path) <<
"!";
1618 out << escape(
demangle(p.first)) <<
"}\n";
1622 <<
"This parameter is an alias for the parameter ``\\texttt{"
1623 << escape(
alias) <<
"}''."
1624 << (p.second.get<std::string>(
"deprecation_status") ==
1626 " Its use is deprecated." :
1631 out <<
"\\end{itemize}" <<
'\n';
1655 p.second.get<
unsigned int>(
"pattern");
1666 << description <<
'\n';
1675 p.second.get<std::string>(
"documentation").
size() != 0)
1678 <<
"(" << p.second.get<std::string>(
"documentation") <<
")"
1714 <<
"subsection " <<
demangle(p.first) <<
'\n';
1718 auto escape = [](
const std::string &input) {
1723 out <<
'\n' <<
"\\subsection{Parameters in section \\tt ";
1728 out << escape(
path) <<
"/";
1732 out <<
"\\label{parameters:";
1735 out << p.first <<
"}";
1792 out.
push(
"parameters");
1829 out <<
demangle(p.first) <<
": " << p.second.get<std::string>(
"value")
1856 if (line.find(
'#') != std::string::npos)
1857 line.erase(line.find(
'#'), std::string::npos);
1860 while (line.find(
'\t') != std::string::npos)
1861 line.replace(line.find(
'\t'), 1,
" ");
1867 if (line.size() == 0)
1876 line.erase(0, std::string(
"subsection").size() + 1);
1895 while ((line.size() > 0) && ((std::isspace(line[0])) != 0))
1902 "Invalid content after 'end' or 'END' statement."));
1906 "There is no subsection to leave here."));
1916 std::string::size_type
pos = line.find(
'=');
1918 pos != std::string::npos,
1921 "Invalid format of 'set' or 'SET' statement."));
1925 std::string entry_value =
1934 "deprecation_status") ==
"true")
1938 <<
">: You are using the deprecated spelling <"
1939 << entry_name <<
"> of the parameter <"
1942 <<
">." << std::endl;
1956 if (entry_value.find(
'{') == std::string::npos)
1980 if (
actions.size() >= index + 1)
1991 std::pair<bool, bool>(
map_iter->second.first,
true);
1995 " in map entries_set_status."));
2003 (
"No entry with name <" + entry_name +
2004 "> was declared in the current subsection.")));
2013 while ((line.size() > 0) && (line[0] ==
' '))
2020 "The current line is an 'include' or "
2021 "'INCLUDE' statement, but it does not "
2022 "name a file for inclusion."));
2024 std::ifstream input(line.c_str());
2041 "could not be parsed: please check to "
2042 "make sure that the file is not missing a "
2043 "'set', 'include', 'subsection', or 'end' "
2066 if (
patterns[
j]->description() !=
prm2.patterns[
j]->description())
2076 std::ostringstream
o1,
o2;
2079 return (
o1.str() ==
o2.str());
2084std::set<std::string>
2090 if (
it.second.first ==
true &&
it.second.second ==
false)
2104 if (entries_wrongly_not_set.size() > 0)
2114 "Not all entries of the parameter handler that were declared with "
2115 "`has_to_be_set = true` have been set. The following parameters " +
2117 " have not been set. "
2118 "A possible reason might be that you did not add these parameter to "
2119 "the input file or that their spelling is not correct."));
2183 std::cerr <<
" The entry value" << std::endl
2185 <<
" for the entry named" << std::endl
2187 <<
" does not have the right number of entries for the "
2190 <<
" variant runs that will be performed." << std::endl;
2197 for (
unsigned int i = 0; i <
n_branches; ++i)
2215 const std::string value = p.second.get<std::string>(
"value");
2216 if (value.find(
'{') != std::string::npos)
2239 std::vector<Entry>::iterator
choice;
2245 std::string entry_value;
2253 <<
"The given array for entry <" <<
choice->entry_name
2254 <<
"> does not contain enough elements! Taking empty string instead."
2295 const std::string &
Name,
2296 const std::string &
Value)
2297 : subsection_path(
ssp)
2299 , entry_value(
Value)
2300 , type(
Entry::array)
2312 std::string
prefix(entry_value, 0, entry_value.find(
'{'));
2314 entry_value.find(
'{') + 1,
2315 entry_value.rfind(
'}') - entry_value.find(
'{') - 1);
2316 std::string
postfix(entry_value,
2317 entry_value.rfind(
'}') + 1,
2327 while (std::isspace(
multiple[0]) != 0)
2329 while (std::isspace(
multiple.back()) != 0)
2333 while (
multiple.find(
" |") != std::string::npos)
2335 while (
multiple.find(
"| ") != std::string::npos)
2338 while (
multiple.find(
'|') != std::string::npos)
2340 different_values.push_back(
2349 if ((entry_value.find(
"{{") != std::string::npos) &&
2350 (entry_value.find(
"}}") != std::string::npos))
value_type * data() const noexcept
void push(const std::string &text)
void split_different_values()
std::size_t memory_consumption() const
void init_branches_current_section()
void fill_entry_values(const unsigned int run_no)
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="", const bool skip_undefined=false) override
std::size_t memory_consumption() const
std::vector< Entry > multiple_choices
static const char path_separator
std::size_t memory_consumption() const
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="", const bool skip_undefined=false)
virtual void parse_input_from_xml(std::istream &input, const bool skip_undefined=false)
std::string get_current_path() const
std::vector< std::unique_ptr< const Patterns::PatternBase > > patterns
std::ostream & print_parameters(std::ostream &out, const OutputStyle style) const
void recursively_print_parameters(const boost::property_tree::ptree &tree, const std::vector< std::string > &target_subsection_path, const ParameterHandler::OutputStyle style, const unsigned int indent_level, std::ostream &out) const
void add_action(const std::string &entry, const std::function< void(const std::string &value)> &action, const bool execute_action=true)
long int get_integer(const std::string &entry_string) const
bool get_bool(const std::string &entry_name) const
void declare_entry(const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation="", const bool has_to_be_set=false)
virtual void parse_input_from_string(const std::string &s, const std::string &last_line="", const bool skip_undefined=false)
std::string get(const std::string &entry_string) const
std::set< std::string > get_entries_wrongly_not_set() const
void set(const std::string &entry_name, const std::string &new_value)
void log_parameters(LogStream &out, const OutputStyle style=DefaultStyle)
std::map< std::string, std::pair< bool, bool > > entries_set_status
std::string get_current_full_path(const std::string &name) const
std::vector< std::function< void(const std::string &)> > actions
void log_parameters_section(LogStream &out, const OutputStyle style=DefaultStyle)
std::unique_ptr< boost::property_tree::ptree > entries
bool subsection_path_exists(const std::vector< std::string > &sub_path) const
void scan_line(std::string line, const std::string &input_filename, const unsigned int current_line_n, const bool skip_undefined)
double get_double(const std::string &entry_name) const
void declare_alias(const std::string &existing_entry_name, const std::string &alias_name, const bool alias_is_deprecated=false)
bool operator==(const ParameterHandler &prm2) const
std::vector< std::string > subsection_path
void enter_subsection(const std::string &subsection)
void assert_that_entries_have_been_set() const
virtual void parse_input_from_json(std::istream &input, const bool skip_undefined=false)
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
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNoSubsection(int arg1, std::string arg2, std::string arg3)
static ::ExceptionBase & ExcCannotOpenIncludeStatementFile(int arg1, std::string arg2, std::string arg3)
static ::ExceptionBase & ExcFileNotFound(std::string arg1, std::string arg2)
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcAlreadyAtTopLevel()
static ::ExceptionBase & ExcInvalidEntryForPattern(int arg1, std::string arg2, std::string arg3, std::string arg4, std::string arg5)
static ::ExceptionBase & ExcEntryUndeclared(std::string arg1)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcValueDoesNotMatchPattern(std::string arg1, std::string arg2)
static ::ExceptionBase & ExcUnbalancedSubsections(std::string arg1, std::string arg2)
static ::ExceptionBase & ExcCannotParseLine(int arg1, std::string arg2, std::string arg3)
static ::ExceptionBase & ExcInvalidXMLParameterFile()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::enable_if_t< std::is_fundamental< T >::value, std::size_t > memory_consumption(const T &t)
std::string escape(const std::string &input, const PatternBase::OutputStyle style)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
std::string replace_in_string(const std::string &input, const std::string &from, const std::string &to)
std::vector< std::string > break_text_into_lines(const std::string &original_text, const unsigned int width, const char delimiter=' ')
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
bool match_at_string_start(const std::string &name, const std::string &pattern)
double string_to_double(const std::string &s)
std::string trim(const std::string &input)
int string_to_int(const std::string &s)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)