NEML2 1.4.0
Loading...
Searching...
No Matches
OptionSet.h
1// Copyright 2023, UChicago Argonne, LLC
2// All Rights Reserved
3// Software Name: NEML2 -- the New Engineering material Model Library, version 2
4// By: Argonne National Laboratory
5// OPEN SOURCE LICENSE (MIT)
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23// THE SOFTWARE.
24
25#pragma once
26
27#include "neml2/misc/error.h"
28#include "neml2/misc/types.h"
29#include "neml2/misc/parser_utils.h"
30
31#include <map>
32#include <sstream>
33#include <string>
34#include <typeinfo>
35#include <vector>
36#include <memory>
37
38namespace neml2
39{
41
45template <typename P>
46void print_helper(std::ostream & os, const P *);
47template <typename P>
48void print_helper(std::ostream & os, const std::vector<P> *);
49template <typename P>
50void print_helper(std::ostream & os, const std::vector<std::vector<P>> *);
52
59{
60public:
61 OptionSet() = default;
62
64 OptionSet(const OptionSet &);
65
66 virtual ~OptionSet() = default;
67
69 virtual OptionSet & operator=(const OptionSet & source);
70
76 virtual void operator+=(const OptionSet & source);
77
79 const std::string & name() const { return _metadata.name; }
81 std::string & name() { return _metadata.name; }
83 const std::string & type() const { return _metadata.type; }
85 std::string & type() { return _metadata.type; }
87 const std::string & path() const { return _metadata.path; }
89 std::string & path() { return _metadata.path; }
91 const std::string & doc() const { return _metadata.doc; }
93 std::string & doc() { return _metadata.doc; }
95 const std::string & section() const { return _metadata.section; }
97 std::string & section() { return _metadata.section; }
98
103 template <typename T>
104 bool contains(const std::string &) const;
105
111 bool contains(const std::string &) const;
112
114 std::size_t size() const { return _values.size(); }
115
117 virtual void clear();
118
120 void print(std::ostream & os = std::cout) const;
121
126 {
127 public:
128 virtual ~OptionBase() = default;
129
131 virtual bool operator==(const OptionBase & other) const = 0;
132
134 const std::string & name() const { return _metadata.name; }
135
137 const std::string & type() const { return _metadata.type; }
138
140 const std::string & doc() const { return _metadata.doc; }
141
143 std::string & doc() { return _metadata.doc; }
144
146 const bool & suppressed() const { return _metadata.suppressed; }
147
149 bool & suppressed() { return _metadata.suppressed; }
150
155 virtual void print(std::ostream &) const = 0;
156
161 virtual std::unique_ptr<OptionBase> clone() const = 0;
162
163 protected:
167 struct Metadata
168 {
181 std::string name = "";
191 std::string type = "";
202 std::string doc = "";
212 bool suppressed = false;
213
214 bool operator==(const Metadata & other) const
215 {
216 return name == other.name && type == other.type && doc == other.doc &&
217 suppressed == other.suppressed;
218 }
220 };
221
226 template <typename T>
227 class Option : public OptionBase
228 {
229 public:
230 Option(const std::string & name)
231 : _value()
232 {
233 _metadata.name = name;
234 _metadata.type = utils::demangle(typeid(T).name());
235 }
236
237 virtual bool operator==(const OptionBase & other) const override;
238
242 const T & get() const { return _value; }
243
247 T & set() { return _value; }
248
249 virtual void print(std::ostream &) const override;
250
251 virtual std::unique_ptr<OptionBase> clone() const override;
252
253 private:
255 T _value;
256 };
257
262 template <typename T>
263 const T & get(const std::string &) const;
264
265 const OptionBase & get(const std::string &) const;
266
272 template <typename T>
273 T & set(const std::string &);
274
275 OptionBase & set(const std::string &);
276
278 typedef std::map<std::string, std::unique_ptr<OptionBase>, std::less<>> map_type;
279
281 typedef map_type::iterator iterator;
282
284 typedef map_type::const_iterator const_iterator;
285
287 iterator begin();
288
290 const_iterator begin() const;
291
293 iterator end();
294
296 const_iterator end() const;
297
298protected:
302 struct Metadata
303 {
317 std::string name = "";
332 std::string type = "";
351 std::string path = "";
362 std::string doc = "";
370 std::string section = "";
372
375};
376
377template <typename T>
378bool
380{
381 const auto other_ptr = dynamic_cast<const Option<T> *>(&other);
382 if (!other_ptr)
383 return false;
384
385 return (_metadata == other_ptr->_metadata) && (other_ptr->get() == this->get());
386}
387
388// LCOV_EXCL_START
389template <typename T>
390void
391OptionSet::Option<T>::print(std::ostream & os) const
392{
393 print_helper(os, static_cast<const T *>(&_value));
394}
395// LCOV_EXCL_STOP
396
397template <typename T>
398std::unique_ptr<OptionSet::OptionBase>
400{
401 auto copy = std::make_unique<Option<T>>(this->name());
402 copy->_value = this->_value;
403 copy->_metadata = this->_metadata;
404 return copy;
405}
406
407std::ostream & operator<<(std::ostream & os, const OptionSet & p);
408
409template <typename T>
410bool
411OptionSet::contains(const std::string & name) const
412{
414 if (it != _values.end())
415 if (dynamic_cast<const Option<T> *>(it->second.get()))
416 return true;
417 return false;
418}
419
420template <typename T>
421const T &
422OptionSet::get(const std::string & name) const
423{
425 "ERROR: no option named \"",
426 name,
427 "\" found.\n\nKnown options:\n",
428 *this);
429
430 auto ptr = dynamic_cast<Option<T> *>(_values.at(name).get());
431 return ptr->get();
432}
433
434template <typename T>
435T &
436OptionSet::set(const std::string & name)
437{
438 if (!this->contains<T>(name))
439 _values[name] = std::make_unique<Option<T>>(name);
440 auto ptr = dynamic_cast<Option<T> *>(_values[name].get());
441 return ptr->set();
442}
443
444// LCOV_EXCL_START
445template <typename P>
446void
447print_helper(std::ostream & os, const P * option)
448{
449 os << *option;
450}
451
452template <>
453inline void
454print_helper(std::ostream & os, const char * option)
455{
456 // Specialization so that we don't print out unprintable characters
458}
459
460template <>
461inline void
462print_helper(std::ostream & os, const unsigned char * option)
463{
464 // Specialization so that we don't print out unprintable characters
466}
467
468template <typename P>
469void
470print_helper(std::ostream & os, const std::vector<P> * option)
471{
472 for (const auto & p : *option)
473 os << p << " ";
474}
475
476template <typename P>
477void
478print_helper(std::ostream & os, const std::vector<std::vector<P>> * option)
479{
480 for (const auto & pv : *option)
481 for (const auto & p : pv)
482 os << p << " ";
483}
484// LCOV_EXCL_STOP
485} // namespace neml2
The wrapper (decorator) for cross-referencing unresolved values at parse time.
Definition CrossRef.h:52
Definition OptionSet.h:126
virtual void print(std::ostream &) const =0
const std::string & name() const
A readonly reference to the option's name.
Definition OptionSet.h:134
const std::string & type() const
A readonly reference to the option's type.
Definition OptionSet.h:137
virtual ~OptionBase()=default
const bool & suppressed() const
A readonly reference to the option's suppression status.
Definition OptionSet.h:146
struct neml2::OptionSet::OptionBase::Metadata _metadata
virtual bool operator==(const OptionBase &other) const =0
Test for option equality.
const std::string & doc() const
A readonly reference to the option's docstring.
Definition OptionSet.h:140
virtual std::unique_ptr< OptionBase > clone() const =0
std::string & doc()
A writable reference to the option's docstring.
Definition OptionSet.h:143
bool & suppressed()
A writable reference to the option's suppression status.
Definition OptionSet.h:149
Definition OptionSet.h:228
virtual void print(std::ostream &) const override
Definition OptionSet.h:391
T & set()
Definition OptionSet.h:247
virtual std::unique_ptr< OptionBase > clone() const override
Definition OptionSet.h:399
virtual bool operator==(const OptionBase &other) const override
Test for option equality.
Definition OptionSet.h:379
Option(const std::string &name)
Definition OptionSet.h:230
const T & get() const
Definition OptionSet.h:242
A custom map-like data structure. The keys are strings, and the values can be nonhomogeneously typed.
Definition OptionSet.h:59
map_type _values
Data structure to map names with values.
Definition OptionSet.h:374
virtual ~OptionSet()=default
const std::string & name() const
A readonly reference to the option set's name.
Definition OptionSet.h:79
OptionSet()=default
const std::string & type() const
A readonly reference to the option set's type.
Definition OptionSet.h:83
std::string & name()
A writable reference to the option set's name.
Definition OptionSet.h:81
std::string & type()
A writable reference to the option set's type.
Definition OptionSet.h:85
const std::string & doc() const
A readonly reference to the option set's docstring.
Definition OptionSet.h:91
map_type::const_iterator const_iterator
Constant option map iterator.
Definition OptionSet.h:284
const std::string & section() const
A readonly reference to the option set's section.
Definition OptionSet.h:95
std::map< std::string, std::unique_ptr< OptionBase >, std::less<> > map_type
The type of the map that we store internally.
Definition OptionSet.h:278
iterator begin()
Iterator pointing to the beginning of the set of options.
Definition OptionSet.cxx:129
iterator end()
Iterator pointing to the end of the set of options.
Definition OptionSet.cxx:141
const std::string & path() const
A readonly reference to the option set's path.
Definition OptionSet.h:87
std::string & doc()
A writable reference to the option set's docstring.
Definition OptionSet.h:93
virtual void operator+=(const OptionSet &source)
Definition OptionSet.cxx:78
const T & get(const std::string &) const
Definition OptionSet.h:422
struct neml2::OptionSet::Metadata _metadata
virtual void clear()
Clear internal data structures & frees any allocated memory.
Definition OptionSet.cxx:63
std::string & path()
A writable reference to the option set's path.
Definition OptionSet.h:89
T & set(const std::string &)
Definition OptionSet.h:436
std::string & section()
A writable reference to the option set's section.
Definition OptionSet.h:97
std::size_t size() const
Definition OptionSet.h:114
void print(std::ostream &os=std::cout) const
Print the contents.
Definition OptionSet.cxx:88
virtual OptionSet & operator=(const OptionSet &source)
Assignment operator. Deep copy.
Definition OptionSet.cxx:69
bool contains(const std::string &) const
Definition OptionSet.h:411
map_type::iterator iterator
Option map iterator.
Definition OptionSet.h:281
std::string demangle(const char *name)
Definition parser_utils.cxx:46
Definition CrossRef.cxx:32
std::ostream & operator<<(std::ostream &os, const OptionCollection &p)
Definition OptionCollection.cxx:37
void print_helper(std::ostream &os, const P *)
Definition OptionSet.h:447
void neml_assert(bool assertion, Args &&... args)
Definition error.h:73
Definition OptionSet.h:303
std::string path
Path to the option set.
Definition OptionSet.h:351
std::string type
Type of the option set.
Definition OptionSet.h:332
std::string name
Name of the option set.
Definition OptionSet.h:317
std::string section
Which NEML2 input file section this object belongs to.
Definition OptionSet.h:370
std::string doc
Option set's doc string.
Definition OptionSet.h:362
Definition OptionSet.h:168
bool suppressed
Whether this option is suppressed.
Definition OptionSet.h:212
std::string type
Type of the option.
Definition OptionSet.h:191
std::string name
Name of the option.
Definition OptionSet.h:181
std::string doc
Option's doc string.
Definition OptionSet.h:202
bool operator==(const Metadata &other) const
Definition OptionSet.h:214