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
{};
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
}
};
+ // 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>>
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+}