]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Added support for magic_enum.
authorLuca Heltai <luca.heltai@unipi.it>
Mon, 12 Aug 2024 21:00:55 +0000 (15:00 -0600)
committerLuca Heltai <luca.heltai@unipi.it>
Mon, 12 Aug 2024 21:00:55 +0000 (15:00 -0600)
cmake/configure/configure_50_magic_enum.cmake [new file with mode: 0644]
cmake/modules/FindDEAL_II_MAGIC_ENUM.cmake [new file with mode: 0644]
doc/news/changes/minor/20240812LucaHeltai [new file with mode: 0644]
include/deal.II/base/config.h.in
include/deal.II/base/patterns.h
tests/parameter_handler/pattern_tools_14.cc [new file with mode: 0644]
tests/parameter_handler/pattern_tools_14.with_magic_enum=true.output [new file with mode: 0644]

diff --git a/cmake/configure/configure_50_magic_enum.cmake b/cmake/configure/configure_50_magic_enum.cmake
new file mode 100644 (file)
index 0000000..0310523
--- /dev/null
@@ -0,0 +1,19 @@
+## ------------------------------------------------------------------------
+##
+## SPDX-License-Identifier: LGPL-2.1-or-later
+## Copyright (C) 2012 - 2022 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## Part of the source code is dual licensed under Apache-2.0 WITH
+## LLVM-exception OR LGPL-2.1-or-later. Detailed license information
+## governing the source code and code contributions can be found in
+## LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
+##
+## ------------------------------------------------------------------------
+
+#
+# Configuration for the MAGIC_ENUM library:
+#
+
+configure_feature(MAGIC_ENUM)
diff --git a/cmake/modules/FindDEAL_II_MAGIC_ENUM.cmake b/cmake/modules/FindDEAL_II_MAGIC_ENUM.cmake
new file mode 100644 (file)
index 0000000..220cfc7
--- /dev/null
@@ -0,0 +1,37 @@
+## ------------------------------------------------------------------------
+##
+## SPDX-License-Identifier: LGPL-2.1-or-later
+## Copyright (C) 2012 - 2022 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## Part of the source code is dual licensed under Apache-2.0 WITH
+## LLVM-exception OR LGPL-2.1-or-later. Detailed license information
+## governing the source code and code contributions can be found in
+## LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
+##
+## ------------------------------------------------------------------------
+
+#
+# Try to find the MAGIC ENUM library
+#
+# This module exports
+#
+#   MAGIC_ENUM_FOUND
+#   MAGIC_ENUM_INCLUDE_DIRS
+#
+
+set(MAGIC_ENUM_DIR "" CACHE PATH "An optional hint to a MAGIC_ENUM installation")
+set_if_empty(MAGIC_ENUM_DIR "$ENV{MAGIC_ENUM_DIR}")
+
+deal_ii_find_path(MAGIC_ENUM_INCLUDE_DIR magic_enum.hpp
+  HINTS ${MAGIC_ENUM_DIR}
+  PATH_SUFFIXES include
+  )
+
+process_feature(MAGIC_ENUM
+  LIBRARIES
+  INCLUDE_DIRS
+    REQUIRED MAGIC_ENUM_INCLUDE_DIR
+  CLEAR MAGIC_ENUM_INCLUDE_DIR
+  )
diff --git a/doc/news/changes/minor/20240812LucaHeltai b/doc/news/changes/minor/20240812LucaHeltai
new file mode 100644 (file)
index 0000000..7dd5a03
--- /dev/null
@@ -0,0 +1,3 @@
+New: Added support for magic_enum.hpp. Now PatternsTools::Convert<T> works also when T is an enum type.
+<br>
+(Luca Heltai, 2024/08/12)
index e09209db4d1e6bd82b8dd2dd4fc028f8a7cf1f1d..b04b8ec1cad2860d981d4647f7b3fad4159eb29f 100644 (file)
@@ -51,6 +51,7 @@
 #cmakedefine DEAL_II_WITH_LAPACK
 #cmakedefine LAPACK_WITH_64BIT_BLAS_INDICES
 #cmakedefine DEAL_II_LAPACK_WITH_MKL
+#cmakedefine DEAL_II_WITH_MAGIC_ENUM
 #cmakedefine DEAL_II_WITH_METIS
 #cmakedefine DEAL_II_WITH_MPI
 #cmakedefine DEAL_II_WITH_MUPARSER
