]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add Convert<tuple>
authorLuca Heltai <luca.heltai@sissa.it>
Fri, 27 Oct 2017 12:03:11 +0000 (14:03 +0200)
committerLuca Heltai <luca.heltai@sissa.it>
Sat, 28 Oct 2017 17:57:07 +0000 (19:57 +0200)
include/deal.II/base/patterns.h
tests/base/pattern_tools_08.cc [new file with mode: 0644]
tests/base/pattern_tools_08.output [new file with mode: 0644]
tests/base/pattern_tools_09.cc [new file with mode: 0644]
tests/base/pattern_tools_09.output [new file with mode: 0644]
tests/base/pattern_tools_10.cc [new file with mode: 0644]
tests/base/pattern_tools_10.output [new file with mode: 0644]

index 184d2a352b24b30ffcd735d9c3cc148e5a8f103a..e4e80971254579f16353f0ee16a7af410ede9aad 100644 (file)
@@ -1517,6 +1517,14 @@ namespace Patterns
         static constexpr int list_rank = std_cxx14::max(RankInfo<Key>::list_rank, RankInfo<Value>::list_rank);
         static constexpr int map_rank = std_cxx14::max(RankInfo<Key>::map_rank, RankInfo<Value>::map_rank)+1;
       };
+
+
+      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;
+      };
     }
 
     // stl containers
@@ -1878,6 +1886,97 @@ namespace Patterns
         return *m.begin();
       }
     };
+
+    // Tuples
+    template <class... Args>
+    struct Convert<std::tuple<Args...>>
+    {
+      typedef std::tuple<Args...> T;
+
+      static std::unique_ptr<Patterns::PatternBase> to_pattern()
+      {
+        static_assert(internal::RankInfo<T>::map_rank > 0,
+                      "Cannot use this class for non tuple-compatible types.");
+        return std_cxx14::make_unique<Patterns::Tuple>(
+                 internal::default_map_separator[internal::RankInfo<T>::map_rank-1],
+                 *Convert<Args>::to_pattern()...);
+      }
+
+      template<std::size_t... I>
+      static
+      decltype(auto) to_string_internal_1(const T &t,
+                                          const Patterns::Tuple &pattern,
+                                          std_cxx14::index_sequence<I...>)
+      {
+        std::array<std::string, std::tuple_size<T>::value> a
+        = {{
+            Convert<typename std::tuple_element<I,T>::type>::
+            to_string(std::get<I>(t), pattern.get_pattern(I).clone())...
+          }
+        };
+        return a;
+      }
+
+      static
+      decltype(auto) to_string_internal_2(const T &t,
+                                          const Patterns::Tuple &pattern)
+      {
+        return Convert<T>::to_string_internal_1(t, pattern,
+                                                std_cxx14::make_index_sequence<std::tuple_size<T>::value> {});
+      }
+
+      static std::string to_string(const T &t,
+                                   const std::unique_ptr<Patterns::PatternBase>
+                                   &pattern = Convert<T>::to_pattern())
+      {
+        auto p = dynamic_cast<const Patterns::Tuple *>(pattern.get());
+        AssertThrow(p,ExcMessage("I need a Tuple pattern to convert a tuple "
+                                 "to a string."));
+
+        const auto string_array = Convert<T>::to_string_internal_2(t,*p);
+        std::string str;
+        for (unsigned int i=0; i< string_array.size(); ++i)
+          str += (i ? " " + p->get_separator() + " " : "") +string_array[i];
+        AssertThrow(p->match(str), ExcNoMatch(str, *p));
+        return str;
+      }
+
+
+      template<std::size_t... I>
+      static
+      T to_value_internal_1(const std::vector<std::string> &s,
+                            const Patterns::Tuple &pattern,
+                            std_cxx14::index_sequence<I...>)
+      {
+        return std::make_tuple(Convert<typename std::tuple_element<I,T>::type>::
+                               to_value(s[I], pattern.get_pattern(I).clone())...);
+      }
+
+      static
+      T to_value_internal_2(const std::vector<std::string> &s,
+                            const Patterns::Tuple &pattern)
+      {
+        return Convert<T>::to_value_internal_1(s, pattern,
+                                               std_cxx14::make_index_sequence<std::tuple_size<T>::value> {});
+      }
+
+
+      static T to_value(const std::string &s,
+                        const std::unique_ptr<Patterns::PatternBase> &pattern =
+                          Convert<T>::to_pattern())
+      {
+        AssertThrow(pattern->match(s), ExcNoMatch(s, *pattern));
+
+        auto p = dynamic_cast<const Patterns::Tuple *>(pattern.get());
+        AssertThrow(p,ExcMessage("I need a Tuple pattern to convert a string "
+                                 "to a tuple type."));
+
+        auto v = Utilities::split_string_list(s, p->get_separator());
+
+        return Convert<T>::to_value_internal_2(v,*p);
+      }
+    };
+
   }
 }
 
