LCOV - code coverage report
Current view: top level - src/utils - MooseEnumBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 94 110 85.5 %
Date: 2025-07-17 01:28:37 Functions: 21 23 91.3 %
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             : #include "MooseEnumBase.h"
      11             : #include "MooseUtils.h"
      12             : #include "MooseError.h"
      13             : #include "Conversion.h"
      14             : 
      15             : #include <sstream>
      16             : #include <algorithm>
      17             : #include <iterator>
      18             : #include <limits>
      19             : #include <string>
      20             : #include <iostream>
      21             : #include <cstdlib>
      22             : 
      23    35980481 : MooseEnumBase::MooseEnumBase(std::string names, bool allow_out_of_range)
      24    35980481 :   : _allow_out_of_range(allow_out_of_range)
      25             : {
      26    35980481 :   if (names.find(',') != std::string::npos)
      27           0 :     mooseError("Spaces are required to separate options, comma support has been removed.");
      28             :   else
      29    35980481 :     addEnumerationNames(names);
      30    35980487 : }
      31             : 
      32    20901203 : MooseEnumBase::MooseEnumBase(const MooseEnumBase & other_enum)
      33    20901203 :   : _items(other_enum._items),
      34    20901203 :     _deprecated_items(other_enum._deprecated_items),
      35    41802406 :     _allow_out_of_range(other_enum._allow_out_of_range)
      36             : {
      37    20901203 : }
      38             : 
      39             : /**
      40             :  * Private constuctor for use by libmesh::Parameters
      41             :  */
      42   104199312 : MooseEnumBase::MooseEnumBase() : _allow_out_of_range(false) {}
      43             : 
      44             : void
      45           3 : MooseEnumBase::deprecate(const std::string & name, const std::string & raw_name)
      46             : {
      47           3 :   std::set<MooseEnumItem>::const_iterator deprecated = find(name);
      48           3 :   if (deprecated == _items.end())
      49           0 :     mooseError("Cannot deprecate the enum item ", name, ", is not an available value.");
      50             : 
      51           3 :   std::set<MooseEnumItem>::const_iterator replaced = find(raw_name);
      52           3 :   if (replaced == _items.end())
      53           1 :     mooseError("Cannot deprecate the enum item ",
      54             :                name,
      55             :                ", since the replaced item ",
      56             :                raw_name,
      57             :                " it is not an available value.");
      58             : 
      59           2 :   _deprecated_items.emplace(std::make_pair(*deprecated, *replaced));
      60           2 :   checkDeprecated();
      61           2 : }
      62             : 
      63             : void
      64    35980481 : MooseEnumBase::addEnumerationNames(const std::string & names)
      65             : {
      66    35980481 :   std::vector<std::string> elements;
      67    35980481 :   MooseUtils::tokenize(names, elements, 1, " ");
      68   215838487 :   for (const std::string & raw_name : elements)
      69   179858009 :     addEnumerationName(raw_name);
      70    35980481 : }
      71             : 
      72             : const MooseEnumItem &
      73   179858009 : MooseEnumBase::addEnumerationName(const std::string & raw_name)
      74             : {
      75             :   // Make sure the option is not malformed
      76   179858009 :   if (raw_name.find_first_of('=') == 0 || raw_name.find_last_of('=') == raw_name.length() - 1)
      77           1 :     mooseError("You cannot place whitespace around the '=' character in MooseEnumBase");
      78             : 
      79             :   // Split on equals sign
      80   179858008 :   std::vector<std::string> name_value;
      81   179858008 :   MooseUtils::tokenize(MooseUtils::trim(raw_name), name_value, 1, "=");
      82             : 
      83             :   // There should be one or two items in the name_value
      84   179858008 :   if (name_value.size() < 1 || name_value.size() > 2)
      85           0 :     mooseError("Invalid option supplied in MooseEnumBase: ", raw_name);
      86             : 
      87             :   // Remove un-wanted space around string
      88   179858008 :   name_value[0] = MooseUtils::trim(name_value[0]);
      89             : 
      90             :   // See if there is a value supplied for this option
      91             :   // strtol allows for proper conversions of both int and hex strings
      92             :   int value;
      93   179858008 :   if (name_value.size() == 2)
      94    20380426 :     value = std::strtol(name_value[1].c_str(), NULL, 0);
      95             :   else
      96   159477582 :     value = getNextValidID();
      97             : 
      98   359716014 :   return addEnumerationName(name_value[0], value);
      99   179858008 : }
     100             : 
     101             : int
     102   174313302 : MooseEnumBase::getNextValidID() const
     103             : {
     104   174313302 :   int value = -1; // Use -1 so if no values exist the first will be zero
     105  1475093730 :   for (const auto & item : _items)
     106  1300780428 :     value = std::max(value, item.id());
     107   174313302 :   return ++value;
     108             : }
     109             : 
     110             : const MooseEnumItem &
     111   179858008 : MooseEnumBase::addEnumerationName(const std::string & name, const int & value)
     112             : {
     113   179858008 :   return addEnumerationItem(MooseEnumItem(name, value));
     114             : }
     115             : 
     116             : const MooseEnumItem &
     117   203957591 : MooseEnumBase::addEnumerationItem(const MooseEnumItem & item)
     118             : {
     119   203957591 :   const auto & item_it = find(item);
     120   203957591 :   if (item_it != _items.end()) // do nothing for identical insertions
     121           0 :     return *item_it;
     122             : 
     123   203957591 :   if (find(item.id()) != _items.end())
     124           1 :     mooseError("The supplied id ",
     125             :                item.id(),
     126             :                " already exists in the enumeration, cannot not add '",
     127             :                item,
     128             :                "'.");
     129   203957590 :   if (find(item.name()) != _items.end())
     130           1 :     mooseError("The name '", item.name(), "' already exists in the enumeration.");
     131             : 
     132   203957589 :   return *_items.insert(item).first;
     133             : }
     134             : 
     135             : void
     136    75287996 : MooseEnumBase::checkDeprecated(const MooseEnumItem & item) const
     137             : {
     138    75287996 :   std::map<MooseEnumItem, MooseEnumItem>::const_iterator it = _deprecated_items.find(item);
     139    75287996 :   if (it != _deprecated_items.end())
     140             :   {
     141           2 :     if (it->second.name().empty())
     142           0 :       mooseWarning(item.name() + " is deprecated");
     143             :     else
     144           6 :       mooseWarning(item.name() + " is deprecated, consider using " + it->second.name());
     145             :   }
     146    75287994 : }
     147             : 
     148             : std::vector<std::string>
     149        1631 : MooseEnumBase::getNames() const
     150             : {
     151        1631 :   std::vector<std::string> out;
     152        1631 :   out.reserve(_items.size());
     153       16941 :   for (const auto & item : _items)
     154       15310 :     out.push_back(item.name());
     155        1631 :   return out;
     156           0 : }
     157             : 
     158             : std::string
     159      673597 : MooseEnumBase::getRawNames() const
     160             : {
     161      673597 :   return Moose::stringify(_items, " ");
     162             : }
     163             : 
     164             : std::vector<int>
     165           2 : MooseEnumBase::getIDs() const
     166             : {
     167           2 :   std::vector<int> out;
     168           2 :   out.reserve(_items.size());
     169           6 :   for (const auto & item : _items)
     170           4 :     out.push_back(item.id());
     171           2 :   return out;
     172           0 : }
     173             : 
     174             : void
     175      280005 : MooseEnumBase::addDocumentation(const std::string & name, const std::string & doc)
     176             : {
     177      280005 :   auto it = find(name);
     178      280005 :   if (it == _items.end())
     179           0 :     mooseError("Item '", name, "' not found in addDocumentation.");
     180      280005 :   _item_documentation[*it] = doc;
     181      280005 : }
     182             : 
     183             : const std::map<MooseEnumItem, std::string> &
     184      615076 : MooseEnumBase::getItemDocumentation() const
     185             : {
     186      615076 :   return _item_documentation;
     187             : }
     188             : 
     189             : std::set<MooseEnumItem>::const_iterator
     190   241538769 : MooseEnumBase::find(const std::string & name) const
     191             : {
     192   241538769 :   std::string upper = MooseUtils::toUpper(name);
     193   241538769 :   return std::find_if(_items.begin(),
     194             :                       _items.end(),
     195  2021442638 :                       [&upper](MooseEnumItem const & item) { return item.name() == upper; });
     196   241538769 : }
     197             : 
     198             : std::set<MooseEnumItem>::const_iterator
     199   204218399 : MooseEnumBase::find(int id) const
     200             : {
     201   204218399 :   return std::find_if(
     202  1659487798 :       _items.begin(), _items.end(), [&id](MooseEnumItem const & item) { return item.id() == id; });
     203             : }
     204             : 
     205             : std::set<MooseEnumItem>::const_iterator
     206   241680989 : MooseEnumBase::find(const MooseEnumItem & other) const
     207             : {
     208   241680989 :   const auto upper = MooseUtils::toUpper(other.name());
     209   241680989 :   return std::find_if(_items.begin(),
     210             :                       _items.end(),
     211  3354611188 :                       [&other, &upper](MooseEnumItem const & item)
     212  2141805873 :                       { return item.id() == other.id() && item.name() == upper; });
     213   241680989 : }
     214             : 
     215             : MooseEnumBase &
     216           0 : MooseEnumBase::operator+=(const std::string & name)
     217             : {
     218           0 :   addEnumerationName(name);
     219           0 :   checkDeprecated();
     220           0 :   return *this;
     221             : }
     222             : 
     223             : MooseEnumBase &
     224           0 : MooseEnumBase::operator+=(const std::initializer_list<std::string> & names)
     225             : {
     226           0 :   for (const auto & name : names)
     227           0 :     *this += name;
     228           0 :   return *this;
     229             : }

Generated by: LCOV version 1.14