stringid: add query-or-insert indexing operator

This commit is contained in:
Danny Robson 2018-09-17 14:50:23 +10:00
parent cffc3bbc46
commit c2f203b5a7
3 changed files with 33 additions and 7 deletions

View File

@ -13,9 +13,23 @@
using cruft::stringid; using cruft::stringid;
//----------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////////
stringid::id_t stringid::id_t
stringid::add (std::string key) { stringid::operator[] (std::string_view const &key)
{
if (auto const pos = m_map.find (key); pos != m_map.cend ())
return pos->second;
auto const &[pos, success] = m_map.emplace (key, m_map.size ());
return pos->second;
}
///////////////////////////////////////////////////////////////////////////////
stringid::id_t
stringid::add (std::string key)
{
auto pos = m_map.find (key); auto pos = m_map.find (key);
if (pos != m_map.end ()) if (pos != m_map.end ())
throw std::invalid_argument ("duplicate stringid key"); throw std::invalid_argument ("duplicate stringid key");
@ -26,9 +40,10 @@ stringid::add (std::string key) {
} }
//----------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////////
stringid::id_t stringid::id_t
stringid::find (const std::string &key) const { stringid::find (const std::string &key) const
{
auto pos = m_map.find (key); auto pos = m_map.find (key);
if (pos == m_map.end ()) if (pos == m_map.end ())
throw std::out_of_range ("invalid stringid key"); throw std::out_of_range ("invalid stringid key");
@ -37,8 +52,9 @@ stringid::find (const std::string &key) const {
} }
//----------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////////
void void
stringid::clear (void) { stringid::clear (void)
{
m_map.clear (); m_map.clear ();
} }

View File

@ -19,6 +19,11 @@ namespace cruft {
public: public:
typedef size_t id_t; typedef size_t id_t;
///////////////////////////////////////////////////////////////////////
/// Returns the ID for the supplied string, or creates and returns a
/// new ID if the string is not present.
id_t operator[] (std::string_view const&);
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
id_t add (std::string); id_t add (std::string);
@ -59,7 +64,7 @@ namespace cruft {
private: private:
std::map<const std::string, id_t> m_map; std::map<const std::string, id_t, std::less<>> m_map;
}; };
} }

View File

@ -23,5 +23,10 @@ main (int, char**) {
tap.expect_eq (id1 + 1, id2, "monotonically increasing IDs"); tap.expect_eq (id1 + 1, id2, "monotonically increasing IDs");
tap.expect_eq (id1, map.find ("first"), "first element still matches"); tap.expect_eq (id1, map.find ("first"), "first element still matches");
tap.expect_eq (map["second"], id2, "index lookup invokes no change");
auto id3 = map["third"];
tap.expect (id3 != id1 && id3 != id2, "index creation adds new value");
return tap.status (); return tap.status ();
} }