LCOV - code coverage report
Current view: top level - include/parser - ParameterRegistry.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 863ef6 Lines: 10 10 100.0 %
Date: 2025-10-15 18:16:15 Functions: 909 1123 80.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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"
      24             : class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, add);
      25             : class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, addExists);
      26             : class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, set);
      27             : class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, setNotRegistered);
      28             : class GTEST_TEST_CLASS_NAME_(ParameterRegistryTest, setCatchMooseError);
      29             : #endif
      30             : 
      31             : namespace hit
      32             : {
      33             : class Field;
      34             : }
      35             : 
      36             : namespace Moose
      37             : {
      38             : 
      39             : /**
      40             :  * Registry that allows for the typeless setting of a parameter value
      41             :  * from a hit field
      42             :  */
      43             : class ParameterRegistry
      44             : {
      45             : public:
      46             :   /**
      47             :    * Get the singleton registry
      48             :    */
      49             :   static ParameterRegistry & get();
      50             : 
      51             :   /**
      52             :    * Add a parameter
      53             :    */
      54             :   template <class T, class F>
      55             :   char add(F && f);
      56             : 
      57             :   /**
      58             :    * Sets a parameter value given a hit field
      59             :    */
      60             :   void set(libMesh::Parameters::Value & value, const hit::Field & field) const;
      61             : 
      62             : private:
      63             :   /**
      64             :    * Constructor; private so that it can only be created with the singleton
      65             :    */
      66       57044 :   ParameterRegistry() {};
      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             : 
      76             :   /// Registration map of type -> function to fill each type
      77             :   std::unordered_map<std::type_index,
      78             :                      std::function<void(libMesh::Parameters::Value & value, const hit::Field &)>>
      79             :       _registry;
      80             : };
      81             : 
      82             : template <class T, class F>
      83             : char
      84    13566462 : ParameterRegistry::add(F && f)
      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    19130428 :   auto setter = [f = std::forward<F>(f)](libMesh::Parameters::Value & param_value,
      93             :                                          const hit::Field & field) -> void
      94             :   {
      95     2782115 :     auto cast_param_value = dynamic_cast<libMesh::Parameters::Parameter<T> *>(&param_value);
      96             :     mooseAssert(cast_param_value, "Cast failed");
      97     2782115 :     f(cast_param_value->set(), field);
      98             :   };
      99             : 
     100    13566462 :   const std::type_index key(typeid(T));
     101    13566462 :   const auto it_inserted_pair = _registry.emplace(key, std::move(setter));
     102             : 
     103    13566462 :   if (!it_inserted_pair.second)
     104           4 :     mooseError("ParameterRegistry: Parameter with type '",
     105             :                MooseUtils::prettyCppType<T>(),
     106             :                "' is already registered");
     107             : 
     108    13566460 :   return 0;
     109             : }
     110             : 
     111             : } // end of namespace Moose

Generated by: LCOV version 1.14