34 #include <boost/any.hpp>
35 #include <boost/lexical_cast.hpp>
36 #include <boost/format.hpp>
37 #include <boost/operators.hpp>
39 #include "rsc/rscexports.h"
57 class RSC_EXPORT
Properties:
public std::map<std::string, boost::any>,
58 public boost::equality_comparable<Properties> {
61 template<
typename Ch,
typename Tr>
62 friend std::basic_ostream<Ch, Tr>
64 operator<<(std::basic_ostream<Ch, Tr>& stream,
93 has(
const std::string& name)
const throw ();
101 get(
const std::string& name)
const;
108 get(
const std::string& name,
const T& default_)
const;
122 T getAs(
const std::string& name)
const;
137 T getAs(
const std::string& name,
const T& default_)
const;
148 template<
typename Target,
typename T>
150 set(
const std::string& name,
const T& value)
throw ();
165 template<
typename Ch,
typename Tr>
166 std::basic_ostream<Ch, Tr>&
167 operator<<(std::basic_ostream<Ch, Tr>& stream,
const std::pair<std::string,
168 boost::any> property);
170 template<
typename Ch,
typename Tr>
171 std::basic_ostream<Ch, Tr>&
172 operator<<(std::basic_ostream<Ch, Tr>& stream,
const Properties& properties);
179 if ((it = find(name)) == end()) {
181 (boost::format(
"no such property `%1%'") % name).str());
185 return boost::any_cast<T>(it->second);
186 }
catch (
const boost::bad_any_cast&) {
189 "properties: type mismatch in get for `%1%': requested: %2%; actual: %3%")
190 % name % typeName<T> () %
typeName(it->second.type()))
199 if ((it = find(name)) == end()) {
204 return boost::any_cast<T>(it->second);
205 }
catch (
const boost::bad_any_cast&) {
206 std::cerr << (boost::format(
207 "properties type mismatch in get for `%1%': requested: %2%; actual: %3%")
208 % name % typeName<T> () %
typeName(it->second.type())) << std::endl;
215 std::string value = get<std::string>(name);
217 return boost::lexical_cast<T>(value);
218 }
catch (
const std::bad_cast&) {
221 "properties: type conversion failure in getAs for `%1%': requested: %2%; value: \"%3%\"")
222 % name % typeName<T> () % value)
231 return getAs<T>(name);
237 template<
typename Target,
typename T>
240 return insert(
std::make_pair(name, static_cast<Target> (value))).second;
245 template<
typename Ch,
typename Tr>
246 std::basic_ostream<Ch, Tr>&
247 operator<<(std::basic_ostream<Ch, Tr>& stream,
const Properties& properties) {
250 for (Properties::const_iterator it = properties.begin(); it
251 != properties.end();) {
252 stream << it->first <<
": ";
254 if (it->second.type() ==
typeid(std::string)) {
255 stream <<
"\"" << boost::any_cast<std::string>(it->second) <<
"\"";
256 }
else if (it->second.type() ==
typeid(bool)) {
257 stream << boost::any_cast<bool>(it->second);
258 }
else if (it->second.type() ==
typeid(int)) {
259 stream << boost::any_cast<int>(it->second);
260 }
else if (it->second.type() ==
typeid(
unsigned int)) {
261 stream << boost::any_cast<unsigned int>(it->second);
262 }
else if (it->second.type() ==
typeid(double)) {
263 stream << boost::any_cast<double>(it->second);
265 stream <<
"<" +
typeName(it->second.type()) +
">";
268 stream << ((++it) != properties.end() ?
", " :
"");
bool set(const std::string &name, const T &value)
Sets a new property in the map.
std::string typeName(const std::type_info &type)
Returns a (demangled) string representation of type.
pair< _T1, _T2 > make_pair(_T1 __x, _T2 __y)
A convenience wrapper for creating a pair from two objects.
T get(const std::string &name) const
T getAs(const std::string &name) const
Parse the value of the property name as type T and return the parsed value.
bool operator==(const pair< _T1, _T2 > &__x, const pair< _T1, _T2 > &__y)
Two pairs of the same type are equal iff their members are equal.
Properties objects are basically glorified map<string, boost::any> objects.
ostream & operator<<(ostream &stream, const Printable &record)
Output operator on std::ostream for reference Printables.
bool has(const std::string &name) const
This exception is thrown if a specified object does not exist.