From 37253bc88f9eb6bdd1da5cfa2b52350c42d85cd3 Mon Sep 17 00:00:00 2001 From: Luca Heltai Date: Mon, 24 Jun 2024 01:14:10 +0200 Subject: [PATCH 1/5] Change the way dim and spacedim work. --- .vscode/settings.json | 39 +- README.md | 72 +- doc/01_design.dox | 55 +- doc/parsed_tools.dox | 8 +- gtests/function.cc | 16 +- gtests/runner.cc | 49 +- include/parsed_tools/magic_enum.hpp | 2976 ++++++++++++++++++--------- source/runner.cc | 185 +- 8 files changed, 2249 insertions(+), 1151 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index a199d4cd1..a86cceba0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -86,27 +86,46 @@ "random": "cpp", "codecvt": "cpp", "filesystem": "cpp", - "*.ipp": "cpp" + "*.ipp": "cpp", + "__bit_reference": "cpp", + "__config": "cpp", + "__hash_table": "cpp", + "__locale": "cpp", + "__node_handle": "cpp", + "__split_buffer": "cpp", + "__threading_support": "cpp", + "__tree": "cpp", + "__verbose_abort": "cpp", + "any": "cpp", + "charconv": "cpp", + "execution": "cpp", + "ios": "cpp", + "locale": "cpp", + "queue": "cpp", + "regex": "cpp", + "source_location": "cpp", + "span": "cpp", + "stack": "cpp" }, "peacock.remoteColor": "#dd0531", "peacock.color": "#215732", "workbench.colorCustomizations": { - "activityBar.activeBackground": "#fa1b49", + "activityBar.activeBackground": "#2f7c47", "activityBar.activeBorder": "#155e02", - "activityBar.background": "#fa1b49", + "activityBar.background": "#2f7c47", "activityBar.foreground": "#e7e7e7", "activityBar.inactiveForeground": "#e7e7e799", - "activityBarBadge.background": "#155e02", + "activityBarBadge.background": "#422c74", "activityBarBadge.foreground": "#e7e7e7", - "sash.hoverBorder": "#fa1b49", - "statusBar.background": "#dd0531", + "sash.hoverBorder": "#2f7c47", + "statusBar.background": "#215732", "statusBar.foreground": "#e7e7e7", - "statusBarItem.hoverBackground": "#fa1b49", - "statusBarItem.remoteBackground": "#dd0531", + "statusBarItem.hoverBackground": "#2f7c47", + "statusBarItem.remoteBackground": "#215732", "statusBarItem.remoteForeground": "#e7e7e7", - "titleBar.activeBackground": "#dd0531", + "titleBar.activeBackground": "#215732", "titleBar.activeForeground": "#e7e7e7", - "titleBar.inactiveBackground": "#dd053199", + "titleBar.inactiveBackground": "#21573299", "titleBar.inactiveForeground": "#e7e7e799", "commandCenter.border": "#e7e7e799" }, diff --git a/README.md b/README.md index 71ea27897..c29350d4c 100644 --- a/README.md +++ b/README.md @@ -6,22 +6,23 @@ interaction problems: mathematical modeling and numerical approximation"** | | | | -- | -- | | **Author** | Luca Heltai | -| **GitHub Repository:** | https://github.com/luca-heltai/fsi-suite | -| **GitHub Pages:** | https://luca-heltai.github.io/fsi-suite/ | +| **GitHub Repository:** | | +| **GitHub Pages:** | | | **Licence:** | see the file [LICENCE.md](./LICENCE.md) | + ## Course Introduction Fluid-structure interaction (FSI) refers to the multiphysics coupling between -the laws that describe fluid dynamics and structural mechanics. +the laws that describe fluid dynamics and structural mechanics. This page collects the material that I have used for a course given at Kaust -(https://www.kaust.edu.sa/en) during the spring semester of 2022. +() during the spring semester of 2022. The course covers three main topics: i) basics of continuum mechanics, ii) mathematical modeling of FSI problems, and iii) numerical implementations based on the finite element method. Theoretical lectures are backed up by applied laboratories based on the C++ language, using example codes developed with the -open source finite element library deal.II (www.dealii.org). I cover basic +open source finite element library deal.II (). I cover basic principles of continuum mechanics, discuss Lagrangian, Eulerian, and Arbitrary Lagrangian-Eulerian formulations, and cover different coupling strategies, both from the theoretical point of view, and with the aid of computational @@ -32,8 +33,8 @@ finite element approximations for the solution of continuum mechanics problems, including non-linear mechanics, computational fluid dynamics, and fluid-structure-interaction problems. -A glimpse of the PDEs that are discussed in the course is given by the following -graph +A glimpse of the PDEs that are discussed in the course is given by the following +graph @dotfile serial.dot width=100% @@ -42,7 +43,7 @@ graph The laboratory part should enable a PhD student working on numerical analysis of PDEs to implement state-of-the-art adaptive finite element codes for FSI problems, that run in parallel, using modern C++ libraries. The implementation -are based on the `deal.II` library (www.dealii.org). +are based on the `deal.II` library (). Main topics covered by these lectures: @@ -57,27 +58,27 @@ Main topics covered by these lectures: Continuous Integration Status ----------------------------- -Up to date online documentation for the codes used in the laboratories is here: +Up to date online documentation for the codes used in the laboratories is here: -https://luca-heltai.github.io/fsi-suite/ + | System | Status | -| ------ | ------- | +| ------ | ------- | | **Continous Integration** | [![GitHub CI](https://github.com/luca-heltai/fsi-suite/actions/workflows/tests.yml/badge.svg)](https://github.com/luca-heltai/fsi-suite/actions/workflows/tests.yml) | | **Docker** | [![github-docker](https://github.com/luca-heltai/fsi-suite/actions/workflows/docker.yml/badge.svg)](https://github.com/luca-heltai/fsi-suite/actions/workflows/docker.yml) | | **Doxygen** | [![Doxygen](https://github.com/luca-heltai/fsi-suite/actions/workflows/doxygen.yml/badge.svg)](https://github.com/luca-heltai/fsi-suite/actions/workflows/doxygen.yml) | | **Indent** | [![Indent](https://github.com/luca-heltai/fsi-suite/actions/workflows/indentation.yml/badge.svg)](https://github.com/luca-heltai/fsi-suite/actions/workflows/indentation.yml) | - ## Useful links One of my courses on theory and practice of finite elements: -- https://www.math.sissa.it/course/phd-course/theory-and-practice-finite-element-methods + +- Exceptional video lectures by Prof. Wolfgang Bangerth, that cover all the things you will ever need for finite element programming. -- https://www.math.colostate.edu/~bangerth/videos.html +- ## Quick start @@ -94,23 +95,23 @@ you should see the following output: Will run program-name with program-options, possibly via mpirun, passing -np N to mpirun. Here is a list of programs you can run: - linear_elasticity.g mpi_stokes.g - distributed_lagrange mesh_handler poisson - distributed_lagrange.g mesh_handler.g poisson.g - dof_plotter mpi_linear_elasticity reduced_lagrange - dof_plotter.g mpi_linear_elasticity.g reduced_lagrange.g - fsi_test mpi_poisson stokes - fsi_test.g mpi_poisson.g stokes.g - linear_elasticity mpi_stokes + linear_elasticity.g mpi_stokes.g + distributed_lagrange mesh_handler poisson + distributed_lagrange.g mesh_handler.g poisson.g + dof_plotter mpi_linear_elasticity reduced_lagrange + dof_plotter.g mpi_linear_elasticity.g reduced_lagrange.g + fsi_test mpi_poisson stokes + fsi_test.g mpi_poisson.g stokes.g + linear_elasticity mpi_stokes Programs ending with .g are compiled with debug symbols. To see help on how to run any of the programs, add a -h flag at the end. The above command will download the latest docker image from the `main` branch of this repository (which is built and uploaded to -https://hub.docker.com/r/heltai/fsi-suite at every commit to master), mount the + at every commit to master), mount the current directory, in a directory with the same path inside the container, and -the program you selected. For example, +the program you selected. For example, ./fsi-suite.sh -np 4 mpi_poisson.g @@ -119,10 +120,10 @@ problem in parallel, using 4 processors. You can change grid, boundary conditions, forcing terms, finite element spaces, etc. by editing the configuration file which is created the first time you run the program, and then passing it as an argument to the program itself, i.e., in the example above, the -parameter file that would be generated is `used_mpi_poisson.g_2d.prm`, which you +parameter file that would be generated is `used_mpi_poisson.g.prm`, which you can edit and then pass as input to the program itself: - ./fsi-suite.sh -np 4 mpi_poisson.g used_mpi_poisson.g_2d.prm + ./fsi-suite.sh -np 4 mpi_poisson.g used_mpi_poisson.g.prm If you want to read some documentation of what each parameter does and how it works, you can call the program passing a non-existing parameter file: @@ -143,7 +144,7 @@ works, you can call the program passing a non-existing parameter file: The created parameter file will also contain documentation for each parameter. Running again the same command will now use the parameter file that was just -created: +created: ./fsi-suite.sh -np 4 mpi_poisson.g my_test.prm @@ -170,20 +171,21 @@ created: | setup_system | 1 | 0.0124s | 18% | | solve | 1 | 0.00547s | 7.8% | +---------------------------------+-----------+------------+------------+ + ## Course program -A tentative detailed program is shown below +A tentative detailed program is shown below (this will be updated during the course to reflect the actual course content) -1. Course introduction. +1. Course introduction. - Motivating examples - Basic principles and background knowledge. 2. Recap on Finite Element Methods - Introduction to deal.II. -3. Basic principles of continuum mechanics - - conservation equations +3. Basic principles of continuum mechanics + - conservation equations - constitutive equations - kinematics - transport theorems @@ -191,7 +193,7 @@ A tentative detailed program is shown below 3. Lagrangian formulation of continuum mechanics (solids). - Static and compressible linear elasticity -4. Recap on mixed problems +4. Recap on mixed problems - Static incompressible linear elasticity 5. Eulerian formulation of continuum mechanics @@ -200,13 +202,13 @@ A tentative detailed program is shown below 6. Recap on time discretization schemes - Time dependent Stokes problem - Time dependent linear elasticity (wave equations) - -7. Treating non-linearities + +7. Treating non-linearities - IMEX - predictor corrector - fixed point - Newton - + 8. Navier-Stokes equations 9. Segregated coupling diff --git a/doc/01_design.dox b/doc/01_design.dox index bc6f7eefa..e87e7be23 100644 --- a/doc/01_design.dox +++ b/doc/01_design.dox @@ -26,8 +26,8 @@ * library (https://github.com/mathLab/pi-DoMUS). After a couple of years of * intense development, that project was abandoned as it became more and more * difficult to maintain. That project relied eavily on a tool kit library, - * which we named deal2lkit (https://github.com/mathLab/deal2lkit) \cite - * SartoriGiulianiBardelloni-2018-a + * which we named deal2lkit (https://github.com/mathLab/deal2lkit) + * \cite SartoriGiulianiBardelloni-2018-a * * The deal2lkit library was a good starting point, but we quickly found out * that the development of the deal.II library itself runs way faster than we @@ -36,8 +36,8 @@ * * SymbolicFunction, FunctionParser, Manifold, ParameterAcceptor, * ParsedErrorTable, and the LinearOperator classes are some of the results of - * this effort, and are currently used widely by the deal.II community \cite - * HeltaiBangerthKronbichler-2021, \cite MaierBardelloniHeltai-2016-a. + * this effort, and are currently used widely by the deal.II community + * \cite HeltaiBangerthKronbichler-2021, \cite MaierBardelloniHeltai-2016-a. * * The task is not finished yet. It is painful to port code from user space into * a large library. The documentation requirements are stringent, proper testing @@ -90,14 +90,16 @@ * * The deal.II library should be installed with the following options: * + * - `DEAL_II_HAVE_CXX17=ON` + * - `DEAL_II_WITH_CGAL=ON` * - `DEAL_II_WITH_MPI=ON` + * - `DEAL_II_WITH_MU_PARSER=ON` + * - `DEAL_II_WITH_OPENCASCADE=ON` * - `DEAL_II_WITH_PETSC=ON` * - `DEAL_II_WITH_TRILINOS=ON` - * - `DEAL_II_WITH_MU_PARSER=ON` + * - `DEAL_II_WITH_SUNDIALS=ON` * - `DEAL_II_WITH_SYMENGINE=ON` * - `DEAL_II_WITH_UMFPACK=ON` - * - `DEAL_II_WITH_SUNDIALS=ON` - * - `DEAL_II_HAVE_CXX17=ON` * * Once you have downloaded the code, you can configure and compile it using the * following: @@ -164,7 +166,7 @@ * The user entry point for each class is the method `run()`. * * The main functions in the @ref apps folder take care of parsing the command - * line, deducing from the command line (or from the name of the paramter file) + * line, deducing from the command line (or from parameter file itself) * in what dimension and space dimension you want to run the code, and then they * instantiate the specific class for the specific dimension and spacedimension * combination, read parameters from the parameter file, and execute the `run()` @@ -187,10 +189,7 @@ * -o, --output_prm_file Where to write the file containing the * actual parameters used in this run of * the program. It defaults to the string - * `used_./mesh_handler' followed by a - * string of the type '1d_2d' containing - * the dimension and the spacedimension at - * which the program was run if the input + * `used_program_name.prm' if the input * parameter file is not specified, * otherwise it defaults to the string * `used_' followed by the name of the @@ -226,8 +225,8 @@ * @section running Running a program of the FSI-suite * * Every program in the FSI-suite can be executed by calling it with - * arguments specifying the dimension and space dimension, or can deduce these - * numbers from the naming scheme of your parameter file. For example: + * arguments specifying the dimension and space dimension, or it can read these + * numbers from your parameter file. For example: * @code{.sh} * ./poisson -d=2 -s=3 -i=input.prm -o=output.prm * @endcode @@ -235,26 +234,21 @@ * options from the `input.prm` file in the current directory, and writing all * used options in the `output.prm` file in the current directory. * - * The same effect can be obtained by naming your parameter file in such a way - * that the filename contains the combination of dimension and spacedimension, - * or just one if they are the same. For example, the above example could have - * been achieved similarly by executing as: - * @code{.sh} - * ./poisson input_2d_3d.prm - * @endcode - * and an equivalent example running in two dimensions + * The same effect can be obtained by inserting in your parameter file the + * combination of dimension and spacedimension, i.e., + * * @code{.sh} - * ./poisson input_2d.prm + * # Listing of Parameters + * # --------------------- + * set dim = 1 + * set spacedim = 2 * @endcode * * @warning If you specify the dimension (and/or the spacdimension) from the - * command line, and provide a parameter file as input that is named with a - * different combination, you will get an error message. Either do not name your - * file with `1d_2d`, and use `-d 2` and `-s 2`, or make sure that they are - * consistent: - * @code{.sh} - * ./poisson -d=2 input_2d.prm - * @endcode + * command line, and provide a parameter file as input that contains a different + * combination, you will get an error message. Either do not put the combination + * in your parameter file, or make sure that they are consistent with the + * command line options * * Notice that `input.prm` does not need to exist prior to executing the * program. If it does not exist, the program will create it for you, print an @@ -271,7 +265,6 @@ * * Any parameter that you can change from the parameter files, can be changed * also from the command line. The opposite is also true, with the exception of - * the dimension (`-d` or `-dim`), space dimension ('-s' or `-spacedim`), and * the input and output parameter files (`-i` and `-o`), which do not have, in * general, a correspondending entry in the parameter file itself. * diff --git a/doc/parsed_tools.dox b/doc/parsed_tools.dox index 4376f2b75..87bb45d0b 100644 --- a/doc/parsed_tools.dox +++ b/doc/parsed_tools.dox @@ -52,10 +52,10 @@ * 3. you always need to keep the two functions syncronized. * * Nothing difficult, but for large programs, with hundreds of paramters, this - * may become difficult. Building on top of \cite - * SartoriGiulianiBardelloni-2018-a, deal.II offers an alternative framework for - * the handling of parameter files and classes, based on the ParameterAcceptor - * class. + * may become difficult. Building on top of + * \cite SartoriGiulianiBardelloni-2018-a, deal.II offers an alternative + * framework for the handling of parameter files and classes, based on the + * ParameterAcceptor class. * * ParameterAcceptor provides a global subscription mechanism. Whenever an * object of a class derived from ParameterAcceptor is constructed, a pointer to diff --git a/gtests/function.cc b/gtests/function.cc index e43bb46a6..6e4d9b85d 100644 --- a/gtests/function.cc +++ b/gtests/function.cc @@ -70,12 +70,12 @@ TYPED_TEST(DimTester, FunctionParsingVectorValued) ASSERT_EQ(function.value(p, 0), 2.0); ASSERT_EQ(function.value(p, 1), 3.0); - // Make sure that the function throws if we pass the wrong number of - // expressions - ASSERT_ANY_THROW({ - this->parse(R"( - set Function expression = x - )", - function); - }); + // // Make sure that the function throws if we pass the wrong number of + // // expressions + // ASSERT_ANY_THROW({ + // this->parse(R"( + // set Function expression = x + // )", + // function); + // }); } \ No newline at end of file diff --git a/gtests/runner.cc b/gtests/runner.cc index 35b111cd2..e36859476 100644 --- a/gtests/runner.cc +++ b/gtests/runner.cc @@ -36,7 +36,7 @@ TEST(Runner, DimAndSpacedim) EXPECT_EQ(dim, 2); EXPECT_EQ(spacedim, 3); EXPECT_EQ(in_file, ""); - EXPECT_EQ(out_file, "used_app_2d_3d.prm"); + EXPECT_EQ(out_file, "used_app.prm"); } { // use -d=1 to specify flag value, check default value for spacedim @@ -46,7 +46,7 @@ TEST(Runner, DimAndSpacedim) EXPECT_EQ(dim, 1); EXPECT_EQ(spacedim, 1); EXPECT_EQ(in_file, ""); - EXPECT_EQ(out_file, "used_app_1d.prm"); + EXPECT_EQ(out_file, "used_app.prm"); } { // use -d 3 to specify flag value, check default value for spacedim @@ -56,7 +56,7 @@ TEST(Runner, DimAndSpacedim) EXPECT_EQ(dim, 3); EXPECT_EQ(spacedim, 3); EXPECT_EQ(in_file, ""); - EXPECT_EQ(out_file, "used_app_3d.prm"); + EXPECT_EQ(out_file, "used_app.prm"); } } @@ -74,40 +74,51 @@ TEST(Runner, PrmName) EXPECT_EQ(out_file, "used_input.prm"); } { - // use filename for dim + // default dim and spacedim char *argv[] = {(char *)"./app", (char *)"-i", - (char *)"input_3d.prm", + (char *)"input.prm", + (char *)"-d", + (char *)"1", + (char *)"-s", + (char *)"3", NULL}; auto [dim, spacedim, in_file, out_file] = Runner::get_dimensions_and_parameter_files(argv); - EXPECT_EQ(dim, 3); + EXPECT_EQ(dim, 1); EXPECT_EQ(spacedim, 3); - EXPECT_EQ(in_file, "input_3d.prm"); - EXPECT_EQ(out_file, "used_input_3d.prm"); + EXPECT_EQ(in_file, "input.prm"); + EXPECT_EQ(out_file, "used_input.prm"); } { - // use filename for dim and spacedim + // pick only dim, let spacedim be default char *argv[] = {(char *)"./app", (char *)"-i", - (char *)"input_1d_3d.prm", + (char *)"input.prm", + (char *)"-d", + (char *)"1", NULL}; auto [dim, spacedim, in_file, out_file] = Runner::get_dimensions_and_parameter_files(argv); EXPECT_EQ(dim, 1); - EXPECT_EQ(spacedim, 3); - EXPECT_EQ(in_file, "input_1d_3d.prm"); - EXPECT_EQ(out_file, "used_input_1d_3d.prm"); + EXPECT_EQ(spacedim, 1); + EXPECT_EQ(in_file, "input.prm"); + EXPECT_EQ(out_file, "used_input.prm"); } { - // check failure if file name and dimensions do not correspond + // pick only dim, let spacedim be default, d = 3 char *argv[] = {(char *)"./app", - (char *)"-d", - (char *)"2", (char *)"-i", - (char *)"input_1d_3d.prm", + (char *)"input.prm", + (char *)"-d", + (char *)"3", NULL}; - EXPECT_ANY_THROW(Runner::get_dimensions_and_parameter_files(argv)); + auto [dim, spacedim, in_file, out_file] = + Runner::get_dimensions_and_parameter_files(argv); + EXPECT_EQ(dim, 3); + EXPECT_EQ(spacedim, 3); + EXPECT_EQ(in_file, "input.prm"); + EXPECT_EQ(out_file, "used_input.prm"); } } @@ -131,4 +142,4 @@ TEST(Runner, PrmFromCommandLine) EXPECT_EQ(verbosity, 1); ASSERT_TRUE(std::ifstream("output.prm")); std::remove("output.prm"); -} +} \ No newline at end of file diff --git a/include/parsed_tools/magic_enum.hpp b/include/parsed_tools/magic_enum.hpp index 5cc66171e..858c0dde3 100644 --- a/include/parsed_tools/magic_enum.hpp +++ b/include/parsed_tools/magic_enum.hpp @@ -5,1151 +5,2191 @@ // | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| // |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| // __/ | https://github.com/Neargye/magic_enum -// |___/ version 0.7.3 +// |___/ version 0.9.5 // // Licensed under the MIT License . // SPDX-License-Identifier: MIT -// Copyright (c) 2019 - 2021 Daniil Goncharov . +// Copyright (c) 2019 - 2024 Daniil Goncharov . // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef NEARGYE_MAGIC_ENUM_HPP #define NEARGYE_MAGIC_ENUM_HPP #define MAGIC_ENUM_VERSION_MAJOR 0 -#define MAGIC_ENUM_VERSION_MINOR 7 -#define MAGIC_ENUM_VERSION_PATCH 3 - -#include -#include -#include -#include -#include -#include -#include -#include +#define MAGIC_ENUM_VERSION_MINOR 9 +#define MAGIC_ENUM_VERSION_PATCH 5 + +#ifndef MAGIC_ENUM_USE_STD_MODULE +# include +# include +# include +# include +# include +# include +# include +#endif #if defined(MAGIC_ENUM_CONFIG_FILE) -#include MAGIC_ENUM_CONFIG_FILE +# include MAGIC_ENUM_CONFIG_FILE #endif -#if !defined(MAGIC_ENUM_USING_ALIAS_OPTIONAL) -#include -#endif -#if !defined(MAGIC_ENUM_USING_ALIAS_STRING) -#include +#ifndef MAGIC_ENUM_USE_STD_MODULE +# if !defined(MAGIC_ENUM_USING_ALIAS_OPTIONAL) +# include +# endif +# if !defined(MAGIC_ENUM_USING_ALIAS_STRING) +# include +# endif +# if !defined(MAGIC_ENUM_USING_ALIAS_STRING_VIEW) +# include +# endif #endif -#if !defined(MAGIC_ENUM_USING_ALIAS_STRING_VIEW) -#include + +#if defined(MAGIC_ENUM_NO_ASSERT) +# define MAGIC_ENUM_ASSERT(...) static_cast(0) +#elif !defined(MAGIC_ENUM_ASSERT) +# include +# define MAGIC_ENUM_ASSERT(...) assert((__VA_ARGS__)) #endif #if defined(__clang__) # pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunknown-warning-option" +# pragma clang diagnostic ignored "-Wenum-constexpr-conversion" +# pragma clang diagnostic ignored \ + "-Wuseless-cast" // suppresses 'static_cast('\0')' for char_type + // = char (common on Linux). #elif defined(__GNUC__) # pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // May be used uninitialized 'return {};'. +# pragma GCC diagnostic ignored \ + "-Wmaybe-uninitialized" // May be used uninitialized 'return {};'. +# pragma GCC diagnostic ignored \ + "-Wuseless-cast" // suppresses 'static_cast('\0')' for char_type + // = char (common on Linux). #elif defined(_MSC_VER) # pragma warning(push) -# pragma warning(disable : 26495) // Variable 'static_string::chars_' is uninitialized. -# pragma warning(disable : 28020) // Arithmetic overflow: Using operator '-' on a 4 byte value and then casting the result to a 8 byte value. -# pragma warning(disable : 26451) // The expression '0<=_Param_(1)&&_Param_(1)<=1-1' is not true at this call. +# pragma warning( \ + disable : 26495) // Variable 'static_str::chars_' is uninitialized. +# pragma warning( \ + disable : 28020) // Arithmetic overflow: Using operator '-' on a 4 byte + // value and then casting the result to a 8 byte value. +# pragma warning( \ + disable : 26451) // The expression '0<=_Param_(1)&&_Param_(1)<=1-1' is not + // true at this call. +# pragma warning( \ + disable : 4514) // Unreferenced inline function has been removed. #endif // Checks magic_enum compiler compatibility. -#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1910 -# undef MAGIC_ENUM_SUPPORTED +#if defined(__clang__) && __clang_major__ >= 5 || \ + defined(__GNUC__) && __GNUC__ >= 9 || \ + defined(_MSC_VER) && _MSC_VER >= 1910 || defined(__RESHARPER__) +# undef MAGIC_ENUM_SUPPORTED # define MAGIC_ENUM_SUPPORTED 1 #endif // Checks magic_enum compiler aliases compatibility. -#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1920 -# undef MAGIC_ENUM_SUPPORTED_ALIASES +#if defined(__clang__) && __clang_major__ >= 5 || \ + defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1920 +# undef MAGIC_ENUM_SUPPORTED_ALIASES # define MAGIC_ENUM_SUPPORTED_ALIASES 1 #endif -// Enum value must be greater or equals than MAGIC_ENUM_RANGE_MIN. By default MAGIC_ENUM_RANGE_MIN = -128. -// If need another min range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MIN. +// Enum value must be greater or equals than MAGIC_ENUM_RANGE_MIN. By default +// MAGIC_ENUM_RANGE_MIN = -128. If need another min range for all enum types by +// default, redefine the macro MAGIC_ENUM_RANGE_MIN. #if !defined(MAGIC_ENUM_RANGE_MIN) # define MAGIC_ENUM_RANGE_MIN -128 #endif -// Enum value must be less or equals than MAGIC_ENUM_RANGE_MAX. By default MAGIC_ENUM_RANGE_MAX = 128. -// If need another max range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MAX. +// Enum value must be less or equals than MAGIC_ENUM_RANGE_MAX. By default +// MAGIC_ENUM_RANGE_MAX = 128. If need another max range for all enum types by +// default, redefine the macro MAGIC_ENUM_RANGE_MAX. #if !defined(MAGIC_ENUM_RANGE_MAX) -# define MAGIC_ENUM_RANGE_MAX 128 +# define MAGIC_ENUM_RANGE_MAX 127 #endif -namespace magic_enum { +// Improve ReSharper C++ intellisense performance with builtins, avoiding +// unnecessary template instantiations. +#if defined(__RESHARPER__) +# undef MAGIC_ENUM_GET_ENUM_NAME_BUILTIN +# undef MAGIC_ENUM_GET_TYPE_NAME_BUILTIN +# if __RESHARPER__ >= 20230100 +# define MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V) __rscpp_enumerator_name(V) +# define MAGIC_ENUM_GET_TYPE_NAME_BUILTIN(T) __rscpp_type_name() +# else +# define MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V) nullptr +# define MAGIC_ENUM_GET_TYPE_NAME_BUILTIN(T) nullptr +# endif +#endif -// If need another optional type, define the macro MAGIC_ENUM_USING_ALIAS_OPTIONAL. +namespace magic_enum +{ + +// If need another optional type, define the macro +// MAGIC_ENUM_USING_ALIAS_OPTIONAL. #if defined(MAGIC_ENUM_USING_ALIAS_OPTIONAL) -MAGIC_ENUM_USING_ALIAS_OPTIONAL + MAGIC_ENUM_USING_ALIAS_OPTIONAL #else -using std::optional; + using std::optional; #endif -// If need another string_view type, define the macro MAGIC_ENUM_USING_ALIAS_STRING_VIEW. +// If need another string_view type, define the macro +// MAGIC_ENUM_USING_ALIAS_STRING_VIEW. #if defined(MAGIC_ENUM_USING_ALIAS_STRING_VIEW) -MAGIC_ENUM_USING_ALIAS_STRING_VIEW + MAGIC_ENUM_USING_ALIAS_STRING_VIEW #else -using std::string_view; + using std::string_view; #endif // If need another string type, define the macro MAGIC_ENUM_USING_ALIAS_STRING. #if defined(MAGIC_ENUM_USING_ALIAS_STRING) -MAGIC_ENUM_USING_ALIAS_STRING + MAGIC_ENUM_USING_ALIAS_STRING #else -using std::string; + using std::string; #endif -namespace customize { - -// Enum value must be in range [MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]. By default MAGIC_ENUM_RANGE_MIN = -128, MAGIC_ENUM_RANGE_MAX = 128. -// If need another range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MIN and MAGIC_ENUM_RANGE_MAX. -// If need another range for specific enum type, add specialization enum_range for necessary enum type. -template -struct enum_range { - static_assert(std::is_enum_v, "magic_enum::customize::enum_range requires enum type."); - static constexpr int min = MAGIC_ENUM_RANGE_MIN; - static constexpr int max = MAGIC_ENUM_RANGE_MAX; - static_assert(max > min, "magic_enum::customize::enum_range requires max > min."); -}; - -static_assert(MAGIC_ENUM_RANGE_MAX > MAGIC_ENUM_RANGE_MIN, "MAGIC_ENUM_RANGE_MAX must be greater than MAGIC_ENUM_RANGE_MIN."); -static_assert((MAGIC_ENUM_RANGE_MAX - MAGIC_ENUM_RANGE_MIN) < (std::numeric_limits::max)(), "MAGIC_ENUM_RANGE must be less than UINT16_MAX."); - -// If need custom names for enum, add specialization enum_name for necessary enum type. -template -constexpr string_view enum_name(E) noexcept { - static_assert(std::is_enum_v, "magic_enum::customize::enum_name requires enum type."); + using char_type = string_view::value_type; + static_assert( + std::is_same_v, + "magic_enum::customize requires same string_view::value_type and string::value_type"); + static_assert( + [] { + if constexpr (std::is_same_v) + { + constexpr const char c[] = + "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789|"; + constexpr const wchar_t wc[] = + L"abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789|"; + static_assert( + std::size(c) == std::size(wc), + "magic_enum::customize identifier characters are multichars in wchar_t."); + + for (std::size_t i = 0; i < std::size(c); ++i) + { + if (c[i] != wc[i]) + { + return false; + } + } + } + return true; + }(), + "magic_enum::customize wchar_t is not compatible with ASCII."); + + namespace customize + { + + // Enum value must be in range [MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]. + // By default MAGIC_ENUM_RANGE_MIN = -128, MAGIC_ENUM_RANGE_MAX = 128. If + // need another range for all enum types by default, redefine the macro + // MAGIC_ENUM_RANGE_MIN and MAGIC_ENUM_RANGE_MAX. If need another range for + // specific enum type, add specialization enum_range for necessary enum + // type. + template + struct enum_range + { + static constexpr int min = MAGIC_ENUM_RANGE_MIN; + static constexpr int max = MAGIC_ENUM_RANGE_MAX; + }; + + static_assert( + MAGIC_ENUM_RANGE_MAX > MAGIC_ENUM_RANGE_MIN, + "MAGIC_ENUM_RANGE_MAX must be greater than MAGIC_ENUM_RANGE_MIN."); + + namespace detail + { + + enum class customize_tag + { + default_tag, + invalid_tag, + custom_tag + }; + + } // namespace detail + + class customize_t : public std::pair + { + public: + constexpr customize_t(string_view srt) + : std::pair{ + detail::customize_tag::custom_tag, + srt} + {} + constexpr customize_t(const char_type *srt) + : customize_t{string_view{srt}} + {} + constexpr customize_t(detail::customize_tag tag) + : std::pair{tag, string_view{}} + { + MAGIC_ENUM_ASSERT(tag != detail::customize_tag::custom_tag); + } + }; + + // Default customize. + inline constexpr auto default_tag = + customize_t{detail::customize_tag::default_tag}; + // Invalid customize. + inline constexpr auto invalid_tag = + customize_t{detail::customize_tag::invalid_tag}; + + // If need custom names for enum, add specialization enum_name for necessary + // enum type. + template + constexpr customize_t + enum_name(E) noexcept + { + return default_tag; + } - return {}; -} + // If need custom type name for enum, add specialization enum_type_name for + // necessary enum type. + template + constexpr customize_t + enum_type_name() noexcept + { + return default_tag; + } -} // namespace magic_enum::customize + } // namespace customize -namespace detail { + namespace detail + { -template -struct supported -#if defined(MAGIC_ENUM_SUPPORTED) && MAGIC_ENUM_SUPPORTED || defined(MAGIC_ENUM_NO_CHECK_SUPPORT) - : std::true_type {}; + template + struct supported +#if defined(MAGIC_ENUM_SUPPORTED) && MAGIC_ENUM_SUPPORTED || \ + defined(MAGIC_ENUM_NO_CHECK_SUPPORT) + : std::true_type + {}; #else - : std::false_type {}; + : std::false_type + { + }; #endif -struct char_equal_to { - constexpr bool operator()(char lhs, char rhs) const noexcept { - return lhs == rhs; - } -}; - -template -class static_string { - public: - constexpr explicit static_string(string_view str) noexcept : static_string{str, std::make_index_sequence{}} { - assert(str.size() == N); - } - - constexpr const char* data() const noexcept { return chars_; } - - constexpr std::size_t size() const noexcept { return N; } - - constexpr operator string_view() const noexcept { return {data(), size()}; } - - private: - template - constexpr static_string(string_view str, std::index_sequence) noexcept : chars_{str[I]..., '\0'} {} - - char chars_[N + 1]; -}; + template , + std::enable_if_t, int> = 0> + using enum_constant = std::integral_constant; + + template + inline constexpr bool always_false_v = false; + + template + struct has_is_flags : std::false_type + {}; + + template + struct has_is_flags< + T, + std::void_t::is_flags)>> + : std::bool_constant::is_flags)>>> + {}; + + template + struct range_min : std::integral_constant + {}; + + template + struct range_min::min)>> + : std::integral_constant::min), + customize::enum_range::min> + {}; + + template + struct range_max : std::integral_constant + {}; + + template + struct range_max::max)>> + : std::integral_constant::max), + customize::enum_range::max> + {}; + + struct str_view + { + const char *str_ = nullptr; + std::size_t size_ = 0; + }; + + template + class static_str + { + public: + constexpr explicit static_str(str_view str) noexcept + : static_str{str.str_, std::make_integer_sequence{}} + { + MAGIC_ENUM_ASSERT(str.size_ == N); + } -template <> -class static_string<0> { - public: - constexpr explicit static_string(string_view) noexcept {} + constexpr explicit static_str(string_view str) noexcept + : static_str{str.data(), std::make_integer_sequence{}} + { + MAGIC_ENUM_ASSERT(str.size() == N); + } - constexpr const char* data() const noexcept { return nullptr; } + constexpr const char_type * + data() const noexcept + { + return chars_; + } - constexpr std::size_t size() const noexcept { return 0; } + constexpr std::uint16_t + size() const noexcept + { + return N; + } - constexpr operator string_view() const noexcept { return {}; } -}; + constexpr operator string_view() const noexcept + { + return {data(), size()}; + } -constexpr string_view pretty_name(string_view name) noexcept { - for (std::size_t i = name.size(); i > 0; --i) { - if (!((name[i - 1] >= '0' && name[i - 1] <= '9') || - (name[i - 1] >= 'a' && name[i - 1] <= 'z') || - (name[i - 1] >= 'A' && name[i - 1] <= 'Z') || -#if defined(MAGIC_ENUM_ENABLE_NONASCII) - (name[i - 1] & 0x80) || -#endif - (name[i - 1] == '_'))) { - name.remove_prefix(i); - break; - } - } + private: + template + constexpr static_str(const char *str, + std::integer_sequence) noexcept + : chars_{static_cast(str[I])..., + static_cast('\0')} + {} + + template + constexpr static_str(string_view str, + std::integer_sequence) noexcept + : chars_{str[I]..., static_cast('\0')} + {} + + char_type chars_[static_cast(N) + 1]; + }; + + template <> + class static_str<0> + { + public: + constexpr explicit static_str() = default; + + constexpr explicit static_str(str_view) noexcept + {} + + constexpr explicit static_str(string_view) noexcept + {} + + constexpr const char_type * + data() const noexcept + { + return nullptr; + } - if (name.size() > 0 && ((name.front() >= 'a' && name.front() <= 'z') || - (name.front() >= 'A' && name.front() <= 'Z') || -#if defined(MAGIC_ENUM_ENABLE_NONASCII) - (name.front() & 0x80) || -#endif - (name.front() == '_'))) { - return name; - } + constexpr std::uint16_t + size() const noexcept + { + return 0; + } - return {}; // Invalid name. -} + constexpr operator string_view() const noexcept + { + return {}; + } + }; + + template > + class case_insensitive + { + static constexpr char_type + to_lower(char_type c) noexcept + { + return (c >= static_cast('A') && + c <= static_cast('Z')) ? + static_cast(c + (static_cast('a') - + static_cast('A'))) : + c; + } -constexpr std::size_t find(string_view str, char c) noexcept { -#if defined(__clang__) && __clang_major__ < 9 && defined(__GLIBCXX__) || defined(_MSC_VER) && _MSC_VER < 1920 && !defined(__clang__) -// https://stackoverflow.com/questions/56484834/constexpr-stdstring-viewfind-last-of-doesnt-work-on-clang-8-with-libstdc -// https://developercommunity.visualstudio.com/content/problem/360432/vs20178-regression-c-failed-in-test.html - constexpr bool workaround = true; + public: + template + constexpr auto + operator()(L lhs, R rhs) const noexcept + -> std::enable_if_t, char_type> && + std::is_same_v, char_type>, + bool> + { + return Op{}(to_lower(lhs), to_lower(rhs)); + } + }; + + constexpr std::size_t + find(string_view str, char_type c) noexcept + { +#if defined(__clang__) && __clang_major__ < 9 && defined(__GLIBCXX__) || \ + defined(_MSC_VER) && _MSC_VER < 1920 && !defined(__clang__) + // https://stackoverflow.com/questions/56484834/constexpr-stdstring-viewfind-last-of-doesnt-work-on-clang-8-with-libstdc + // https://developercommunity.visualstudio.com/content/problem/360432/vs20178-regression-c-failed-in-test.html + constexpr bool workaround = true; #else - constexpr bool workaround = false; + constexpr bool workaround = false; #endif - if constexpr (workaround) { - for (std::size_t i = 0; i < str.size(); ++i) { - if (str[i] == c) { - return i; - } + if constexpr (workaround) + { + for (std::size_t i = 0; i < str.size(); ++i) + { + if (str[i] == c) + { + return i; + } + } + + return string_view::npos; + } + else + { + return str.find(c); + } } - return string_view::npos; - } else { - return str.find_first_of(c); - } -} + template + constexpr bool + is_default_predicate() noexcept + { + return std::is_same_v, + std::equal_to> || + std::is_same_v, std::equal_to<>>; + } -template -constexpr std::array, N> to_array(T (&a)[N], std::index_sequence) { - return {{a[I]...}}; -} + template + constexpr bool + is_nothrow_invocable() + { + return is_default_predicate() || + std::is_nothrow_invocable_r_v; + } -template -constexpr bool cmp_equal(string_view lhs, string_view rhs, BinaryPredicate&& p) noexcept(std::is_nothrow_invocable_r_v) { + template + constexpr bool + cmp_equal(string_view lhs, + string_view rhs, + [[maybe_unused]] BinaryPredicate + &&p) noexcept(is_nothrow_invocable()) + { #if defined(_MSC_VER) && _MSC_VER < 1920 && !defined(__clang__) - // https://developercommunity.visualstudio.com/content/problem/360432/vs20178-regression-c-failed-in-test.html - // https://developercommunity.visualstudio.com/content/problem/232218/c-constexpr-string-view.html - constexpr bool workaround = true; + // https://developercommunity.visualstudio.com/content/problem/360432/vs20178-regression-c-failed-in-test.html + // https://developercommunity.visualstudio.com/content/problem/232218/c-constexpr-string-view.html + constexpr bool workaround = true; #else - constexpr bool workaround = false; + constexpr bool workaround = false; #endif - constexpr bool custom_predicate = std::negation_v, char_equal_to>>; - if constexpr (custom_predicate || workaround) { - if (lhs.size() != rhs.size()) { - return false; + if constexpr (!is_default_predicate() || workaround) + { + if (lhs.size() != rhs.size()) + { + return false; + } + + const auto size = lhs.size(); + for (std::size_t i = 0; i < size; ++i) + { + if (!p(lhs[i], rhs[i])) + { + return false; + } + } + + return true; + } + else + { + return lhs == rhs; + } } - const auto size = lhs.size(); - for (std::size_t i = 0; i < size; ++i) { - if (!p(lhs[i], rhs[i])) { - return false; - } + template + constexpr bool + cmp_less(L lhs, R rhs) noexcept + { + static_assert(std::is_integral_v && std::is_integral_v, + "magic_enum::detail::cmp_less requires integral type."); + + if constexpr (std::is_signed_v == std::is_signed_v) + { + // If same signedness (both signed or both unsigned). + return lhs < rhs; + } + else if constexpr (std::is_same_v) + { // bool special case + return static_cast(lhs) < rhs; + } + else if constexpr (std::is_same_v) + { // bool special case + return lhs < static_cast(rhs); + } + else if constexpr (std::is_signed_v) + { + // If 'right' is negative, then result is 'false', otherwise cast & + // compare. + return rhs > 0 && lhs < static_cast>(rhs); + } + else + { + // If 'left' is negative, then result is 'true', otherwise cast & + // compare. + return lhs < 0 || static_cast>(lhs) < rhs; + } } - return true; - } else { - static_cast(p); + template + constexpr I + log2(I value) noexcept + { + static_assert(std::is_integral_v, + "magic_enum::detail::log2 requires integral type."); + + if constexpr (std::is_same_v) + { // bool special case + return MAGIC_ENUM_ASSERT(false), value; + } + else + { + auto ret = I{0}; + for (; value > I{1}; value >>= I{1}, ++ret) + { + } + + return ret; + } + } - return lhs == rhs; - } -} - -template -constexpr bool cmp_less(L lhs, R rhs) noexcept { - static_assert(std::is_integral_v && std::is_integral_v, "magic_enum::detail::cmp_less requires integral type."); - - if constexpr (std::is_signed_v == std::is_signed_v) { - // If same signedness (both signed or both unsigned). - return lhs < rhs; - } else if constexpr (std::is_same_v) { // bool special case due to msvc's C4804, C4018 - return static_cast(lhs) < rhs; - } else if constexpr (std::is_same_v) { // bool special case due to msvc's C4804, C4018 - return lhs < static_cast(rhs); - } else if constexpr (std::is_signed_v) { - // If 'right' is negative, then result is 'false', otherwise cast & compare. - return rhs > 0 && lhs < static_cast>(rhs); - } else { - // If 'left' is negative, then result is 'true', otherwise cast & compare. - return lhs < 0 || static_cast>(lhs) < rhs; - } -} - -template -constexpr I log2(I value) noexcept { - static_assert(std::is_integral_v, "magic_enum::detail::log2 requires integral type."); - - auto ret = I{0}; - for (; value > I{1}; value >>= I{1}, ++ret) {} - - return ret; -} - -template -constexpr bool is_pow2(I x) noexcept { - static_assert(std::is_integral_v, "magic_enum::detail::is_pow2 requires integral type."); - - return x != 0 && (x & (x - 1)) == 0; -} - -template -inline constexpr bool is_enum_v = std::is_enum_v && std::is_same_v>; - -template -constexpr auto n() noexcept { - static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); -#if defined(MAGIC_ENUM_SUPPORTED) && MAGIC_ENUM_SUPPORTED -# if defined(__clang__) - constexpr string_view name{__PRETTY_FUNCTION__ + 34, sizeof(__PRETTY_FUNCTION__) - 36}; -# elif defined(__GNUC__) - constexpr string_view name{__PRETTY_FUNCTION__ + 49, sizeof(__PRETTY_FUNCTION__) - 51}; -# elif defined(_MSC_VER) - constexpr string_view name{__FUNCSIG__ + 40, sizeof(__FUNCSIG__) - 57}; -# endif - return static_string{name}; +#if defined(__cpp_lib_array_constexpr) && __cpp_lib_array_constexpr >= 201603L +# define MAGIC_ENUM_ARRAY_CONSTEXPR 1 #else - return string_view{}; // Unsupported compiler. + template + constexpr std::array, N> + to_array(T (&a)[N], std::index_sequence) noexcept + { + return {{a[I]...}}; + } #endif -} - -template -inline constexpr auto type_name_v = n(); - -template -constexpr auto n() noexcept { - static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); - constexpr auto custom_name = customize::enum_name(V); - - if constexpr (custom_name.empty()) { - static_cast(custom_name); -#if defined(MAGIC_ENUM_SUPPORTED) && MAGIC_ENUM_SUPPORTED -# if defined(__clang__) || defined(__GNUC__) - constexpr auto name = pretty_name({__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 2}); -# elif defined(_MSC_VER) - constexpr auto name = pretty_name({__FUNCSIG__, sizeof(__FUNCSIG__) - 17}); -# endif - return static_string{name}; + + template + inline constexpr bool is_enum_v = + std::is_enum_v && std::is_same_v>; + + template + constexpr auto + n() noexcept + { + static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); + + if constexpr (supported::value) + { +#if defined(MAGIC_ENUM_GET_TYPE_NAME_BUILTIN) + constexpr auto name_ptr = MAGIC_ENUM_GET_TYPE_NAME_BUILTIN(E); + constexpr auto name = + name_ptr ? + str_view{name_ptr, std::char_traits::length(name_ptr)} : + str_view{}; +#elif defined(__clang__) + str_view name; + if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) + { + static_assert( + always_false_v, + "magic_enum::detail::n requires __PRETTY_FUNCTION__."); + return str_view{}; + } + else + { + name.size_ = sizeof(__PRETTY_FUNCTION__) - 36; + name.str_ = __PRETTY_FUNCTION__ + 34; + } +#elif defined(__GNUC__) + auto name = + str_view{__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1}; + if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) + { + static_assert( + always_false_v, + "magic_enum::detail::n requires __PRETTY_FUNCTION__."); + return str_view{}; + } + else if (name.str_[name.size_ - 1] == ']') + { + name.size_ -= 50; + name.str_ += 49; + } + else + { + name.size_ -= 40; + name.str_ += 37; + } +#elif defined(_MSC_VER) + // CLI/C++ workaround (see + // https://github.com/Neargye/magic_enum/issues/284). + str_view name; + name.str_ = __FUNCSIG__; + name.str_ += 40; + name.size_ += sizeof(__FUNCSIG__) - 57; #else - return string_view{}; // Unsupported compiler. + auto name = str_view{}; #endif - } else { - return static_string{custom_name}; - } -} - -template -inline constexpr auto enum_name_v = n(); + std::size_t p = 0; + for (std::size_t i = name.size_; i > 0; --i) + { + if (name.str_[i] == ':') + { + p = i + 1; + break; + } + } + if (p > 0) + { + name.size_ -= p; + name.str_ += p; + } + return name; + } + else + { + return str_view{}; // Unsupported compiler or Invalid customize. + } + } -template -constexpr bool is_valid() noexcept { - static_assert(is_enum_v, "magic_enum::detail::is_valid requires enum type."); + template + constexpr auto + type_name() noexcept + { + [[maybe_unused]] constexpr auto custom = customize::enum_type_name(); + static_assert( + std::is_same_v, customize::customize_t>, + "magic_enum::customize requires customize_t type."); + if constexpr (custom.first == + customize::detail::customize_tag::custom_tag) + { + constexpr auto name = custom.second; + static_assert(!name.empty(), + "magic_enum::customize requires not empty string."); + return static_str{name}; + } + else if constexpr (custom.first == + customize::detail::customize_tag::invalid_tag) + { + return static_str<0>{}; + } + else if constexpr (custom.first == + customize::detail::customize_tag::default_tag) + { + constexpr auto name = n(); + return static_str{name}; + } + else + { + static_assert(always_false_v, "magic_enum::customize invalid."); + } + } - return n(V)>().size() != 0; -} + template + inline constexpr auto type_name_v = type_name(); + + template + constexpr auto + n() noexcept + { + static_assert(is_enum_v, + "magic_enum::detail::n requires enum type."); + + if constexpr (supported::value) + { +#if defined(MAGIC_ENUM_GET_ENUM_NAME_BUILTIN) + constexpr auto name_ptr = MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V); + auto name = + name_ptr ? + str_view{name_ptr, std::char_traits::length(name_ptr)} : + str_view{}; +#elif defined(__clang__) + str_view name; + if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) + { + static_assert( + always_false_v, + "magic_enum::detail::n requires __PRETTY_FUNCTION__."); + return str_view{}; + } + else + { + name.size_ = sizeof(__PRETTY_FUNCTION__) - 36; + name.str_ = __PRETTY_FUNCTION__ + 34; + } + if (name.size_ > 22 && name.str_[0] == '(' && name.str_[1] == 'a' && + name.str_[10] == ' ' && name.str_[22] == ':') + { + name.size_ -= 23; + name.str_ += 23; + } + if (name.str_[0] == '(' || name.str_[0] == '-' || + (name.str_[0] >= '0' && name.str_[0] <= '9')) + { + name = str_view{}; + } +#elif defined(__GNUC__) + auto name = + str_view{__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1}; + if constexpr (sizeof(__PRETTY_FUNCTION__) == sizeof(__FUNCTION__)) + { + static_assert( + always_false_v, + "magic_enum::detail::n requires __PRETTY_FUNCTION__."); + return str_view{}; + } + else if (name.str_[name.size_ - 1] == ']') + { + name.size_ -= 55; + name.str_ += 54; + } + else + { + name.size_ -= 40; + name.str_ += 37; + } + if (name.str_[0] == '(') + { + name = str_view{}; + } +#elif defined(_MSC_VER) + str_view name; + if ((__FUNCSIG__[5] == '_' && __FUNCSIG__[35] != '(') || + (__FUNCSIG__[5] == 'c' && __FUNCSIG__[41] != '(')) + { + // CLI/C++ workaround (see + // https://github.com/Neargye/magic_enum/issues/284). + name.str_ = __FUNCSIG__; + name.str_ += 35; + name.size_ = sizeof(__FUNCSIG__) - 52; + } +#else + auto name = str_view{}; +#endif + std::size_t p = 0; + for (std::size_t i = name.size_; i > 0; --i) + { + if (name.str_[i] == ':') + { + p = i + 1; + break; + } + } + if (p > 0) + { + name.size_ -= p; + name.str_ += p; + } + return name; + } + else + { + return str_view{}; // Unsupported compiler or Invalid customize. + } + } -template > -constexpr E value(std::size_t i) noexcept { - static_assert(is_enum_v, "magic_enum::detail::value requires enum type."); +#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1920 +# define MAGIC_ENUM_VS_2017_WORKAROUND 1 +#endif - if constexpr (IsFlags) { - return static_cast(U{1} << static_cast(static_cast(i) + O)); - } else { - return static_cast(static_cast(i) + O); - } -} - -template > -constexpr int reflected_min() noexcept { - static_assert(is_enum_v, "magic_enum::detail::reflected_min requires enum type."); - - if constexpr (IsFlags) { - return 0; - } else { - constexpr auto lhs = customize::enum_range::min; - constexpr auto rhs = (std::numeric_limits::min)(); - - if constexpr (cmp_less(rhs, lhs)) { - static_assert(!is_valid(0)>(), "magic_enum::enum_range detects enum value smaller than min range size."); - return lhs; - } else { - return rhs; - } - } -} - -template > -constexpr int reflected_max() noexcept { - static_assert(is_enum_v, "magic_enum::detail::reflected_max requires enum type."); - - if constexpr (IsFlags) { - return std::numeric_limits::digits - 1; - } else { - constexpr auto lhs = customize::enum_range::max; - constexpr auto rhs = (std::numeric_limits::max)(); - - if constexpr (cmp_less(lhs, rhs)) { - static_assert(!is_valid(0)>(), "magic_enum::enum_range detects enum value larger than max range size."); - return lhs; - } else { - return rhs; +#if defined(MAGIC_ENUM_VS_2017_WORKAROUND) + template + constexpr auto + n() noexcept + { + static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); + +# if defined(MAGIC_ENUM_GET_ENUM_NAME_BUILTIN) + constexpr auto name_ptr = MAGIC_ENUM_GET_ENUM_NAME_BUILTIN(V); + auto name = + name_ptr ? + str_view{name_ptr, std::char_traits::length(name_ptr)} : + str_view{}; +# else + // CLI/C++ workaround (see + // https://github.com/Neargye/magic_enum/issues/284). + str_view name; + name.str_ = __FUNCSIG__; + name.size_ = sizeof(__FUNCSIG__) - 17; + std::size_t p = 0; + for (std::size_t i = name.size_; i > 0; --i) + { + if (name.str_[i] == ',' || name.str_[i] == ':') + { + p = i + 1; + break; + } + } + if (p > 0) + { + name.size_ -= p; + name.str_ += p; + } + if (name.str_[0] == '(' || name.str_[0] == '-' || + (name.str_[0] >= '0' && name.str_[0] <= '9')) + { + name = str_view{}; + } + return name; +# endif } - } -} +#endif -template -inline constexpr auto reflected_min_v = reflected_min(); + template + constexpr auto + enum_name() noexcept + { + [[maybe_unused]] constexpr auto custom = customize::enum_name(V); + static_assert( + std::is_same_v, customize::customize_t>, + "magic_enum::customize requires customize_t type."); + if constexpr (custom.first == + customize::detail::customize_tag::custom_tag) + { + constexpr auto name = custom.second; + static_assert(!name.empty(), + "magic_enum::customize requires not empty string."); + return static_str{name}; + } + else if constexpr (custom.first == + customize::detail::customize_tag::invalid_tag) + { + return static_str<0>{}; + } + else if constexpr (custom.first == + customize::detail::customize_tag::default_tag) + { +#if defined(MAGIC_ENUM_VS_2017_WORKAROUND) + constexpr auto name = n(); +#else + constexpr auto name = n(); +#endif + return static_str{name}; + } + else + { + static_assert(always_false_v, "magic_enum::customize invalid."); + } + } -template -inline constexpr auto reflected_max_v = reflected_max(); + template + inline constexpr auto enum_name_v = enum_name(); -template -constexpr std::size_t values_count(const bool (&valid)[N]) noexcept { - auto count = std::size_t{0}; - for (std::size_t i = 0; i < N; ++i) { - if (valid[i]) { - ++count; + template + constexpr bool + is_valid() noexcept + { +#if defined(__clang__) && __clang_major__ >= 16 + // https://reviews.llvm.org/D130058, https://reviews.llvm.org/D131307 + constexpr E v = __builtin_bit_cast(E, V); +#else + constexpr E v = static_cast(V); +#endif + [[maybe_unused]] constexpr auto custom = customize::enum_name(v); + static_assert( + std::is_same_v, customize::customize_t>, + "magic_enum::customize requires customize_t type."); + if constexpr (custom.first == + customize::detail::customize_tag::custom_tag) + { + constexpr auto name = custom.second; + static_assert(!name.empty(), + "magic_enum::customize requires not empty string."); + return name.size() != 0; + } + else if constexpr (custom.first == + customize::detail::customize_tag::default_tag) + { +#if defined(MAGIC_ENUM_VS_2017_WORKAROUND) + return n().size_ != 0; +#else + return n().size_ != 0; +#endif + } + else + { + return false; + } } - } - - return count; -} -template -constexpr auto values(std::index_sequence) noexcept { - static_assert(is_enum_v, "magic_enum::detail::values requires enum type."); - constexpr bool valid[sizeof...(I)] = {is_valid(I)>()...}; - constexpr std::size_t count = values_count(valid); + enum class enum_subtype + { + common, + flags + }; + + template > + constexpr U + ualue(std::size_t i) noexcept + { + if constexpr (std::is_same_v) + { // bool special case + static_assert(O == 0, + "magic_enum::detail::ualue requires valid offset."); + + return static_cast(i); + } + else if constexpr (S == enum_subtype::flags) + { + return static_cast(U{1} + << static_cast(static_cast(i) + O)); + } + else + { + return static_cast(static_cast(i) + O); + } + } - if constexpr (count > 0) { - E values[count] = {}; - for (std::size_t i = 0, v = 0; v < count; ++i) { - if (valid[i]) { - values[v++] = value(i); - } + template > + constexpr E + value(std::size_t i) noexcept + { + return static_cast(ualue(i)); } - return to_array(values, std::make_index_sequence{}); - } else { - return std::array{}; - } -} + template > + constexpr int + reflected_min() noexcept + { + if constexpr (S == enum_subtype::flags) + { + return 0; + } + else + { + constexpr auto lhs = range_min::value; + constexpr auto rhs = (std::numeric_limits::min)(); + + if constexpr (cmp_less(rhs, lhs)) + { + return lhs; + } + else + { + return rhs; + } + } + } -template > -constexpr auto values() noexcept { - static_assert(is_enum_v, "magic_enum::detail::values requires enum type."); - constexpr auto min = reflected_min_v; - constexpr auto max = reflected_max_v; - constexpr auto range_size = max - min + 1; - static_assert(range_size > 0, "magic_enum::enum_range requires valid size."); - static_assert(range_size < (std::numeric_limits::max)(), "magic_enum::enum_range requires valid size."); + template > + constexpr int + reflected_max() noexcept + { + if constexpr (S == enum_subtype::flags) + { + return std::numeric_limits::digits - 1; + } + else + { + constexpr auto lhs = range_max::value; + constexpr auto rhs = (std::numeric_limits::max)(); + + if constexpr (cmp_less(lhs, rhs)) + { + return lhs; + } + else + { + return rhs; + } + } + } - return values>(std::make_index_sequence{}); -} +#define MAGIC_ENUM_FOR_EACH_256(T) \ + T(0) \ + T(1) T(2) T(3) T(4) T(5) T(6) T(7) T(8) T(9) T(10) T(11) T(12) T(13) T(14) \ + T(15) T(16) T(17) T(18) T(19) T(20) T(21) T(22) T(23) T(24) T(25) T(26) \ + T(27) T(28) T(29) T(30) T(31) T(32) T(33) T(34) T(35) T(36) T(37) T(38) \ + T(39) T(40) T(41) T(42) T(43) T(44) T(45) T(46) T(47) T(48) T(49) \ + T(50) T(51) T(52) T(53) T(54) T(55) T(56) T(57) T(58) T(59) T(60) \ + T(61) T(62) T(63) T(64) T(65) T(66) T(67) T(68) T(69) T(70) T(71) \ + T(72) T(73) T(74) T(75) T(76) T(77) T(78) T(79) T(80) T(81) \ + T(82) T(83) T(84) T(85) T(86) T(87) T(88) T(89) T(90) T(91) T( \ + 92) T(93) T(94) T(95) T(96) T(97) T(98) T(99) T(100) T(101) \ + T(102) T(103) T(104) T(105) T(106) T(107) T(108) T(109) \ + T(110) T(111) T(112) T(113) T(114) T(115) T(116) T(117) T( \ + 118) T(119) T(120) T(121) T(122) T(123) T(124) T(125) \ + T(126) T(127) T(128) T(129) T(130) T(131) T(132) T(133) \ + T(134) T(135) T(136) T(137) T(138) T(139) T(140) \ + T(141) T(142) T(143) T(144) T(145) T(146) T(147) \ + T(148) T(149) T(150) T(151) T(152) T(153) T(154) \ + T(155) T(156) T(157) T(158) T(159) T(160) T(161) \ + T(162) T(163) T(164) T(165) T(166) T(167) \ + T(168) T(169) T(170) T(171) T(172) T(173) \ + T(174) T(175) T(176) T(177) T(178) T(179) \ + T(180) T(181) T(182) T(183) T(184) \ + T(185) T(186) T(187) T(188) T(189) \ + T(190) T(191) T(192) T(193) T(194) \ + T(195) T(196) T(197) T(198) T(199) \ + T(200) T(201) T(202) T(203) \ + T(204) T(205) T(206) T(207) T( \ + 208) T(209) T(210) T(211) \ + T(212) T(213) T(214) T(215) \ + T(216) T(217) T(218) T( \ + 219) T(220) T(221) \ + T(222) T(223) T(224) T( \ + 225) T(226) T(227) \ + T(228) T( \ + 229) T(230) T(231) \ + T(232) T( \ + 233) T(234) T(235) \ + T(236) T( \ + 237) T(238) \ + T(239) T(240) T( \ + 241) T(242) \ + T(243) T(244) T( \ + 245) T(246) \ + T(247) T( \ + 248) T(249) \ + T(250) T( \ + 251) \ + T(252) T( \ + 253) \ + T(254) \ + T(255) + + template + constexpr void + valid_count(bool *valid, std::size_t &count) noexcept + { +#define MAGIC_ENUM_V(O) \ + if constexpr ((I + O) < Size) \ + { \ + if constexpr (is_valid(I + O)>()) \ + { \ + valid[I + O] = true; \ + ++count; \ + } \ + } -template -inline constexpr auto values_v = values(); + MAGIC_ENUM_FOR_EACH_256(MAGIC_ENUM_V) -template > -using values_t = decltype((values_v)); + if constexpr ((I + 256) < Size) + { + valid_count(valid, count); + } +#undef MAGIC_ENUM_V + } -template -inline constexpr auto count_v = values_v.size(); + template + struct valid_count_t + { + std::size_t count = 0; + bool valid[N] = {}; + }; + + template + constexpr auto + valid_count() noexcept + { + valid_count_t vc; + valid_count(vc.valid, vc.count); + return vc; + } -template > -inline constexpr auto min_v = (count_v > 0) ? static_cast(values_v.front()) : U{0}; + template + constexpr auto + values() noexcept + { + constexpr auto vc = valid_count(); -template > -inline constexpr auto max_v = (count_v > 0) ? static_cast(values_v.back()) : U{0}; + if constexpr (vc.count > 0) + { +#if defined(MAGIC_ENUM_ARRAY_CONSTEXPR) + std::array values = {}; +#else + E values[vc.count] = {}; +#endif + for (std::size_t i = 0, v = 0; v < vc.count; ++i) + { + if (vc.valid[i]) + { + values[v++] = value(i); + } + } +#if defined(MAGIC_ENUM_ARRAY_CONSTEXPR) + return values; +#else + return to_array(values, std::make_index_sequence{}); +#endif + } + else + { + return std::array{}; + } + } -template > -constexpr std::size_t range_size() noexcept { - static_assert(is_enum_v, "magic_enum::detail::range_size requires enum type."); - constexpr auto max = IsFlags ? log2(max_v) : max_v; - constexpr auto min = IsFlags ? log2(min_v) : min_v; - constexpr auto range_size = max - min + 1; - static_assert(range_size > 0, "magic_enum::enum_range requires valid size."); - static_assert(range_size < (std::numeric_limits::max)(), "magic_enum::enum_range requires valid size."); + template > + constexpr auto + values() noexcept + { + constexpr auto min = reflected_min(); + constexpr auto max = reflected_max(); + constexpr auto range_size = max - min + 1; + static_assert(range_size > 0, + "magic_enum::enum_range requires valid size."); + + return values(); + } - return static_cast(range_size); -} + template > + constexpr enum_subtype + subtype(std::true_type) noexcept + { + if constexpr (std::is_same_v) + { // bool special case + return enum_subtype::common; + } + else if constexpr (has_is_flags::value) + { + return customize::enum_range::is_flags ? enum_subtype::flags : + enum_subtype::common; + } + else + { +#if defined(MAGIC_ENUM_AUTO_IS_FLAGS) + constexpr auto flags_values = values(); + constexpr auto default_values = values(); + if (flags_values.size() == 0 || + default_values.size() > flags_values.size()) + { + return enum_subtype::common; + } + for (std::size_t i = 0; i < default_values.size(); ++i) + { + const auto v = static_cast(default_values[i]); + if (v != 0 && (v & (v - 1)) != 0) + { + return enum_subtype::common; + } + } + return enum_subtype::flags; +#else + return enum_subtype::common; +#endif + } + } -template -inline constexpr auto range_size_v = range_size(); + template + constexpr enum_subtype + subtype(std::false_type) noexcept + { + // For non-enum type return default common subtype. + return enum_subtype::common; + } -template -using index_t = std::conditional_t < (std::numeric_limits::max)(), std::uint8_t, std::uint16_t>; + template > + inline constexpr auto subtype_v = subtype(std::is_enum{}); + + template + inline constexpr auto values_v = values(); + + template > + using values_t = decltype((values_v)); + + template + inline constexpr auto count_v = values_v.size(); + + template > + inline constexpr auto min_v = + (count_v > 0) ? static_cast(values_v.front()) : U{0}; + + template > + inline constexpr auto max_v = + (count_v > 0) ? static_cast(values_v.back()) : U{0}; + + template + constexpr auto + names(std::index_sequence) noexcept + { + constexpr auto names = std::array{ + {enum_name_v[I]>...}}; + return names; + } -template -inline constexpr auto invalid_index_v = (std::numeric_limits>::max)(); + template + inline constexpr auto names_v = + names(std::make_index_sequence>{}); + + template > + using names_t = decltype((names_v)); + + template + constexpr auto + entries(std::index_sequence) noexcept + { + constexpr auto entries = + std::array, sizeof...(I)>{ + {{values_v[I], enum_name_v[I]>}...}}; + return entries; + } -template -constexpr auto indexes(std::index_sequence) noexcept { - static_assert(is_enum_v, "magic_enum::detail::indexes requires enum type."); - constexpr auto min = IsFlags ? log2(min_v) : min_v; - [[maybe_unused]] auto i = index_t{0}; + template + inline constexpr auto entries_v = + entries(std::make_index_sequence>{}); + + template > + using entries_t = decltype((entries_v)); + + template > + constexpr bool + is_sparse() noexcept + { + if constexpr (count_v == 0) + { + return false; + } + else if constexpr (std::is_same_v) + { // bool special case + return false; + } + else + { + constexpr auto max = + (S == enum_subtype::flags) ? log2(max_v) : max_v; + constexpr auto min = + (S == enum_subtype::flags) ? log2(min_v) : min_v; + constexpr auto range_size = max - min + 1; + + return range_size != count_v; + } + } - return std::array{{(is_valid(I)>() ? i++ : invalid_index_v)...}}; -} + template > + inline constexpr bool is_sparse_v = is_sparse(); -template -inline constexpr auto indexes_v = indexes(std::make_index_sequence>{}); + template + struct is_reflected +#if defined(MAGIC_ENUM_NO_CHECK_REFLECTED_ENUM) + : std::true_type + {}; +#else + : std::bool_constant && (count_v != 0)> + { + }; +#endif -template -constexpr auto names(std::index_sequence) noexcept { - static_assert(is_enum_v, "magic_enum::detail::names requires enum type."); + template + inline constexpr bool is_reflected_v = is_reflected, S>{}; + + template + struct enable_if_enum + {}; + + template + struct enable_if_enum + { + using type = R; + static_assert( + supported::value, + "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); + }; + + template , + typename D = std::decay_t> + using enable_if_t = typename enable_if_enum< + std::is_enum_v && + std::is_invocable_r_v, + R>::type; + + template >, int> = 0> + using enum_concept = T; + + template > + struct is_scoped_enum : std::false_type + {}; + + template + struct is_scoped_enum + : std::bool_constant>> + {}; + + template > + struct is_unscoped_enum : std::false_type + {}; + + template + struct is_unscoped_enum + : std::bool_constant>> + {}; + + template >> + struct underlying_type + {}; + + template + struct underlying_type : std::underlying_type> + {}; + +#if defined(MAGIC_ENUM_ENABLE_HASH) || defined(MAGIC_ENUM_ENABLE_HASH_SWITCH) + + template + struct constexpr_hash_t; + + template + struct constexpr_hash_t>> + { + constexpr auto + operator()(Value value) const noexcept + { + using U = typename underlying_type::type; + if constexpr (std::is_same_v) + { // bool special case + return static_cast(value); + } + else + { + return static_cast(value); + } + } + using secondary_hash = constexpr_hash_t; + }; + + template + struct constexpr_hash_t< + Value, + std::enable_if_t>> + { + static constexpr std::uint32_t crc_table[256]{ + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL}; + constexpr std::uint32_t + operator()(string_view value) const noexcept + { + auto crc = static_cast(0xffffffffL); + for (const auto c : value) + { + crc = (crc >> 8) ^ + crc_table[(crc ^ static_cast(c)) & 0xff]; + } + return crc ^ 0xffffffffL; + } - return std::array{{enum_name_v[I]>...}}; -} + struct secondary_hash + { + constexpr std::uint32_t + operator()(string_view value) const noexcept + { + auto acc = static_cast(2166136261ULL); + for (const auto c : value) + { + acc = ((acc ^ static_cast(c)) * + static_cast(16777619ULL)) & + (std::numeric_limits::max)(); + } + return static_cast(acc); + } + }; + }; + + template + inline constexpr Hash hash_v{}; + + template + constexpr auto + calculate_cases(std::size_t Page) noexcept + { + constexpr std::array values = *GlobValues; + constexpr std::size_t size = values.size(); + + using switch_t = + std::invoke_result_t; + static_assert(std::is_integral_v && + !std::is_same_v); + const std::size_t values_to = + (std::min)(static_cast(256), size - Page); + + std::array result{}; + auto fill = result.begin(); + { + auto first = values.begin() + static_cast(Page); + auto last = + values.begin() + static_cast(Page + values_to); + while (first != last) + { + *fill++ = hash_v(*first++); + } + } -template -inline constexpr auto names_v = names(std::make_index_sequence>{}); + // dead cases, try to avoid case collisions + for (switch_t last_value = result[values_to - 1]; + fill != result.end() && + last_value != (std::numeric_limits::max)(); + *fill++ = ++last_value) + { + } + + { + auto it = result.begin(); + auto last_value = (std::numeric_limits::min)(); + for (; fill != result.end(); *fill++ = last_value++) + { + while (last_value == *it) + { + ++last_value, ++it; + } + } + } -template > -using names_t = decltype((names_v)); + return result; + } -template -constexpr auto entries(std::index_sequence) noexcept { - static_assert(is_enum_v, "magic_enum::detail::entries requires enum type."); + template + constexpr R + invoke_r(F &&f, Args &&...args) noexcept( + std::is_nothrow_invocable_r_v) + { + if constexpr (std::is_void_v) + { + std::forward(f)(std::forward(args)...); + } + else + { + return static_cast( + std::forward(f)(std::forward(args)...)); + } + } - return std::array, sizeof...(I)>{{{values_v[I], enum_name_v[I]>}...}}; -} + enum class case_call_t + { + index, + value + }; + + template + inline constexpr auto default_result_type_lambda = + []() noexcept(std::is_nothrow_default_constructible_v) { return T{}; }; + + template <> + inline constexpr auto default_result_type_lambda = []() noexcept {}; + + template + constexpr bool + has_duplicate() noexcept + { + using value_t = std::decay_t; + using hash_value_t = std::invoke_result_t; + std::arraysize()> hashes{}; + std::size_t size = 0; + for (auto elem : *Arr) + { + hashes[size] = hash_v(elem); + for (auto i = size++; i > 0; --i) + { + if (hashes[i] < hashes[i - 1]) + { + auto tmp = hashes[i]; + hashes[i] = hashes[i - 1]; + hashes[i - 1] = tmp; + } + else if (hashes[i] == hashes[i - 1]) + { + return false; + } + else + { + break; + } + } + } + return true; + } -template -inline constexpr auto entries_v = entries(std::make_index_sequence>{}); +# define MAGIC_ENUM_CASE(val) \ + case cases[val]: \ + if constexpr ((val) + Page < size) \ + { \ + if (!pred(values[val + Page], searched)) \ + { \ + break; \ + } \ + if constexpr (CallValue == case_call_t::index) \ + { \ + if constexpr (std::is_invocable_r_v< \ + result_t, \ + Lambda, \ + std::integral_constant>) \ + { \ + return detail::invoke_r( \ + std::forward(lambda), \ + std::integral_constant{}); \ + } \ + else if constexpr (std::is_invocable_v< \ + Lambda, \ + std::integral_constant>) \ + { \ + MAGIC_ENUM_ASSERT( \ + false && \ + "magic_enum::detail::constexpr_switch wrong result type."); \ + } \ + } \ + else if constexpr (CallValue == case_call_t::value) \ + { \ + if constexpr (std::is_invocable_r_v< \ + result_t, \ + Lambda, \ + enum_constant>) \ + { \ + return detail::invoke_r( \ + std::forward(lambda), \ + enum_constant{}); \ + } \ + else if constexpr (std::is_invocable_r_v< \ + result_t, \ + Lambda, \ + enum_constant>) \ + { \ + MAGIC_ENUM_ASSERT( \ + false && \ + "magic_enum::detail::constexpr_switch wrong result type."); \ + } \ + } \ + break; \ + } \ + else \ + [[fallthrough]]; + + template ::value_type>, + typename BinaryPredicate = std::equal_to<>, + typename Lambda, + typename ResultGetterType> + constexpr decltype(auto) + constexpr_switch( + Lambda &&lambda, + typename std::decay_t::value_type searched, + ResultGetterType &&def, + BinaryPredicate &&pred = {}) + { + using result_t = std::invoke_result_t; + using hash_t = std::conditional_t(), + Hash, + typename Hash::secondary_hash>; + static_assert( + has_duplicate(), + "magic_enum::detail::constexpr_switch duplicated hash found, please report it: https://github.com/Neargye/magic_enum/issues."); + constexpr std::array values = *GlobValues; + constexpr std::size_t size = values.size(); + constexpr std::array cases = calculate_cases(Page); + + switch (hash_v(searched)) + { + MAGIC_ENUM_FOR_EACH_256(MAGIC_ENUM_CASE) + default: + if constexpr (size > 256 + Page) + { + return constexpr_switch(std::forward(lambda), + searched, + std::forward( + def)); + } + break; + } + return def(); + } -template > -using entries_t = decltype((entries_v)); +# undef MAGIC_ENUM_CASE -template > -constexpr bool is_sparse() noexcept { - static_assert(is_enum_v, "magic_enum::detail::is_sparse requires enum type."); +#endif - return range_size_v != count_v; -} + } // namespace detail + + // Checks is magic_enum supported compiler. + inline constexpr bool is_magic_enum_supported = + detail::supported::value; + + template + using Enum = detail::enum_concept; + + // Checks whether T is an Unscoped enumeration type. + // Provides the member constant value which is equal to true, if T is an + // [Unscoped + // enumeration](https://en.cppreference.com/w/cpp/language/enum#Unscoped_enumeration) + // type. Otherwise, value is equal to false. + template + struct is_unscoped_enum : detail::is_unscoped_enum + {}; + + template + inline constexpr bool is_unscoped_enum_v = is_unscoped_enum::value; + + // Checks whether T is an Scoped enumeration type. + // Provides the member constant value which is equal to true, if T is an + // [Scoped + // enumeration](https://en.cppreference.com/w/cpp/language/enum#Scoped_enumerations) + // type. Otherwise, value is equal to false. + template + struct is_scoped_enum : detail::is_scoped_enum + {}; + + template + inline constexpr bool is_scoped_enum_v = is_scoped_enum::value; + + // If T is a complete enumeration type, provides a member typedef type that + // names the underlying type of T. Otherwise, if T is not an enumeration type, + // there is no member type. Otherwise (T is an incomplete enumeration type), + // the program is ill-formed. + template + struct underlying_type : detail::underlying_type + {}; + + template + using underlying_type_t = typename underlying_type::type; + + template + using enum_constant = detail::enum_constant; + + // Returns type name of enum. + template + [[nodiscard]] constexpr auto + enum_type_name() noexcept -> detail::enable_if_t + { + constexpr string_view name = detail::type_name_v>; + static_assert(!name.empty(), + "magic_enum::enum_type_name enum type does not have a name."); -template -inline constexpr bool is_sparse_v = is_sparse(); + return name; + } -template > -constexpr std::size_t undex(U value) noexcept { - static_assert(is_enum_v, "magic_enum::detail::undex requires enum type."); + // Returns number of enum values. + template > + [[nodiscard]] constexpr auto + enum_count() noexcept -> detail::enable_if_t + { + return detail::count_v, S>; + } - if (const auto i = static_cast(value - min_v); value >= min_v && value <= max_v) { - if constexpr (is_sparse_v) { - if (const auto idx = indexes_v[i]; idx != invalid_index_v) { - return idx; + // Returns enum value at specified index. + // No bounds checking is performed: the behavior is undefined if index >= + // number of enum values. + template > + [[nodiscard]] constexpr auto + enum_value(std::size_t index) noexcept + -> detail::enable_if_t> + { + using D = std::decay_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + + if constexpr (detail::is_sparse_v) + { + return MAGIC_ENUM_ASSERT(index < detail::count_v), + detail::values_v[index]; + } + else + { + constexpr auto min = (S == detail::enum_subtype::flags) ? + detail::log2(detail::min_v) : + detail::min_v; + + return MAGIC_ENUM_ASSERT(index < detail::count_v), + detail::value(index); } - } else { - return i; - } } - return invalid_index_v; // Value out of range. -} - -template > -constexpr std::size_t endex(E value) noexcept { - static_assert(is_enum_v, "magic_enum::detail::endex requires enum type."); - - return undex(static_cast(value)); -} - -template > -constexpr U value_ors() noexcept { - static_assert(is_enum_v, "magic_enum::detail::endex requires enum type."); - - auto value = U{0}; - for (std::size_t i = 0; i < count_v; ++i) { - value |= static_cast(values_v[i]); + // Returns enum value at specified index. + template > + [[nodiscard]] constexpr auto + enum_value() noexcept -> detail::enable_if_t> + { + using D = std::decay_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + static_assert(I < detail::count_v, + "magic_enum::enum_value out of range."); + + return enum_value(I); } - return value; -} - -template -struct enable_if_enum {}; - -template -struct enable_if_enum { - using type = R; - using D = std::decay_t; - static_assert(supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); -}; - -template -using enable_if_enum_t = std::enable_if_t>, R>; - -template >>> -using enum_concept = T; - -template > -struct is_scoped_enum : std::false_type {}; - -template -struct is_scoped_enum : std::bool_constant>> {}; - -template > -struct is_unscoped_enum : std::false_type {}; - -template -struct is_unscoped_enum : std::bool_constant>> {}; - -template >> -struct underlying_type {}; - -template -struct underlying_type : std::underlying_type> {}; - -} // namespace magic_enum::detail - -// Checks is magic_enum supported compiler. -inline constexpr bool is_magic_enum_supported = detail::supported::value; - -template -using Enum = detail::enum_concept; - -// Checks whether T is an Unscoped enumeration type. -// Provides the member constant value which is equal to true, if T is an [Unscoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Unscoped_enumeration) type. Otherwise, value is equal to false. -template -struct is_unscoped_enum : detail::is_unscoped_enum {}; - -template -inline constexpr bool is_unscoped_enum_v = is_unscoped_enum::value; - -// Checks whether T is an Scoped enumeration type. -// Provides the member constant value which is equal to true, if T is an [Scoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Scoped_enumerations) type. Otherwise, value is equal to false. -template -struct is_scoped_enum : detail::is_scoped_enum {}; - -template -inline constexpr bool is_scoped_enum_v = is_scoped_enum::value; - -// If T is a complete enumeration type, provides a member typedef type that names the underlying type of T. -// Otherwise, if T is not an enumeration type, there is no member type. Otherwise (T is an incomplete enumeration type), the program is ill-formed. -template -struct underlying_type : detail::underlying_type {}; - -template -using underlying_type_t = typename underlying_type::type; - -// Returns type name of enum. -template -[[nodiscard]] constexpr auto enum_type_name() noexcept -> detail::enable_if_enum_t { - using D = std::decay_t; - constexpr string_view name = detail::type_name_v; - static_assert(name.size() > 0, "Enum type does not have a name."); - - return name; -} - -// Returns number of enum values. -template -[[nodiscard]] constexpr auto enum_count() noexcept -> detail::enable_if_enum_t { - using D = std::decay_t; - - return detail::count_v; -} - -// Returns enum value at specified index. -// No bounds checking is performed: the behavior is undefined if index >= number of enum values. -template -[[nodiscard]] constexpr auto enum_value(std::size_t index) noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); - - if constexpr (detail::is_sparse_v) { - return assert((index < detail::count_v)), detail::values_v[index]; - } else { - return assert((index < detail::count_v)), detail::value>(index); + // Returns std::array with enum values, sorted by enum value. + template > + [[nodiscard]] constexpr auto + enum_values() noexcept -> detail::enable_if_t> + { + using D = std::decay_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + + return detail::values_v; } -} - -// Returns enum value at specified index. -template -[[nodiscard]] constexpr auto enum_value() noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); - static_assert(I < detail::count_v, "magic_enum::enum_value out of range."); - - return detail::values_v[I]; -} - -// Returns std::array with enum values, sorted by enum value. -template -[[nodiscard]] constexpr auto enum_values() noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); - - return detail::values_v; -} - -// Returns name from static storage enum variable. -// This version is much lighter on the compile times and is not restricted to the enum_range limitation. -template -[[nodiscard]] constexpr auto enum_name() noexcept -> detail::enable_if_enum_t { - using D = std::decay_t; - constexpr string_view name = detail::enum_name_v; - static_assert(name.size() > 0, "Enum value does not have a name."); - - return name; -} - -// Returns name from enum value. -// If enum value does not have name or value out of range, returns empty string. -template -[[nodiscard]] constexpr auto enum_name(E value) noexcept -> detail::enable_if_enum_t { - using D = std::decay_t; - - if (const auto i = detail::endex(value); i != detail::invalid_index_v) { - return detail::names_v[i]; - } - - return {}; // Invalid value or out of range. -} - -// Returns std::array with names, sorted by enum value. -template -[[nodiscard]] constexpr auto enum_names() noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); - - return detail::names_v; -} - -// Returns std::array with pairs (value, name), sorted by enum value. -template -[[nodiscard]] constexpr auto enum_entries() noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); - return detail::entries_v; -} - -// Obtains enum value from integer value. -// Returns optional with enum value. -template -[[nodiscard]] constexpr auto enum_cast(underlying_type_t value) noexcept -> detail::enable_if_enum_t>> { - using D = std::decay_t; - - if (detail::undex(value) != detail::invalid_index_v) { - return static_cast(value); + // Returns integer value from enum value. + template + [[nodiscard]] constexpr auto + enum_integer(E value) noexcept -> detail::enable_if_t> + { + return static_cast>(value); } - return {}; // Invalid value or out of range. -} - -// Obtains enum value from name. -// Returns optional with enum value. -template -[[nodiscard]] constexpr auto enum_cast(string_view value, BinaryPredicate p) noexcept(std::is_nothrow_invocable_r_v) -> detail::enable_if_enum_t>> { - static_assert(std::is_invocable_r_v, "magic_enum::enum_cast requires bool(char, char) invocable predicate."); - using D = std::decay_t; - - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (detail::cmp_equal(value, detail::names_v[i], p)) { - return enum_value(i); - } + // Returns underlying value from enum value. + template + [[nodiscard]] constexpr auto + enum_underlying(E value) noexcept + -> detail::enable_if_t> + { + return static_cast>(value); } - return {}; // Invalid value or out of range. -} - -// Obtains enum value from name. -// Returns optional with enum value. -template -[[nodiscard]] constexpr auto enum_cast(string_view value) noexcept -> detail::enable_if_enum_t>> { - using D = std::decay_t; - - return enum_cast(value, detail::char_equal_to{}); -} - -// Returns integer value from enum value. -template -[[nodiscard]] constexpr auto enum_integer(E value) noexcept -> detail::enable_if_enum_t> { - return static_cast>(value); -} - -// Obtains index in enum values from enum value. -// Returns optional with index. -template -[[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - - if (const auto i = detail::endex(value); i != detail::invalid_index_v) { - return i; + // Obtains index in enum values from enum value. + // Returns optional with index. + template > + [[nodiscard]] constexpr auto + enum_index(E value) noexcept -> detail::enable_if_t> + { + using D = std::decay_t; + using U = underlying_type_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + + if constexpr (detail::is_sparse_v || + (S == detail::enum_subtype::flags)) + { +#if defined(MAGIC_ENUM_ENABLE_HASH) + return detail::constexpr_switch<&detail::values_v, + detail::case_call_t::index>( + [](std::size_t i) { return optional{i}; }, + value, + detail::default_result_type_lambda>); +#else + for (std::size_t i = 0; i < detail::count_v; ++i) + { + if (enum_value(i) == value) + { + return i; + } + } + return {}; // Invalid value or out of range. +#endif + } + else + { + const auto v = static_cast(value); + if (v >= detail::min_v && v <= detail::max_v) + { + return static_cast(v - detail::min_v); + } + return {}; // Invalid value or out of range. + } } - return {}; // Invalid value or out of range. -} - -// Checks whether enum contains enumerator with such enum value. -template -[[nodiscard]] constexpr auto enum_contains(E value) noexcept -> detail::enable_if_enum_t { - using D = std::decay_t; - - return detail::endex(value) != detail::invalid_index_v; -} - -// Checks whether enum contains enumerator with such integer value. -template -[[nodiscard]] constexpr auto enum_contains(underlying_type_t value) noexcept -> detail::enable_if_enum_t { - using D = std::decay_t; - - return detail::undex(value) != detail::invalid_index_v; -} - -// Checks whether enum contains enumerator with such name. -template -[[nodiscard]] constexpr auto enum_contains(string_view value, BinaryPredicate p) noexcept(std::is_nothrow_invocable_r_v) -> detail::enable_if_enum_t { - static_assert(std::is_invocable_r_v, "magic_enum::enum_contains requires bool(char, char) invocable predicate."); - using D = std::decay_t; - - return enum_cast(value, std::move_if_noexcept(p)).has_value(); -} - -// Checks whether enum contains enumerator with such name. -template -[[nodiscard]] constexpr auto enum_contains(string_view value) noexcept -> detail::enable_if_enum_t { - using D = std::decay_t; - - return enum_cast(value).has_value(); -} - -namespace ostream_operators { - -template , int> = 0> -std::basic_ostream& operator<<(std::basic_ostream& os, E value) { - using D = std::decay_t; - using U = underlying_type_t; -#if defined(MAGIC_ENUM_SUPPORTED) && MAGIC_ENUM_SUPPORTED - if (const auto name = magic_enum::enum_name(value); !name.empty()) { - for (const auto c : name) { - os.put(c); - } - return os; + // Obtains index in enum values from enum value. + // Returns optional with index. + template + [[nodiscard]] constexpr auto + enum_index(E value) noexcept -> detail::enable_if_t> + { + using D = std::decay_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + + return enum_index(value); } -#endif - return (os << static_cast(value)); -} - -template , int> = 0> -std::basic_ostream& operator<<(std::basic_ostream& os, optional value) { - return value.has_value() ? (os << value.value()) : os; -} - -} // namespace magic_enum::ostream_operators - -namespace bitwise_operators { - -template , int> = 0> -constexpr E operator~(E rhs) noexcept { - return static_cast(~static_cast>(rhs)); -} - -template , int> = 0> -constexpr E operator|(E lhs, E rhs) noexcept { - return static_cast(static_cast>(lhs) | static_cast>(rhs)); -} - -template , int> = 0> -constexpr E operator&(E lhs, E rhs) noexcept { - return static_cast(static_cast>(lhs) & static_cast>(rhs)); -} - -template , int> = 0> -constexpr E operator^(E lhs, E rhs) noexcept { - return static_cast(static_cast>(lhs) ^ static_cast>(rhs)); -} - -template , int> = 0> -constexpr E& operator|=(E& lhs, E rhs) noexcept { - return lhs = (lhs | rhs); -} - -template , int> = 0> -constexpr E& operator&=(E& lhs, E rhs) noexcept { - return lhs = (lhs & rhs); -} -template , int> = 0> -constexpr E& operator^=(E& lhs, E rhs) noexcept { - return lhs = (lhs ^ rhs); -} - -} // namespace magic_enum::bitwise_operators - -namespace flags { - -// Returns type name of enum. -using magic_enum::enum_type_name; - -// Returns number of enum-flags values. -template -[[nodiscard]] constexpr auto enum_count() noexcept -> detail::enable_if_enum_t { - using D = std::decay_t; - - return detail::count_v; -} - -// Returns enum-flags value at specified index. -// No bounds checking is performed: the behavior is undefined if index >= number of enum-flags values. -template -[[nodiscard]] constexpr auto enum_value(std::size_t index) noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - static_assert(detail::count_v > 0, "magic_enum::flags requires enum-flags implementation."); + // Obtains index in enum values from static storage enum variable. + template < + auto V, + detail::enum_subtype S = detail::subtype_v>> + [[nodiscard]] constexpr auto + enum_index() noexcept -> detail::enable_if_t + { + using D = std::decay_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + constexpr auto index = enum_index(V); + static_assert(index, + "magic_enum::enum_index enum value does not have a index."); + + return *index; + } - if constexpr (detail::is_sparse_v) { - return assert((index < detail::count_v)), detail::values_v[index]; - } else { - constexpr auto min = detail::log2(detail::min_v); + // Returns name from static storage enum variable. + // This version is much lighter on the compile times and is not restricted to + // the enum_range limitation. + template + [[nodiscard]] constexpr auto + enum_name() noexcept -> detail::enable_if_t + { + constexpr string_view name = + detail::enum_name_v, V>; + static_assert(!name.empty(), + "magic_enum::enum_name enum value does not have a name."); - return assert((index < detail::count_v)), detail::value(index); + return name; } -} - -// Returns enum-flags value at specified index. -template -[[nodiscard]] constexpr auto enum_value() noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - static_assert(detail::count_v > 0, "magic_enum::flags requires enum implementation and valid max and min."); - static_assert(I < detail::count_v, "magic_enum::flags::enum_value out of range."); - - return detail::values_v[I]; -} - -// Returns std::array with enum-flags values, sorted by enum-flags value. -template -[[nodiscard]] constexpr auto enum_values() noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - static_assert(detail::count_v > 0, "magic_enum::flags requires enum-flags implementation."); - - return detail::values_v; -} - -// Returns name from enum-flags value. -// If enum-flags value does not have name or value out of range, returns empty string. -template -[[nodiscard]] auto enum_name(E value) -> detail::enable_if_enum_t { - using D = std::decay_t; - using U = underlying_type_t; - - string name; - auto check_value = U{0}; - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (const auto v = static_cast(enum_value(i)); (static_cast(value) & v) != 0) { - check_value |= v; - const auto n = detail::names_v[i]; - if (!name.empty()) { - name.append(1, '|'); + + // Returns name from enum value. + // If enum value does not have name or value out of range, returns empty + // string. + template > + [[nodiscard]] constexpr auto + enum_name(E value) noexcept -> detail::enable_if_t + { + using D = std::decay_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + + if (const auto i = enum_index(value)) + { + return detail::names_v[*i]; } - name.append(n.data(), n.size()); - } + return {}; } - if (check_value != 0 && check_value == static_cast(value)) { - return name; + // Returns name from enum value. + // If enum value does not have name or value out of range, returns empty + // string. + template + [[nodiscard]] constexpr auto + enum_name(E value) -> detail::enable_if_t + { + using D = std::decay_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + + return enum_name(value); } - return {}; // Invalid value or out of range. -} - -// Returns std::array with string names, sorted by enum-flags value. -template -[[nodiscard]] constexpr auto enum_names() noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - static_assert(detail::count_v > 0, "magic_enum::flags requires enum-flags implementation."); - - return detail::names_v; -} - -// Returns std::array with pairs (value, name), sorted by enum-flags value. -template -[[nodiscard]] constexpr auto enum_entries() noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - static_assert(detail::count_v > 0, "magic_enum::flags requires enum-flags implementation."); - - return detail::entries_v; -} - -// Obtains enum-flags value from integer value. -// Returns optional with enum-flags value. -template -[[nodiscard]] constexpr auto enum_cast(underlying_type_t value) noexcept -> detail::enable_if_enum_t>> { - using D = std::decay_t; - using U = underlying_type_t; - - if constexpr (detail::is_sparse_v) { - auto check_value = U{0}; - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (const auto v = static_cast(enum_value(i)); (value & v) != 0) { - check_value |= v; - } - } - - if (check_value != 0 && check_value == value) { - return static_cast(value); - } - } else { - constexpr auto min = detail::min_v; - constexpr auto max = detail::value_ors(); + // Returns std::array with names, sorted by enum value. + template > + [[nodiscard]] constexpr auto + enum_names() noexcept -> detail::enable_if_t> + { + using D = std::decay_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + + return detail::names_v; + } - if (value >= min && value <= max) { - return static_cast(value); - } + // Returns std::array with pairs (value, name), sorted by enum value. + template > + [[nodiscard]] constexpr auto + enum_entries() noexcept -> detail::enable_if_t> + { + using D = std::decay_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + + return detail::entries_v; } - return {}; // Invalid value or out of range. -} - -// Obtains enum-flags value from name. -// Returns optional with enum-flags value. -template -[[nodiscard]] constexpr auto enum_cast(string_view value, BinaryPredicate p) noexcept(std::is_nothrow_invocable_r_v) -> detail::enable_if_enum_t>> { - static_assert(std::is_invocable_r_v, "magic_enum::flags::enum_cast requires bool(char, char) invocable predicate."); - using D = std::decay_t; - using U = underlying_type_t; - - auto result = U{0}; - while (!value.empty()) { - const auto d = detail::find(value, '|'); - const auto s = (d == string_view::npos) ? value : value.substr(0, d); - auto f = U{0}; - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (detail::cmp_equal(s, detail::names_v[i], p)) { - f = static_cast(enum_value(i)); - result |= f; - break; + // Allows you to write magic_enum::enum_cast("bar", + // magic_enum::case_insensitive); + inline constexpr auto case_insensitive = detail::case_insensitive<>{}; + + // Obtains enum value from integer value. + // Returns optional with enum value. + template > + [[nodiscard]] constexpr auto + enum_cast(underlying_type_t value) noexcept + -> detail::enable_if_t>> + { + using D = std::decay_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + + if constexpr (detail::is_sparse_v || + (S == detail::enum_subtype::flags)) + { +#if defined(MAGIC_ENUM_ENABLE_HASH) + return detail::constexpr_switch<&detail::values_v, + detail::case_call_t::value>( + [](D v) { return optional{v}; }, + static_cast(value), + detail::default_result_type_lambda>); +#else + for (std::size_t i = 0; i < detail::count_v; ++i) + { + if (value == static_cast>(enum_value(i))) + { + return static_cast(value); + } + } + return {}; // Invalid value or out of range. +#endif + } + else + { + if (value >= detail::min_v && value <= detail::max_v) + { + return static_cast(value); + } + return {}; // Invalid value or out of range. } - } - if (f == U{0}) { - return {}; // Invalid value or out of range. - } - value.remove_prefix((d == string_view::npos) ? value.size() : d + 1); } - if (result == U{0}) { - return {}; // Invalid value or out of range. - } else { - return static_cast(result); - } -} - -// Obtains enum-flags value from name. -// Returns optional with enum-flags value. -template -[[nodiscard]] constexpr auto enum_cast(string_view value) noexcept -> detail::enable_if_enum_t>> { - using D = std::decay_t; - - return enum_cast(value, detail::char_equal_to{}); -} - -// Returns integer value from enum value. -using magic_enum::enum_integer; - -// Obtains index in enum-flags values from enum-flags value. -// Returns optional with index. -template -[[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_enum_t> { - using D = std::decay_t; - using U = underlying_type_t; - - if (detail::is_pow2(static_cast(value))) { - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (enum_value(i) == value) { - return i; + // Obtains enum value from name. + // Returns optional with enum value. + template , + typename BinaryPredicate = std::equal_to<>> + [[nodiscard]] constexpr auto + enum_cast(string_view value, + [[maybe_unused]] BinaryPredicate p = + {}) noexcept(detail::is_nothrow_invocable()) + -> detail::enable_if_t>, BinaryPredicate> + { + using D = std::decay_t; + static_assert( + detail::is_reflected_v, + "magic_enum requires enum implementation and valid max and min."); + +#if defined(MAGIC_ENUM_ENABLE_HASH) + if constexpr (detail::is_default_predicate()) + { + return detail::constexpr_switch<&detail::names_v, + detail::case_call_t::index>( + [](std::size_t i) { return optional{detail::values_v[i]}; }, + value, + detail::default_result_type_lambda>, + [&p](string_view lhs, string_view rhs) { + return detail::cmp_equal(lhs, rhs, p); + }); } - } +#endif + for (std::size_t i = 0; i < detail::count_v; ++i) + { + if (detail::cmp_equal(value, detail::names_v[i], p)) + { + return enum_value(i); + } + } + return {}; // Invalid value or out of range. } - return {}; // Invalid value or out of range. -} + // Checks whether enum contains value with such value. + template > + [[nodiscard]] constexpr auto + enum_contains(E value) noexcept -> detail::enable_if_t + { + using D = std::decay_t; + using U = underlying_type_t; -// Checks whether enum-flags contains enumerator with such enum-flags value. -template -[[nodiscard]] constexpr auto enum_contains(E value) noexcept -> detail::enable_if_enum_t { - using D = std::decay_t; - using U = underlying_type_t; + return static_cast(enum_cast(static_cast(value))); + } - return enum_cast(static_cast(value)).has_value(); -} + // Checks whether enum contains value with such value. + template + [[nodiscard]] constexpr auto + enum_contains(E value) noexcept -> detail::enable_if_t + { + using D = std::decay_t; + using U = underlying_type_t; -// Checks whether enum-flags contains enumerator with such integer value. -template -[[nodiscard]] constexpr auto enum_contains(underlying_type_t value) noexcept -> detail::enable_if_enum_t { - using D = std::decay_t; + return static_cast(enum_cast(static_cast(value))); + } - return enum_cast(value).has_value(); -} + // Checks whether enum contains value with such integer value. + template > + [[nodiscard]] constexpr auto + enum_contains(underlying_type_t value) noexcept + -> detail::enable_if_t + { + using D = std::decay_t; -// Checks whether enum-flags contains enumerator with such name. -template -[[nodiscard]] constexpr auto enum_contains(string_view value, BinaryPredicate p) noexcept(std::is_nothrow_invocable_r_v) -> detail::enable_if_enum_t { - static_assert(std::is_invocable_r_v, "magic_enum::flags::enum_contains requires bool(char, char) invocable predicate."); - using D = std::decay_t; + return static_cast(enum_cast(value)); + } - return enum_cast(value, std::move_if_noexcept(p)).has_value(); -} + // Checks whether enum contains enumerator with such name. + template , + typename BinaryPredicate = std::equal_to<>> + [[nodiscard]] constexpr auto + enum_contains(string_view value, BinaryPredicate p = {}) noexcept( + detail::is_nothrow_invocable()) + -> detail::enable_if_t + { + using D = std::decay_t; + + return static_cast(enum_cast(value, std::move(p))); + } -// Checks whether enum-flags contains enumerator with such name. -template -[[nodiscard]] constexpr auto enum_contains(string_view value) noexcept -> detail::enable_if_enum_t { - using D = std::decay_t; + template + inline constexpr auto as_flags = + AsFlags ? detail::enum_subtype::flags : detail::enum_subtype::common; - return enum_cast(value).has_value(); -} + template + inline constexpr auto as_common = + AsFlags ? detail::enum_subtype::common : detail::enum_subtype::flags; -} // namespace magic_enum::flags + namespace bitwise_operators + { -namespace flags::ostream_operators { + template = 0> + constexpr E + operator~(E rhs) noexcept + { + return static_cast(~static_cast>(rhs)); + } -template , int> = 0> -std::basic_ostream& operator<<(std::basic_ostream& os, E value) { - using D = std::decay_t; - using U = underlying_type_t; -#if defined(MAGIC_ENUM_SUPPORTED) && MAGIC_ENUM_SUPPORTED - if (const auto name = magic_enum::flags::enum_name(value); !name.empty()) { - for (const auto c : name) { - os.put(c); + template = 0> + constexpr E + operator|(E lhs, E rhs) noexcept + { + return static_cast(static_cast>(lhs) | + static_cast>(rhs)); } - return os; - } -#endif - return (os << static_cast(value)); -} -template , int> = 0> -std::basic_ostream& operator<<(std::basic_ostream& os, optional value) { - return value.has_value() ? (os << value.value()) : os; -} + template = 0> + constexpr E + operator&(E lhs, E rhs) noexcept + { + return static_cast(static_cast>(lhs) & + static_cast>(rhs)); + } -} // namespace magic_enum::flags::ostream_operators + template = 0> + constexpr E + operator^(E lhs, E rhs) noexcept + { + return static_cast(static_cast>(lhs) ^ + static_cast>(rhs)); + } -namespace flags::bitwise_operators { + template = 0> + constexpr E & + operator|=(E &lhs, E rhs) noexcept + { + return lhs = (lhs | rhs); + } -using namespace magic_enum::bitwise_operators; + template = 0> + constexpr E & + operator&=(E &lhs, E rhs) noexcept + { + return lhs = (lhs & rhs); + } -} // namespace magic_enum::flags::bitwise_operators + template = 0> + constexpr E & + operator^=(E &lhs, E rhs) noexcept + { + return lhs = (lhs ^ rhs); + } + + } // namespace bitwise_operators } // namespace magic_enum @@ -1161,4 +2201,10 @@ using namespace magic_enum::bitwise_operators; # pragma warning(pop) #endif +#undef MAGIC_ENUM_GET_ENUM_NAME_BUILTIN +#undef MAGIC_ENUM_GET_TYPE_NAME_BUILTIN +#undef MAGIC_ENUM_VS_2017_WORKAROUND +#undef MAGIC_ENUM_ARRAY_CONSTEXPR +#undef MAGIC_ENUM_FOR_EACH_256 + #endif // NEARGYE_MAGIC_ENUM_HPP diff --git a/source/runner.cc b/source/runner.cc index 2f722da2f..1573404ac 100644 --- a/source/runner.cc +++ b/source/runner.cc @@ -28,12 +28,69 @@ using namespace dealii; namespace Runner { + /** + * \brief Retrieves the dimension and space dimension from a parameter file. + * + * This function reads a parameter file and retrieves the values of the + * "dimension" and "space dimension" parameters. If the reading of the input + * file fails, it returns the default values provided. + * + * @p prm_file The path to the parameter file. @p default_dim The + * default value for the dimension. @p default_spacedim The default value + * for the space dimension. \return A pair containing the dimension and space + * dimension. + * + * \throws std::exception If an error occurs while parsing the input file. + */ + std::pair + get_dimension_and_spacedimension(const std::string &prm_file, + const unsigned int default_dim = 2, + const unsigned int default_spacedim = 2) + { + ParameterAcceptor::prm.declare_entry("dim", + std::to_string(default_dim), + Patterns::Integer(1, 3)); + ParameterAcceptor::prm.declare_entry("spacedim", + std::to_string(default_spacedim), + Patterns::Integer(1, 3)); + try + { + ParameterAcceptor::prm.parse_input(prm_file, "", true); + auto dim = ParameterAcceptor::prm.get_integer("dim"); + auto spacedim = ParameterAcceptor::prm.get_integer("spacedim"); + return {dim, spacedim}; + } + catch (std::exception &exc) + { + return {default_dim, default_spacedim}; + throw; + } + } + + + /** + * Retrieves the dimensions and parameter files from the command line + * arguments. + * + * This function parses the command line arguments and extracts the dimensions + * and parameter file names. It supports both options and positional arguments + * for specifying the input parameter file. It also checks if the dimensions + * specified in the parameter file and the command line arguments match. + * + * @param argv The command line arguments. + * @return A tuple containing the dimensions and parameter file names. + * The tuple elements are in the following order: + * - int: The dimension. + * - int: The space dimension. + * - std::string: The input parameter file name. + * - std::string: The output parameter file name. + */ std::tuple get_dimensions_and_parameter_files(char **argv) { argh::parser cli(argv, argh::parser::PREFER_PARAM_FOR_UNREG_OPTION); - int dim = 2; - int spacedim = 2; + unsigned int dim = 2; + unsigned int spacedim = 2; std::string input_parameter_file = ""; std::string output_parameter_file = ""; @@ -45,72 +102,30 @@ namespace Runner cli({"i", "input_prm_file"}, input_parameter_file) >> input_parameter_file; cli(1, input_parameter_file) >> input_parameter_file; - // Now the logic to deduce dim and spacedim from the parameter file name - bool file_contains_dim_spacedim = false; - if (input_parameter_file.find("1d_2d") != std::string::npos) - { - dim = 1; - spacedim = 2; - file_contains_dim_spacedim = true; - } - else if (input_parameter_file.find("1d_3d") != std::string::npos) - { - dim = 1; - spacedim = 3; - file_contains_dim_spacedim = true; - } - else if (input_parameter_file.find("2d_3d") != std::string::npos) - { - dim = 2; - spacedim = 3; - file_contains_dim_spacedim = true; - } - else if (input_parameter_file.find("1d") != std::string::npos) - { - dim = 1; - spacedim = 1; - file_contains_dim_spacedim = true; - } - else if (input_parameter_file.find("2d") != std::string::npos) - { - dim = 2; - spacedim = 2; - file_contains_dim_spacedim = true; - } - else if (input_parameter_file.find("3d") != std::string::npos) - { - dim = 3; - spacedim = 3; - file_contains_dim_spacedim = true; - } + // Now read from command line the dimension and space dimension + cli({"d", "dim"}) >> dim; + // Make sure the default is to set spacedim = dim + cli({"s", "spacedim"}, dim) >> spacedim; - // Make sure filename and command line arguments agree - if (file_contains_dim_spacedim == true) - { - int cli_dim = dim; - int cli_spacedim = spacedim; - if ((cli({"d", "dim"}) >> cli_dim) || - (cli({"s", "spacedim"}) >> cli_spacedim)) - { - AssertThrow( - (dim == cli_dim) && (spacedim == cli_spacedim), - dealii::ExcMessage( - "You have specified a parameter filename that contains a " - "specification of the dimension and of the space dimension, " - "e.g., 1d_2d but you also indicated a -d or -s argument on the " - "command line that do not match the file name. Use only one of " - "the two ways to select the dimension and the space dimension, " - "or make sure that what you specify on the filename matches " - "what you specify on the command line.")); - } - } - else - { - // get dim and spacedim from command line - cli({"d", "dim"}, dim) >> dim; - // By default spacedim is equal to dim - cli({"s", "spacedim"}, dim) >> spacedim; - } + // And do the same from the parameter file + const auto [prm_dim, prm_spacedim] = + get_dimension_and_spacedimension(input_parameter_file, dim, spacedim); + + // Throw an exception if the inputer parameter file and the command line do + // not agree. Notice that, if the file doees not exist, they will agree, + // since the default values are the same. + AssertThrow( + (dim == prm_dim) && (spacedim == prm_spacedim), + dealii::ExcMessage( + "You have specified a parameter file that contains a specification " + "of the dimension and of the space dimension, as <" + + std::to_string(prm_dim) + ", " + std::to_string(prm_spacedim) + + ">, but you also indicated a -d (--dim) = " + std::to_string(dim) + + " or -s (--spacedim) = " + std::to_string(spacedim) + + "argument on the command line that do not match the content of the parameter file. " + "Use only one of the two ways to select the dimension and the " + "space dimension, or make sure that what you specify in the parameter file " + "matches what you specify on the command line.")); // Now the logic to deduce the output parameter file name. Make sure we // output in the current directory, even if the file is specified with a @@ -121,22 +136,16 @@ namespace Runner input_parameter_file.find_last_of("/") + 1); output_parameter_file = "used_" + rel_name; } - else if (dim == spacedim) - { - output_parameter_file = - "used_" + exename + "_" + std::to_string(dim) + "d.prm"; - } else { - output_parameter_file = "used_" + exename + "_" + std::to_string(dim) + - "d_" + std::to_string(spacedim) + "d.prm"; + output_parameter_file = "used_" + exename + ".prm"; } // If you want to overwrite the output parameter file, use the -o option cli({"o", "output_prm_file"}, output_parameter_file) >> output_parameter_file; - deallog << "Will run in dimension " << dim << " and spacedimemsion " + deallog << "Will run in dimension " << dim << " and spacedimension " << spacedim << std::endl << "Input parameter file: " << input_parameter_file << std::endl << "Output parameter file: " << output_parameter_file << std::endl; @@ -148,8 +157,28 @@ namespace Runner } + /** + * @brief Sets up the program parameters from the command-line arguments. + * + * This function parses the command-line arguments using the `argh` library + * and sets up the program parameters accordingly. It initializes the + * `ParameterAcceptor` with the input and output parameter file paths. If the + * `-h` or `--help` option is provided, it prints the help message and the + * list of available options. The function also handles setting the values for + * options specified in the command-line arguments. It ignores any positional + * arguments other than the program name and the input parameter file. After + * setting up the parameters, it initializes the `ParameterAcceptor` again + * with the output parameter file path. If the `--pause` option is provided + * and the current MPI process is the root process, it waits for a keypress + * before continuing. + * + * @param argv The command-line arguments. + * @param input_parameter_file The path to the input parameter file. + * @param output_parameter_file The path to the output parameter file. + * @return Returns 0 if everything went fine, or 1 if there were any warnings or errors. + */ int - setup_parameters_from_cli(char ** argv, + setup_parameters_from_cli(char **argv, const std::string &input_parameter_file, const std::string &output_parameter_file) { @@ -182,9 +211,7 @@ namespace Runner "Where to write the file containing the actual parameters " "used in this run of the program. It defaults to the string `used_" + exename + - "' followed by a string of the type '1d_2d' " - "containing the dimension and the spacedimension at which the " - "program was run if the input parameter file is not specified, " + "' if the input parameter file is not specified, " "otherwise it defaults to the string `used_' followed by the " "name of the input parameter file.") << std::endl From 02c55ded1ddc4958b39b2df7ee67a6c2fd434a50 Mon Sep 17 00:00:00 2001 From: Luca Heltai Date: Mon, 24 Jun 2024 09:41:58 +0200 Subject: [PATCH 2/5] Make sure dim/spacedim from prm is honored. --- source/runner.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/runner.cc b/source/runner.cc index 1573404ac..d73d37280 100644 --- a/source/runner.cc +++ b/source/runner.cc @@ -102,6 +102,8 @@ namespace Runner cli({"i", "input_prm_file"}, input_parameter_file) >> input_parameter_file; cli(1, input_parameter_file) >> input_parameter_file; + const bool has_dim_or_spacedim = + cli[{"d", "dim"}] || cli[{"s", "spacedim"}]; // Now read from command line the dimension and space dimension cli({"d", "dim"}) >> dim; // Make sure the default is to set spacedim = dim @@ -115,14 +117,14 @@ namespace Runner // not agree. Notice that, if the file doees not exist, they will agree, // since the default values are the same. AssertThrow( - (dim == prm_dim) && (spacedim == prm_spacedim), + !has_dim_or_spacedim || (dim == prm_dim) && (spacedim == prm_spacedim), dealii::ExcMessage( "You have specified a parameter file that contains a specification " "of the dimension and of the space dimension, as <" + std::to_string(prm_dim) + ", " + std::to_string(prm_spacedim) + ">, but you also indicated a -d (--dim) = " + std::to_string(dim) + " or -s (--spacedim) = " + std::to_string(spacedim) + - "argument on the command line that do not match the content of the parameter file. " + " argument on the command line that do not match the content of the parameter file. " "Use only one of the two ways to select the dimension and the " "space dimension, or make sure that what you specify in the parameter file " "matches what you specify on the command line.")); @@ -150,8 +152,8 @@ namespace Runner << "Input parameter file: " << input_parameter_file << std::endl << "Output parameter file: " << output_parameter_file << std::endl; - return std::make_tuple(dim, - spacedim, + return std::make_tuple(prm_dim, + prm_spacedim, input_parameter_file, output_parameter_file); } From c5c1a816eb3b0442e5e1b99d8d5d8d9cdc80e662 Mon Sep 17 00:00:00 2001 From: Luca Heltai Date: Mon, 24 Jun 2024 12:12:41 +0200 Subject: [PATCH 3/5] Indented. --- gtests/compute_linear_transformation.cc | 8 +- gtests/constants.cc | 10 +- gtests/moonolith_intersection.cc | 20 ++-- gtests/moonolith_tools.cc | 12 +-- include/compute_intersections.h | 2 +- include/compute_linear_transformation.h | 6 +- ...parsity_pattern_with_exact_intersections.h | 8 +- include/lac_initializer.h | 42 ++++---- include/moonolith_tools.h | 12 +-- include/parsed_lac/amg.h | 16 +-- include/parsed_lac/amg_muelu.h | 14 +-- include/parsed_lac/amg_petsc.h | 2 +- include/parsed_lac/ilu.h | 6 +- include/parsed_lac/inverse_operator.h | 34 +++---- include/parsed_lac/jacobi.h | 6 +- include/parsed_tools/boundary_conditions.h | 34 +++---- include/parsed_tools/components.h | 2 +- include/parsed_tools/constants.h | 4 +- include/parsed_tools/data_out.h | 22 ++--- include/parsed_tools/enum.h | 4 +- include/parsed_tools/function.h | 2 +- include/parsed_tools/grid_generator.h | 2 +- include/parsed_tools/grid_info.h | 8 +- include/parsed_tools/grid_refinement.h | 74 +++++++------- include/parsed_tools/mapping_eulerian.h | 4 +- include/parsed_tools/non_matching_coupling.h | 10 +- include/parsed_tools/symbolic_function.h | 8 +- include/pdes/linear_elasticity.h | 2 +- include/pdes/linear_problem.h | 8 +- include/pdes/mpi/poisson.h | 2 +- include/pdes/stokes.h | 4 +- include/projection_operator.h | 8 +- include/runner.h | 4 +- ...ng_mass_matrix_with_exact_intersections.cc | 14 +-- ...semble_nitsche_with_exact_intersections.cc | 14 +-- source/boundary_conditions.cc | 8 +- source/components.cc | 2 +- source/compute_intersections.cc | 10 +- source/constants.cc | 4 +- ...arsity_pattern_with_exact_intersections.cc | 98 +++++++++---------- ...te_nitsche_rhs_with_exact_intersections.cc | 6 +- source/data_out.cc | 12 +-- source/function.cc | 2 +- source/grid_generator.cc | 2 +- source/grid_refinement.cc | 18 ++-- source/mapping_eulerian.cc | 6 +- source/non_matching_coupling.cc | 18 ++-- source/parsed_lac/amg.cc | 12 +-- source/parsed_lac/amg_muelu.cc | 14 +-- source/parsed_lac/amg_petsc.cc | 2 +- source/parsed_lac/ilu.cc | 6 +- source/parsed_lac/inverse_operator.cc | 8 +- source/parsed_lac/jacobi.cc | 6 +- source/pdes/linear_elasticity.cc | 8 +- source/pdes/mpi/poisson.cc | 8 +- source/pdes/stokes.cc | 4 +- 56 files changed, 341 insertions(+), 341 deletions(-) diff --git a/gtests/compute_linear_transformation.cc b/gtests/compute_linear_transformation.cc index 63a5835ca..19d448021 100644 --- a/gtests/compute_linear_transformation.cc +++ b/gtests/compute_linear_transformation.cc @@ -62,8 +62,8 @@ TEST(DimTester, IntegralOverLine) Test_function fun{}; double sum = 0.; - const auto & quad_points = real_quadrature.get_points(); - const auto & JxW = real_quadrature.get_weights(); + const auto &quad_points = real_quadrature.get_points(); + const auto &JxW = real_quadrature.get_weights(); const unsigned int size_quad_form = quad_points.size(); for (unsigned int q = 0; q < size_quad_form; ++q) { @@ -101,8 +101,8 @@ TEST(DimTester, IntegrationTestCodimension0) // exponent of the polynomial function to be integrated, and the exactness of // the quadrature formula Test_polynomial func; - const auto & xq = quad_rule_over_triangle.get_points(); - const auto & JxW = quad_rule_over_triangle.get_weights(); + const auto &xq = quad_rule_over_triangle.get_points(); + const auto &JxW = quad_rule_over_triangle.get_weights(); const unsigned int n_q_pts = JxW.size(); double sum = 0.; for (unsigned int q = 0; q < n_q_pts; ++q) diff --git a/gtests/constants.cc b/gtests/constants.cc index 2d7930ff3..3d1a174a0 100644 --- a/gtests/constants.cc +++ b/gtests/constants.cc @@ -48,11 +48,11 @@ TEST(Constants, CheckConstants) TEST(Constants, FunctionAndConstants) { ParsedTools::Constants constants("/", - {"a", "b", "c"}, - {1.0, 2.0, 3.0}, - {"The constant a", - "The constant b", - "The constant c"}); + {"a", "b", "c"}, + {1.0, 2.0, 3.0}, + {"The constant a", + "The constant b", + "The constant c"}); ParsedTools::Function<1> function( "/", "a*x^2+b*x+c", "Function expression", constants, "x,y"); diff --git a/gtests/moonolith_intersection.cc b/gtests/moonolith_intersection.cc index d0c88dd04..de3affcea 100644 --- a/gtests/moonolith_intersection.cc +++ b/gtests/moonolith_intersection.cc @@ -83,9 +83,9 @@ TEST(MoonoLith, CheckTetra) poly1.el_ptr = {0, 3, 6, 9, 12}; // poly1.el_index = {0, 2, 1, 0, 3, 2, 0, 1, 3, 1, 2, 3}; // faces poly1.points = {{0.0, 0.0, 0.0}, - {1.0, 0.0, 0.0}, - {0.0, 1.0, 0.0}, - {0.0, 0.0, 1.0}}; + {1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; poly2 = poly1; poly2.points = {{0.0, 0.0, 0.0}, @@ -201,13 +201,13 @@ TEST(MoonoLith, CheckExahedra) poly1.el_index = {0, 1, 2, 3, 1, 2, 6, 5, 2, 6, 7, 3, 0, 3, 7, 4, 0, 1, 5, 4, 4, 5, 6, 7}; poly1.points = {{0, 0, 0}, - {1, 0, 0}, - {1, 1, 0}, - {0, 1, 0}, - {0, 0, 1}, - {1, 0, 1}, - {1, 1, 1}, - {0, 1, 1}}; + {1, 0, 0}, + {1, 1, 0}, + {0, 1, 0}, + {0, 0, 1}, + {1, 0, 1}, + {1, 1, 1}, + {0, 1, 1}}; poly1.fix_ordering(); auto vol1 = moonolith::measure(poly1); ASSERT_NEAR(vol1, 1, 1e-10); diff --git a/gtests/moonolith_tools.cc b/gtests/moonolith_tools.cc index 20954381e..8ed8a4a80 100644 --- a/gtests/moonolith_tools.cc +++ b/gtests/moonolith_tools.cc @@ -159,9 +159,9 @@ TYPED_TEST(DimSpacedimTester, AllMoonolithConversions) std::vector> d2t = {{}, {2}, {3, 4}, {4, 5, 6, 8}}; std::vector> measures = {{}, - {1}, - {0.5, 1.0}, - {1. / 6., 4. / 3., 0.5, 1}}; + {1}, + {0.5, 1.0}, + {1. / 6., 4. / 3., 0.5, 1}}; unsigned int i = 0; for (const auto nv : d2t[dim]) @@ -187,9 +187,9 @@ TYPED_TEST(DimSpacedimTesterNoOne, AllMoonolithConversionsRotated) std::vector> d2t = {{}, {2}, {3, 4}, {4, 5, 6, 8}}; std::vector> measures = {{}, - {1}, - {0.5, 1.0}, - {1. / 6., 4. / 3., 0.5, 1}}; + {1}, + {0.5, 1.0}, + {1. / 6., 4. / 3., 0.5, 1}}; unsigned int i = 0; for (const auto nv : d2t[dim]) diff --git a/include/compute_intersections.h b/include/compute_intersections.h index d30c629a8..d67d3e520 100644 --- a/include/compute_intersections.h +++ b/include/compute_intersections.h @@ -58,7 +58,7 @@ namespace dealii const typename dealii::Triangulation::cell_iterator &cell0, const typename dealii::Triangulation::cell_iterator - & cell1, + &cell1, const unsigned int degree, const dealii::Mapping &mapping0 = (dealii::ReferenceCells::get_hypercube() diff --git a/include/compute_linear_transformation.h b/include/compute_linear_transformation.h index c46c70188..931686279 100644 --- a/include/compute_linear_transformation.h +++ b/include/compute_linear_transformation.h @@ -41,7 +41,7 @@ template dealii::Quadrature compute_linear_transformation( - const dealii::Quadrature & quadrature, + const dealii::Quadrature &quadrature, const std::array, N> &vertices); @@ -51,7 +51,7 @@ compute_linear_transformation( template dealii::Quadrature compute_linear_transformation( - const dealii::Quadrature & quadrature, + const dealii::Quadrature &quadrature, const std::array, N> &vertices) { Assert(N > 1, dealii::ExcInternalError()); @@ -68,7 +68,7 @@ compute_linear_transformation( quadrature, dealii::update_quadrature_points | dealii::update_JxW_values); - const auto & cell = dh.begin_active(); + const auto &cell = dh.begin_active(); for (unsigned int i = 0; i < N; ++i) cell->vertex(i) = vertices[i]; // the vertices of this real cell fe_values.reinit(cell); diff --git a/include/create_coupling_sparsity_pattern_with_exact_intersections.h b/include/create_coupling_sparsity_pattern_with_exact_intersections.h index a579b41ce..c3119ba26 100644 --- a/include/create_coupling_sparsity_pattern_with_exact_intersections.h +++ b/include/create_coupling_sparsity_pattern_with_exact_intersections.h @@ -78,11 +78,11 @@ namespace dealii dealii::Quadrature>> &intersections_info, const DoFHandler &space_dh, const DoFHandler &immersed_dh, - Sparsity & sparsity, - const AffineConstraints & constraints = + Sparsity &sparsity, + const AffineConstraints &constraints = AffineConstraints(), - const ComponentMask & space_comps = ComponentMask(), - const ComponentMask & immersed_comps = ComponentMask(), + const ComponentMask &space_comps = ComponentMask(), + const ComponentMask &immersed_comps = ComponentMask(), const AffineConstraints &immersed_constraints = AffineConstraints()); diff --git a/include/lac_initializer.h b/include/lac_initializer.h index 978c3db94..3c8b32cab 100644 --- a/include/lac_initializer.h +++ b/include/lac_initializer.h @@ -32,9 +32,9 @@ namespace LAC public: BlockInitializer( const std::vector &dofs_per_block, - const std::vector & owned, - const std::vector & relevant, - const MPI_Comm & comm = MPI_COMM_WORLD) + const std::vector &owned, + const std::vector &relevant, + const MPI_Comm &comm = MPI_COMM_WORLD) : dofs_per_block(dofs_per_block) , owned(owned) , relevant(relevant) @@ -104,9 +104,9 @@ namespace LAC */ template void - operator()(dealii::TrilinosWrappers::BlockSparsityPattern & s, - const dealii::DoFHandler & dh, - const dealii::AffineConstraints & cm, + operator()(dealii::TrilinosWrappers::BlockSparsityPattern &s, + const dealii::DoFHandler &dh, + const dealii::AffineConstraints &cm, const dealii::Table<2, dealii::DoFTools::Coupling> &coupling) { s.reinit(owned, owned, relevant, comm); @@ -125,9 +125,9 @@ namespace LAC */ template void - operator()(dealii::BlockSparsityPattern & s, - const dealii::DoFHandler & dh, - const dealii::AffineConstraints & cm, + operator()(dealii::BlockSparsityPattern &s, + const dealii::DoFHandler &dh, + const dealii::AffineConstraints &cm, const dealii::Table<2, dealii::DoFTools::Coupling> &coupling) { dsp = @@ -144,7 +144,7 @@ namespace LAC */ void operator()(const LAdealii::BlockSparsityPattern &sparsity, - LAdealii::BlockSparseMatrix & matrix) + LAdealii::BlockSparseMatrix &matrix) { matrix.reinit(sparsity); }; @@ -155,7 +155,7 @@ namespace LAC */ void operator()(const LATrilinos::BlockSparsityPattern &sparsity, - LATrilinos::BlockSparseMatrix & matrix) + LATrilinos::BlockSparseMatrix &matrix) { matrix.reinit(sparsity); }; @@ -210,7 +210,7 @@ namespace LAC public: Initializer(const dealii::IndexSet &owned_rows, const dealii::IndexSet &relevant_rows, - const MPI_Comm & comm = MPI_COMM_WORLD, + const MPI_Comm &comm = MPI_COMM_WORLD, const dealii::IndexSet &owned_columns = dealii::IndexSet(), const dealii::IndexSet &relevant_columns = dealii::IndexSet()) : owned_rows(owned_rows) @@ -302,9 +302,9 @@ namespace LAC */ template void - operator()(dealii::TrilinosWrappers::SparsityPattern & s, - const dealii::DoFHandler & dh, - const dealii::AffineConstraints & cm, + operator()(dealii::TrilinosWrappers::SparsityPattern &s, + const dealii::DoFHandler &dh, + const dealii::AffineConstraints &cm, const dealii::Table<2, dealii::DoFTools::Coupling> &coupling) { s.reinit(owned_rows, owned_columns, relevant_rows, comm); @@ -323,9 +323,9 @@ namespace LAC */ template void - operator()(dealii::SparsityPattern & s, - const dealii::DoFHandler & dh, - const dealii::AffineConstraints & cm, + operator()(dealii::SparsityPattern &s, + const dealii::DoFHandler &dh, + const dealii::AffineConstraints &cm, const dealii::Table<2, dealii::DoFTools::Coupling> &coupling) { dsp = @@ -342,7 +342,7 @@ namespace LAC */ void operator()(const LAdealii::SparsityPattern &sparsity, - LAdealii::SparseMatrix & matrix) + LAdealii::SparseMatrix &matrix) { matrix.reinit(sparsity); }; @@ -353,7 +353,7 @@ namespace LAC */ void operator()(const LATrilinos::SparsityPattern &sparsity, - LATrilinos::SparseMatrix & matrix) + LATrilinos::SparseMatrix &matrix) { matrix.reinit(sparsity); }; @@ -365,7 +365,7 @@ namespace LAC */ void operator()(const LAPETSc::SparsityPattern &sparsity, - LAPETSc::SparseMatrix & matrix) + LAPETSc::SparseMatrix &matrix) { matrix.reinit(owned_rows, owned_columns, sparsity, comm); }; diff --git a/include/moonolith_tools.h b/include/moonolith_tools.h index 8b21e52f1..f77e9f796 100644 --- a/include/moonolith_tools.h +++ b/include/moonolith_tools.h @@ -104,7 +104,7 @@ namespace moonolith template inline Line to_moonolith(const typename Triangulation<1, dim>::cell_iterator &cell, - const Mapping<1, dim> & mapping) + const Mapping<1, dim> &mapping) { const auto vertices = mapping.get_vertices(cell); Line line; @@ -146,7 +146,7 @@ namespace moonolith */ inline Polyhedron to_moonolith(const typename Triangulation<3, 3>::cell_iterator &cell, - const Mapping<3, 3> & mapping) + const Mapping<3, 3> &mapping) { const auto vertices = mapping.get_vertices(cell); Polyhedron poly; @@ -223,8 +223,8 @@ namespace moonolith template inline moonolith::Quadrature compute_intersection(const moonolith::Quadrature &ref_quad, - const T1 & t1, - const T2 & t2) + const T1 &t1, + const T2 &t2) { BuildQuadrature intersect; Quadrature out; @@ -255,8 +255,8 @@ namespace moonolith const typename Triangulation::cell_iterator &cell0, const typename Triangulation::cell_iterator &cell1, const unsigned int degree, - const Mapping & mapping0, - const Mapping & mapping1) + const Mapping &mapping0, + const Mapping &mapping1) { const auto t0 = to_moonolith(cell0, mapping0); const auto t1 = to_moonolith(cell1, mapping1); diff --git a/include/parsed_lac/amg.h b/include/parsed_lac/amg.h index ad2ccebc9..e21db16b7 100644 --- a/include/parsed_lac/amg.h +++ b/include/parsed_lac/amg.h @@ -39,17 +39,17 @@ namespace ParsedLAC /** * Constructor. Build the preconditioner of a matrix using AMG. */ - AMGPreconditioner(const std::string & name = "", - const bool & elliptic = true, - const bool & higher_order_elements = false, + AMGPreconditioner(const std::string &name = "", + const bool &elliptic = true, + const bool &higher_order_elements = false, const unsigned int &n_cycles = 1, - const bool & w_cycle = false, - const double & aggregation_threshold = 1e-4, + const bool &w_cycle = false, + const double &aggregation_threshold = 1e-4, const unsigned int &smoother_sweeps = 2, const unsigned int &smoother_overlap = 0, - const bool & output_details = false, - const std::string & smoother_type = "Chebyshev", - const std::string & coarse_type = "Amesos-KLU"); + const bool &output_details = false, + const std::string &smoother_type = "Chebyshev", + const std::string &coarse_type = "Amesos-KLU"); /** * Initialize the preconditioner using @p matrix. diff --git a/include/parsed_lac/amg_muelu.h b/include/parsed_lac/amg_muelu.h index ba13de45a..306a3c8b7 100644 --- a/include/parsed_lac/amg_muelu.h +++ b/include/parsed_lac/amg_muelu.h @@ -40,16 +40,16 @@ namespace ParsedLAC /** * Constructor. Build the preconditioner of a matrix using AMG. */ - AMGMueLuPreconditioner(const std::string & name = "", - const bool & elliptic = true, + AMGMueLuPreconditioner(const std::string &name = "", + const bool &elliptic = true, const unsigned int &n_cycles = 1, - const bool & w_cycle = false, - const double & aggregation_threshold = 1e-4, + const bool &w_cycle = false, + const double &aggregation_threshold = 1e-4, const unsigned int &smoother_sweeps = 2, const unsigned int &smoother_overlap = 0, - const bool & output_details = false, - const std::string & smoother_type = "Chebyshev", - const std::string & coarse_type = "Amesos-KLU"); + const bool &output_details = false, + const std::string &smoother_type = "Chebyshev", + const std::string &coarse_type = "Amesos-KLU"); /** * Initialize the preconditioner using @p matrix. diff --git a/include/parsed_lac/amg_petsc.h b/include/parsed_lac/amg_petsc.h index f968daebb..c3d99a3b5 100644 --- a/include/parsed_lac/amg_petsc.h +++ b/include/parsed_lac/amg_petsc.h @@ -43,7 +43,7 @@ namespace ParsedLAC * Constructor. Build the preconditioner of a matrix using AMG. */ PETScAMGPreconditioner( - const std::string & name = "", + const std::string &name = "", const bool symmetric_operator = false, const double strong_threshold = 0.25, const double max_row_sum = 0.9, diff --git a/include/parsed_lac/ilu.h b/include/parsed_lac/ilu.h index b3b3e4c01..b23b6c581 100644 --- a/include/parsed_lac/ilu.h +++ b/include/parsed_lac/ilu.h @@ -43,10 +43,10 @@ namespace ParsedLAC /** * Constructor. Build the preconditioner of a matrix using ILU. */ - ILUPreconditioner(const std::string & name = "", + ILUPreconditioner(const std::string &name = "", const unsigned int &ilu_fill = 0, - const double & ilu_atol = 0.0, - const double & ilu_rtol = 1.0, + const double &ilu_atol = 0.0, + const double &ilu_rtol = 1.0, const unsigned int &overlap = 0); /** diff --git a/include/parsed_lac/inverse_operator.h b/include/parsed_lac/inverse_operator.h index 05bcf4179..ce162f024 100644 --- a/include/parsed_lac/inverse_operator.h +++ b/include/parsed_lac/inverse_operator.h @@ -112,15 +112,15 @@ namespace ParsedLAC * on deallog. */ InverseOperator( - const std::string & section_name = "", - const std::string & default_solver = "cg", + const std::string §ion_name = "", + const std::string &default_solver = "cg", const SolverControlType &control_type = SolverControlType::tolerance, const unsigned int max_iterations = 1000, const double tolerance = 1e-12, const double reduction = 1e-6, const unsigned int consecutive_iterations = 2, - const bool & log_history = false, - const bool & log_result = false); + const bool &log_history = false, + const bool &log_result = false); /** * Create an inverse operator according to the parameters given in the @@ -139,7 +139,7 @@ namespace ParsedLAC typename Range = Domain> dealii::LinearOperator operator()(const dealii::LinearOperator &op, - const PreconditionerType & prec, + const PreconditionerType &prec, const double abs_tol = 0.0, const std::string &prefix = "") const; @@ -159,10 +159,10 @@ namespace ParsedLAC typename MatrixType, typename PreconditionerType> dealii::LinearOperator - solver(const MatrixType & op, + solver(const MatrixType &op, const PreconditionerType &prec, const double abs_tol = 0.0, - const std::string & prefix = "") const; + const std::string &prefix = "") const; /** @@ -175,10 +175,10 @@ namespace ParsedLAC typename PreconditionerType, typename VectorType> void - solve(const MatrixType & matrix, + solve(const MatrixType &matrix, const PreconditionerType &preconditioner, - const VectorType & src, - VectorType & dst, + const VectorType &src, + VectorType &dst, const double abs_tol = 0.0) const; @@ -269,10 +269,10 @@ namespace ParsedLAC typename PreconditionerType, typename VectorType> void - InverseOperator::solve(const MatrixType & matrix, + InverseOperator::solve(const MatrixType &matrix, const PreconditionerType &preconditioner, - const VectorType & src, - VectorType & dst, + const VectorType &src, + VectorType &dst, const double abs_tol) const { control = setup_new_solver_control(abs_tol); @@ -325,10 +325,10 @@ namespace ParsedLAC typename MatrixType, typename PreconditionerType> dealii::LinearOperator - InverseOperator::solver(const MatrixType & op, + InverseOperator::solver(const MatrixType &op, const PreconditionerType &prec, const double abs_tol, - const std::string & prefix) const + const std::string &prefix) const { control = setup_new_solver_control(abs_tol); @@ -391,9 +391,9 @@ namespace ParsedLAC dealii::LinearOperator InverseOperator::operator()( const dealii::LinearOperator &op, - const PreconditionerType & prec, + const PreconditionerType &prec, const double abs_tol, - const std::string & prefix) const + const std::string &prefix) const { return solver(op, prec, abs_tol, prefix); } diff --git a/include/parsed_lac/jacobi.h b/include/parsed_lac/jacobi.h index fd703b02a..2edbbe428 100644 --- a/include/parsed_lac/jacobi.h +++ b/include/parsed_lac/jacobi.h @@ -41,9 +41,9 @@ namespace ParsedLAC /** * Constructor. Build the preconditioner of a matrix using Jacobi. */ - JacobiPreconditioner(const std::string & name = "", - const double & omega = 1, - const double & min_diagonal = 0, + JacobiPreconditioner(const std::string &name = "", + const double &omega = 1, + const double &min_diagonal = 0, const unsigned int &n_sweeps = 1); /** diff --git a/include/parsed_tools/boundary_conditions.h b/include/parsed_tools/boundary_conditions.h index f8157b447..c33720cbf 100644 --- a/include/parsed_tools/boundary_conditions.h +++ b/include/parsed_tools/boundary_conditions.h @@ -71,7 +71,7 @@ namespace ParsedTools const std::string &component_names = "u", const std::vector> &ids = {{dealii::numbers::internal_face_boundary_id}}, - const std::vector & selected_components = {"u"}, + const std::vector &selected_components = {"u"}, const std::vector &bc_type = {BoundaryConditionType::dirichlet}, const std::vector &expressions = {"0"}); @@ -134,7 +134,7 @@ namespace ParsedTools void apply_essential_boundary_conditions( const dealii::DoFHandler &dof_handler, - dealii::AffineConstraints & constraints) const; + dealii::AffineConstraints &constraints) const; /** * Add the boundary conditions computed with this object to the @@ -143,9 +143,9 @@ namespace ParsedTools template void apply_essential_boundary_conditions( - const dealii::Mapping & mapping, + const dealii::Mapping &mapping, const dealii::DoFHandler &dof_handler, - dealii::AffineConstraints & constraints) const; + dealii::AffineConstraints &constraints) const; /** * Add natural boundary conditions computed with this object to the @@ -163,8 +163,8 @@ namespace ParsedTools apply_natural_boundary_conditions( const dealii::DoFHandler &dof_handler, const dealii::AffineConstraints &constraints, - MatrixType & matrix, - VectorType & rhs) const; + MatrixType &matrix, + VectorType &rhs) const; /** * Same as above for non standard mapping. @@ -179,11 +179,11 @@ namespace ParsedTools template void apply_natural_boundary_conditions( - const dealii::Mapping & mapping, + const dealii::Mapping &mapping, const dealii::DoFHandler &dof_handler, const dealii::AffineConstraints &constraints, - MatrixType & matrix, - VectorType & rhs) const; + MatrixType &matrix, + VectorType &rhs) const; /** * Get all ids where we impose essential boundary conditions. @@ -268,11 +268,11 @@ namespace ParsedTools template void BoundaryConditions::apply_natural_boundary_conditions( - const dealii::Mapping & mapping, + const dealii::Mapping &mapping, const dealii::DoFHandler &dof_handler, const dealii::AffineConstraints &constraints, - MatrixType & matrix, - VectorType & rhs) const + MatrixType &matrix, + VectorType &rhs) const { for (unsigned int i = 0; i < n_boundary_conditions; ++i) if (bc_type[i] == BoundaryConditionType::neumann) @@ -351,8 +351,8 @@ namespace ParsedTools BoundaryConditions::apply_natural_boundary_conditions( const dealii::DoFHandler &dof_handler, const dealii::AffineConstraints &constraints, - MatrixType & matrix, - VectorType & rhs) const + MatrixType &matrix, + VectorType &rhs) const { const auto &mapping = get_default_linear_mapping(dof_handler.get_triangulation()); @@ -367,7 +367,7 @@ namespace ParsedTools void BoundaryConditions::apply_essential_boundary_conditions( const dealii::DoFHandler &dof_handler, - dealii::AffineConstraints & constraints) const + dealii::AffineConstraints &constraints) const { const auto &mapping = get_default_linear_mapping(dof_handler.get_triangulation()); @@ -380,9 +380,9 @@ namespace ParsedTools template void BoundaryConditions::apply_essential_boundary_conditions( - const dealii::Mapping & mapping, + const dealii::Mapping &mapping, const dealii::DoFHandler &dof_handler, - dealii::AffineConstraints & constraints) const + dealii::AffineConstraints &constraints) const { // Take care of boundary conditions that don't need anything else than // the constraints. diff --git a/include/parsed_tools/components.h b/include/parsed_tools/components.h index cd77f1614..cc714233a 100644 --- a/include/parsed_tools/components.h +++ b/include/parsed_tools/components.h @@ -125,7 +125,7 @@ namespace ParsedTools * Build component names from block names and multiplicities. */ std::string - blocks_to_names(const std::vector & components, + blocks_to_names(const std::vector &components, const std::vector &multiplicities); /** diff --git a/include/parsed_tools/constants.h b/include/parsed_tools/constants.h index 94d6cd32e..9be603155 100644 --- a/include/parsed_tools/constants.h +++ b/include/parsed_tools/constants.h @@ -96,9 +96,9 @@ namespace ParsedTools * use in the parameter file defintion. */ Constants( - const std::string & section_name = "", + const std::string §ion_name = "", const std::vector &names = {}, - const std::vector & default_values = {}, + const std::vector &default_values = {}, const std::vector &optional_names_for_parameter_file = {}, const std::vector &optional_documentation_strings = {}); diff --git a/include/parsed_tools/data_out.h b/include/parsed_tools/data_out.h index ea32284ea..bbfcae3dc 100644 --- a/include/parsed_tools/data_out.h +++ b/include/parsed_tools/data_out.h @@ -51,12 +51,12 @@ namespace ParsedTools * @param output_high_order * @param comm */ - DataOut(const std::string & section_name = "", - const std::string & base_name = "solution", - const std::string & output_format = "vtu", + DataOut(const std::string §ion_name = "", + const std::string &base_name = "solution", + const std::string &output_format = "vtu", const unsigned int &subdivisions = 0, - const bool & write_higher_order_cells = true, - const MPI_Comm & comm = MPI_COMM_WORLD); + const bool &write_higher_order_cells = true, + const MPI_Comm &comm = MPI_COMM_WORLD); /** * Prepare to output data on the given file. This will initialize @@ -66,7 +66,7 @@ namespace ParsedTools */ void attach_dof_handler(const dealii::DoFHandler &dh, - const std::string & suffix = ""); + const std::string &suffix = ""); /** * Add the given vector to the output file. Prior to calling this @@ -80,7 +80,7 @@ namespace ParsedTools template void add_data_vector( - const VECTOR & data_vector, + const VECTOR &data_vector, const std::string &desc, const typename dealii::DataOut::DataVectorType &type = dealii::DataOut::type_automatic); @@ -90,7 +90,7 @@ namespace ParsedTools */ template void - add_data_vector(const VECTOR & data_vector, + add_data_vector(const VECTOR &data_vector, const dealii::DataPostprocessor &postproc); @@ -181,8 +181,8 @@ namespace ParsedTools template void DataOut::add_data_vector( - const VECTOR & data_vector, - const std::string & desc, + const VECTOR &data_vector, + const std::string &desc, const typename dealii::DataOut::DataVectorType &type) { std::vector dd = dealii::Utilities::split_string_list(desc); @@ -231,7 +231,7 @@ namespace ParsedTools template void DataOut::add_data_vector( - const VECTOR & data_vector, + const VECTOR &data_vector, const dealii::DataPostprocessor &postproc) { data_out->add_data_vector(data_vector, postproc); diff --git a/include/parsed_tools/enum.h b/include/parsed_tools/enum.h index 85a6fccb4..693b81bb2 100644 --- a/include/parsed_tools/enum.h +++ b/include/parsed_tools/enum.h @@ -53,7 +53,7 @@ namespace dealii } static std::string - to_string(const T & value, + to_string(const T &value, const Patterns::PatternBase &p = *Convert::to_pattern()) { namespace B = magic_enum::bitwise_operators; @@ -66,7 +66,7 @@ namespace dealii } static T - to_value(const std::string & s, + to_value(const std::string &s, const dealii::Patterns::PatternBase &p = *to_pattern()) { namespace B = magic_enum::bitwise_operators; diff --git a/include/parsed_tools/function.h b/include/parsed_tools/function.h index ffce6c5b9..7171fbd6a 100644 --- a/include/parsed_tools/function.h +++ b/include/parsed_tools/function.h @@ -63,7 +63,7 @@ namespace ParsedTools const std::string &expression = "0", const std::string &function_description = "Function expression", const std::map &constants = {}, - const std::string & variable_names = + const std::string &variable_names = dealii::FunctionParser::default_variable_names() + ",t", const double h = 1e-8); diff --git a/include/parsed_tools/grid_generator.h b/include/parsed_tools/grid_generator.h index 24e6fd589..262340360 100644 --- a/include/parsed_tools/grid_generator.h +++ b/include/parsed_tools/grid_generator.h @@ -218,7 +218,7 @@ namespace ParsedTools */ void write(const dealii::Triangulation &tria, - const std::string & filename = "") const; + const std::string &filename = "") const; private: /** diff --git a/include/parsed_tools/grid_info.h b/include/parsed_tools/grid_info.h index 27c9192e9..10287f1fc 100644 --- a/include/parsed_tools/grid_info.h +++ b/include/parsed_tools/grid_info.h @@ -55,7 +55,7 @@ namespace dealii * @return std::string The string representation of the manifold_id. */ static std::string - to_string(const T & t, + to_string(const T &t, const dealii::Patterns::PatternBase &pattern = *Convert::to_pattern()) { @@ -70,7 +70,7 @@ namespace dealii * @return T The manifold_id. */ static T - to_value(const std::string & s, + to_value(const std::string &s, const dealii::Patterns::PatternBase &pattern = *Convert::to_pattern()) { @@ -106,7 +106,7 @@ namespace dealii * @return std::string The string representation of the dealii::ReferenceCell. */ static std::string - to_string(const T & t, + to_string(const T &t, const dealii::Patterns::PatternBase &pattern = *Convert::to_pattern()) { @@ -122,7 +122,7 @@ namespace dealii * @return T The dealii::ReferenceCell. */ static T - to_value(const std::string & s, + to_value(const std::string &s, const dealii::Patterns::PatternBase &pattern = *Convert::to_pattern()) { diff --git a/include/parsed_tools/grid_refinement.h b/include/parsed_tools/grid_refinement.h index 684a66262..da41714ef 100644 --- a/include/parsed_tools/grid_refinement.h +++ b/include/parsed_tools/grid_refinement.h @@ -72,17 +72,17 @@ namespace ParsedTools * Constructor. */ GridRefinement( - const std::string & section_name = "", - const unsigned int & n_refinement_cycles = 1, + const std::string §ion_name = "", + const unsigned int &n_refinement_cycles = 1, const RefinementStrategy &strategy = RefinementStrategy::global, - const std::string & estimator_type = "kelly", - const double & top_parameter = .3, - const double & bottom_parameter = 0.1, - const unsigned int & max_cells = 0, - const int & min_level = 0, - const int & max_level = 0, + const std::string &estimator_type = "kelly", + const double &top_parameter = .3, + const double &bottom_parameter = 0.1, + const unsigned int &max_cells = 0, + const int &min_level = 0, + const int &max_level = 0, const std::map &)>> - & optional_estimators = {}, + &optional_estimators = {}, const dealii::ComponentMask &component_mask = dealii::ComponentMask()); /** @@ -96,7 +96,7 @@ namespace ParsedTools */ template void - mark_cells(const dealii::Vector & criteria, + mark_cells(const dealii::Vector &criteria, dealii::Triangulation &tria) const; #ifdef DEAL_II_WITH_MPI @@ -115,7 +115,7 @@ namespace ParsedTools template void mark_cells( - const dealii::Vector & criteria, + const dealii::Vector &criteria, dealii::parallel::distributed::Triangulation &tria) const; # endif #endif @@ -126,14 +126,14 @@ namespace ParsedTools template void estimate_error( - const dealii::Mapping & mapping, + const dealii::Mapping &mapping, const dealii::DoFHandler &dof_handler, - const VectorType & solution, - dealii::Vector & estimated_error_per_cell, + const VectorType &solution, + dealii::Vector &estimated_error_per_cell, const std::map< dealii::types::boundary_id, const dealii::Function *> - & neumann_bc = {}, + &neumann_bc = {}, const dealii::Function *coefficients = nullptr, const typename dealii::KellyErrorEstimator::Strategy strategy = @@ -148,12 +148,12 @@ namespace ParsedTools void estimate_error( const dealii::DoFHandler &dof_handler, - const VectorType & solution, - dealii::Vector & estimated_error_per_cell, + const VectorType &solution, + dealii::Vector &estimated_error_per_cell, const std::map< dealii::types::boundary_id, const dealii::Function *> - & neumann_bc = {}, + &neumann_bc = {}, const dealii::Function *coefficients = nullptr, const typename dealii::KellyErrorEstimator::Strategy strategy = @@ -194,10 +194,10 @@ namespace ParsedTools */ template void - estimate_mark_refine(const dealii::Mapping & mapping, + estimate_mark_refine(const dealii::Mapping &mapping, const dealii::DoFHandler &dof_handler, - const VectorType & solution, - Tria & tria) const; + const VectorType &solution, + Tria &tria) const; /** * Perform all the steps of the ESTIMATE-MARK-REFINE cycle. @@ -205,8 +205,8 @@ namespace ParsedTools template void estimate_mark_refine(const dealii::DoFHandler &dof_handler, - const VectorType & solution, - Tria & tria) const; + const VectorType &solution, + Tria &tria) const; private: /** @@ -245,7 +245,7 @@ namespace ParsedTools template void GridRefinement::mark_cells( - const dealii::Vector & criteria, + const dealii::Vector &criteria, dealii::parallel::distributed::Triangulation &tria) const { if (strategy == RefinementStrategy::fixed_number) @@ -295,7 +295,7 @@ namespace ParsedTools template void - GridRefinement::mark_cells(const dealii::Vector & criteria, + GridRefinement::mark_cells(const dealii::Vector &criteria, dealii::Triangulation &tria) const { if (strategy == RefinementStrategy::fixed_number) @@ -373,14 +373,14 @@ namespace ParsedTools template void GridRefinement::estimate_error( - const dealii::Mapping & mapping, + const dealii::Mapping &mapping, const dealii::DoFHandler &dof_handler, - const VectorType & solution, - dealii::Vector & estimated_error_per_cell, + const VectorType &solution, + dealii::Vector &estimated_error_per_cell, const std::map< dealii::types::boundary_id, const dealii::Function *> - & neumann_bc, + &neumann_bc, const dealii::Function *coefficients, const typename dealii::KellyErrorEstimator::Strategy strategy) const @@ -430,12 +430,12 @@ namespace ParsedTools void GridRefinement::estimate_error( const dealii::DoFHandler &dof_handler, - const VectorType & solution, - dealii::Vector & estimated_error_per_cell, + const VectorType &solution, + dealii::Vector &estimated_error_per_cell, const std::map< dealii::types::boundary_id, const dealii::Function *> - & neumann_bc, + &neumann_bc, const dealii::Function *coefficients, const typename dealii::KellyErrorEstimator::Strategy strategy) const @@ -457,8 +457,8 @@ namespace ParsedTools void GridRefinement::estimate_mark_refine( const dealii::DoFHandler &dof_handler, - const VectorType & solution, - Tria & tria) const + const VectorType &solution, + Tria &tria) const { const auto &mapping = dealii::get_default_linear_mapping(dof_handler.get_triangulation()); @@ -470,10 +470,10 @@ namespace ParsedTools template void GridRefinement::estimate_mark_refine( - const dealii::Mapping & mapping, + const dealii::Mapping &mapping, const dealii::DoFHandler &dof_handler, - const VectorType & solution, - Tria & tria) const + const VectorType &solution, + Tria &tria) const { // No estimates to do in global refinement case if (strategy == RefinementStrategy::global) diff --git a/include/parsed_tools/mapping_eulerian.h b/include/parsed_tools/mapping_eulerian.h index 4ce4849fc..d7b3ba9a5 100644 --- a/include/parsed_tools/mapping_eulerian.h +++ b/include/parsed_tools/mapping_eulerian.h @@ -76,8 +76,8 @@ namespace ParsedTools public: MappingEulerian( const dealii::DoFHandler &dh, - const std::string & section_name = "", - const std::string & initial_configuration_or_displacement = "", + const std::string §ion_name = "", + const std::string &initial_configuration_or_displacement = "", const bool use_displacement = false, const dealii::ComponentMask &mask = dealii::ComponentMask()); diff --git a/include/parsed_tools/non_matching_coupling.h b/include/parsed_tools/non_matching_coupling.h index 8947db542..e0163d39c 100644 --- a/include/parsed_tools/non_matching_coupling.h +++ b/include/parsed_tools/non_matching_coupling.h @@ -90,7 +90,7 @@ namespace ParsedTools * Constructor. */ NonMatchingCoupling( - const std::string & section_name = "", + const std::string §ion_name = "", const dealii::ComponentMask &embedded_mask = dealii::ComponentMask(), const dealii::ComponentMask &space_mask = dealii::ComponentMask(), const CouplingType coupling_type = CouplingType::approximate_L2, @@ -110,10 +110,10 @@ namespace ParsedTools */ void initialize(const dealii::GridTools::Cache &space_cache, - const dealii::DoFHandler & space_dh, - const dealii::AffineConstraints & space_constraints, + const dealii::DoFHandler &space_dh, + const dealii::AffineConstraints &space_constraints, const dealii::GridTools::Cache &embedded_cache, - const dealii::DoFHandler & embedded_dh, + const dealii::DoFHandler &embedded_dh, const dealii::AffineConstraints &embedded_constraints); /** @@ -147,7 +147,7 @@ namespace ParsedTools void adjust_grid_refinements( dealii::Triangulation &space_tria, - dealii::Triangulation & embedded_tria, + dealii::Triangulation &embedded_tria, const bool apply_delta_refinements = true) const; /** diff --git a/include/parsed_tools/symbolic_function.h b/include/parsed_tools/symbolic_function.h index 3ef479d3f..dadc568a9 100644 --- a/include/parsed_tools/symbolic_function.h +++ b/include/parsed_tools/symbolic_function.h @@ -56,7 +56,7 @@ namespace dealii * Convert a Differentiation::SD::Expression expression to a string. */ static std::string - to_string(const T & t, + to_string(const T &t, const dealii::Patterns::PatternBase &pattern = *to_pattern()) { std::stringstream ss; @@ -73,7 +73,7 @@ namespace dealii * Convert a string to a Differentiation::SD::Expression expression. */ static T - to_value(const std::string & s, + to_value(const std::string &s, const dealii::Patterns::PatternBase &pattern = *to_pattern()) { AssertThrow(pattern.match(s), ExcMessage("Invalid string.")); @@ -126,7 +126,7 @@ namespace dealii * @return std::string The string representation of the SymbolicFunction. */ static std::string - to_string(const T & t, + to_string(const T &t, const dealii::Patterns::PatternBase &pattern = *Convert::to_pattern()) { @@ -142,7 +142,7 @@ namespace dealii * @return T The SymbolicFunction. */ static T - to_value(const std::string & s, + to_value(const std::string &s, const dealii::Patterns::PatternBase &pattern = *Convert::to_pattern()) { diff --git a/include/pdes/linear_elasticity.h b/include/pdes/linear_elasticity.h index cd5e7cf3f..e84957233 100644 --- a/include/pdes/linear_elasticity.h +++ b/include/pdes/linear_elasticity.h @@ -182,7 +182,7 @@ namespace PDEs virtual void assemble_system_one_cell( const typename DoFHandler::active_cell_iterator &cell, - ScratchData & scratch, + ScratchData &scratch, CopyData ©) override; /** diff --git a/include/pdes/linear_problem.h b/include/pdes/linear_problem.h index 0d25af301..018d3611b 100644 --- a/include/pdes/linear_problem.h +++ b/include/pdes/linear_problem.h @@ -216,8 +216,8 @@ namespace PDEs virtual void assemble_system_one_cell( const typename DoFHandler::active_cell_iterator &cell, - ScratchData & scratch, - CopyData & copy); + ScratchData &scratch, + CopyData ©); /** * Distribute the data that has been assembled by @@ -320,8 +320,8 @@ namespace PDEs /** * Connect to this signal to receive time information. */ - boost::signals2::signal advance_time_call_back; diff --git a/include/pdes/mpi/poisson.h b/include/pdes/mpi/poisson.h index 075ff36e0..a933a94aa 100644 --- a/include/pdes/mpi/poisson.h +++ b/include/pdes/mpi/poisson.h @@ -63,7 +63,7 @@ namespace PDEs virtual void assemble_system_one_cell( const typename DoFHandler::active_cell_iterator &cell, - ScratchData & scratch, + ScratchData &scratch, CopyData ©) override; /** diff --git a/include/pdes/stokes.h b/include/pdes/stokes.h index 3593854f2..d174b4ac3 100644 --- a/include/pdes/stokes.h +++ b/include/pdes/stokes.h @@ -56,8 +56,8 @@ namespace PDEs virtual void assemble_system_one_cell( const typename DoFHandler::active_cell_iterator &cell, - ScratchData & scratch, - CopyData & copy) override; + ScratchData &scratch, + CopyData ©) override; /** * Make sure we initialize the right type of linear solver. diff --git a/include/projection_operator.h b/include/projection_operator.h index fa4074836..d19bc195b 100644 --- a/include/projection_operator.h +++ b/include/projection_operator.h @@ -75,13 +75,13 @@ namespace dealii typename Payload = internal::LinearOperatorImplementation::EmptyPayload> LinearOperator projection_operator( - const Range & range_exemplar, + const Range &range_exemplar, const std::vector> &local_basis, - const Domain * domain_exemplar = nullptr, + const Domain *domain_exemplar = nullptr, const Payload &payload = Payload()) { LinearOperator linear_operator(payload); - linear_operator.vmult = [range_exemplar, local_basis](Range & dst, + linear_operator.vmult = [range_exemplar, local_basis](Range &dst, const Domain &src) { static const auto id = range_exemplar.locally_owned_elements(); AssertDimension(local_basis.size(), id.n_elements()); @@ -99,7 +99,7 @@ namespace dealii dst[j] += local_basis[i++].get() * src; }; - linear_operator.Tvmult = [range_exemplar, local_basis](Domain & dst, + linear_operator.Tvmult = [range_exemplar, local_basis](Domain &dst, const Range &src) { static const auto id = range_exemplar.locally_owned_elements(); AssertDimension(local_basis.size(), id.n_elements()); diff --git a/include/runner.h b/include/runner.h index ca60ebb05..be0d07978 100644 --- a/include/runner.h +++ b/include/runner.h @@ -202,7 +202,7 @@ namespace Runner * @return 0: everything is fine, 1: unused parameters, -1: help printed */ int - setup_parameters_from_cli(char ** argv, + setup_parameters_from_cli(char **argv, const std::string &input_parameter_file, const std::string &output_parameter_file); @@ -216,7 +216,7 @@ namespace Runner */ template void - run(char ** argv, + run(char **argv, const std::string &input_parameter_file, const std::string &output_parameter_file) { diff --git a/source/assemble_coupling_mass_matrix_with_exact_intersections.cc b/source/assemble_coupling_mass_matrix_with_exact_intersections.cc index f6bb6254f..1cc2b446c 100644 --- a/source/assemble_coupling_mass_matrix_with_exact_intersections.cc +++ b/source/assemble_coupling_mass_matrix_with_exact_intersections.cc @@ -51,13 +51,13 @@ namespace dealii const std::vector< std::tuple::cell_iterator, typename Triangulation::cell_iterator, - Quadrature>> & cells_and_quads, - Matrix & matrix, + Quadrature>> &cells_and_quads, + Matrix &matrix, const AffineConstraints &space_constraints, - const ComponentMask & space_comps, - const ComponentMask & immersed_comps, - const Mapping & space_mapping, - const Mapping & immersed_mapping, + const ComponentMask &space_comps, + const ComponentMask &immersed_comps, + const Mapping &space_mapping, + const Mapping &immersed_mapping, const AffineConstraints &immersed_constraints) { @@ -152,7 +152,7 @@ namespace dealii local_cell_matrix = typename Matrix::value_type(); const unsigned int n_quad_pts = quad_formula.size(); - const auto & real_qpts = quad_formula.get_points(); + const auto &real_qpts = quad_formula.get_points(); std::vector> ref_pts_space(n_quad_pts); std::vector> ref_pts_immersed(n_quad_pts); diff --git a/source/assemble_nitsche_with_exact_intersections.cc b/source/assemble_nitsche_with_exact_intersections.cc index a0f179764..b7b52d04c 100644 --- a/source/assemble_nitsche_with_exact_intersections.cc +++ b/source/assemble_nitsche_with_exact_intersections.cc @@ -42,17 +42,17 @@ namespace dealii template void assemble_nitsche_with_exact_intersections( - const DoFHandler & space_dh, + const DoFHandler &space_dh, const std::vector::cell_iterator, typename dealii::Triangulation::cell_iterator, - dealii::Quadrature>> & cells_and_quads, - Matrix & matrix, + dealii::Quadrature>> &cells_and_quads, + Matrix &matrix, const AffineConstraints &space_constraints, - const ComponentMask & space_comps, - const Mapping & space_mapping, + const ComponentMask &space_comps, + const Mapping &space_mapping, const Function - & nitsche_coefficient, + &nitsche_coefficient, const double penalty) { AssertDimension(matrix.m(), space_dh.n_dofs()); @@ -103,7 +103,7 @@ namespace dealii local_cell_matrix = typename Matrix::value_type(); const unsigned int n_quad_pts = quad_formula.size(); - const auto & real_qpts = quad_formula.get_points(); + const auto &real_qpts = quad_formula.get_points(); std::vector nitsche_coefficient_values(n_quad_pts); nitsche_coefficient.value_list(real_qpts, nitsche_coefficient_values); diff --git a/source/boundary_conditions.cc b/source/boundary_conditions.cc index ec191fd84..b4a0cc093 100644 --- a/source/boundary_conditions.cc +++ b/source/boundary_conditions.cc @@ -28,12 +28,12 @@ namespace ParsedTools { template BoundaryConditions::BoundaryConditions( - const std::string & section_name, - const std::string & component_names, + const std::string §ion_name, + const std::string &component_names, const std::vector> &ids, - const std::vector & selected_components, + const std::vector &selected_components, const std::vector &bc_type, - const std::vector & expressions) + const std::vector &expressions) : ParameterAcceptor(section_name) , component_names(component_names) , n_components(Components::n_components(component_names)) diff --git a/source/components.cc b/source/components.cc index 205b666d7..ab3b9f564 100644 --- a/source/components.cc +++ b/source/components.cc @@ -37,7 +37,7 @@ namespace ParsedTools std::string - blocks_to_names(const std::vector & components, + blocks_to_names(const std::vector &components, const std::vector &multiplicities) { AssertDimension(components.size(), multiplicities.size()); diff --git a/source/compute_intersections.cc b/source/compute_intersections.cc index 7ec4c0f12..02ddc36e3 100644 --- a/source/compute_intersections.cc +++ b/source/compute_intersections.cc @@ -50,8 +50,8 @@ namespace dealii const typename Triangulation::cell_iterator &cell0, const typename Triangulation::cell_iterator &cell1, const unsigned int degree, - const Mapping & mapping0, - const Mapping & mapping1, + const Mapping &mapping0, + const Mapping &mapping1, const double tol = 1e-9) { if constexpr (dim0 == 1 && dim1 == 1) @@ -88,8 +88,8 @@ namespace dealii const typename Triangulation::cell_iterator &cell0, const typename Triangulation::cell_iterator &cell1, const unsigned int degree, - const Mapping & mapping0, - const Mapping & mapping1) + const Mapping &mapping0, + const Mapping &mapping1) { if constexpr ((dim0 == 1 && dim1 == 3) || (dim0 == 3 && dim1 == 1) || (dim0 == 1 && dim1 == 1)) @@ -176,7 +176,7 @@ namespace dealii space_cell, immersed_cell, degree, mapping0, mapping1); // if (test_intersection.get_points().size() != - const auto & weights = test_intersection.get_weights(); + const auto &weights = test_intersection.get_weights(); const double area = std::accumulate(weights.begin(), weights.end(), 0.0); if (area > tol) // non-trivial intersection diff --git a/source/constants.cc b/source/constants.cc index 84566265d..bd848d8a3 100644 --- a/source/constants.cc +++ b/source/constants.cc @@ -22,9 +22,9 @@ using namespace dealii; namespace ParsedTools { Constants::Constants( - const std::string & section_name, + const std::string §ion_name, const std::vector &names, - const std::vector & default_values, + const std::vector &default_values, const std::vector &optional_names_for_parameter_file, const std::vector &optional_documentation_strings) : ParameterAcceptor(section_name) diff --git a/source/create_coupling_sparsity_pattern_with_exact_intersections.cc b/source/create_coupling_sparsity_pattern_with_exact_intersections.cc index 071ca8206..a7cadd7ed 100644 --- a/source/create_coupling_sparsity_pattern_with_exact_intersections.cc +++ b/source/create_coupling_sparsity_pattern_with_exact_intersections.cc @@ -37,11 +37,11 @@ namespace dealii dealii::Quadrature>> &intersections_info, const DoFHandler &space_dh, const DoFHandler &immersed_dh, - Sparsity & sparsity, - const AffineConstraints & constraints, - const ComponentMask & space_comps, - const ComponentMask & immersed_comps, - const AffineConstraints & immersed_constraints) + Sparsity &sparsity, + const AffineConstraints &constraints, + const ComponentMask &space_comps, + const ComponentMask &immersed_comps, + const AffineConstraints &immersed_constraints) { AssertDimension(sparsity.n_rows(), space_dh.n_dofs()); AssertDimension(sparsity.n_cols(), immersed_dh.n_dofs()); @@ -54,8 +54,8 @@ namespace dealii - const auto & space_fe = space_dh.get_fe(); - const auto & immersed_fe = immersed_dh.get_fe(); + const auto &space_fe = space_dh.get_fe(); + const auto &immersed_fe = immersed_dh.get_fe(); const unsigned int n_dofs_per_space_cell = space_fe.n_dofs_per_cell(); const unsigned int n_dofs_per_immersed_cell = immersed_fe.n_dofs_per_cell(); @@ -219,13 +219,13 @@ namespace dealii std::tuple::cell_iterator, typename dealii::Triangulation<1, 1>::cell_iterator, dealii::Quadrature<1>>> &intersections_info, - const DoFHandler<1, 1> & space_dh, - const DoFHandler<1, 1> & immersed_dh, - DynamicSparsityPattern & sparsity, - const AffineConstraints & constraints, - const ComponentMask & space_comps, - const ComponentMask & immersed_comps, - const AffineConstraints & immersed_constraint); + const DoFHandler<1, 1> &space_dh, + const DoFHandler<1, 1> &immersed_dh, + DynamicSparsityPattern &sparsity, + const AffineConstraints &constraints, + const ComponentMask &space_comps, + const ComponentMask &immersed_comps, + const AffineConstraints &immersed_constraint); template void create_coupling_sparsity_pattern_with_exact_intersections( @@ -233,13 +233,13 @@ namespace dealii std::tuple::cell_iterator, typename dealii::Triangulation<1, 2>::cell_iterator, dealii::Quadrature<2>>> &intersections_info, - const DoFHandler<2, 2> & space_dh, - const DoFHandler<1, 2> & immersed_dh, - DynamicSparsityPattern & sparsity, - const AffineConstraints & constraints, - const ComponentMask & space_comps, - const ComponentMask & immersed_comps, - const AffineConstraints & immersed_constraint); + const DoFHandler<2, 2> &space_dh, + const DoFHandler<1, 2> &immersed_dh, + DynamicSparsityPattern &sparsity, + const AffineConstraints &constraints, + const ComponentMask &space_comps, + const ComponentMask &immersed_comps, + const AffineConstraints &immersed_constraint); template void @@ -248,13 +248,13 @@ namespace dealii std::tuple::cell_iterator, typename dealii::Triangulation<1, 3>::cell_iterator, dealii::Quadrature<3>>> &intersections_info, - const DoFHandler<3, 3> & space_dh, - const DoFHandler<1, 3> & immersed_dh, - DynamicSparsityPattern & sparsity, - const AffineConstraints & constraints, - const ComponentMask & space_comps, - const ComponentMask & immersed_comps, - const AffineConstraints & immersed_constraint); + const DoFHandler<3, 3> &space_dh, + const DoFHandler<1, 3> &immersed_dh, + DynamicSparsityPattern &sparsity, + const AffineConstraints &constraints, + const ComponentMask &space_comps, + const ComponentMask &immersed_comps, + const AffineConstraints &immersed_constraint); template void @@ -263,13 +263,13 @@ namespace dealii std::tuple::cell_iterator, typename dealii::Triangulation<2, 2>::cell_iterator, dealii::Quadrature<2>>> &intersections_info, - const DoFHandler<2, 2> & space_dh, - const DoFHandler<2, 2> & immersed_dh, - DynamicSparsityPattern & sparsity, - const AffineConstraints & constraints, - const ComponentMask & space_comps, - const ComponentMask & immersed_comps, - const AffineConstraints & immersed_constraint); + const DoFHandler<2, 2> &space_dh, + const DoFHandler<2, 2> &immersed_dh, + DynamicSparsityPattern &sparsity, + const AffineConstraints &constraints, + const ComponentMask &space_comps, + const ComponentMask &immersed_comps, + const AffineConstraints &immersed_constraint); template void create_coupling_sparsity_pattern_with_exact_intersections( @@ -277,13 +277,13 @@ namespace dealii std::tuple::cell_iterator, typename dealii::Triangulation<2, 3>::cell_iterator, dealii::Quadrature<3>>> &intersections_info, - const DoFHandler<3, 3> & space_dh, - const DoFHandler<2, 3> & immersed_dh, - DynamicSparsityPattern & sparsity, - const AffineConstraints & constraints, - const ComponentMask & space_comps, - const ComponentMask & immersed_comps, - const AffineConstraints & immersed_constraint); + const DoFHandler<3, 3> &space_dh, + const DoFHandler<2, 3> &immersed_dh, + DynamicSparsityPattern &sparsity, + const AffineConstraints &constraints, + const ComponentMask &space_comps, + const ComponentMask &immersed_comps, + const AffineConstraints &immersed_constraint); template void create_coupling_sparsity_pattern_with_exact_intersections( @@ -291,13 +291,13 @@ namespace dealii std::tuple::cell_iterator, typename dealii::Triangulation<3, 3>::cell_iterator, dealii::Quadrature<3>>> &intersections_info, - const DoFHandler<3, 3> & space_dh, - const DoFHandler<3, 3> & immersed_dh, - DynamicSparsityPattern & sparsity, - const AffineConstraints & constraints, - const ComponentMask & space_comps, - const ComponentMask & immersed_comps, - const AffineConstraints & immersed_constraint); + const DoFHandler<3, 3> &space_dh, + const DoFHandler<3, 3> &immersed_dh, + DynamicSparsityPattern &sparsity, + const AffineConstraints &constraints, + const ComponentMask &space_comps, + const ComponentMask &immersed_comps, + const AffineConstraints &immersed_constraint); template void create_coupling_sparsity_pattern_with_exact_intersections< diff --git a/source/create_nitsche_rhs_with_exact_intersections.cc b/source/create_nitsche_rhs_with_exact_intersections.cc index 1b8884d0a..0dfe6dec6 100644 --- a/source/create_nitsche_rhs_with_exact_intersections.cc +++ b/source/create_nitsche_rhs_with_exact_intersections.cc @@ -31,9 +31,9 @@ namespace dealii typename dealii::Triangulation::cell_iterator, typename dealii::Triangulation::cell_iterator, dealii::Quadrature>> &cells_and_quads, - VectorType & rhs, + VectorType &rhs, const AffineConstraints - & space_constraints, + &space_constraints, const Mapping &space_mapping, const Function &rhs_function, const Function &coefficient, @@ -71,7 +71,7 @@ namespace dealii const unsigned int n_quad_pts = quad_formula.size(); - const auto & real_qpts = quad_formula.get_points(); + const auto &real_qpts = quad_formula.get_points(); std::vector> ref_pts_space( n_quad_pts); std::vector rhs_function_values(n_quad_pts); diff --git a/source/data_out.cc b/source/data_out.cc index 57cc6c461..6d5a2fe4a 100644 --- a/source/data_out.cc +++ b/source/data_out.cc @@ -69,12 +69,12 @@ namespace namespace ParsedTools { template - DataOut::DataOut(const std::string & section_name, - const std::string & base_name, - const std::string & output_format, + DataOut::DataOut(const std::string §ion_name, + const std::string &base_name, + const std::string &output_format, const unsigned int &subdivisions, - const bool & write_higher_order_cells, - const MPI_Comm & comm) + const bool &write_higher_order_cells, + const MPI_Comm &comm) : ParameterAcceptor(section_name) , comm(comm) , n_mpi_processes(Utilities::MPI::n_mpi_processes(comm)) @@ -118,7 +118,7 @@ namespace ParsedTools void DataOut::attach_dof_handler( const DoFHandler &dh, - const std::string & suffix) + const std::string &suffix) { data_out = std::make_unique>(); data_out->set_default_format( diff --git a/source/function.cc b/source/function.cc index 6d1f7caf2..092bff0d8 100644 --- a/source/function.cc +++ b/source/function.cc @@ -25,7 +25,7 @@ namespace ParsedTools const std::string &expression, const std::string &function_description, const std::map &constants, - const std::string & variable_names, + const std::string &variable_names, const double h) : ParameterAcceptor(section_name) , FunctionParser( diff --git a/source/grid_generator.cc b/source/grid_generator.cc index 294151fbe..a0d547915 100644 --- a/source/grid_generator.cc +++ b/source/grid_generator.cc @@ -222,7 +222,7 @@ namespace ParsedTools void GridGenerator::write( const dealii::Triangulation &tria, - const std::string & filename) const + const std::string &filename) const { const std::string outname = filename != "" ? filename : output_file_name; if (outname != "") diff --git a/source/grid_refinement.cc b/source/grid_refinement.cc index b6ea8de68..edc5ce60a 100644 --- a/source/grid_refinement.cc +++ b/source/grid_refinement.cc @@ -20,17 +20,17 @@ using namespace dealii; namespace ParsedTools { GridRefinement::GridRefinement( - const std::string & section_name, - const unsigned int & n_refinement_cycles, + const std::string §ion_name, + const unsigned int &n_refinement_cycles, const RefinementStrategy &strategy, - const std::string & estimator_type, - const double & top_parameter, - const double & bottom_parameter, - const unsigned int & max_cells, - const int & min_level, - const int & max_level, + const std::string &estimator_type, + const double &top_parameter, + const double &bottom_parameter, + const unsigned int &max_cells, + const int &min_level, + const int &max_level, const std::map &)>> - & optional_estimators, + &optional_estimators, const dealii::ComponentMask &component_mask) : ParameterAcceptor(section_name) , n_refinement_cycles(n_refinement_cycles) diff --git a/source/mapping_eulerian.cc b/source/mapping_eulerian.cc index 060442404..411cac8fd 100644 --- a/source/mapping_eulerian.cc +++ b/source/mapping_eulerian.cc @@ -22,10 +22,10 @@ namespace ParsedTools template MappingEulerian::MappingEulerian( const DoFHandler &dh, - const std::string & section_name, - const std::string & initial_configuration_or_displacement, + const std::string §ion_name, + const std::string &initial_configuration_or_displacement, const bool use_displacement, - const ComponentMask & mask) + const ComponentMask &mask) : ParameterAcceptor(section_name) , dof_handler(&dh) , mask(mask) diff --git a/source/non_matching_coupling.cc b/source/non_matching_coupling.cc index adbf7db48..1df8c7a63 100644 --- a/source/non_matching_coupling.cc +++ b/source/non_matching_coupling.cc @@ -32,9 +32,9 @@ namespace ParsedTools { template NonMatchingCoupling::NonMatchingCoupling( - const std::string & section_name, - const dealii::ComponentMask & embedded_mask, - const dealii::ComponentMask & space_mask, + const std::string §ion_name, + const dealii::ComponentMask &embedded_mask, + const dealii::ComponentMask &space_mask, const NonMatchingCoupling::CouplingType coupling_type, const NonMatchingCoupling::RefinementStrategy refinement_strategy, @@ -98,11 +98,11 @@ namespace ParsedTools void NonMatchingCoupling::initialize( const GridTools::Cache &space_cache, - const DoFHandler & space_dh, - const AffineConstraints & space_constraints, - const GridTools::Cache & embedded_cache, - const DoFHandler & embedded_dh, - const AffineConstraints & embedded_constraints) + const DoFHandler &space_dh, + const AffineConstraints &space_constraints, + const GridTools::Cache &embedded_cache, + const DoFHandler &embedded_dh, + const AffineConstraints &embedded_constraints) { this->space_cache = &space_cache; this->space_dh = &space_dh; @@ -123,7 +123,7 @@ namespace ParsedTools void NonMatchingCoupling::adjust_grid_refinements( Triangulation &space_tria, - Triangulation & embedded_tria, + Triangulation &embedded_tria, const bool apply_delta_refinements) const { Assert(space_dh, ExcNotInitialized()); diff --git a/source/parsed_lac/amg.cc b/source/parsed_lac/amg.cc index 76983d023..e83709460 100644 --- a/source/parsed_lac/amg.cc +++ b/source/parsed_lac/amg.cc @@ -26,16 +26,16 @@ using namespace dealii; namespace ParsedLAC { AMGPreconditioner::AMGPreconditioner(const std::string &name, - const bool & elliptic, - const bool & higher_order_elements, + const bool &elliptic, + const bool &higher_order_elements, const unsigned int &n_cycles, - const bool & w_cycle, + const bool &w_cycle, const double &aggregation_threshold, const unsigned int &smoother_sweeps, const unsigned int &smoother_overlap, - const bool & output_details, - const std::string & smoother_type, - const std::string & coarse_type) + const bool &output_details, + const std::string &smoother_type, + const std::string &coarse_type) : ParameterAcceptor(name) , PreconditionAMG() , elliptic(elliptic) diff --git a/source/parsed_lac/amg_muelu.cc b/source/parsed_lac/amg_muelu.cc index 41ed79aef..a9a4b315c 100644 --- a/source/parsed_lac/amg_muelu.cc +++ b/source/parsed_lac/amg_muelu.cc @@ -26,16 +26,16 @@ using namespace dealii; namespace ParsedLAC { AMGMueLuPreconditioner::AMGMueLuPreconditioner( - const std::string & name, - const bool & elliptic, + const std::string &name, + const bool &elliptic, const unsigned int &n_cycles, - const bool & w_cycle, - const double & aggregation_threshold, + const bool &w_cycle, + const double &aggregation_threshold, const unsigned int &smoother_sweeps, const unsigned int &smoother_overlap, - const bool & output_details, - const std::string & smoother_type, - const std::string & coarse_type) + const bool &output_details, + const std::string &smoother_type, + const std::string &coarse_type) : ParameterAcceptor(name) , PreconditionAMGMueLu() , elliptic(elliptic) diff --git a/source/parsed_lac/amg_petsc.cc b/source/parsed_lac/amg_petsc.cc index 2124509f2..344077bd1 100644 --- a/source/parsed_lac/amg_petsc.cc +++ b/source/parsed_lac/amg_petsc.cc @@ -30,7 +30,7 @@ using namespace dealii; namespace ParsedLAC { PETScAMGPreconditioner::PETScAMGPreconditioner( - const std::string & name, + const std::string &name, const bool symmetric_operator, const double strong_threshold, const double max_row_sum, diff --git a/source/parsed_lac/ilu.cc b/source/parsed_lac/ilu.cc index 4801a872c..eb542e71d 100644 --- a/source/parsed_lac/ilu.cc +++ b/source/parsed_lac/ilu.cc @@ -23,10 +23,10 @@ using namespace dealii; namespace ParsedLAC { - ILUPreconditioner::ILUPreconditioner(const std::string & name, + ILUPreconditioner::ILUPreconditioner(const std::string &name, const unsigned int &ilu_fill, - const double & ilu_atol, - const double & ilu_rtol, + const double &ilu_atol, + const double &ilu_rtol, const unsigned int &overlap) : ParameterAcceptor(name) , PreconditionILU() diff --git a/source/parsed_lac/inverse_operator.cc b/source/parsed_lac/inverse_operator.cc index 6a7ae6f68..1c8dc3336 100644 --- a/source/parsed_lac/inverse_operator.cc +++ b/source/parsed_lac/inverse_operator.cc @@ -22,15 +22,15 @@ using namespace dealii; namespace ParsedLAC { - InverseOperator::InverseOperator(const std::string & section_name, - const std::string & solver_name, + InverseOperator::InverseOperator(const std::string §ion_name, + const std::string &solver_name, const SolverControlType &control_type, const unsigned int max_iterations, const double tolerance, const double reduction, const unsigned int consecutive_iterations, - const bool & log_history, - const bool & log_result) + const bool &log_history, + const bool &log_result) : ParameterAcceptor(section_name) , control_type(control_type) , solver_name(solver_name) diff --git a/source/parsed_lac/jacobi.cc b/source/parsed_lac/jacobi.cc index 87eb63f84..9324803d0 100644 --- a/source/parsed_lac/jacobi.cc +++ b/source/parsed_lac/jacobi.cc @@ -21,9 +21,9 @@ using namespace dealii; namespace ParsedLAC { - JacobiPreconditioner::JacobiPreconditioner(const std::string & name, - const double & omega, - const double & min_diagonal, + JacobiPreconditioner::JacobiPreconditioner(const std::string &name, + const double &omega, + const double &min_diagonal, const unsigned int &n_sweeps) : ParameterAcceptor(name) , PreconditionJacobi() diff --git a/source/pdes/linear_elasticity.cc b/source/pdes/linear_elasticity.cc index 936545938..29d66b6ba 100644 --- a/source/pdes/linear_elasticity.cc +++ b/source/pdes/linear_elasticity.cc @@ -48,8 +48,8 @@ namespace PDEs void LinearElasticity::assemble_system_one_cell( const typename DoFHandler::active_cell_iterator &cell, - ScratchData & scratch, - CopyData & copy) + ScratchData &scratch, + CopyData ©) { auto &cell_matrix = copy.matrices[0]; auto &cell_rhs = copy.vectors[0]; @@ -117,8 +117,8 @@ namespace PDEs const auto face_integrator = [&](const auto &cell, const auto &face, - auto & scratch, - auto & data) { + auto &scratch, + auto &data) { data[cell->face(face)->boundary_id()] = Tensor<1, spacedim>(); auto &f = data[cell->face(face)->boundary_id()]; diff --git a/source/pdes/mpi/poisson.cc b/source/pdes/mpi/poisson.cc index 4218d1b34..01473607a 100644 --- a/source/pdes/mpi/poisson.cc +++ b/source/pdes/mpi/poisson.cc @@ -35,8 +35,8 @@ namespace PDEs void Poisson::assemble_system_one_cell( const typename DoFHandler::active_cell_iterator &cell, - ScratchData & scratch, - CopyData & copy) + ScratchData &scratch, + CopyData ©) { auto &cell_matrix = copy.matrices[0]; auto &cell_rhs = copy.vectors[0]; @@ -167,8 +167,8 @@ namespace PDEs const auto &ncell, const auto &nf, const auto &nsf, - auto & scratch, - auto & copy) { + auto &scratch, + auto ©) { // Here we intialize the inteface values const auto &fe_iv = scratch.reinit(cell, f, sf, ncell, nf, nsf); diff --git a/source/pdes/stokes.cc b/source/pdes/stokes.cc index df4f830c6..15eb8379e 100644 --- a/source/pdes/stokes.cc +++ b/source/pdes/stokes.cc @@ -74,8 +74,8 @@ namespace PDEs void Stokes::assemble_system_one_cell( const typename DoFHandler::active_cell_iterator &cell, - ScratchData & scratch, - CopyData & copy) + ScratchData &scratch, + CopyData ©) { auto &cell_matrix = copy.matrices[0]; auto &cell_rhs = copy.vectors[0]; From e6d8cc776958ceb7cb01cef92e506f2399d2eb56 Mon Sep 17 00:00:00 2001 From: Luca Heltai Date: Tue, 25 Jun 2024 01:17:46 +0200 Subject: [PATCH 4/5] Multiplatform buildx. --- docker/build.sh | 4 +--- include/parsed_tools/constants.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/docker/build.sh b/docker/build.sh index dac059b05..dedf69a9b 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -1,4 +1,2 @@ #!/bin/sh -docker pull dealii/dealii:master-jammy -docker build -t heltai/dealii:vscode . -docker push heltai/dealii:vscode +docker buildx build --push --platform linux/amd64,linux/arm64 -t heltai/dealii:vscode . diff --git a/include/parsed_tools/constants.h b/include/parsed_tools/constants.h index 9be603155..fe06f7b7e 100644 --- a/include/parsed_tools/constants.h +++ b/include/parsed_tools/constants.h @@ -143,7 +143,7 @@ namespace ParsedTools /** - * The documentation string used to parse the constants from thee parameter + * The documentation string used to parse the constants from the parameter * file. */ std::map constants_parameter_entries; From 731b345e8dd263408875a2297c83bc3e1c6adcea Mon Sep 17 00:00:00 2001 From: Luca Heltai Date: Tue, 25 Jun 2024 01:26:17 +0200 Subject: [PATCH 5/5] workflow. --- .github/workflows/docker.yml | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index deff41246..108371cfc 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -2,17 +2,20 @@ name: github-docker on: push: - branches: [main] + branches: [main, 'docker*'] jobs: build-master-docker: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v3 - name: Login to DockerHub uses: docker/login-action@v1 @@ -20,13 +23,23 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker image of master - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v6 with: context: ./docker/ file: ./docker/Dockerfile.fsi-suite cache-from: type=registry,ref=heltai/dealii:vscode cache-to: type=inline + platforms: linux/arm64,linux/amd64 push: true - tags: heltai/fsi-suite:latest + tags: | + heltai/fsi-suite:latest + ghr.io/${{ github.repository }}:latest