X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fcore%2Fmaputils.h;h=8c642fb9c57a1f9acda6ba5ab2d0dc5311316306;hp=9548714658d806fad41614357bc0e60fa8444cdf;hb=1e0abc3a49ade6a4fa1b38f744df070c40a87724;hpb=468ec9f6554c89b52e10a280411c9b9d99ef451b diff --git a/source/core/maputils.h b/source/core/maputils.h index 9548714..8c642fb 100644 --- a/source/core/maputils.h +++ b/source/core/maputils.h @@ -3,14 +3,48 @@ #include #include +#include namespace Msp { +namespace MapUtilsInternal { + +/* This must be hidden in the internal namespace to avoid interfering with +other things. There may be problems if a key type has operator<< for ostream +but not LexicalConverter. */ +template +void operator<<(LexicalConverter &, const T &) +{ } + +template +static std::string stringify_key(const T &k) +{ + try + { + LexicalConverter conv((Fmt())); + conv<"; + } +} + +} // namespace Internal + class key_error: public std::runtime_error { public: - key_error(const std::type_info &); - ~key_error() throw() { } + template + key_error(const T &k): + runtime_error(make_what(typeid(T), MapUtilsInternal::stringify_key(k))) + { } + + virtual ~key_error() throw() { } + +private: + static std::string make_what(const std::type_info &, const std::string &); }; @@ -19,7 +53,7 @@ typename T::mapped_type &get_item(T &map, const typename T::key_type &key) { typename T::iterator i = map.find(key); if(i==map.end()) - throw key_error(typeid(T)); + throw key_error(key); return i->second; } @@ -29,7 +63,7 @@ const typename T::mapped_type &get_item(const T &map, const typename T::key_type { typename T::const_iterator i = map.find(key); if(i==map.end()) - throw key_error(typeid(T)); + throw key_error(key); return i->second; } @@ -38,7 +72,7 @@ template const typename T::iterator insert_unique(T &map, const typename T::key_type &key, const typename T::mapped_type &item) { if(map.count(key)) - throw key_error(typeid(T)); + throw key_error(key); return map.insert(typename T::value_type(key, item)).first; }