LCOV - code coverage report
Current view: top level - include/utils - parameters.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 26 74 35.1 %
Date: 2025-08-19 19:27:09 Functions: 20 45 44.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : 
      20             : #ifndef LIBMESH_PARAMETERS_H
      21             : #define LIBMESH_PARAMETERS_H
      22             : 
      23             : // Local includes
      24             : #include "libmesh/libmesh_common.h"
      25             : #include "libmesh/reference_counted_object.h"
      26             : #include "libmesh/print_trace.h"
      27             : 
      28             : // C++ includes
      29             : #include <cstddef>
      30             : #include <map>
      31             : #include <sstream>
      32             : #include <string>
      33             : #include <typeinfo>
      34             : #include <vector>
      35             : #include <memory>
      36             : #include <set>
      37             : 
      38             : namespace libMesh
      39             : {
      40             : /**
      41             :  * Helper functions for printing scalar, vector, vector<vector> and vector<vector<vector>>
      42             :  * types.  Called from Parameters::Parameter<T>::print(...).
      43             :  */
      44             : template<typename P>
      45             : void print_helper(std::ostream & os, const P * param);
      46             : 
      47             : template<typename P>
      48             : void print_helper(std::ostream & os, const std::vector<P> * param);
      49             : 
      50             : template<typename P>
      51             : void print_helper(std::ostream & os, const std::vector<std::vector<P>> * param);
      52             : 
      53             : template<typename P>
      54             : void print_helper(std::ostream & os, const std::vector<std::vector<std::vector<P>>> * param);
      55             : 
      56             : template<typename P1, typename P2, typename C, typename A>
      57             : void print_helper(std::ostream & os, const std::map<P1, P2, C, A> * param);
      58             : 
      59             : template <typename P, typename C, typename A>
      60             : void print_helper(std::ostream & os, const std::set<P, C, A> * param);
      61             : 
      62             : /**
      63             :  * This class provides the ability to map between
      64             :  * arbitrary, user-defined strings and several data
      65             :  * types.  This can be used to provide arbitrary
      66             :  * user-specified options.
      67             :  *
      68             :  * \author Benjamin S. Kirk
      69             :  * \date 2004
      70             :  */
      71             : class Parameters
      72             : {
      73             : public:
      74             : 
      75             :   /**
      76             :    * Default constructor.
      77             :    */
      78      459725 :   Parameters () = default;
      79             : 
      80             :   /**
      81             :    * Copy constructor. Makes an independent copy by cloning the
      82             :    * contents of the passed-in Parameters object.
      83             :    */
      84             :   Parameters (const Parameters &);
      85             : 
      86             :   /**
      87             :    * Destructor.
      88             :    */
      89      458071 :   virtual ~Parameters () = default;
      90             : 
      91             :   /**
      92             :    * Assignment operator.  Removes all parameters in \p this
      93             :    * and inserts copies of all parameters from \p source
      94             :    */
      95             :   virtual Parameters & operator= (const Parameters & source);
      96             : 
      97             :   /**
      98             :    * Addition/Assignment operator.  Inserts copies of all parameters
      99             :    * from \p source.  Any parameters of the same name already in \p
     100             :    * this are replaced.
     101             :    */
     102             :   virtual Parameters & operator+= (const Parameters & source);
     103             : 
     104             :   /**
     105             :    * \returns \p true if a parameter of type \p T
     106             :    * with a specified name exists, \p false otherwise.
     107             :    *
     108             :    * If RTTI has been disabled then we return \p true
     109             :    * if a parameter of specified name exists regardless of its type.
     110             :    */
     111             :   template <typename T>
     112             :   bool have_parameter (std::string_view) const;
     113             : 
     114             :   /**
     115             :    * \returns A constant reference to the specified parameter
     116             :    * value.  Requires, of course, that the parameter exists.
     117             :    */
     118             :   template <typename T>
     119             :   const T & get (std::string_view) const;
     120             : 
     121             :   /**
     122             :    * Inserts a new Parameter into the object but does not return
     123             :    * a writable reference.  The value of the newly inserted
     124             :    * parameter may not be valid.
     125             :    */
     126             :   template <typename T>
     127             :   void insert (const std::string &);
     128             : 
     129             :   /**
     130             :    * \returns A writable reference to the specified parameter.
     131             :    * This method will create the parameter if it does not exist,
     132             :    * so it can be used to define parameters which will later be
     133             :    * accessed with the \p get() member.
     134             :    */
     135             :   template <typename T>
     136             :   T & set (const std::string &);
     137             : 
     138             :   /**
     139             :    * Overridable function to set any extended attributes for
     140             :    * classes inheriting from this class.
     141             :    */
     142      465936 :   virtual void set_attributes(const std::string &, bool /*inserted_only*/) {}
     143             : 
     144             :   /**
     145             :    * Removes the specified parameter from the list, if it exists.
     146             :    */
     147             :   void remove (std::string_view);
     148             : 
     149             :   /**
     150             :    * \returns The total number of parameters.
     151             :    */
     152             :   std::size_t n_parameters () const { return _values.size(); }
     153             : 
     154             : #ifdef LIBMESH_HAVE_RTTI
     155             :   /**
     156             :    * \returns The number of parameters of the requested type.
     157             :    */
     158             :   template <typename T>
     159             :   unsigned int n_parameters () const;
     160             : #endif // LIBMESH_HAVE_RTTI
     161             : 
     162             :   /**
     163             :    * Clears internal data structures & frees any allocated memory.
     164             :    */
     165             :   virtual void clear ();
     166             : 
     167             :   /**
     168             :    * Prints the contents, by default to libMesh::out.
     169             :    */
     170             :   void print (std::ostream & os=libMesh::out) const;
     171             : 
     172             :   /**
     173             :    * Abstract definition of a parameter value.
     174             :    */
     175             :   class Value : public ReferenceCountedObject<Value>
     176             :   {
     177             :   public:
     178             : 
     179             :     /**
     180             :      * Destructor.
     181             :      */
     182         792 :     virtual ~Value() = default;
     183             : 
     184             : #ifdef LIBMESH_HAVE_RTTI
     185             :     /**
     186             :      * String identifying the type of parameter stored.
     187             :      * Must be reimplemented in derived classes.
     188             :      */
     189             :     virtual std::string type () const = 0;
     190             : #endif // LIBMESH_HAVE_RTTI
     191             : 
     192             :     /**
     193             :      * Prints the parameter value to the specified stream.
     194             :      * Must be reimplemented in derived classes.
     195             :      */
     196             :     virtual void print(std::ostream &) const = 0;
     197             : 
     198             :     /**
     199             :      * Clone this value.  Useful in copy-construction.
     200             :      * Must be reimplemented in derived classes.
     201             :      */
     202             :     virtual std::unique_ptr<Value> clone () const = 0;
     203             :   };
     204             : 
     205             :   /**
     206             :    * Concrete definition of a parameter value
     207             :    * for a specified type.
     208             :    */
     209             :   template <typename T>
     210      464165 :   class Parameter : public Value
     211             :   {
     212             :   public:
     213             : 
     214             :     /**
     215             :      * \returns A read-only reference to the parameter value.
     216             :      */
     217      835935 :     const T & get () const { return _value; }
     218             : 
     219             :     /**
     220             :      * \returns A writable reference to the parameter value.
     221             :      */
     222      467176 :     T & set () { return _value; }
     223             : 
     224             : #ifdef LIBMESH_HAVE_RTTI
     225             :     /**
     226             :      * String identifying the type of parameter stored.
     227             :      */
     228             :     virtual std::string type () const override;
     229             : #endif // LIBMESH_HAVE_RTTI
     230             : 
     231             :     /**
     232             :      * Prints the parameter value to the specified stream.
     233             :      */
     234             :     virtual void print(std::ostream &) const override;
     235             : 
     236             :     /**
     237             :      * Clone this value.  Useful in copy-construction.
     238             :      */
     239             :     virtual std::unique_ptr<Value> clone () const override;
     240             : 
     241             :   private:
     242             :     /**
     243             :      * Stored parameter value.
     244             :      */
     245             :     T _value;
     246             :   };
     247             : 
     248             :   /**
     249             :    * The type of the map that we store internally.
     250             :    */
     251             :   typedef std::map<std::string, std::unique_ptr<Value>, std::less<>> map_type;
     252             : 
     253             :   /**
     254             :    * Parameter map iterator.
     255             :    */
     256             :   typedef map_type::iterator iterator;
     257             : 
     258             :   /**
     259             :    * Constant parameter map iterator.
     260             :    */
     261             :   typedef map_type::const_iterator const_iterator;
     262             : 
     263             :   /**
     264             :    * Iterator pointing to the beginning of the set of parameters.
     265             :    */
     266             :   iterator begin();
     267             : 
     268             :   /**
     269             :    * Iterator pointing to the beginning of the set of parameters.
     270             :    */
     271             :   const_iterator begin() const;
     272             : 
     273             :   /**
     274             :    * Iterator pointing to the end of the set of parameters
     275             :    */
     276             :   iterator end();
     277             : 
     278             :   /**
     279             :    * Iterator pointing to the end of the set of parameters
     280             :    */
     281             :   const_iterator end() const;
     282             : 
     283             : protected:
     284             : 
     285             :   /**
     286             :    * Data structure to map names with values.
     287             :    */
     288             :   map_type _values;
     289             : };
     290             : 
     291             : // ------------------------------------------------------------
     292             : // Parameters::Parameter<> class inline methods
     293             : 
     294             : // This only works with Run-Time Type Information, even though
     295             : // typeid(T) *should* be determinable at compile time regardless...
     296             : #ifdef LIBMESH_HAVE_RTTI
     297             : template <typename T>
     298             : inline
     299           0 : std::string Parameters::Parameter<T>::type () const
     300             : {
     301           0 :   return demangle(typeid(T).name());
     302             : }
     303             : #endif
     304             : 
     305             : template <typename T>
     306             : inline
     307           0 : void Parameters::Parameter<T>::print (std::ostream & os) const
     308             : {
     309             :   // Call helper function overloaded for basic scalar and vector types
     310           0 :   print_helper(os, static_cast<const T *>(&_value));
     311           0 : }
     312             : 
     313             : template <typename T>
     314             : inline
     315           0 : std::unique_ptr<Parameters::Value> Parameters::Parameter<T>::clone () const
     316             : {
     317           0 :   auto copy = std::make_unique<Parameter<T>>();
     318             : 
     319           0 :   copy->_value = this->_value; // assign value
     320             : 
     321           0 :   return copy; // as unique_ptr to base class
     322           0 : }
     323             : 
     324             : 
     325             : // ------------------------------------------------------------
     326             : // Parameters class inline methods
     327             : inline
     328           0 : void Parameters::clear ()
     329             : {
     330           0 :   _values.clear();
     331           0 : }
     332             : 
     333             : 
     334             : 
     335             : inline
     336           0 : Parameters & Parameters::operator= (const Parameters & source)
     337             : {
     338           0 :   this->Parameters::clear();
     339           0 :   *this += source;
     340             : 
     341           0 :   return *this;
     342             : }
     343             : 
     344             : inline
     345           0 : Parameters & Parameters::operator+= (const Parameters & source)
     346             : {
     347             :   // Overwrite each value (if it exists) or create a new entry
     348           0 :   for (const auto & [key, value] : source._values)
     349           0 :     _values[key] = value->clone();
     350             : 
     351           0 :   return *this;
     352             : }
     353             : 
     354             : inline
     355             : Parameters::Parameters (const Parameters & p)
     356             : {
     357             :   // calls assignment operator
     358             :   *this = p;
     359             : }
     360             : 
     361             : 
     362             : 
     363             : inline
     364           0 : void Parameters::print (std::ostream & os) const
     365             : {
     366           0 :   Parameters::const_iterator it = _values.begin();
     367             : 
     368             :   os << "Name\t Type\t Value\n"
     369           0 :      << "---------------------\n";
     370           0 :   while (it != _values.end())
     371             :     {
     372           0 :       os << " "   << it->first
     373             : #ifdef LIBMESH_HAVE_RTTI
     374           0 :          << "\t " << it->second->type()
     375             : #endif // LIBMESH_HAVE_RTTI
     376           0 :          << "\t ";   it->second->print(os);
     377           0 :       os << '\n';
     378             : 
     379           0 :       ++it;
     380             :     }
     381           0 : }
     382             : 
     383             : 
     384             : 
     385             : // Declare this now that Parameters::print() is defined.
     386             : // By declaring this early we can use it in subsequent
     387             : // methods.  Required for gcc-4.0.2 -- 11/30/2005, BSK
     388             : inline
     389           0 : std::ostream & operator << (std::ostream & os, const Parameters & p)
     390             : {
     391           0 :   p.print(os);
     392           0 :   return os;
     393             : }
     394             : 
     395             : 
     396             : 
     397             : template <typename T>
     398             : inline
     399     3194899 : bool Parameters::have_parameter (std::string_view name) const
     400             : {
     401      225128 :   Parameters::const_iterator it = _values.find(name);
     402             : 
     403     3194899 :   if (it != _values.end())
     404             :     {
     405             : #ifdef LIBMESH_HAVE_RTTI
     406             : 
     407      836446 :       if (dynamic_cast<const Parameter<T> *>(it->second.get()))
     408      836446 :         return true;
     409             : 
     410             : #else // !LIBMESH_HAVE_RTTI
     411             : 
     412             :       // cast_ptr will simply do a static_cast here when RTTI is not
     413             :       // enabled, and it will return a non-nullptr regardless of
     414             :       // whether or not the cast actually succeeds.
     415             :       libmesh_warning("Parameters::have_parameter() may return false positives when RTTI is not enabled.");
     416             : 
     417             :       if (cast_ptr<const Parameter<T> *>(it->second.get()))
     418             :         return true;
     419             : 
     420             : #endif
     421             :     }
     422             : 
     423      202558 :   return false;
     424             : }
     425             : 
     426             : 
     427             : 
     428             : template <typename T>
     429             : inline
     430      835935 : const T & Parameters::get (std::string_view name) const
     431             : {
     432      835935 :   if (!this->have_parameter<T>(name))
     433             :     {
     434           0 :       std::ostringstream oss;
     435             : 
     436           0 :       oss << "ERROR: no";
     437             : #ifdef LIBMESH_HAVE_RTTI
     438           0 :       oss << ' ' << demangle(typeid(T).name());
     439             : #endif
     440             :       oss << " parameter named \""
     441             :           << name << "\" found.\n\n"
     442           0 :           << "Known parameters:\n"
     443           0 :           << *this;
     444             : 
     445           0 :       libmesh_error_msg(oss.str());
     446           0 :     }
     447             : 
     448       23968 :   Parameters::const_iterator it = _values.find(name);
     449             : 
     450       23968 :   libmesh_assert(it != _values.end());
     451       23968 :   libmesh_assert(it->second);
     452             : 
     453             :   // Get pointer to derived type
     454       23968 :   auto ptr = cast_ptr<Parameter<T> *>(it->second.get());
     455             : 
     456             :   // Return const reference
     457      859903 :   return ptr->get();
     458             : }
     459             : 
     460             : template <typename T>
     461             : inline
     462             : void Parameters::insert (const std::string & name)
     463             : {
     464             :   if (!this->have_parameter<T>(name))
     465             :     _values[name] = std::make_unique<Parameter<T>>();
     466             : 
     467             :   set_attributes(name, true);
     468             : }
     469             : 
     470             : 
     471             : template <typename T>
     472             : inline
     473      467176 : T & Parameters::set (const std::string & name)
     474             : {
     475      467176 :   if (!this->have_parameter<T>(name))
     476      479003 :     _values[name] = std::make_unique<Parameter<T>>();
     477             : 
     478      467176 :   set_attributes(name, false);
     479             : 
     480             :   // Get pointer to existing or just-added entry
     481      467176 :   auto ptr = cast_ptr<Parameter<T> *>(_values[name].get());
     482             : 
     483             :   // Return writeable reference
     484      467176 :   return ptr->set();
     485             : }
     486             : 
     487             : inline
     488           0 : void Parameters::remove (std::string_view name)
     489             : {
     490             :   Parameters::iterator it = _values.find(name);
     491             : 
     492           0 :   if (it != _values.end())
     493           0 :     _values.erase(it);
     494           0 : }
     495             : 
     496             : 
     497             : 
     498             : #ifdef LIBMESH_HAVE_RTTI
     499             : template <typename T>
     500             : inline
     501             : unsigned int Parameters::n_parameters () const
     502             : {
     503             :   unsigned int cnt = 0;
     504             : 
     505             :   for (const auto & pr : _values)
     506             :     if (dynamic_cast<Parameter<T> *>(pr.second.get()))
     507             :       cnt++;
     508             : 
     509             :   return cnt;
     510             : }
     511             : #endif
     512             : 
     513             : inline
     514             : Parameters::iterator Parameters::begin()
     515             : {
     516             :   return _values.begin();
     517             : }
     518             : 
     519             : inline
     520             : Parameters::const_iterator Parameters::begin() const
     521             : {
     522             :   return _values.begin();
     523             : }
     524             : 
     525             : inline
     526             : Parameters::iterator Parameters::end()
     527             : {
     528             :   return _values.end();
     529             : }
     530             : 
     531             : inline
     532             : Parameters::const_iterator Parameters::end() const
     533             : {
     534             :   return _values.end();
     535             : }
     536             : 
     537             : //non-member scalar print function
     538             : template<typename P>
     539           0 : void print_helper(std::ostream & os, const P * param)
     540             : {
     541           0 :   os << *param;
     542           0 : }
     543             : 
     544             : template<>
     545             : inline
     546             : void print_helper(std::ostream & os, const char * param)
     547             : {
     548             :   // Specialization so that we don't print out unprintable characters
     549             :   os << static_cast<int>(*param);
     550             : }
     551             : 
     552             : template<>
     553             : inline
     554             : void print_helper(std::ostream & os, const unsigned char * param)
     555             : {
     556             :   // Specialization so that we don't print out unprintable characters
     557             :   os << static_cast<int>(*param);
     558             : }
     559             : 
     560             : //non-member vector print function
     561             : template<typename P>
     562             : void print_helper(std::ostream & os, const std::vector<P> * param)
     563             : {
     564             :   for (const auto & p : *param)
     565             :     os << p << " ";
     566             : }
     567             : 
     568             : //non-member vector<vector> print function
     569             : template<typename P>
     570             : void print_helper(std::ostream & os, const std::vector<std::vector<P>> * param)
     571             : {
     572             :   for (const auto & pv : *param)
     573             :     for (const auto & p : pv)
     574             :       os << p << " ";
     575             : }
     576             : 
     577             : //non-member vector<vector<vector>> print function
     578             : template<typename P>
     579             : void print_helper(std::ostream & os, const std::vector<std::vector<std::vector<P>>> * param)
     580             : {
     581             :   for (const auto & pvv : *param)
     582             :     for (const auto & pv : pvv)
     583             :       for (const auto & p : pv)
     584             :         os << p << " ";
     585             : }
     586             : 
     587             : //non-member map print function
     588             : template<typename P1, typename P2, typename C, typename A>
     589             : void print_helper(std::ostream & os, const std::map<P1, P2, C, A> * param)
     590             : {
     591             :   os << '{';
     592             :   std::size_t sz = param->size();
     593             :   for (auto KV : *param)
     594             :     {
     595             :       os << '\'' << KV.first << "\' => \'" << KV.second << '\'';
     596             :       if (--sz)
     597             :         os << ", ";
     598             :     }
     599             :   os << '}';
     600             : }
     601             : 
     602             : //non-member set print function
     603             : template<typename P, typename C, typename A>
     604             : void print_helper(std::ostream & os, const std::set<P, C, A> * param)
     605             : {
     606             :   for (const auto & p : *param)
     607             :     os << p << " ";
     608             : }
     609             : 
     610             : 
     611             : } // namespace libMesh
     612             : 
     613             : #endif // LIBMESH_PARAMETERS_H

Generated by: LCOV version 1.14