https://mooseframework.inl.gov
ParameterRegistry.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 #include <functional>
13 #include <map>
14 
15 #include "libmesh/parameters.h"
16 
17 #include "MooseError.h"
18 
19 #ifdef MOOSE_UNIT_TEST
20 #include "gtest/gtest.h"
21 class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, add);
22 class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, addExists);
23 class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, set);
24 class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, setNotRegistered);
25 class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, setCatchMooseError);
26 #endif
27 
28 namespace hit
29 {
30 class Field;
31 }
32 
33 namespace Moose
34 {
35 
41 {
42 public:
46  static ParameterRegistry & get();
47 
51  template <class T, class F>
52  char add(F && f);
53 
57  void set(libMesh::Parameters::Value & value, const hit::Field & field) const;
58 
59 private:
64 
65 #ifdef MOOSE_UNIT_TEST
66  FRIEND_TEST(::ParameterRegistryTest, add);
67  FRIEND_TEST(::ParameterRegistryTest, addExists);
68  FRIEND_TEST(::ParameterRegistryTest, set);
69  FRIEND_TEST(::ParameterRegistryTest, setNotRegistered);
70  FRIEND_TEST(::ParameterRegistryTest, setCatchMooseError);
71 #endif
72 
74  std::map<std::string, std::function<void(libMesh::Parameters::Value & value, const hit::Field &)>>
76 };
77 
78 template <class T, class F>
79 char
81 {
82  static_assert(std::is_invocable_r_v<void, F &, T &, const hit::Field &>,
83  "Setter function must be callable with (T &, const hit::Field &) and return void");
84 
85  // We register a function that stores T &, but the registry will only ever be
86  // called from a bare libMesh::Parameters::Value. Thus, we need to cast the
87  // bare Value to the derived value and then call the setter.
88  auto setter = [f = std::forward<F>(f)](libMesh::Parameters::Value & param_value,
89  const hit::Field & field) -> void
90  {
91  auto cast_param_value = dynamic_cast<libMesh::Parameters::Parameter<T> *>(&param_value);
92  mooseAssert(cast_param_value, "Cast failed");
93  f(cast_param_value->set(), field);
94  };
95 
96  const auto key = demangle(typeid(T).name());
97  const auto it_inserted_pair = _registry.emplace(key, std::move(setter));
98 
99  if (!it_inserted_pair.second)
100  mooseError("ParameterRegistry: Parameter with type '", key, "' is already registered");
101 
102  return 0;
103 }
104 
105 } // end of namespace Moose
std::string name(const ElemQuality q)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:323
Registry that allows for the typeless setting of a parameter value from a hit field.
ParameterRegistry()
Constructor; private so that it can only be created with the singleton.
class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, add)
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
std::string demangle(const char *name)
Definition: Moose.h:42
FRIEND_TEST(::ParameterRegistryTest, add)
char add(F &&f)
Add a parameter.
std::map< std::string, std::function< void(libMesh::Parameters::Value &value, const hit::Field &)> > _registry
Registration map of type -> function to fill each type.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...