]> https://gitweb.dealii.org/ - dealii.git/commitdiff
ParameterHandler can now print in unsorted order 9263/head
authorPasquale Africa <pasqualeclaudio.africa@polimi.it>
Tue, 21 Jan 2020 23:23:00 +0000 (23:23 +0000)
committerPasquale Africa <pasqualeclaudio.africa@polimi.it>
Tue, 28 Jan 2020 09:14:44 +0000 (09:14 +0000)
15 files changed:
doc/news/changes/minor/20200128PasqualeClaudioAfrica [new file with mode: 0644]
include/deal.II/base/parameter_handler.h
source/base/parameter_handler.cc
tests/parameter_handler/multiple_parameter_loop_01.output
tests/parameter_handler/multiple_parameter_loop_02.output
tests/parameter_handler/parameter_acceptor_02.output
tests/parameter_handler/parameter_acceptor_05.output
tests/parameter_handler/parameter_handler_3_with_sorting_01.cc [new file with mode: 0644]
tests/parameter_handler/parameter_handler_3_with_sorting_01.output [new file with mode: 0644]
tests/parameter_handler/parameter_handler_read_json.output
tests/parameter_handler/parameter_handler_read_xml.output
tests/parameter_handler/parameter_handler_write_json.output
tests/parameter_handler/parameter_handler_write_section_xml.output
tests/parameter_handler/parameter_handler_write_xml.output
tests/parameter_handler/patterns_06.output

diff --git a/doc/news/changes/minor/20200128PasqualeClaudioAfrica b/doc/news/changes/minor/20200128PasqualeClaudioAfrica
new file mode 100644 (file)
index 0000000..22baa23
--- /dev/null
@@ -0,0 +1,4 @@
+Improved: ParameterHandler class can now optionally print parameters in the same
+order as they are declared, rather than sorted in alphabetical order.
+<br>
+(Pasquale Claudio Africa, 2020/01/28)
index 8f48ddb11601cfbbfd642d22498d628393e94520..cc6efd571526adcb840a165c5ac028c82278cb1a 100644 (file)
@@ -842,6 +842,7 @@ class MultipleParameterLoop;
  * @author Alberto Sartori, 2015
  * @author David Wells, 2016
  * @author Denis Davydov, 2018
+ * @author Pasquale Claudio Africa, 2020
  */
 class ParameterHandler : public Subscriptor
 {
@@ -1332,10 +1333,15 @@ public:
   void
   set(const std::string &entry_name, const bool new_value);
 
-
   /**
    * Print all parameters with the given style to <tt>out</tt>.
    *
+   * Before printing, all current parameters and subsections are sorted
+   * alphabetically by default.
+   * This behavior can be disabled setting the last parameter @p sort_alphabetical
+   * to @p false: in this case entries are printed in the same order
+   * as they have been declared.
+   *
    * In <tt>Text</tt> format, the output is formatted in such a way that it is
    * possible to use it for later input again. This is most useful to record
    * the parameters for a specific run, since if you output the parameters
@@ -1393,7 +1399,9 @@ public:
    * @endcode
    */
   std::ostream &
-  print_parameters(std::ostream &out, const OutputStyle style) const;
+  print_parameters(std::ostream &    out,
+                   const OutputStyle style,
+                   const bool        sort_alphabetical = true) const;
 
   /**
    * Print out the parameters of the present subsection as given by the
@@ -1406,6 +1414,12 @@ public:
    * to get a valid XML document and output starts with one root element
    * <tt>ParameterHandler</tt>.
    *
+   * Before printing, all parameters and subsections of the present subsection
+   * are sorted alphabetically by default.
+   * This behavior can be disabled setting the last parameter @p sort_alphabetical
+   * to @p false: in this case entries are printed in the same order
+   * as they have been declared.
+   *
    * In most cases, you will not want to use this function directly, but have
    * it called recursively by the previous function.
    *
@@ -1417,15 +1431,22 @@ public:
   print_parameters_section(std::ostream &     out,
                            const OutputStyle  style,
                            const unsigned int indent_level,
-                           const bool include_top_level_elements = false);
+                           const bool include_top_level_elements = false,
+                           const bool sort_alphabetical          = true);
 
   /**
    * Print parameters to a logstream. This function allows to print all
    * parameters into a log-file. Sections will be indented in the usual log-
    * file style.
+   *
+   * All current parameters and subsections are sorted
+   * alphabetically by default.
+   * This behavior can be disabled setting the last parameter @p sort_alphabetical
+   * to @p false: in this case entries are printed in the same order
+   * as they have been declared.
    */
   void
-  log_parameters(LogStream &out);
+  log_parameters(LogStream &out, const bool sort_alphabetical = true);
 
   /**
    * Log parameters in the present subsection. The subsection is determined by
@@ -1433,11 +1454,17 @@ public:
    * by entering and leaving subsections through the enter_subsection() and
    * leave_subsection() functions.
    *
+   * All current parameters and subsections are sorted
+   * alphabetically by default.
+   * This behavior can be disabled setting the last parameter @p sort_alphabetical
+   * to @p false: in this case entries are printed in the same order
+   * as they have been declared.
+   *
    * In most cases, you will not want to use this function directly, but have
    * it called recursively by the previous function.
    */
   void
-  log_parameters_section(LogStream &out);
+  log_parameters_section(LogStream &out, const bool sort_alphabetical = true);
 
   /**
    * Determine an estimate for the memory consumption (in bytes) of this
@@ -1694,6 +1721,16 @@ private:
             const unsigned int current_line_n,
             const bool         skip_undefined);
 
+  /**
+   * Sort all parameters of the subsection given by the
+   * @p target_subsection_path argument in alphabetical order,
+   * as well as all subsections within it recursively.
+   */
+  static void
+  recursively_sort_parameters(
+    const std::vector<std::string> &target_subsection_path,
+    boost::property_tree::ptree &   tree);
+
   /**
    * Print out the parameters of the subsection given by the
    * @p target_subsection_path argument, as well as all subsections
@@ -1707,10 +1744,11 @@ private:
    */
   void
   recursively_print_parameters(
-    const std::vector<std::string> &target_subsection_path,
-    const OutputStyle               style,
-    const unsigned int              indent_level,
-    std::ostream &                  out) const;
+    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;
 
   friend class MultipleParameterLoop;
 };
