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 : // MOOSE includes 13 : #include "Moose.h" 14 : #include "MooseEnumBase.h" 15 : #include "MooseError.h" 16 : 17 : // C++ includes 18 : #include <vector> 19 : 20 : // Forward declarations 21 : class ExecFlagEnum; 22 : namespace libMesh 23 : { 24 : class Parameters; 25 : } 26 : 27 : typedef std::vector<MooseEnumItem>::const_iterator MooseEnumIterator; 28 : 29 : /** 30 : * This is a "smart" enum class intended to replace many of the 31 : * shortcomings in the C++ enum type. There are two parts to a MultiMooseEnum: 32 : * 1) The list of all possible values that a variable can have and 33 : * 2) The subset of these values that the variable is actually set to. 34 : * It should be initialized with a comma-separated list of strings which 35 : * become the possible enum values. You may also optionally supply numeric 36 : * ints for one or more values similar to a C++ enum. This is done with the 37 : * "=" sign. It can be used any place where an integer (switch statements), 38 : * const char* or * std::string is expected. In addition the 39 : * InputParameters system has full support for this Enum type. 40 : */ 41 : class MultiMooseEnum : public MooseEnumBase 42 : { 43 : public: 44 : ///@{ 45 : /** 46 : * Constructor that takes a list of valid enumeration values, and a separate string to set default 47 : * values for this instance 48 : * @param valid_names - a list of all possible values (names) for this enumeration 49 : * @param initialization_values - the value(s) to set this enumeration instance to 50 : * @param allow_out_of_range - determines whether this enumeration will accept values outside of 51 : * its range of initially defined values. A value of true allows the addition of valid 52 : * values to an object after it has been initialized. 53 : */ 54 : MultiMooseEnum(std::string valid_names, 55 : std::string initialization_values, 56 : bool allow_out_of_range = false); 57 : // We need to explicitly define this version so MultiMooseEnum("one two", "one") 58 : // doesn't implicitly convert "one" to a bool and use the 2-parameter constructor 59 : MultiMooseEnum(std::string valid_names, 60 : const char * initialization_values, 61 : bool allow_out_of_range = false); 62 : ///@} 63 : 64 : /** 65 : * Constructor that takes a list of valid enumeration values, and does not set this instance to 66 : * any particular value. 67 : * @param valid_names - a list of all possible values (names) for this enumeration 68 : * @param allow_out_of_range - determines whether this enumeration will accept values outside of 69 : * its range of initially defined values. A value of true allows the addition of valid 70 : * values to an object after it has been initialized. 71 : */ 72 : MultiMooseEnum(std::string valid_names, bool allow_out_of_range = false); 73 : 74 : /** 75 : * Copy Constructor 76 : * @param other_enum - The other enumeration to copy state from 77 : */ 78 : MultiMooseEnum(const MultiMooseEnum & other_enum); 79 : 80 : /** 81 : * Copy Assignment operator must be explicitly defined when a copy ctor exists and this 82 : * method is used. 83 : */ 84 73886249 : MultiMooseEnum & operator=(const MultiMooseEnum & other_enum) = default; 85 : 86 : ///@{ 87 : /** 88 : * Comparison operators for comparing with character constants, MultiMooseEnums 89 : * or integer values 90 : * @param value - RHS value to compare against 91 : * @return bool - the truth value for the comparison 92 : */ 93 : bool operator==(const MultiMooseEnum & value) const; 94 : bool operator!=(const MultiMooseEnum & value) const; 95 : ///@} 96 : 97 : ///@{ 98 : /** 99 : * Methods for seeing if a value is set in the MultiMooseEnum. 100 : * @return bool - the truth value indicating whether the value is set 101 : */ 102 214535 : bool contains(const std::string & value) const { return isValueSet(value); } 103 : bool contains(int value) const { return isValueSet(value); } 104 : bool contains(unsigned short value) const { return isValueSet(value); } 105 : bool contains(const MultiMooseEnum & value) const { return isValueSet(value); } 106 190 : bool contains(const MooseEnumItem & value) const { return isValueSet(value); } 107 : ///@} 108 : 109 : // The following are aliases for contains with more descriptive name 110 : ///@{ 111 : /** 112 : * Methods for seeing if a value is set in the MultiMooseEnum. 113 : * @return bool - the truth value indicating whether the value is set 114 : */ 115 : bool isValueSet(const std::string & value) const; 116 : bool isValueSet(int value) const; 117 : bool isValueSet(unsigned short value) const; 118 : bool isValueSet(const MultiMooseEnum & value) const; 119 : bool isValueSet(const MooseEnumItem & value) const; 120 : ///@} 121 : 122 : ///@{ 123 : /** 124 : * Assignment operators to set the objects value from the list of possible values. 125 : * @param names - a string, set, or vector representing one of the enumeration values. 126 : * @return A reference to this object for chaining 127 : */ 128 : MultiMooseEnum & operator=(const std::string & names); 129 : MultiMooseEnum & operator=(const std::vector<std::string> & names); 130 : MultiMooseEnum & operator=(const std::set<std::string> & names); 131 : ///@} 132 : 133 : ///@{ 134 : /** 135 : * Un-assign, or unset a value. Deprecated, use eraseSetValue instead. 136 : * @param names - a string, set, or vector giving the name to erase from the enumeration values 137 : */ 138 : void erase(const std::string & names); 139 : void erase(const std::vector<std::string> & names); 140 : void erase(const std::set<std::string> & names); 141 : ///@} 142 : 143 : // The following replaces erase with a more descriptive name 144 : ///@{ 145 : /** 146 : * Un-assign, or unset a value 147 : * @param names - a string, set, or vector giving the name to erase from the enumeration values 148 : */ 149 : void eraseSetValue(const std::string & names); 150 : void eraseSetValue(const std::vector<std::string> & names); 151 : void eraseSetValue(const std::set<std::string> & names); 152 : ///@} 153 : 154 : ///@{ 155 : /** 156 : * Insert operators 157 : * Operator to insert (push_back) values into the enum. Existing values are preserved and 158 : * duplicates are stored. Deprecated, use setAdditionalValue instead. 159 : * @param names - a string, set, or vector representing the enumeration values to set. 160 : */ 161 : void push_back(const std::string & names); 162 : void push_back(const std::vector<std::string> & names); 163 : void push_back(const std::set<std::string> & names); 164 : void push_back(const MultiMooseEnum & other_enum); 165 : ///@} 166 : 167 : // The following replaces push_back with a more descriptive name 168 : ///@{ 169 : /** 170 : * Insert operators 171 : * Operator to insert (push_back) values into the enum. Existing values are preserved and 172 : * duplicates are stored. 173 : * @param names - a string, set, or vector representing the enumeration values to set. 174 : */ 175 : void setAdditionalValue(const std::string & names); 176 : void setAdditionalValue(const std::vector<std::string> & names); 177 : void setAdditionalValue(const std::set<std::string> & names); 178 : void setAdditionalValue(const MultiMooseEnum & other_enum); 179 : ///@} 180 : 181 : /** 182 : * Indexing operator 183 : * Operator to retrieve an item from the MultiMooseEnum. The reference may not be used to change 184 : * the item. 185 : * @param i index 186 : * @returns a read/read-write reference to the item as a string. 187 : */ 188 : const std::string & operator[](unsigned int i) const; 189 : 190 : /** 191 : * Indexing operator 192 : * Operator to retrieve the id of an item from the MultiMooseEnum. 193 : * @param i index corresponding to the desired item 194 : * @returns the id of the MooseEnumItem at the supplied index 195 : */ 196 : unsigned int get(unsigned int i) const; 197 : 198 : /// get the current values cast to a vector of enum type T. Deprecated, use getSetValueIDs instead. 199 : template <typename T> 200 : std::vector<T> getEnum() const; 201 : 202 : // The following replaces getEnum with a more descriptive name 203 : /// get the current values cast to a vector of enum type T 204 : template <typename T> 205 : std::vector<T> getSetValueIDs() const; 206 : 207 : ///@{ 208 : /** 209 : * Returns a begin/end iterator to all of the set values in the enum. 210 : * Items will always be capitalized. 211 : */ 212 1224054 : MooseEnumIterator begin() const { return _current_values.begin(); } 213 1213882 : MooseEnumIterator end() const { return _current_values.end(); } 214 : ///@} 215 : 216 : ///@{ 217 : /** 218 : * Clear the MultiMooseEnum 219 : */ 220 : void clearSetValues(); 221 : void clear(); 222 : ///@} 223 : 224 : /** 225 : * Return the number of active items in the MultiMooseEnum 226 : */ 227 : unsigned int size() const; 228 : 229 : /** 230 : * IsValid 231 : * @return - a Boolean indicating whether this Enumeration has been set 232 : */ 233 8672350 : virtual bool isValid() const override { return !_current_values.empty(); } 234 : 235 : // InputParameters and Output is allowed to create an empty enum but is responsible for 236 : // filling it in after the fact 237 : friend class libMesh::Parameters; 238 : 239 : /// Operator for printing to iostreams 240 : friend std::ostream & operator<<(std::ostream & out, const MultiMooseEnum & obj); 241 : 242 : // The following functions would add possible values 243 : // (to _items) that an enumerated variable can take. However "+=" is not a 244 : // descriptive enough funtion name for this and should not be used in case 245 : // users get confused that the operator actually changes the set values of the 246 : // variable (_current_values). We have re-implemented this logic under a method 247 : // with a more descirptive name to force users to be informed. These are deprecated. 248 : MooseEnumBase & operator+=(const std::string & name); 249 : MooseEnumBase & operator+=(const std::initializer_list<std::string> & names); 250 : 251 : // The following replaces operator+= with a more descriptive name 252 : /// Extends the range of possible values the variable can be set to 253 : void addValidName(const std::string & name); 254 : void addValidName(const std::initializer_list<std::string> & names); 255 : void addValidName(const MultiMooseEnum & names); 256 : 257 : protected: 258 : /// Check whether any of the current values are deprecated when called 259 : virtual void checkDeprecated() const override; 260 : 261 : /** 262 : * Helper method for all inserts and assignment operators 263 : * @param first An iterator specifying the beginning of the range of values to set 264 : * @param last An iterator specifying the end of the range of values to set 265 : */ 266 : template <typename InputIterator> 267 : MultiMooseEnum & assignValues(InputIterator first, InputIterator last, bool append); 268 : 269 : /** 270 : * Helper method for un-assigning enumeration values 271 : * @param first An iterator specifying the beginning of the range of values to set 272 : * @param last An iterator specifying the end of the range of values to set 273 : */ 274 : template <typename InputIterator> 275 : void removeSetValues(InputIterator first, InputIterator last); 276 : 277 : /// The current value(s) of the MultiMooseEnum. 278 : std::vector<MooseEnumItem> _current_values; 279 : 280 : /** 281 : * Protected constructor for use by libmesh::Parameters 282 : */ 283 : MultiMooseEnum(); 284 : 285 : /** 286 : * Protected constructor that can accept a MooseEnumBase for ::withOptionsFrom() 287 : * @param other_enum - MooseEnumBase type to copy names and out-of-range data from 288 : */ 289 : MultiMooseEnum(const MooseEnumBase & other_enum); 290 : }; 291 : 292 : template <typename T> 293 : std::vector<T> 294 4497 : MultiMooseEnum::getSetValueIDs() const 295 : { 296 : #ifdef LIBMESH_HAVE_CXX11_TYPE_TRAITS 297 : static_assert(std::is_enum<T>::value == true, 298 : "The type requested from MooseEnum::getEnum must be an enum type!\n\n"); 299 : #endif 300 4497 : std::vector<T> enum_vec; 301 5791 : for (const auto & current_value : _current_values) 302 1294 : enum_vec.push_back(static_cast<T>(current_value.id())); 303 4497 : return enum_vec; 304 0 : } 305 : 306 : template <typename T> 307 : std::vector<T> 308 : MultiMooseEnum::getEnum() const 309 : { 310 : mooseDeprecated("MultiMooseEnum::getEnum is deprecated, use MultiMooseEnum::getSetValueIDs"); 311 : return MultiMooseEnum::getSetValueIDs<T>(); 312 : }