https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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#include <typeinfo>
15#include <typeindex>
16
17#include "libmesh/parameters.h"
18
19#include "MooseError.h"
20#include "MooseUtils.h"
21
22#ifdef MOOSE_UNIT_TEST
23#include "gtest/gtest.h"
24class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, add);
25class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, addExists);
26class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, set);
27class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, setNotRegistered);
28class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, setCatchMooseError);
29#endif
30
31namespace hit
32{
33class Field;
34}
35
36namespace Moose
37{
38
44{
45public:
49 static ParameterRegistry & get();
50
54 template <class T, class F>
55 char add(F && f);
56
60 void set(libMesh::Parameters::Value & value, const hit::Field & field) const;
61
62private:
67
68#ifdef MOOSE_UNIT_TEST
69 FRIEND_TEST(::ParameterRegistryTest, add);
70 FRIEND_TEST(::ParameterRegistryTest, addExists);
71 FRIEND_TEST(::ParameterRegistryTest, set);
72 FRIEND_TEST(::ParameterRegistryTest, setNotRegistered);
73 FRIEND_TEST(::ParameterRegistryTest, setCatchMooseError);
74#endif
75
77 std::unordered_map<std::type_index,
78 std::function<void(libMesh::Parameters::Value & value, const hit::Field &)>>
80};
81
82template <class T, class F>
83char
85{
86 static_assert(std::is_invocable_r_v<void, F &, T &, const hit::Field &>,
87 "Setter function must be callable with (T &, const hit::Field &) and return void");
88
89 // We register a function that stores T &, but the registry will only ever be
90 // called from a bare libMesh::Parameters::Value. Thus, we need to cast the
91 // bare Value to the derived value and then call the setter.
92 auto setter = [f = std::forward<F>(f)](libMesh::Parameters::Value & param_value,
93 const hit::Field & field) -> void
94 {
95 auto cast_param_value = dynamic_cast<libMesh::Parameters::Parameter<T> *>(&param_value);
96 mooseAssert(cast_param_value, "Cast failed");
97 f(cast_param_value->set(), field);
98 };
99
100 const std::type_index key(typeid(T));
101 const auto it_inserted_pair = _registry.emplace(key, std::move(setter));
102
103 if (!it_inserted_pair.second)
104 mooseError("ParameterRegistry: Parameter with type '",
105 MooseUtils::prettyCppType<T>(),
106 "' is already registered");
107
108 return 0;
109}
110
111} // end of namespace Moose
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, add)
Registry that allows for the typeless setting of a parameter value from a hit field.
char add(F &&f)
Add a parameter.
std::unordered_map< std::type_index, std::function< void(libMesh::Parameters::Value &value, const hit::Field &)> > _registry
Registration map of type -> function to fill each type.
static ParameterRegistry & get()
Get the singleton registry.
void set(libMesh::Parameters::Value &value, const hit::Field &field) const
Sets a parameter value given a hit field.
FRIEND_TEST(::ParameterRegistryTest, set)
FRIEND_TEST(::ParameterRegistryTest, setCatchMooseError)
ParameterRegistry()
Constructor; private so that it can only be created with the singleton.
FRIEND_TEST(::ParameterRegistryTest, setNotRegistered)
FRIEND_TEST(::ParameterRegistryTest, addExists)
FRIEND_TEST(::ParameterRegistryTest, add)
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
Definition Moose.h:48