1 #ifndef MSP_CORE_MAPUTILS_H_
2 #define MSP_CORE_MAPUTILS_H_
6 #include <msp/strings/lexicalcast.h>
7 #include "mspcore_api.h"
11 namespace MapUtilsInternal {
13 /* This dummy struct is used to introduce a conversion, making the overloaded
14 operator below worse than the templated one provided in lexicalcast.h. */
21 /* This must be hidden in the internal namespace to avoid interfering with
23 inline void operator<<(LexicalConverter &, Any)
27 static std::string stringify_key(const T &k)
31 LexicalConverter conv((Fmt()));
35 catch(const lexical_error &)
37 return "<cannot display value>";
41 } // namespace Internal
43 class MSPCORE_API key_error: public std::runtime_error
47 key_error(const T &k):
48 runtime_error(make_what(typeid(T), MapUtilsInternal::stringify_key(k)))
51 ~key_error() throw() override = default;
54 static std::string make_what(const std::type_info &, const std::string &);
59 typename T::mapped_type &get_item(T &map, const typename T::key_type &key)
61 auto i = map.find(key);
69 const typename T::mapped_type &get_item(const T &map, const typename T::key_type &key)
71 auto i = map.find(key);
78 template<typename D, typename T>
79 D *get_item(const T &map, const typename T::key_type &key)
81 return dynamic_cast<D *>(get_item(map, key));
85 typename T::iterator insert_unique(T &map, const typename T::key_type &key, const typename T::mapped_type &item)
90 return map.insert(std::make_pair(key, item)).first;
94 void remove_existing(T &map, const typename T::key_type &key)