diff --git a/tests/base/pattern_tools_08.cc b/tests/base/pattern_tools_08.cc
new file mode 100644 (file)
index 0000000..2d50f94
--- /dev/null
@@ -0,0 +1,31 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2005 - 2015 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 at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+// Check Convert<tuple>::to_pattern()
+
+#include "../tests.h"
+#include <deal.II/base/parameter_handler.h>
+#include <deal.II/base/std_cxx14/memory.h>
+#include <memory>
+
+int main()
+{
+  initlog();
+
+  auto a = std::make_tuple(Point<3>(), double(3.5), std::string("ciao"));
+  const auto &pattern = Patterns::Tools::Convert<decltype(a)>::to_pattern();
+
+  deallog << pattern->description() << std::endl;
+}
diff --git a/tests/base/pattern_tools_08.output b/tests/base/pattern_tools_08.output
new file mode 100644 (file)
index 0000000..042b14b
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEAL::[Tuple of <3> elements <[List of <[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]> of length 3...3 (inclusive)]>, <[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]>, <[Anything]>]
diff --git a/tests/base/pattern_tools_09.cc b/tests/base/pattern_tools_09.cc
new file mode 100644 (file)
index 0000000..7adb76d
--- /dev/null
@@ -0,0 +1,34 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2005 - 2015 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 at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+// Check Convert<tuple>::to_string.
+
+#include "../tests.h"
+#include <deal.II/base/parameter_handler.h>
+#include <deal.II/base/std_cxx14/memory.h>
+#include <memory>
+
+int main()
+{
+  initlog();
+
+  auto a = std::make_tuple(Point<3>(), double(3.5), std::string("ciao"));
+  const auto &pattern = Patterns::Tools::Convert<decltype(a)>::to_pattern();
+
+  deallog << pattern->description() << std::endl;
+
+  deallog << Patterns::Tools::Convert<decltype(a)>::to_string(a) << std::endl;
+
+}
diff --git a/tests/base/pattern_tools_09.output b/tests/base/pattern_tools_09.output
new file mode 100644 (file)
index 0000000..f58e4e5
--- /dev/null
@@ -0,0 +1,3 @@
+
+DEAL::[Tuple of <3> elements <[List of <[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]> of length 3...3 (inclusive)]>, <[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]>, <[Anything]>]
+DEAL::0.000000, 0.000000, 0.000000 : 3.500000 : ciao
diff --git a/tests/base/pattern_tools_10.cc b/tests/base/pattern_tools_10.cc
new file mode 100644 (file)
index 0000000..4244d34
--- /dev/null
@@ -0,0 +1,37 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2005 - 2015 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 at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+// Check Convert<tuple>::to_value.
+
+#include "../tests.h"
+#include <deal.II/base/parameter_handler.h>
+#include <deal.II/base/std_cxx14/memory.h>
+#include <memory>
+
+int main()
+{
+  initlog();
+
+  auto a = std::make_tuple(Point<3>(), double(3.5), std::string("ciao"));
+  const auto &pattern = Patterns::Tools::Convert<decltype(a)>::to_pattern();
+
+  deallog << pattern->description() << std::endl;
+
+  deallog << Patterns::Tools::Convert<decltype(a)>::to_string(a) << std::endl;
+
+  a = Patterns::Tools::Convert<decltype(a)>::to_value("1.0, 2.0, 3.0 : 3.14 : mondo");
+
+  deallog << Patterns::Tools::Convert<decltype(a)>::to_string(a) << std::endl;
+}
diff --git a/tests/base/pattern_tools_10.output b/tests/base/pattern_tools_10.output
new file mode 100644 (file)
index 0000000..3f6232b
--- /dev/null
@@ -0,0 +1,4 @@
+
+DEAL::[Tuple of <3> elements <[List of <[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]> of length 3...3 (inclusive)]>, <[Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]>, <[Anything]>]
+DEAL::0.000000, 0.000000, 0.000000 : 3.500000 : ciao
+DEAL::1.000000, 2.000000, 3.000000 : 3.140000 : mondo

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.