]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add support for Patterns::Tools::Convert<std::array<...,..>> 13397/head
authorLuca Heltai <luca.heltai@sissa.it>
Wed, 16 Feb 2022 12:14:11 +0000 (12:14 +0000)
committerLuca Heltai <luca.heltai@sissa.it>
Thu, 17 Feb 2022 05:43:57 +0000 (05:43 +0000)
doc/news/changes/minor/20220216LucaHeltai [new file with mode: 0644]
include/deal.II/base/patterns.h
tests/parameter_handler/pattern_tools_13.cc [new file with mode: 0644]
tests/parameter_handler/pattern_tools_13.output [new file with mode: 0644]

diff --git a/doc/news/changes/minor/20220216LucaHeltai b/doc/news/changes/minor/20220216LucaHeltai
new file mode 100644 (file)
index 0000000..276ba60
--- /dev/null
@@ -0,0 +1,3 @@
+Fixed: Patterns::Tools::Convert now supports also std::array types.
+<br>
+(Luca Heltai, 2022/02/16)
index b75b70bca9cc5223b3772d9d72dfaa7c098decc6..d5409522586d156e04269bbd741e3f6d7a370709 100644 (file)
@@ -1584,9 +1584,6 @@ namespace Patterns
       template <typename T>
       struct is_list_compatible : std::false_type
       {};
-      template <typename T, std::size_t N>
-      struct is_list_compatible<std::array<T, N>> : std::true_type
-      {};
       template <typename... Args>
       struct is_list_compatible<std::vector<Args...>> : std::true_type
       {};
@@ -1750,13 +1747,21 @@ namespace Patterns
           std::max(RankInfo<Key>::map_rank, RankInfo<Value>::map_rank) + 1;
       };
 
-
+      // Rank of std::tuple types
       template <class... Types>
       struct RankInfo<std::tuple<Types...>>
       {
         static constexpr int list_rank = max_list_rank<Types...>();
         static constexpr int map_rank  = max_map_rank<Types...>() + 1;
       };
+
+      // Rank of std::array types
+      template <class T, std::size_t N>
+      struct RankInfo<std::array<T, N>>
+      {
+        static constexpr int list_rank = RankInfo<T>::list_rank + 1;
+        static constexpr int map_rank  = RankInfo<T>::map_rank;
+      };
     } // namespace internal
 
     // stl containers
@@ -1909,6 +1914,74 @@ namespace Patterns
       }
     };
 
+    // std::array
+    template <class ValueType, std::size_t N>
+    struct Convert<std::array<ValueType, N>>
+    {
+      using T = std::array<ValueType, N>;
+
+      static std::unique_ptr<Patterns::PatternBase>
+      to_pattern()
+      {
+        static_assert(internal::RankInfo<T>::list_rank > 0,
+                      "Cannot use this class for non List-compatible types.");
+        return std::make_unique<Patterns::List>(
+          *Convert<typename T::value_type>::to_pattern(),
+          N,
+          N,
+          internal::default_list_separator[internal::RankInfo<T>::list_rank -
+                                           1]);
+      }
+
+      static std::string
+      to_string(
+        const T &                    t,
+        const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
+      {
+        auto p = dynamic_cast<const Patterns::List *>(&pattern);
+        AssertThrow(p,
+                    ExcMessage("I need a List pattern to convert a "
+                               "string to a std::array."));
+        auto                     base_p = p->get_base_pattern().clone();
+        std::vector<std::string> vec(t.size());
+
+        std::transform(
+          t.cbegin(), t.cend(), vec.begin(), [&base_p](const auto &entry) {
+            return Convert<typename T::value_type>::to_string(entry, *base_p);
+          });
+
+        std::string s;
+        if (vec.size() > 0)
+          s = vec[0];
+        for (unsigned int i = 1; i < vec.size(); ++i)
+          s += p->get_separator() + " " + vec[i];
+
+        AssertThrow(pattern.match(s), ExcNoMatch(s, p->description()));
+        return s;
+      }
+
+      static T
+      to_value(const std::string &          s,
+               const Patterns::PatternBase &pattern = *Convert<T>::to_pattern())
+      {
+        AssertThrow(pattern.match(s), ExcNoMatch(s, pattern.description()));
+
+        auto p = dynamic_cast<const Patterns::List *>(&pattern);
+        AssertThrow(p,
+                    ExcMessage("I need a List pattern to convert a string "
+                               "to a std::array."));
+
+        auto base_p = p->get_base_pattern().clone();
+        T    t;
+
+        auto v = Utilities::split_string_list(s, p->get_separator());
+        AssertDimension(v.size(), N);
+        for (unsigned int i = 0; i < N; ++i)
+          t[i] = Convert<typename T::value_type>::to_value(v[i], *base_p);
+        return t;
+      }
+    };
+
     // Tensors
     template <int rank, int dim, class Number>
     struct Convert<Tensor<rank, dim, Number>>
diff --git a/tests/parameter_handler/pattern_tools_13.cc b/tests/parameter_handler/pattern_tools_13.cc
new file mode 100644 (file)
index 0000000..2f81e03
--- /dev/null
@@ -0,0 +1,37 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2005 - 2020 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.
+//
+// ---------------------------------------------------------------------
+
+// Check Patterns::Tools::Convert for std::array types
+
+#include <deal.II/base/parameter_handler.h>
+
+#include <memory>
+
+#include "../tests.h"
+
+int
+main()
+{
+  initlog();
+
+  std::array<Point<2>, 2> points{{Point<2>(0, 1), Point<2>(2, 3)}};
+
+  auto s = Patterns::Tools::to_string(points);
+
+  Patterns::Tools::to_value("4,5 ; 6,7", points);
+
+  deallog << "From: " << s << " to " << Patterns::Tools::to_string(points)
+          << std::endl;
+}
diff --git a/tests/parameter_handler/pattern_tools_13.output b/tests/parameter_handler/pattern_tools_13.output
new file mode 100644 (file)
index 0000000..e9b9939
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEAL::From: 0, 1; 2, 3 to 4, 5; 6, 7

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.