index 0001f9e833150532f88fcd6595f651c01d995b55..f906cea13b19df063d0fcac74a6211f2f9efbb90 100644 (file)
 #include <utility>
 #include <vector>
 
+#ifdef DEAL_II_WITH_MAGIC_ENUM
+#  include <magic_enum.hpp>
+#endif
+
 DEAL_II_NAMESPACE_OPEN
 
 // forward declarations for interfaces and friendship
@@ -2384,6 +2388,64 @@ namespace Patterns
       }
     };
 
+#ifdef DEAL_II_WITH_MAGIC_ENUM
+    // Enums
+    template <class T>
+    struct Convert<T, typename std::enable_if<std::is_enum<T>::value>::type>
+    {
+      static std::unique_ptr<Patterns::PatternBase>
+      to_pattern()
+      {
+        const auto               n     = magic_enum::enum_names<T>();
+        std::vector<std::string> names = {n.begin(), n.end()};
+        const auto               selection =
+          Patterns::Tools::Convert<decltype(names)>::to_string(
+            names,
+            Patterns::List(
+              Patterns::Anything(), names.size(), names.size(), "|"));
+        // Allow parsing a list of enums, and make bitwise or between them
+        return Patterns::List(Patterns::Selection(selection),
+                              0,
+                              names.size(),
+                              "|")
+          .clone();
+      }
+
+      static std::string
+      to_string(const T                     &value,
+                const Patterns::PatternBase &p = *Convert<T>::to_pattern())
+      {
+        namespace B                     = magic_enum::bitwise_operators;
+        const auto               values = magic_enum::enum_values<T>();
+        std::vector<std::string> names;
+        for (const auto &v : values)
+          if (B::operator&(value, v) == v)
+            names.push_back(std::string(magic_enum::enum_name(v)));
+        return Patterns::Tools::Convert<decltype(names)>::to_string(names, p);
+      }
+
+      static T
+      to_value(const std::string                   &s,
+               const dealii::Patterns::PatternBase &p = *to_pattern())
+      {
+        namespace B = magic_enum::bitwise_operators;
+        // Make sure we have a valid enum value, or empty value
+        AssertThrow(p.match(s), ExcNoMatch(s, p.description()));
+        T                        value = T();
+        std::vector<std::string> value_names;
+        value_names =
+          Patterns::Tools::Convert<decltype(value_names)>::to_value(s, p);
+        for (const auto &name : value_names)
+          {
+            auto v = magic_enum::enum_cast<T>(name);
+            if (v.has_value())
+              value = B::operator|(value, v.value());
+          }
+        return value;
+      }
+    };
+#endif
+
     // Utility function with default Pattern
     template <typename T>
     std::string
diff --git a/tests/parameter_handler/pattern_tools_14.cc b/tests/parameter_handler/pattern_tools_14.cc
new file mode 100644 (file)
index 0000000..3500246
--- /dev/null
@@ -0,0 +1,38 @@
+// ------------------------------------------------------------------------
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (C) 2010 - 2022 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// Part of the source code is dual licensed under Apache-2.0 WITH
+// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
+// governing the source code and code contributions can be found in
+// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
+//
+// ------------------------------------------------------------------------
+
+// Check Patterns::Tools::Convert for enum types
+
+#include <deal.II/fe/fe_values.h>
+
+#include <memory>
+
+#include "../tests.h"
+
+int
+main()
+{
+  initlog();
+
+  UpdateFlags flags = update_values;
+
+  deallog << Patterns::Tools::Convert<UpdateFlags>::to_string(flags)
+          << std::endl;
+
+  flags = Patterns::Tools::Convert<UpdateFlags>::to_value(
+    "update_values|update_gradients");
+
+  deallog << Patterns::Tools::Convert<UpdateFlags>::to_string(flags)
+          << std::endl;
+}
diff --git a/tests/parameter_handler/pattern_tools_14.with_magic_enum=true.output b/tests/parameter_handler/pattern_tools_14.with_magic_enum=true.output
new file mode 100644 (file)
index 0000000..947cc1c
--- /dev/null
@@ -0,0 +1,3 @@
+
+DEAL::update_default| update_values
+DEAL::update_default| update_values| update_gradients

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.