Cantera  2.4.0
AnyMap.h
Go to the documentation of this file.
1 //! @file AnyMap.h
2 
3 #ifndef CT_ANYMAP_H
4 #define CT_ANYMAP_H
5 
6 #include "cantera/base/ct_defs.h"
7 #include "cantera/base/global.h"
9 
10 #include <string>
11 #include <vector>
12 #include <memory>
13 #include <unordered_map>
14 
15 namespace boost
16 {
17 class any;
18 }
19 
20 namespace Cantera
21 {
22 
23 class AnyMap;
24 
25 //! A wrapper for a variable whose type is determined at runtime
26 /*!
27  * Instances of AnyValue are used as values in an AnyMap. Values are converted
28  * to a concrete type using the templated as() method or convenience methods
29  * such as asString() and asDouble(). See AnyMap for usage examples.
30  *
31  * Elements are set using assignment, and the assignment operator has been
32  * overloaded for specific types so that only those types are allowed to be
33  * used in an AnyValue.
34  */
35 class AnyValue
36 {
37 public:
38  AnyValue();
39  ~AnyValue();
40  AnyValue(AnyValue const& other);
41  AnyValue(AnyValue&& other);
42  AnyValue& operator=(AnyValue const& other);
43  AnyValue& operator=(AnyValue&& other);
44 
45  AnyValue& operator[](const std::string& key);
46 
47  bool hasKey(const std::string& key) const;
48 
49  // The value knows the name of its corresponding key in order to provide
50  // comprehensible error messages.
51  void setKey(const std::string& key);
52 
53  template<class T>
54  const T& as() const;
55 
56  template<class T>
57  T& as();
58 
59  const std::type_info& type();
60 
61  template<class T>
62  bool is() const;
63 
64  AnyValue& operator=(const std::string& value);
65  AnyValue& operator=(const char* value);
66  const std::string& asString() const;
67 
68  AnyValue& operator=(double value);
69  double asDouble() const;
70 
71  AnyValue& operator=(bool value);
72  bool asBool() const;
73 
74  AnyValue& operator=(long int value);
75  AnyValue& operator=(int value);
76  long int asInt() const;
77 
78  template<class T>
79  AnyValue& operator=(const std::vector<T>& value);
80  template<class T>
81  const std::vector<T>& asVector() const;
82  template<class T>
83  std::vector<T>& asVector();
84 
85  AnyValue& operator=(const AnyMap& value);
86  AnyValue& operator=(AnyMap&& value);
87 
88  template<class T>
89  AnyValue& operator=(const std::unordered_map<std::string, T> items);
90 
91  template<class T>
92  AnyValue& operator=(const std::map<std::string, T> items);
93 
94  template<class T>
95  std::map<std::string, T> asMap();
96 
97 private:
98  std::string demangle(const std::type_info& type) const;
99 
100  std::string m_key;
101  std::unique_ptr<boost::any> m_value;
102  static std::map<std::string, std::string> s_typenames;
103 };
104 
105 //! A map of string keys to values whose type can vary at runtime
106 /*!
107  * Values in an AnyMap are held by instances of AnyValue. Instances of AnyMap
108  * can be nested to form a tree.
109  *
110  * ## Setting elements
111  *
112  * ```
113  * AnyMap breakfast;
114  * breakfast["spam"] = 123.4; // Creates a value of type 'double'
115  * breakfast["eggs"] = "scrambled"; // Creates a value of type 'std::string'
116  *
117  * // Create a nested AnyMap named "beans" which has a key named "baked"
118  * // whose value is a vector<double>
119  * std::vector<double> v{3.14, 1.59, 2.65};
120  * breakfast["beans/baked"] = v;
121  * // Equivalently:
122  * breakfast["beans"]["baked"] = v;
123  *
124  * // Create a nested AnyMap with values of the same type
125  * std::map<std::string, double> breads{{"wheat", 4.0}, {"white", 2.5}};
126  * breakfast["toast"] = breads;
127  * // Equivalent to:
128  * breakfast["toast"]["wheat"] = 4.0
129  * breakfast["toast"]["white"] = 2.5
130  * ```
131  *
132  * ## Accessing elements
133  *
134  * ```
135  * double val1 = breakfast["spam"].asDouble();
136  * std::string val2 = breakfast["eggs"].asString();
137  * vector_fp val3 = breakfast["beans"]["baked"].asVector<double>();
138  *
139  * std::map<std::string, double> = breakfast["toast"].asMap<double>();
140  * ```
141  *
142  * ## Checking for elements
143  *
144  * ```
145  * try {
146  * breakfast["waffle"].asDouble();
147  * } except (std::exception& err) {
148  * // Exception will be thrown.
149  * // 'breakfast' will have an empty key named "waffle"
150  * }
151  *
152  * try {
153  * breakfast.at("grits").asDouble();
154  * } except (std::exception& err) {
155  * // Exception will be thrown and no new key will be added
156  * }
157  *
158  * if (breakfast.hasKey("grits")) {
159  * // do something with this entry
160  * }
161  * ```
162  *
163  * ## Checking element types
164  *
165  * ```
166  * if (breakfast["sausage"].is<vector<double>>()) {
167  * // access using asVector<double>
168  * } else if (breakfast["sausage"].type() == typeid(vector<std::string>)) {
169  * // access using asVector<std::string>
170  * }
171  * ```
172  */
173 class AnyMap
174 {
175 public:
176  AnyMap() {};
177 
178  AnyValue& operator[](const std::string& key);
179 
180  AnyValue& at(const std::string& key);
181 
182  bool hasKey(const std::string& key) const;
183 
184 private:
185  std::unordered_map<std::string, AnyValue> m_data;
186  friend class AnyValue;
187 };
188 
189 }
190 
191 #ifndef CANTERA_API_NO_BOOST
192 #include "cantera/base/AnyMap.inl.h"
193 #endif
194 
195 #endif
Definition: AnyMap.h:15
A wrapper for a variable whose type is determined at runtime.
Definition: AnyMap.h:35
This file contains definitions of terms that are used in internal routines and are unlikely to need m...
This file contains definitions for utility functions and text for modules, inputfiles, logs, textlogs, (see Input File Handling, Diagnostic Output, and Writing messages to the screen).
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:173
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:8
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...