From: Luca Heltai Date: Wed, 16 Feb 2022 12:14:11 +0000 (+0000) Subject: Add support for Patterns::Tools::Convert> X-Git-Tag: v9.4.0-rc1~472^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e62211d97babe3befced0b381ee84d657ab85b6f;p=dealii.git Add support for Patterns::Tools::Convert> --- diff --git a/doc/news/changes/minor/20220216LucaHeltai b/doc/news/changes/minor/20220216LucaHeltai new file mode 100644 index 0000000000..276ba60146 --- /dev/null +++ b/doc/news/changes/minor/20220216LucaHeltai @@ -0,0 +1,3 @@ +Fixed: Patterns::Tools::Convert now supports also std::array types. +
+(Luca Heltai, 2022/02/16) diff --git a/include/deal.II/base/patterns.h b/include/deal.II/base/patterns.h index b75b70bca9..d540952258 100644 --- a/include/deal.II/base/patterns.h +++ b/include/deal.II/base/patterns.h @@ -1584,9 +1584,6 @@ namespace Patterns template struct is_list_compatible : std::false_type {}; - template - struct is_list_compatible> : std::true_type - {}; template struct is_list_compatible> : std::true_type {}; @@ -1750,13 +1747,21 @@ namespace Patterns std::max(RankInfo::map_rank, RankInfo::map_rank) + 1; }; - + // Rank of std::tuple types template struct RankInfo> { static constexpr int list_rank = max_list_rank(); static constexpr int map_rank = max_map_rank() + 1; }; + + // Rank of std::array types + template + struct RankInfo> + { + static constexpr int list_rank = RankInfo::list_rank + 1; + static constexpr int map_rank = RankInfo::map_rank; + }; } // namespace internal // stl containers @@ -1909,6 +1914,74 @@ namespace Patterns } }; + // std::array + template + struct Convert> + { + using T = std::array; + + static std::unique_ptr + to_pattern() + { + static_assert(internal::RankInfo::list_rank > 0, + "Cannot use this class for non List-compatible types."); + return std::make_unique( + *Convert::to_pattern(), + N, + N, + internal::default_list_separator[internal::RankInfo::list_rank - + 1]); + } + + static std::string + to_string( + const T & t, + const Patterns::PatternBase &pattern = *Convert::to_pattern()) + { + auto p = dynamic_cast(&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 vec(t.size()); + + std::transform( + t.cbegin(), t.cend(), vec.begin(), [&base_p](const auto &entry) { + return Convert::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::to_pattern()) + { + AssertThrow(pattern.match(s), ExcNoMatch(s, pattern.description())); + + auto p = dynamic_cast(&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::to_value(v[i], *base_p); + return t; + } + }; + // Tensors template struct Convert> diff --git a/tests/parameter_handler/pattern_tools_13.cc b/tests/parameter_handler/pattern_tools_13.cc new file mode 100644 index 0000000000..2f81e034a5 --- /dev/null +++ b/tests/parameter_handler/pattern_tools_13.cc @@ -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 + +#include + +#include "../tests.h" + +int +main() +{ + initlog(); + + std::array, 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 index 0000000000..e9b9939b6e --- /dev/null +++ b/tests/parameter_handler/pattern_tools_13.output @@ -0,0 +1,2 @@ + +DEAL::From: 0, 1; 2, 3 to 4, 5; 6, 7