index e764da8981f5e5f16ebaeae91af4202b94bf5722..ef0b8aca96068a775694288d7a842d796610c569 100644 (file)
@@ -484,22 +484,20 @@ namespace
     const std::vector<std::unique_ptr<const Patterns::PatternBase>> &patterns,
     ParameterHandler &                                               prm)
   {
-    for (boost::property_tree::ptree::const_iterator p = source.begin();
-         p != source.end();
-         ++p)
+    for (const auto &p : source)
       {
         // a sub-tree must either be a parameter node or a subsection
-        if (p->second.get_optional<std::string>("value"))
+        if (p.second.get_optional<std::string>("value"))
           {
             // set the found parameter in the destination argument
-            prm.set(demangle(p->first), p->second.get<std::string>("value"));
+            prm.set(demangle(p.first), p.second.get<std::string>("value"));
 
             // this node might have sub-nodes in addition to "value", such as
             // "default_value", "documentation", etc. we might at some point
             // in the future want to make sure that if they exist that they
             // match the ones in the 'destination' tree
           }
-        else if (p->second.get_optional<std::string>("alias"))
+        else if (p.second.get_optional<std::string>("alias"))
           {
             // it is an alias node. alias nodes are static and there is
             // nothing to do here (but the same applies as mentioned in the
@@ -508,11 +506,11 @@ namespace
         else
           {
             // it must be a subsection
-            prm.enter_subsection(demangle(p->first));
-            read_xml_recursively(p->second,
+            prm.enter_subsection(demangle(p.first));
+            read_xml_recursively(p.second,
                                  (current_path.empty() ?
-                                    p->first :
-                                    current_path + path_separator + p->first),
+                                    p.first :
+                                    current_path + path_separator + p.first),
                                  path_separator,
                                  patterns,
                                  prm);
@@ -1009,7 +1007,6 @@ ParameterHandler::set(const std::string &entry_string, const long int new_value)
 }
 
 
-
 void
 ParameterHandler::set(const std::string &entry_string, const bool new_value)
 {
@@ -1018,14 +1015,80 @@ ParameterHandler::set(const std::string &entry_string, const bool new_value)
   set(entry_string, (new_value ? "true" : "false"));
 }
 
+void
+ParameterHandler::recursively_sort_parameters(
+  const std::vector<std::string> &target_subsection_path,
+  boost::property_tree::ptree &   tree)
+{
+  boost::property_tree::ptree &current_section =
+    tree.get_child(collate_path_string(target_subsection_path));
+
+  // Custom comparator to ensure that the order of sorting is:
+  // - sorted parameters and aliases;
+  // - sorted subsections.
+  static auto compare =
+    [](const std::pair<std::string, boost::property_tree::ptree> &a,
+       const std::pair<std::string, boost::property_tree::ptree> &b) {
+      bool a_is_param =
+        (is_parameter_node(a.second) || is_alias_node(a.second));
+
+      bool b_is_param =
+        (is_parameter_node(b.second) || is_alias_node(b.second));
+
+      // If a is a parameter/alias and b is a subsection,
+      // a should go first, and viceversa.
+      if (a_is_param && !b_is_param)
+        return true;
+
+      if (!a_is_param && b_is_param)
+        return false;
+
+      // Otherwise, compare a and b.
+      return a.first < b.first;
+    };
+
+  current_section.sort(compare);
+
+  // Now transverse subsections tree recursively.
+  for (auto &p : current_section)
+    {
+      if ((is_parameter_node(p.second) == false) &&
+          (is_alias_node(p.second) == false))
+        {
+          const std::string subsection = demangle(p.first);
+
+          std::vector<std::string> subsection_path = target_subsection_path;
+          subsection_path.emplace_back(subsection);
 
+          recursively_sort_parameters(subsection_path, tree);
+        }
+    }
+}
 
 std::ostream &
 ParameterHandler::print_parameters(std::ostream &    out,
-                                   const OutputStyle style) const
+                                   const OutputStyle style,
+                                   const bool        sort_alphabetical) const
 {
   AssertThrow(out, ExcIO());
 
+  // Create entries copy and sort it, if needed.
+  // In this way we ensure that the class state is never
+  // modified by this function.
+  boost::property_tree::ptree  sorted_entries;
+  boost::property_tree::ptree *current_entries = entries.get();
+
+  // Sort parameters alphabetically, if needed.
+  if (sort_alphabetical)
+    {
+      sorted_entries  = *entries;
+      current_entries = &sorted_entries;
+
+      // Dive recursively into the subsections,
+      // starting from the top level.
+      recursively_sort_parameters(std::vector<std::string>(), sorted_entries);
+    }
+
   // we'll have to print some text that is padded with spaces;
   // set the appropriate fill character, but also make sure that
   // we will restore the previous setting (and all other stream
@@ -1049,7 +1112,7 @@ ParameterHandler::print_parameters(std::ostream &    out,
       // single top-level node "ParameterHandler" and
       // assign the existing tree under it
       boost::property_tree::ptree single_node_tree;
-      single_node_tree.add_child("ParameterHandler", *entries);
+      single_node_tree.add_child("ParameterHandler", *current_entries);
 
       write_xml(out, single_node_tree);
       return out;
@@ -1057,7 +1120,7 @@ ParameterHandler::print_parameters(std::ostream &    out,
 
   if (style == JSON)
     {
-      write_json(out, *entries);
+      write_json(out, *current_entries);
       return out;
     }
 
@@ -1088,6 +1151,7 @@ ParameterHandler::print_parameters(std::ostream &    out,
 
   // dive recursively into the subsections
   recursively_print_parameters(
+    *current_entries,
     std::vector<std::string>(), // start at the top level
     style,
     0,
@@ -1096,22 +1160,21 @@ ParameterHandler::print_parameters(std::ostream &    out,
   return out;
 }
 
-
-
 void
 ParameterHandler::recursively_print_parameters(
-  const std::vector<std::string> &target_subsection_path,
-  const OutputStyle               style,
-  const unsigned int              indent_level,
-  std::ostream &                  out) const
+  const boost::property_tree::ptree &tree,
+  const std::vector<std::string> &   target_subsection_path,
+  const OutputStyle                  style,
+  const unsigned int                 indent_level,
+  std::ostream &                     out) const
 {
   AssertThrow(out, ExcIO());
 
   // this function should not be necessary for XML or JSON output...
   Assert((style != XML) && (style != JSON), ExcInternalError());
 
-  const boost::property_tree::ptree &current_section =
-    entries->get_child(collate_path_string(target_subsection_path));
+  const boost::property_tree::ptree &current_section = tree.get_child(
+    ParameterHandler::collate_path_string(target_subsection_path));
 
   unsigned int overall_indent_level = indent_level;
 
@@ -1129,29 +1192,22 @@ ParameterHandler::recursively_print_parameters(
           // can align the default and documentation strings
           std::size_t longest_name  = 0;
           std::size_t longest_value = 0;
-          for (boost::property_tree::ptree::const_iterator p =
-                 current_section.begin();
-               p != current_section.end();
-               ++p)
-            if (is_parameter_node(p->second) == true)
+          for (const auto &p : current_section)
+            if (is_parameter_node(p.second) == true)
               {
                 longest_name =
-                  std::max(longest_name, demangle(p->first).length());
+                  std::max(longest_name, demangle(p.first).length());
                 longest_value =
                   std::max(longest_value,
-                           p->second.get<std::string>("value").length());
+                           p.second.get<std::string>("value").length());
               }
 
-          // print entries one by one. make sure they are sorted by using
-          // the appropriate iterators
+          // print entries one by one
           bool first_entry = true;
-          for (boost::property_tree::ptree::const_assoc_iterator p =
-                 current_section.ordered_begin();
-               p != current_section.not_found();
-               ++p)
-            if (is_parameter_node(p->second) == true)
+          for (const auto &p : current_section)
+            if (is_parameter_node(p.second) == true)
               {
-                const std::string value = p->second.get<std::string>("value");
+                const std::string value = p.second.get<std::string>("value");
 
                 // if there is documentation, then add an empty line
                 // (unless this is the first entry in a subsection), print
@@ -1159,7 +1215,7 @@ ParameterHandler::recursively_print_parameters(
                 // documentation into readable chunks such that the whole
                 // thing is at most 78 characters wide
                 if ((style == Text) &&
-                    !p->second.get<std::string>("documentation").empty())
+                    !p.second.get<std::string>("documentation").empty())
                   {
                     if (first_entry == false)
                       out << '\n';
@@ -1168,7 +1224,7 @@ ParameterHandler::recursively_print_parameters(
 
                     const std::vector<std::string> doc_lines =
                       Utilities::break_text_into_lines(
-                        p->second.get<std::string>("documentation"),
+                        p.second.get<std::string>("documentation"),
                         78 - overall_indent_level * 2 - 2);
 
                     for (const auto &doc_line : doc_lines)
@@ -1180,20 +1236,20 @@ ParameterHandler::recursively_print_parameters(
 
                 // print name and value of this entry
                 out << std::setw(overall_indent_level * 2) << ""
-                    << "set " << demangle(p->first)
-                    << std::setw(longest_name - demangle(p->first).length() + 1)
+                    << "set " << demangle(p.first)
+                    << std::setw(longest_name - demangle(p.first).length() + 1)
                     << " "
                     << "= " << value;
 
                 // finally print the default value, but only if it differs
                 // from the actual value
                 if ((style == Text) &&
-                    value != p->second.get<std::string>("default_value"))
+                    value != p.second.get<std::string>("default_value"))
                   {
                     out << std::setw(longest_value - value.length() + 1) << ' '
                         << "# ";
                     out << "default: "
-                        << p->second.get<std::string>("default_value");
+                        << p.second.get<std::string>("default_value");
                   }
 
                 out << '\n';
@@ -1212,12 +1268,9 @@ ParameterHandler::recursively_print_parameters(
           // if there are any parameters in this section then print them
           // as an itemized list
           bool parameters_exist_here = false;
-          for (boost::property_tree::ptree::const_assoc_iterator p =
-                 current_section.ordered_begin();
-               p != current_section.not_found();
-               ++p)
-            if ((is_parameter_node(p->second) == true) ||
-                (is_alias_node(p->second) == true))
+          for (const auto &p : current_section)
+            if ((is_parameter_node(p.second) == true) ||
+                (is_alias_node(p.second) == true))
               {
                 parameters_exist_here = true;
                 break;
@@ -1227,30 +1280,27 @@ ParameterHandler::recursively_print_parameters(
             {
               out << "\\begin{itemize}" << '\n';
 
-              // print entries one by one. make sure they are sorted by
-              // using the appropriate iterators
-              for (boost::property_tree::ptree::const_assoc_iterator p =
-                     current_section.ordered_begin();
-                   p != current_section.not_found();
-                   ++p)
-                if (is_parameter_node(p->second) == true)
+              // print entries one by one
+              for (const auto &p : current_section)
+                if (is_parameter_node(p.second) == true)
                   {
                     const std::string value =
-                      p->second.get<std::string>("value");
+                      p.second.get<std::string>("value");
 
                     // print name
                     out << "\\item {\\it Parameter name:} {\\tt "
-                        << escape(demangle(p->first)) << "}\n"
+                        << escape(demangle(p.first)) << "}\n"
                         << "\\phantomsection";
                     {
-                      // create label: labels are not to be escaped but mangled
+                      // create label: labels are not to be escaped but
+                      // mangled
                       std::string label = "parameters:";
                       for (const auto &path : target_subsection_path)
                         {
                           label.append(mangle(path));
                           label.append("/");
                         }
-                      label.append(p->first);
+                      label.append(p.first);
                       // Backwards-compatibility. Output the label with and
                       // without escaping whitespace:
                       if (label.find("_20") != std::string::npos)
@@ -1261,56 +1311,57 @@ ParameterHandler::recursively_print_parameters(
                     }
                     out << "\n\n";
 
-                    out << "\\index[prmindex]{" << escape(demangle(p->first))
+                    out << "\\index[prmindex]{" << escape(demangle(p.first))
                         << "}\n";
                     out << "\\index[prmindexfull]{";
                     for (const auto &path : target_subsection_path)
                       out << escape(path) << "!";
-                    out << escape(demangle(p->first)) << "}\n";
+                    out << escape(demangle(p.first)) << "}\n";
 
                     // finally print value and default
                     out << "{\\it Value:} " << escape(value) << "\n\n"
                         << '\n'
                         << "{\\it Default:} "
-                        << escape(p->second.get<std::string>("default_value"))
+                        << escape(p.second.get<std::string>("default_value"))
                         << "\n\n"
                         << '\n';
 
                     // if there is a documenting string, print it as well but
                     // don't escape to allow formatting/formulas
-                    if (!p->second.get<std::string>("documentation").empty())
+                    if (!p.second.get<std::string>("documentation").empty())
                       out << "{\\it Description:} "
-                          << p->second.get<std::string>("documentation")
+                          << p.second.get<std::string>("documentation")
                           << "\n\n"
                           << '\n';
 
                     // also output possible values, do not escape because the
                     // description internally will use LaTeX formatting
                     const unsigned int pattern_index =
-                      p->second.get<unsigned int>("pattern");
+                      p.second.get<unsigned int>("pattern");
                     const std::string desc_str =
                       patterns[pattern_index]->description(
                         Patterns::PatternBase::LaTeX);
                     out << "{\\it Possible values:} " << desc_str << '\n';
                   }
-                else if (is_alias_node(p->second) == true)
+                else if (is_alias_node(p.second) == true)
                   {
                     const std::string alias =
-                      p->second.get<std::string>("alias");
+                      p.second.get<std::string>("alias");
 
                     // print name
                     out << "\\item {\\it Parameter name:} {\\tt "
-                        << escape(demangle(p->first)) << "}\n"
+                        << escape(demangle(p.first)) << "}\n"
                         << "\\phantomsection";
                     {
-                      // create label: labels are not to be escaped but mangled
+                      // create label: labels are not to be escaped but
+                      // mangled
                       std::string label = "parameters:";
                       for (const auto &path : target_subsection_path)
                         {
                           label.append(mangle(path));
                           label.append("/");
                         }
-                      label.append(p->first);
+                      label.append(p.first);
                       // Backwards-compatibility. Output the label with and
                       // without escaping whitespace:
                       if (label.find("_20") != std::string::npos)
@@ -1321,18 +1372,18 @@ ParameterHandler::recursively_print_parameters(
                     }
                     out << "\n\n";
 
-                    out << "\\index[prmindex]{" << escape(demangle(p->first))
+                    out << "\\index[prmindex]{" << escape(demangle(p.first))
                         << "}\n";
                     out << "\\index[prmindexfull]{";
                     for (const auto &path : target_subsection_path)
                       out << escape(path) << "!";
-                    out << escape(demangle(p->first)) << "}\n";
+                    out << escape(demangle(p.first)) << "}\n";
 
                     // finally print alias and indicate if it is deprecated
                     out
                       << "This parameter is an alias for the parameter ``\\texttt{"
                       << escape(alias) << "}''."
-                      << (p->second.get<std::string>("deprecation_status") ==
+                      << (p.second.get<std::string>("deprecation_status") ==
                               "true" ?
                             " Its use is deprecated." :
                             "")
@@ -1350,32 +1401,24 @@ ParameterHandler::recursively_print_parameters(
           // first find out the longest entry name to be able to align the
           // equal signs
           std::size_t longest_name = 0;
-          for (boost::property_tree::ptree::const_iterator p =
-                 current_section.begin();
-               p != current_section.end();
-               ++p)
-            if (is_parameter_node(p->second) == true)
-              longest_name =
-                std::max(longest_name, demangle(p->first).length());
-
-          // print entries one by one. make sure they are sorted by using
-          // the appropriate iterators
-          for (boost::property_tree::ptree::const_assoc_iterator p =
-                 current_section.ordered_begin();
-               p != current_section.not_found();
-               ++p)
-            if (is_parameter_node(p->second) == true)
+          for (const auto &p : current_section)
+            if (is_parameter_node(p.second) == true)
+              longest_name = std::max(longest_name, demangle(p.first).length());
+
+          // print entries one by one
+          for (const auto &p : current_section)
+            if (is_parameter_node(p.second) == true)
               {
                 // print name and value
                 out << std::setw(overall_indent_level * 2) << ""
-                    << "set " << demangle(p->first)
-                    << std::setw(longest_name - demangle(p->first).length() + 1)
+                    << "set " << demangle(p.first)
+                    << std::setw(longest_name - demangle(p.first).length() + 1)
                     << " "
                     << " = ";
 
                 // print possible values:
                 const unsigned int pattern_index =
-                  p->second.get<unsigned int>("pattern");
+                  p.second.get<unsigned int>("pattern");
                 const std::string full_desc_str =
                   patterns[pattern_index]->description(
                     Patterns::PatternBase::Text);
@@ -1395,10 +1438,10 @@ ParameterHandler::recursively_print_parameters(
                   out << '\n';
 
                 // if there is a documenting string, print it as well
-                if (p->second.get<std::string>("documentation").length() != 0)
+                if (p.second.get<std::string>("documentation").length() != 0)
                   out << std::setw(overall_indent_level * 2 + longest_name + 10)
                       << ""
-                      << "(" << p->second.get<std::string>("documentation")
+                      << "(" << p.second.get<std::string>("documentation")
                       << ")" << '\n';
               }
 
@@ -1415,13 +1458,10 @@ ParameterHandler::recursively_print_parameters(
   {
     unsigned int n_parameters = 0;
     unsigned int n_sections   = 0;
-    for (boost::property_tree::ptree::const_iterator p =
-           current_section.begin();
-         p != current_section.end();
-         ++p)
-      if (is_parameter_node(p->second) == true)
+    for (const auto &p : current_section)
+      if (is_parameter_node(p.second) == true)
         ++n_parameters;
-      else if (is_alias_node(p->second) == false)
+      else if (is_alias_node(p.second) == false)
         ++n_sections;
 
     if ((style != Description) && (style != ShortText) && (n_parameters != 0) &&
@@ -1429,13 +1469,10 @@ ParameterHandler::recursively_print_parameters(
       out << "\n\n";
   }
 
-  // now traverse subsections tree, in alphabetical order
-  for (boost::property_tree::ptree::const_assoc_iterator p =
-         current_section.ordered_begin();
-       p != current_section.not_found();
-       ++p)
-    if ((is_parameter_node(p->second) == false) &&
-        (is_alias_node(p->second) == false))
+  // now transverse subsections tree
+  for (const auto &p : current_section)
+    if ((is_parameter_node(p.second) == false) &&
+        (is_alias_node(p.second) == false))
       {
         // first print the subsection header
         switch (style)
@@ -1444,7 +1481,7 @@ ParameterHandler::recursively_print_parameters(
             case Description:
             case ShortText:
               out << std::setw(overall_indent_level * 2) << ""
-                  << "subsection " << demangle(p->first) << '\n';
+                  << "subsection " << demangle(p.first) << '\n';
               break;
 
             case LaTeX:
@@ -1460,13 +1497,13 @@ ParameterHandler::recursively_print_parameters(
                 // print it in the \subsection{...} heading
                 for (const auto &path : target_subsection_path)
                   out << escape(path) << "/";
-                out << escape(demangle(p->first));
+                out << escape(demangle(p.first));
 
                 out << "}" << '\n';
                 out << "\\label{parameters:";
                 for (const auto &path : target_subsection_path)
                   out << mangle(path) << "/";
-                out << p->first << "}";
+                out << p.first << "}";
                 out << '\n';
 
                 out << '\n';
@@ -1478,14 +1515,12 @@ ParameterHandler::recursively_print_parameters(
           }
 
         // then the contents of the subsection
-        const std::string        subsection     = demangle(p->first);
+        const std::string        subsection     = demangle(p.first);
         std::vector<std::string> directory_path = target_subsection_path;
         directory_path.emplace_back(subsection);
 
-        recursively_print_parameters(directory_path,
-                                     style,
-                                     overall_indent_level + 1,
-                                     out);
+        recursively_print_parameters(
+          tree, directory_path, style, overall_indent_level + 1, out);
 
         switch (style)
           {
@@ -1521,8 +1556,6 @@ ParameterHandler::recursively_print_parameters(
       }
 }
 
-
-
 // Print a section in the desired style. The styles are separated into
 // several verbosity classes depending on the higher bits.
 //
@@ -1533,12 +1566,30 @@ ParameterHandler::print_parameters_section(
   std::ostream &     out,
   const OutputStyle  style,
   const unsigned int indent_level,
-  const bool         include_top_level_elements)
+  const bool         include_top_level_elements,
+  const bool         sort_alphabetical)
 {
   AssertThrow(out, ExcIO());
 
+  // Create entries copy and sort it, if needed.
+  // In this way we ensure that the class state is never
+  // modified by this function.
+  boost::property_tree::ptree  sorted_entries;
+  boost::property_tree::ptree *current_entries = entries.get();
+
+  // Sort parameters alphabetically, if needed.
+  if (sort_alphabetical)
+    {
+      sorted_entries  = *entries;
+      current_entries = &sorted_entries;
+
+      // Dive recursively into the subsections,
+      // starting from current level.
+      recursively_sort_parameters(subsection_path, sorted_entries);
+    }
+
   const boost::property_tree::ptree &current_section =
-    entries->get_child(get_current_path());
+    current_entries->get_child(get_current_path());
 
   unsigned int overall_indent_level = indent_level;
 
@@ -1564,7 +1615,8 @@ ParameterHandler::print_parameters_section(
               // subsection under it
               if (subsection_path.size() == 0)
                 {
-                  single_node_tree.add_child("ParameterHandler", *entries);
+                  single_node_tree.add_child("ParameterHandler",
+                                             *current_entries);
                 }
               else
                 {
@@ -1601,37 +1653,26 @@ ParameterHandler::print_parameters_section(
           // tree, select the parameter nodes (and discard sub-tree nodes)
           // and take the maximum of their lengths
           std::size_t longest_name = 0;
-          for (boost::property_tree::ptree::const_iterator p =
-                 current_section.begin();
-               p != current_section.end();
-               ++p)
-            if (is_parameter_node(p->second) == true)
-              longest_name =
-                std::max(longest_name, demangle(p->first).length());
+          for (const auto &p : current_section)
+            if (is_parameter_node(p.second) == true)
+              longest_name = std::max(longest_name, demangle(p.first).length());
 
           // likewise find the longest actual value string to make sure we
           // can align the default and documentation strings
           std::size_t longest_value = 0;
-          for (boost::property_tree::ptree::const_iterator p =
-                 current_section.begin();
-               p != current_section.end();
-               ++p)
-            if (is_parameter_node(p->second) == true)
+          for (const auto &p : current_section)
+            if (is_parameter_node(p.second) == true)
               longest_value =
                 std::max(longest_value,
-                         p->second.get<std::string>("value").length());
+                         p.second.get<std::string>("value").length());
 
 
-          // print entries one by one. make sure they are sorted by using
-          // the appropriate iterators
+          // print entries one by one
           bool first_entry = true;
-          for (boost::property_tree::ptree::const_assoc_iterator p =
-                 current_section.ordered_begin();
-               p != current_section.not_found();
-               ++p)
-            if (is_parameter_node(p->second) == true)
+          for (const auto &p : current_section)
+            if (is_parameter_node(p.second) == true)
               {
-                const std::string value = p->second.get<std::string>("value");
+                const std::string value = p.second.get<std::string>("value");
 
                 // if there is documentation, then add an empty line
                 // (unless this is the first entry in a subsection), print
@@ -1639,7 +1680,7 @@ ParameterHandler::print_parameters_section(
                 // documentation into readable chunks such that the whole
                 // thing is at most 78 characters wide
                 if ((!(style & 128)) &&
-                    !p->second.get<std::string>("documentation").empty())
+                    !p.second.get<std::string>("documentation").empty())
                   {
                     if (first_entry == false)
                       out << std::endl;
@@ -1648,7 +1689,7 @@ ParameterHandler::print_parameters_section(
 
                     const std::vector<std::string> doc_lines =
                       Utilities::break_text_into_lines(
-                        p->second.get<std::string>("documentation"),
+                        p.second.get<std::string>("documentation"),
                         78 - overall_indent_level * 2 - 2);
 
                     for (const auto &doc_line : doc_lines)
@@ -1660,20 +1701,20 @@ ParameterHandler::print_parameters_section(
 
                 // print name and value of this entry
                 out << std::setw(overall_indent_level * 2) << ""
-                    << "set " << demangle(p->first)
-                    << std::setw(longest_name - demangle(p->first).length() + 1)
+                    << "set " << demangle(p.first)
+                    << std::setw(longest_name - demangle(p.first).length() + 1)
                     << " "
                     << "= " << value;
 
                 // finally print the default value, but only if it differs
                 // from the actual value
                 if ((!(style & 64)) &&
-                    value != p->second.get<std::string>("default_value"))
+                    value != p.second.get<std::string>("default_value"))
                   {
                     out << std::setw(longest_value - value.length() + 1) << ' '
                         << "# ";
                     out << "default: "
-                        << p->second.get<std::string>("default_value");
+                        << p.second.get<std::string>("default_value");
                   }
 
                 out << std::endl;
@@ -1692,12 +1733,9 @@ ParameterHandler::print_parameters_section(
           // if there are any parameters in this section then print them
           // as an itemized list
           bool parameters_exist_here = false;
-          for (boost::property_tree::ptree::const_assoc_iterator p =
-                 current_section.ordered_begin();
-               p != current_section.not_found();
-               ++p)
-            if ((is_parameter_node(p->second) == true) ||
-                (is_alias_node(p->second) == true))
+          for (const auto &p : current_section)
+            if ((is_parameter_node(p.second) == true) ||
+                (is_alias_node(p.second) == true))
               {
                 parameters_exist_here = true;
                 break;
@@ -1707,82 +1745,78 @@ ParameterHandler::print_parameters_section(
             {
               out << "\\begin{itemize}" << std::endl;
 
-              // print entries one by one. make sure they are sorted by
-              // using the appropriate iterators
-              for (boost::property_tree::ptree::const_assoc_iterator p =
-                     current_section.ordered_begin();
-                   p != current_section.not_found();
-                   ++p)
-                if (is_parameter_node(p->second) == true)
+              // print entries one by one
+              for (const auto &p : current_section)
+                if (is_parameter_node(p.second) == true)
                   {
                     const std::string value =
-                      p->second.get<std::string>("value");
+                      p.second.get<std::string>("value");
 
                     // print name
                     out << "\\item {\\it Parameter name:} {\\tt "
-                        << escape(demangle(p->first)) << "}\n"
+                        << escape(demangle(p.first)) << "}\n"
                         << "\\phantomsection\\label{parameters:";
                     for (const auto &path : subsection_path)
                       out << mangle(path) << "/";
-                    out << p->first;
+                    out << p.first;
                     out << "}\n\n" << std::endl;
 
-                    out << "\\index[prmindex]{" << escape(demangle(p->first))
+                    out << "\\index[prmindex]{" << escape(demangle(p.first))
                         << "}\n";
                     out << "\\index[prmindexfull]{";
                     for (const auto &path : subsection_path)
                       out << escape(path) << "!";
-                    out << escape(demangle(p->first)) << "}\n";
+                    out << escape(demangle(p.first)) << "}\n";
 
                     // finally print value and default
                     out << "{\\it Value:} " << escape(value) << "\n\n"
                         << std::endl
                         << "{\\it Default:} "
-                        << escape(p->second.get<std::string>("default_value"))
+                        << escape(p.second.get<std::string>("default_value"))
                         << "\n\n"
                         << std::endl;
 
                     // if there is a documenting string, print it as well
-                    if (!p->second.get<std::string>("documentation").empty())
+                    if (!p.second.get<std::string>("documentation").empty())
                       out << "{\\it Description:} "
-                          << p->second.get<std::string>("documentation")
+                          << p.second.get<std::string>("documentation")
                           << "\n\n"
                           << std::endl;
 
                     // also output possible values
                     const unsigned int pattern_index =
-                      p->second.get<unsigned int>("pattern");
+                      p.second.get<unsigned int>("pattern");
                     const std::string desc_str =
                       patterns[pattern_index]->description(
                         Patterns::PatternBase::LaTeX);
                     out << "{\\it Possible values:} " << desc_str << std::endl;
                   }
-                else if (is_alias_node(p->second) == true)
+                else if (is_alias_node(p.second) == true)
                   {
                     const std::string alias =
-                      p->second.get<std::string>("alias");
+                      p.second.get<std::string>("alias");
 
                     // print name
                     out << "\\item {\\it Parameter name:} {\\tt "
-                        << escape(demangle(p->first)) << "}\n"
+                        << escape(demangle(p.first)) << "}\n"
                         << "\\phantomsection\\label{parameters:";
                     for (const auto &path : subsection_path)
                       out << mangle(path) << "/";
-                    out << p->first;
+                    out << p.first;
                     out << "}\n\n" << std::endl;
 
-                    out << "\\index[prmindex]{" << escape(demangle(p->first))
+                    out << "\\index[prmindex]{" << escape(demangle(p.first))
                         << "}\n";
                     out << "\\index[prmindexfull]{";
                     for (const auto &path : subsection_path)
                       out << escape(path) << "!";
-                    out << escape(demangle(p->first)) << "}\n";
+                    out << escape(demangle(p.first)) << "}\n";
 
                     // finally print alias and indicate if it is deprecated
                     out
                       << "This parameter is an alias for the parameter ``\\texttt{"
                       << escape(alias) << "}''."
-                      << (p->second.get<std::string>("deprecation_status") ==
+                      << (p.second.get<std::string>("deprecation_status") ==
                               "true" ?
                             " Its use is deprecated." :
                             "")
@@ -1809,32 +1843,24 @@ ParameterHandler::print_parameters_section(
           // first find out the longest entry name to be able to align the
           // equal signs
           std::size_t longest_name = 0;
-          for (boost::property_tree::ptree::const_iterator p =
-                 current_section.begin();
-               p != current_section.end();
-               ++p)
-            if (is_parameter_node(p->second) == true)
-              longest_name =
-                std::max(longest_name, demangle(p->first).length());
-
-          // print entries one by one. make sure they are sorted by using
-          // the appropriate iterators
-          for (boost::property_tree::ptree::const_assoc_iterator p =
-                 current_section.ordered_begin();
-               p != current_section.not_found();
-               ++p)
-            if (is_parameter_node(p->second) == true)
+          for (const auto &p : current_section)
+            if (is_parameter_node(p.second) == true)
+              longest_name = std::max(longest_name, demangle(p.first).length());
+
+          // print entries one by one
+          for (const auto &p : current_section)
+            if (is_parameter_node(p.second) == true)
               {
                 // print name and value
                 out << std::setw(overall_indent_level * 2) << ""
-                    << "set " << demangle(p->first)
-                    << std::setw(longest_name - demangle(p->first).length() + 1)
+                    << "set " << demangle(p.first)
+                    << std::setw(longest_name - demangle(p.first).length() + 1)
                     << " "
                     << " = ";
 
                 // print possible values:
                 const unsigned int pattern_index =
-                  p->second.get<unsigned int>("pattern");
+                  p.second.get<unsigned int>("pattern");
                 const std::string full_desc_str =
                   patterns[pattern_index]->description(
                     Patterns::PatternBase::Text);
@@ -1854,10 +1880,10 @@ ParameterHandler::print_parameters_section(
                   out << std::endl;
 
                 // if there is a documenting string, print it as well
-                if (p->second.get<std::string>("documentation").length() != 0)
+                if (p.second.get<std::string>("documentation").length() != 0)
                   out << std::setw(overall_indent_level * 2 + longest_name + 10)
                       << ""
-                      << "(" << p->second.get<std::string>("documentation")
+                      << "(" << p.second.get<std::string>("documentation")
                       << ")" << std::endl;
               }
 
@@ -1875,26 +1901,20 @@ ParameterHandler::print_parameters_section(
     {
       unsigned int n_parameters = 0;
       unsigned int n_sections   = 0;
-      for (boost::property_tree::ptree::const_iterator p =
-             current_section.begin();
-           p != current_section.end();
-           ++p)
-        if (is_parameter_node(p->second) == true)
+      for (const auto &p : current_section)
+        if (is_parameter_node(p.second) == true)
           ++n_parameters;
-        else if (is_alias_node(p->second) == false)
+        else if (is_alias_node(p.second) == false)
           ++n_sections;
 
       if ((style != Description) && (!(style & 128)) && (n_parameters != 0) &&
           (n_sections != 0))
         out << std::endl << std::endl;
 
-      // now traverse subsections tree, in alphabetical order
-      for (boost::property_tree::ptree::const_assoc_iterator p =
-             current_section.ordered_begin();
-           p != current_section.not_found();
-           ++p)
-        if ((is_parameter_node(p->second) == false) &&
-            (is_alias_node(p->second) == false))
+      // now transverse subsections tree
+      for (const auto &p : current_section)
+        if ((is_parameter_node(p.second) == false) &&
+            (is_alias_node(p.second) == false))
           {
             // first print the subsection header
             switch (style)
@@ -1903,7 +1923,7 @@ ParameterHandler::print_parameters_section(
                 case Description:
                 case ShortText:
                   out << std::setw(overall_indent_level * 2) << ""
-                      << "subsection " << demangle(p->first) << std::endl;
+                      << "subsection " << demangle(p.first) << std::endl;
                   break;
                 case LaTeX:
                   {
@@ -1919,13 +1939,13 @@ ParameterHandler::print_parameters_section(
                     // print it in the \subsection{...} heading
                     for (const auto &path : subsection_path)
                       out << escape(path) << "/";
-                    out << escape(demangle(p->first));
+                    out << escape(demangle(p.first));
 
                     out << "}" << std::endl;
                     out << "\\label{parameters:";
                     for (const auto &path : subsection_path)
                       out << mangle(path) << "/";
-                    out << p->first << "}";
+                    out << p.first << "}";
                     out << std::endl;
 
                     out << std::endl;
@@ -1937,7 +1957,7 @@ ParameterHandler::print_parameters_section(
               }
 
             // then the contents of the subsection
-            enter_subsection(demangle(p->first));
+            enter_subsection(demangle(p.first));
             print_parameters_section(out, style, overall_indent_level + 1);
             leave_subsection();
             switch (style)
@@ -1999,47 +2019,53 @@ ParameterHandler::print_parameters_section(
 
 
 void
-ParameterHandler::log_parameters(LogStream &out)
+ParameterHandler::log_parameters(LogStream &out, const bool sort_alphabetical)
 {
   out.push("parameters");
   // dive recursively into the subsections
-  log_parameters_section(out);
+  log_parameters_section(out, sort_alphabetical);
 
   out.pop();
 }
 
 
-
 void
-ParameterHandler::log_parameters_section(LogStream &out)
+ParameterHandler::log_parameters_section(LogStream &out,
+                                         const bool sort_alphabetical)
 {
+  // Create entries copy and sort it, if needed.
+  // In this way we ensure that the class state is never
+  // modified by this function.
+  boost::property_tree::ptree  sorted_entries;
+  boost::property_tree::ptree *current_entries = entries.get();
+
+  // Sort parameters alphabetically, if needed.
+  if (sort_alphabetical)
+    {
+      sorted_entries  = *entries;
+      current_entries = &sorted_entries;
+
+      // Dive recursively into the subsections,
+      // starting from the current level.
+      recursively_sort_parameters(subsection_path, sorted_entries);
+    }
+
   const boost::property_tree::ptree &current_section =
-    entries->get_child(get_current_path());
+    current_entries->get_child(get_current_path());
 
-  // print entries one by
-  // one. make sure they are
-  // sorted by using the
-  // appropriate iterators
-  for (boost::property_tree::ptree::const_assoc_iterator p =
-         current_section.ordered_begin();
-       p != current_section.not_found();
-       ++p)
-    if (is_parameter_node(p->second) == true)
-      out << demangle(p->first) << ": " << p->second.get<std::string>("value")
+  // print entries one by one
+  for (const auto &p : current_section)
+    if (is_parameter_node(p.second) == true)
+      out << demangle(p.first) << ": " << p.second.get<std::string>("value")
           << std::endl;
 
   // now transverse subsections tree
-  // now traverse subsections tree,
-  // in alphabetical order
-  for (boost::property_tree::ptree::const_assoc_iterator p =
-         current_section.ordered_begin();
-       p != current_section.not_found();
-       ++p)
-    if (is_parameter_node(p->second) == false)
+  for (const auto &p : current_section)
+    if (is_parameter_node(p.second) == false)
       {
-        out.push(demangle(p->first));
-        enter_subsection(demangle(p->first));
-        log_parameters_section(out);
+        out.push(demangle(p.first));
+        enter_subsection(demangle(p.first));
+        log_parameters_section(out, sort_alphabetical);
         leave_subsection();
         out.pop();
       }
@@ -2363,31 +2389,21 @@ MultipleParameterLoop::init_branches_current_section()
   // check all entries in the present
   // subsection whether they are
   // multiple entries
-  //
-  // we loop over entries in sorted
-  // order to guarantee backward
-  // compatibility to an earlier
-  // implementation
-  for (boost::property_tree::ptree::const_assoc_iterator p =
-         current_section.ordered_begin();
-       p != current_section.not_found();
-       ++p)
-    if (is_parameter_node(p->second) == true)
+  for (const auto &p : current_section)
+    if (is_parameter_node(p.second) == true)
       {
-        const std::string value = p->second.get<std::string>("value");
+        const std::string value = p.second.get<std::string>("value");
         if (value.find('{') != std::string::npos)
           multiple_choices.emplace_back(subsection_path,
-                                        demangle(p->first),
+                                        demangle(p.first),
                                         value);
       }
 
   // then loop over all subsections
-  for (boost::property_tree::ptree::const_iterator p = current_section.begin();
-       p != current_section.end();
-       ++p)
-    if (is_parameter_node(p->second) == false)
+  for (const auto &p : current_section)
+    if (is_parameter_node(p.second) == false)
       {
-        enter_subsection(demangle(p->first));
+        enter_subsection(demangle(p.first));
         init_branches_current_section();
         leave_subsection();
       }
index 566633bcf27cdce29363debb5185ac39137e3502..9527242a89af7d4e09d06954792811dc85a05ea5 100644 (file)
@@ -17,11 +17,11 @@ DEAL::Number of run: 2
 # ---------------------
 subsection Testing
   # docs 3
-  set double      = 3.9999  # default: 3.1415926
-  set int         = 333     # default: 1
+  set double      = 3.141592 # default: 3.1415926
+  set int         = 393      # default: 1
 
   # docs 1
-  set string list = a, b, c # default: a
+  set string list = a, b, c  # default: a
 end
 
 
@@ -30,11 +30,11 @@ DEAL::Number of run: 3
 # ---------------------
 subsection Testing
   # docs 3
-  set double      = 3.141592 # default: 3.1415926
-  set int         = 393      # default: 1
+  set double      = 3.9999  # default: 3.1415926
+  set int         = 333     # default: 1
 
   # docs 1
-  set string list = a, b, c  # default: a
+  set string list = a, b, c # default: a
 end
 
 
index 1e68cfed1d0b3e20a00982b5fcdc2727feec801a..1112bc686c38efbf255a62d6071f364b0b28bd65 100644 (file)
@@ -17,11 +17,11 @@ DEAL::Number of run: 2
 # ---------------------
 subsection Testing
   # docs 3
-  set double      = 3.9999 # default: 3.1415926
-  set int         = 333    # default: 1
+  set double      = 3.141592 # default: 3.1415926
+  set int         = 393      # default: 1
 
   # docs 1
-  set string list = b      # default: a
+  set string list = b        # default: a
 end
 
 
@@ -30,11 +30,11 @@ DEAL::Number of run: 3
 # ---------------------
 subsection Testing
   # docs 3
-  set double      = 3.141592 # default: 3.1415926
-  set int         = 393      # default: 1
+  set double      = 3.9999 # default: 3.1415926
+  set int         = 333    # default: 1
 
   # docs 1
-  set string list = c        # default: a
+  set string list = c      # default: a
 end
 
 
index e2e44a3e850b8160c1a4cbc54937500f1036d872..3743aaa8b37a8859b55a914d041e5ce032f03025 100644 (file)
@@ -1,10 +1,10 @@
 
 DEAL:parameters:Test<1>::A bool: true
-DEAL:parameters:Test<1>::A double: 1.0
+DEAL:parameters:Test<1>::A double: 1
 DEAL:parameters:Test<1>::A string: Ciao
 DEAL:parameters:Test<1>::An int: 2
 DEAL:parameters:Test<2>::A bool: true
-DEAL:parameters:Test<2>::A double: 1.0
+DEAL:parameters:Test<2>::A double: 1
 DEAL:parameters:Test<2>::A string: Ciao
 DEAL:parameters:Test<2>::An int: 2
 DEAL::My type: Test<1>
index f166385c3a43d393e3ea452046a7656023660aec..1ce6b94efc6cfe585b24fc188955ae6b4958ffc6 100644 (file)
@@ -9,4 +9,4 @@ DEAL:parameters:Second Class::Second int: 5
 DEAL:parameters:Second Class::Second string: bye bye
 DEAL::reading used_parameter_acceptor_05.xml
 DEAL::<?xml version="1.0" encoding="utf-8"?>
-DEAL::<ParameterHandler><First_20Class><First_20int><value>3</value><default_value>3</default_value><documentation/><pattern>0</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description><actions>0</actions></First_20int><First_20double><value>7.7</value><default_value>7.700000</default_value><documentation/><pattern>1</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description><actions>1</actions></First_20double><First_20bool><value>true</value><default_value>true</default_value><documentation/><pattern>2</pattern><pattern_description>[Bool]</pattern_description><actions>2</actions></First_20bool><First_20string><value>hello</value><default_value>hello</default_value><documentation/><pattern>3</pattern><pattern_description>[Anything]</pattern_description><actions>3</actions></First_20string></First_20Class><Second_20Class><Second_20int><value>5</value><default_value>5</default_value><documentation/><pattern>4</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description><actions>4</actions></Second_20int><Second_20double><value>9.9</value><default_value>9.900000</default_value><documentation/><pattern>5</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description><actions>5</actions></Second_20double><Second_20bool><value>false</value><default_value>false</default_value><documentation/><pattern>6</pattern><pattern_description>[Bool]</pattern_description><actions>6</actions></Second_20bool><Second_20string><value>bye bye</value><default_value>bye bye</default_value><documentation/><pattern>7</pattern><pattern_description>[Anything]</pattern_description><actions>7</actions></Second_20string></Second_20Class></ParameterHandler>
+DEAL::<ParameterHandler><First_20Class><First_20bool><value>true</value><default_value>true</default_value><documentation/><pattern>2</pattern><pattern_description>[Bool]</pattern_description><actions>2</actions></First_20bool><First_20double><value>7.7</value><default_value>7.7</default_value><documentation/><pattern>1</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description><actions>1</actions></First_20double><First_20int><value>3</value><default_value>3</default_value><documentation/><pattern>0</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description><actions>0</actions></First_20int><First_20string><value>hello</value><default_value>hello</default_value><documentation/><pattern>3</pattern><pattern_description>[Anything]</pattern_description><actions>3</actions></First_20string></First_20Class><Second_20Class><Second_20bool><value>false</value><default_value>false</default_value><documentation/><pattern>6</pattern><pattern_description>[Bool]</pattern_description><actions>6</actions></Second_20bool><Second_20double><value>9.9</value><default_value>9.9</default_value><documentation/><pattern>5</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description><actions>5</actions></Second_20double><Second_20int><value>5</value><default_value>5</default_value><documentation/><pattern>4</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description><actions>4</actions></Second_20int><Second_20string><value>bye bye</value><default_value>bye bye</default_value><documentation/><pattern>7</pattern><pattern_description>[Anything]</pattern_description><actions>7</actions></Second_20string></Second_20Class></ParameterHandler>
diff --git a/tests/parameter_handler/parameter_handler_3_with_sorting_01.cc b/tests/parameter_handler/parameter_handler_3_with_sorting_01.cc
new file mode 100644 (file)
index 0000000..d025bb0
--- /dev/null
@@ -0,0 +1,77 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2003 - 2018 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+
+// Like _3, but print parameters in the same order as they are declared
+// rather than alphabetically.
+
+#include <deal.II/base/parameter_handler.h>
+
+#include "../tests.h"
+
+
+int
+main()
+{
+  try
+    {
+      initlog();
+
+      ParameterHandler prm;
+      prm.enter_subsection("Testing");
+      prm.declare_entry("string list",
+                        "a",
+                        Patterns::List(Patterns::Selection("a|b|c|d|e|f|g|h")),
+                        "docs 1");
+      prm.declare_entry("int", "1", Patterns::Integer());
+      prm.declare_entry("double", "3.1415926", Patterns::Double(), "docs 3");
+      prm.leave_subsection();
+
+      // read and then write parameters
+      prm.parse_input(SOURCE_DIR "/prm/parameter_handler_3.prm");
+      prm.print_parameters(deallog.get_file_stream(),
+                           ParameterHandler::Text,
+                           false);
+    }
+  catch (std::exception &exc)
+    {
+      deallog << std::endl
+              << std::endl
+              << "----------------------------------------------------"
+              << std::endl;
+      deallog << "Exception on processing: " << std::endl
+              << exc.what() << std::endl
+              << "Aborting!" << std::endl
+              << "----------------------------------------------------"
+              << std::endl;
+
+      return 1;
+    }
+  catch (...)
+    {
+      deallog << std::endl
+              << std::endl
+              << "----------------------------------------------------"
+              << std::endl;
+      deallog << "Unknown exception!" << std::endl
+              << "Aborting!" << std::endl
+              << "----------------------------------------------------"
+              << std::endl;
+      return 1;
+    };
+
+  return 0;
+}
diff --git a/tests/parameter_handler/parameter_handler_3_with_sorting_01.output b/tests/parameter_handler/parameter_handler_3_with_sorting_01.output
new file mode 100644 (file)
index 0000000..af90259
--- /dev/null
@@ -0,0 +1,13 @@
+
+# Listing of Parameters
+# ---------------------
+subsection Testing
+  # docs 1
+  set string list = a, b, c   # default: a
+  set int         = 3         # default: 1
+
+  # docs 3
+  set double      = 3.1415926
+end
+
+
index f2790c891d929260b527aaef4abc832f9464da7c..6b2b26bbdb7d87cc07d50d1cc832a8bf920ac8a3 100644 (file)
         "pattern_description": "[Integer range -2147483648...2147483647 (inclusive)]",
         "actions": "1"
     },
+    "Testing_25testing":
+    {
+        "double_2bdouble":
+        {
+            "value": "7.1415926",
+            "default_value": "6.14159",
+            "documentation": "docs 3",
+            "pattern": "6",
+            "pattern_description": "[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]",
+            "actions": "6"
+        },
+        "int_2aint":
+        {
+            "value": "2",
+            "default_value": "2",
+            "documentation": "",
+            "pattern": "5",
+            "pattern_description": "[Integer range -2147483648...2147483647 (inclusive)]",
+            "actions": "5"
+        },
+        "string_26list":
+        {
+            "value": "< & > ; \/",
+            "default_value": "< & > ; \/",
+            "documentation": "docs 1",
+            "pattern": "4",
+            "pattern_description": "[Anything]",
+            "actions": "4"
+        }
+    },
     "ss1":
     {
         "double_201":
                 "actions": "3"
             }
         }
-    },
-    "Testing_25testing":
-    {
-        "string_26list":
-        {
-            "value": "< & > ; \/",
-            "default_value": "< & > ; \/",
-            "documentation": "docs 1",
-            "pattern": "4",
-            "pattern_description": "[Anything]",
-            "actions": "4"
-        },
-        "int_2aint":
-        {
-            "value": "2",
-            "default_value": "2",
-            "documentation": "",
-            "pattern": "5",
-            "pattern_description": "[Integer range -2147483648...2147483647 (inclusive)]",
-            "actions": "5"
-        },
-        "double_2bdouble":
-        {
-            "value": "7.1415926",
-            "default_value": "6.14159",
-            "documentation": "docs 3",
-            "pattern": "6",
-            "pattern_description": "[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]",
-            "actions": "6"
-        }
     }
 }
 
index 7115313c6d56810111b72f2570f545cc8e3db1e1..d1ecf78ff863e15d2a73ab7f23355dea442b1487 100644 (file)
@@ -1,3 +1,3 @@
 
 <?xml version="1.0" encoding="utf-8"?>
-<ParameterHandler><int1><value>2</value><default_value>1</default_value><documentation>doc 1</documentation><pattern>0</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int1><int2><value>3</value><default_value>2</default_value><documentation>doc 2</documentation><pattern>1</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int2><ss1><double_201><value>2.234</value><default_value>1.234</default_value><documentation>doc 3</documentation><pattern>2</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_201><ss2><double_202><value>5.321</value><default_value>4.321</default_value><documentation>doc 4</documentation><pattern>3</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_202></ss2></ss1><Testing_25testing><string_26list><value>__&lt; &amp; &gt; ; /</value><default_value>&lt; &amp; &gt; ; /</default_value><documentation>docs 1</documentation><pattern>4</pattern><pattern_description>[Anything]</pattern_description></string_26list><int_2aint><value>2</value><default_value>2</default_value><documentation/><pattern>5</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int_2aint><double_2bdouble><value>7.1415926</value><default_value>6.1415926</default_value><documentation>docs 3</documentation><pattern>6</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_2bdouble></Testing_25testing></ParameterHandler>
+<ParameterHandler><int1><value>2</value><default_value>1</default_value><documentation>doc 1</documentation><pattern>0</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int1><int2><value>3</value><default_value>2</default_value><documentation>doc 2</documentation><pattern>1</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int2><Testing_25testing><double_2bdouble><value>7.1415926</value><default_value>6.1415926</default_value><documentation>docs 3</documentation><pattern>6</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_2bdouble><int_2aint><value>2</value><default_value>2</default_value><documentation/><pattern>5</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int_2aint><string_26list><value>__&lt; &amp; &gt; ; /</value><default_value>&lt; &amp; &gt; ; /</default_value><documentation>docs 1</documentation><pattern>4</pattern><pattern_description>[Anything]</pattern_description></string_26list></Testing_25testing><ss1><double_201><value>2.234</value><default_value>1.234</default_value><documentation>doc 3</documentation><pattern>2</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_201><ss2><double_202><value>5.321</value><default_value>4.321</default_value><documentation>doc 4</documentation><pattern>3</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_202></ss2></ss1></ParameterHandler>
index 112eb08986162738679c1e083b50b605dcdcd3b3..3a33dbda3d083ec01437d8a623f3c4e07cddac21 100644 (file)
         "pattern": "1",
         "pattern_description": "[Integer range -2147483648...2147483647 (inclusive)]"
     },
+    "Testing_25testing":
+    {
+        "double_2bdouble":
+        {
+            "value": "6.1415926",
+            "default_value": "6.1415926",
+            "documentation": "docs 3",
+            "pattern": "6",
+            "pattern_description": "[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]"
+        },
+        "int_2aint":
+        {
+            "value": "2",
+            "default_value": "2",
+            "documentation": "",
+            "pattern": "5",
+            "pattern_description": "[Integer range -2147483648...2147483647 (inclusive)]"
+        },
+        "string_26list":
+        {
+            "value": "< & > ; \/",
+            "default_value": "< & > ; \/",
+            "documentation": "docs 1",
+            "pattern": "4",
+            "pattern_description": "[Anything]"
+        }
+    },
     "ss1":
     {
         "double_201":
                 "pattern_description": "[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]"
             }
         }
-    },
-    "Testing_25testing":
-    {
-        "string_26list":
-        {
-            "value": "< & > ; \/",
-            "default_value": "< & > ; \/",
-            "documentation": "docs 1",
-            "pattern": "4",
-            "pattern_description": "[Anything]"
-        },
-        "int_2aint":
-        {
-            "value": "2",
-            "default_value": "2",
-            "documentation": "",
-            "pattern": "5",
-            "pattern_description": "[Integer range -2147483648...2147483647 (inclusive)]"
-        },
-        "double_2bdouble":
-        {
-            "value": "6.1415926",
-            "default_value": "6.1415926",
-            "documentation": "docs 3",
-            "pattern": "6",
-            "pattern_description": "[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]"
-        }
     }
 }
 
index 98f71460514c7e8c70ec1c9ba8167312633096fb..9c7514142eb693b5bf8750c155a9210067bddda3 100644 (file)
@@ -1,3 +1,3 @@
 
 <?xml version="1.0" encoding="utf-8"?>
-<ParameterHandler><ss1><Testing_25testing><double_202><value>4.321</value><default_value>4.321</default_value><documentation>doc 4</documentation><pattern>2</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_202><string_26list><value>&lt; &amp; &gt; ; /</value><default_value>&lt; &amp; &gt; ; /</default_value><documentation>docs 1</documentation><pattern>3</pattern><pattern_description>[Anything]</pattern_description></string_26list><int_2aint><value>2</value><default_value>2</default_value><documentation/><pattern>4</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int_2aint><double_2bdouble><value>6.1415926</value><default_value>6.1415926</default_value><documentation>docs 3</documentation><pattern>5</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_2bdouble></Testing_25testing></ss1></ParameterHandler>
+<ParameterHandler><ss1><Testing_25testing><double_202><value>4.321</value><default_value>4.321</default_value><documentation>doc 4</documentation><pattern>2</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_202><double_2bdouble><value>6.1415926</value><default_value>6.1415926</default_value><documentation>docs 3</documentation><pattern>5</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_2bdouble><int_2aint><value>2</value><default_value>2</default_value><documentation/><pattern>4</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int_2aint><string_26list><value>&lt; &amp; &gt; ; /</value><default_value>&lt; &amp; &gt; ; /</default_value><documentation>docs 1</documentation><pattern>3</pattern><pattern_description>[Anything]</pattern_description></string_26list></Testing_25testing></ss1></ParameterHandler>
index 2f87f6668002d6b45c589c6d157da17b1bf6d86b..f2911de69c31a17205bdd052148e97936e06ab8f 100644 (file)
@@ -1,3 +1,3 @@
 
 <?xml version="1.0" encoding="utf-8"?>
-<ParameterHandler><int1><value>1</value><default_value>1</default_value><documentation>doc 1</documentation><pattern>0</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int1><int2><value>2</value><default_value>2</default_value><documentation>doc 2</documentation><pattern>1</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int2><ss1><double_201><value>1.234</value><default_value>1.234</default_value><documentation>doc 3</documentation><pattern>2</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_201><ss2><double_202><value>4.321</value><default_value>4.321</default_value><documentation>doc 4</documentation><pattern>3</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_202></ss2></ss1><Testing_25testing><string_26list><value>&lt; &amp; &gt; ; /</value><default_value>&lt; &amp; &gt; ; /</default_value><documentation>docs 1</documentation><pattern>4</pattern><pattern_description>[Anything]</pattern_description></string_26list><int_2aint><value>2</value><default_value>2</default_value><documentation/><pattern>5</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int_2aint><double_2bdouble><value>6.1415926</value><default_value>6.1415926</default_value><documentation>docs 3</documentation><pattern>6</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_2bdouble></Testing_25testing></ParameterHandler>
+<ParameterHandler><int1><value>1</value><default_value>1</default_value><documentation>doc 1</documentation><pattern>0</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int1><int2><value>2</value><default_value>2</default_value><documentation>doc 2</documentation><pattern>1</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int2><Testing_25testing><double_2bdouble><value>6.1415926</value><default_value>6.1415926</default_value><documentation>docs 3</documentation><pattern>6</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_2bdouble><int_2aint><value>2</value><default_value>2</default_value><documentation/><pattern>5</pattern><pattern_description>[Integer range -2147483648...2147483647 (inclusive)]</pattern_description></int_2aint><string_26list><value>&lt; &amp; &gt; ; /</value><default_value>&lt; &amp; &gt; ; /</default_value><documentation>docs 1</documentation><pattern>4</pattern><pattern_description>[Anything]</pattern_description></string_26list></Testing_25testing><ss1><double_201><value>1.234</value><default_value>1.234</default_value><documentation>doc 3</documentation><pattern>2</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_201><ss2><double_202><value>4.321</value><default_value>4.321</default_value><documentation>doc 4</documentation><pattern>3</pattern><pattern_description>[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]</pattern_description></double_202></ss2></ss1></ParameterHandler>
index c011853fdbd2164dbb9dd8bf2c16772808686fb9..549302e25f58d56c4327f78840026f2128d00462 100644 (file)
@@ -1,14 +1,14 @@
 
-DEAL:parameters::A Point<1>: 5.000000
-DEAL:parameters::A Point<2>: 6.000000, 7.000000
-DEAL:parameters::A Point<3>: 8.000000, 9.000000, 10.000000
-DEAL:parameters::A complex: 3.000000, 4.000000
-DEAL:parameters::A double: 2.000000
-DEAL:parameters::A list of Point<1>: 5.000000; 5.000000
-DEAL:parameters::A list of Point<2>: 6.000000, 7.000000; 6.000000, 7.000000
-DEAL:parameters::A list of Point<3>: 8.000000, 9.000000, 10.000000; 8.000000, 9.000000, 10.000000
-DEAL:parameters::A list of complexes: 3.000000, 4.000000; 3.000000, 4.000000
-DEAL:parameters::A list of doubles: 2.000000, 2.000000
+DEAL:parameters::A Point<1>: 5
+DEAL:parameters::A Point<2>: 6, 7
+DEAL:parameters::A Point<3>: 8, 9, 10
+DEAL:parameters::A complex: 3, 4
+DEAL:parameters::A double: 2
+DEAL:parameters::A list of Point<1>: 5; 5
+DEAL:parameters::A list of Point<2>: 6, 7; 6, 7
+DEAL:parameters::A list of Point<3>: 8, 9, 10; 8, 9, 10
+DEAL:parameters::A list of complexes: 3, 4; 3, 4
+DEAL:parameters::A list of doubles: 2, 2
 DEAL:parameters::A list of signed integers: -1, -1
 DEAL:parameters::A list of strings: foo, foo
 DEAL:parameters::A list of unsigned integers: 1, 1

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.