From e5d0284ec5db7118d8115fb866c8e966c2da274d Mon Sep 17 00:00:00 2001
From: Luca Heltai <luca.heltai@sissa.it>
Date: Wed, 19 Jul 2017 21:08:48 +0200
Subject: [PATCH] Added convert for std::complex types.

---
 include/deal.II/base/patterns_tools.h | 60 +++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/include/deal.II/base/patterns_tools.h b/include/deal.II/base/patterns_tools.h
index b15f5569d9..cc61706fa1 100644
--- a/include/deal.II/base/patterns_tools.h
+++ b/include/deal.II/base/patterns_tools.h
@@ -352,6 +352,13 @@ namespace PatternsTools
     template <int dim, class Number>
     struct RankInfo<Point<dim,Number>>:RankInfo<Tensor<1,dim,Number>> {};
 
+    // Rank of complex types
+    template <class Number>
+    struct RankInfo<std::complex<Number>>
+    {
+      static constexpr int list_rank = RankInfo<Number>::list_rank+1;
+      static constexpr int map_rank = RankInfo<Number>::map_rank;
+    };
   }
 
 
@@ -560,6 +567,59 @@ namespace PatternsTools
   };
 
 
+
+  template<class Number>
+  struct Convert<std::complex<Number>>
+  {
+    typedef std::complex<Number> T;
+
+    static std::unique_ptr<PatternBase> to_pattern()
+    {
+      return std_cxx14::make_unique<List>(*Convert<typename T::value_type>::to_pattern(),
+                                          2, 2,
+                                          internal::default_list_separator[internal::RankInfo<T>::list_rank]);
+    }
+
+    static std::string to_string(const T &t,
+                                 const std::unique_ptr<PatternBase> &pattern = Convert<T>::to_pattern())
+    {
+
+      auto p = dynamic_cast<const Patterns::List *>(pattern.get());
+      AssertThrow(p, ExcMessage("I need a List pattern to convert a string to a List type."));
+      auto base_p = p->get_base_pattern().clone();
+      std::string s =
+        Convert<typename T::value_type>::to_string(t.real(), base_p) +
+        p->get_separator() + " " +
+        Convert<typename T::value_type>::to_string(t.imag(), base_p);
+
+      AssertThrow(pattern->match(s), ExcNoMatch(s, *p));
+      return s;
+    }
+
+    /**
+     * Convert a string to a value, using the given pattern, or a default one.
+     */
+    static T to_value(const std::string &s,
+                      const std::unique_ptr<PatternBase> &pattern = Convert<T>::to_pattern())
+    {
+
+      AssertThrow(pattern->match(s), ExcNoMatch(s, *pattern));
+
+      auto p = dynamic_cast<const Patterns::List *>(pattern.get());
+      AssertThrow(p, ExcMessage("I need a List pattern to convert a string to a List type."));
+
+      auto base_p = p->get_base_pattern().clone();
+
+      auto v = Utilities::split_string_list(s,p->get_separator());
+      AssertDimension(v.size(), 2);
+      T t(Convert<typename T::value_type>::to_value(v[0], base_p),
+          Convert<typename T::value_type>::to_value(v[1], base_p));
+      return t;
+    }
+  };
+
+
+
   template <class ParameterType>
   void add_parameter(const std::string           &entry,
                      ParameterType                &parameter,
-- 
2.39.5