map/fixed: add a find function, and use it internally

This commit is contained in:
Danny Robson 2019-06-04 17:42:59 +10:00
parent 538349cb3f
commit bde7cc58c7

View File

@ -35,6 +35,7 @@ namespace cruft::map {
using value_type = std::pair<KeyT,ValueT>; using value_type = std::pair<KeyT,ValueT>;
using iterator = value_type*; using iterator = value_type*;
using const_iterator = value_type const*;
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
@ -68,13 +69,31 @@ namespace cruft::map {
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
mapped_type& at (KeyT const &key) & iterator find (KeyT const &key)&
{ {
ComparatorT cmp {}; ComparatorT cmp {};
for (auto &i: *this) for (auto cursor = begin (), last = end (); cursor != last; ++cursor)
if (cmp (i.first, key)) if (cmp (cursor->first, key))
return i.second; return cursor;
return end ();
}
//---------------------------------------------------------------------
const_iterator find (KeyT const &key) const&
{
ComparatorT cmp {};
for (auto cursor = begin (), last = end (); cursor != last; ++cursor)
if (cmp (cursor->first, key))
return cursor;
return end ();
}
///////////////////////////////////////////////////////////////////////
mapped_type& at (KeyT const &key) &
{
if (auto pos = find (key); pos != end ())
return pos->second;
throw std::out_of_range ("Element out of range"); throw std::out_of_range ("Element out of range");
} }
@ -82,11 +101,8 @@ namespace cruft::map {
//--------------------------------------------------------------------- //---------------------------------------------------------------------
mapped_type const& at (KeyT const &key) const& mapped_type const& at (KeyT const &key) const&
{ {
ComparatorT cmp {}; if (auto pos = find (key); pos != end ())
for (auto &i: *this) return pos->second;
if (cmp (i.first, key))
return i.second;
throw std::out_of_range ("Element out of range"); throw std::out_of_range ("Element out of range");
} }
@ -94,12 +110,8 @@ namespace cruft::map {
//--------------------------------------------------------------------- //---------------------------------------------------------------------
std::pair<iterator,bool> insert (value_type const &keyval) std::pair<iterator,bool> insert (value_type const &keyval)
{ {
ComparatorT cmp {}; if (auto pos = find (keyval.first); pos != end ())
for (auto &i: *this) { return { pos, false };
if (cmp (i.first, keyval.first)) {
return { &i, false };
}
}
if (m_size >= capacity ()) if (m_size >= capacity ())
throw std::bad_alloc (); throw std::bad_alloc ();
@ -115,22 +127,18 @@ namespace cruft::map {
//--------------------------------------------------------------------- //---------------------------------------------------------------------
mapped_type const& operator[] (KeyT const &key) const mapped_type const& operator[] (KeyT const &key) const
{ {
ComparatorT cmp {}; return at (key);
for (auto &i: *this)
if (cmp (i.first, key))
return i.second;
throw std::out_of_range ("Invalid key");
} }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
mapped_type& operator[] (KeyT const &key) mapped_type& operator[] (KeyT const &key)
{ {
ComparatorT cmp {}; // If it's present, then return a reference to the value
for (auto &i: *this) if (auto pos = find (key); pos != end ())
if (cmp (i.first, key)) return pos->second;
return i.second;
// Make space for a new entry, initialise it, and return that.
if (m_size >= capacity ()) if (m_size >= capacity ())
throw std::bad_alloc (); throw std::bad_alloc ();
@ -152,12 +160,14 @@ namespace cruft::map {
//--------------------------------------------------------------------- //---------------------------------------------------------------------
auto begin (void)& { return std::begin (m_store.data); } iterator begin (void)& { return std::begin (m_store.data); }
auto end (void)& { return begin () + m_size; } iterator end (void)& { return begin () + m_size; }
auto begin (void) const& { return std::begin (m_store.data); } const_iterator begin (void) const& { return std::begin (m_store.data); }
auto end (void) const& { return begin () + m_size; } const_iterator end (void) const& { return begin () + m_size; }
const_iterator cbegin (void) const& { return begin (); }
const_iterator cend (void) const& { return end (); }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
auto size (void) const { return m_size; } auto size (void) const { return m_size; }