Line data Source code
1 : /*
2 : * File: Properties.h
3 : * Author: Pantelis Sopasakis
4 : *
5 : * Created on March 4, 2016, 4:07 PM
6 : *
7 : * ForBES is free software: you can redistribute it and/or modify
8 : * it under the terms of the GNU Lesser General Public License as published by
9 : * the Free Software Foundation, either version 3 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * ForBES is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU Lesser General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU Lesser General Public License
18 : * along with ForBES. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #ifndef FORBES_PROPERTIES_H
22 : #define FORBES_PROPERTIES_H
23 :
24 : #include <stdlib.h>
25 : #include <utility>
26 : #include <map>
27 : #include <vector>
28 : #include <string>
29 :
30 : /**
31 : * \class Properties
32 : * \brief Generic properties class
33 : * \version version 0.1
34 : * \date Created on March 4, 2016, 4:07 PM
35 : * \author Pantelis Sopasakis
36 : *
37 : *
38 : * This class can be used to provide options to solvers as well as to
39 : * get generic results and statistics from the solver's output.
40 : */
41 : class Properties {
42 : public:
43 : Properties();
44 : virtual ~Properties();
45 :
46 :
47 : const static int DOUBLE_TYPE; /**< <code>double</code> type */
48 : const static int INT_TYPE; /**< <code>size_t</code> type */
49 : const static int SIZE_T_TYPE; /**< <code>size_t</code> type */
50 : const static int STRING_TYPE; /**< <code>std::string</code> type */
51 : const static int VECTOR_TYPE; /**< type <code>std::vector</code> type */
52 : const static int CUSTOM_TYPE; /**< any custom type not listed here */
53 :
54 : /**
55 : *
56 : * Adds a new key-value pair.
57 : *
58 : * Example of use:
59 : *
60 : * \code{.cpp}
61 : * Properties stats;
62 : * double a = 34.11;
63 : * std::string key = "key-1";
64 : * bool status = stats.add_property<double>(key, Properties::DOUBLE_TYPE, &a);
65 : * \endcode
66 : *
67 : * @param key key as a string
68 : * @param type data-type
69 : * @param value pointer to where the data are stored
70 : * @return returns <code>true</code> iff the key-value pair did not pre-exist
71 : * and it was created now for the first time.
72 : */
73 8 : template<typename T> bool add_property(std::string key, int type, T* value) {
74 8 : TypedPair pair = std::make_pair<int, void*>(type, value);
75 : std::pair < PropertiesMap::iterator, bool> insertion_status =
76 8 : m_map->insert(std::make_pair<std::string, TypedPair>(key, pair));
77 8 : return insertion_status.second;
78 : }
79 :
80 : /**
81 : *
82 : * Returns the value stored under a key (if found) as well as its type.
83 : *
84 : * This method is suitable in case you are unsure about the type of the stored
85 : * value.
86 : *
87 : * Here is an example of use:
88 : *
89 : * \code{.cpp}
90 : * Properties stats;
91 : *
92 : * // Add data in Properties
93 : * double a = 34.11;
94 : * std::string key = "key-1";
95 : * bool status = stats.add_property<double>(key, Properties::DOUBLE_TYPE, &a);
96 : *
97 : * // Look-up data
98 : * int retrieved_type;
99 : * void * retrieved_value;
100 : * bool found = stats.get_typed_property(key, retrieved_type, retrieved_value);
101 : *
102 : * // Make sure that the data-type is indeed Properties::DOUBLE_TYPE
103 : * if (found && retrieved_type == Properties::DOUBLE_TYPE) {
104 : * double * dbl_data = static_cast<double*>(retrieved_value);
105 : * }
106 : * \endcode
107 : *
108 : * @param key property name
109 : * @param type property type (output value)
110 : * @param value pointer to where the data can be found
111 : * @return returns <code>true</code> iff the value is found
112 : */
113 : bool get_typed_property(std::string key, int& type, void*& value);
114 :
115 : /**
116 : *
117 : * In case the data-type is known, this method can be used to easily retrieve
118 : * the stored value under a given key.
119 : *
120 : * Example of use:
121 : *
122 : * \code{.cpp}
123 : * Properties stats;
124 : *
125 : * // Add data in Properties
126 : * std::vector<double> x;
127 : * x.push_back(1.23);
128 : * x.push_back(2.34);
129 : *
130 : * std::string key = "key-1";
131 : * bool status = stats.add_property<>(key, Properties::VECTOR_TYPE, &x);
132 : *
133 : * // Look-up data
134 : * std::vector<double> * retrieved_x;
135 : * bool found = stats.get_property<>(retrieved_x);
136 : * \endcode
137 : *
138 : *
139 : * @param key property name
140 : * @param value value (if found)
141 : * @return returns <code>true</code> iff the value is found
142 : */
143 4 : template<typename T> bool get_property(std::string key, T*& value) {
144 4 : PropertiesMap::iterator value_it = m_map->find(key);
145 4 : if (value_it != m_map->end()) {
146 2 : TypedPair value_found = value_it->second;
147 : /*
148 : * here, static_cast may result in erroneous interpretation of (void*)
149 : * if the method is not used properly. The use of:
150 : * bool get_typed_property(std::string key, int& type, void*& value);
151 : * is recommended when the return type is unknown.
152 : */
153 2 : value = static_cast<T*> (value_found.second);
154 2 : return true;
155 : }
156 2 : return false;
157 : }
158 :
159 : /**
160 : * Returns the number of key-value pairs stored.
161 : * @return size of internal map.
162 : */
163 : size_t size();
164 :
165 : private:
166 :
167 : /**
168 : * A typed pair (type, data)
169 : */
170 : typedef std::pair<int, void*> TypedPair;
171 : /**
172 : * A map used to store the data
173 : */
174 : typedef std::map<std::string, TypedPair> PropertiesMap;
175 : /**
176 : * An entry of the above map
177 : */
178 : typedef std::pair<std::string, TypedPair> PropertiesPair;
179 :
180 : void init();
181 :
182 : PropertiesMap * m_map;
183 :
184 :
185 :
186 : };
187 :
188 : #endif /* Properties_H */
189 :
|