From 47f2ad55096cd4c23d69acea482ceff9ed8431fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0mundur=20F=2E=20A=C3=B0alsteinsson?= Date: Fri, 16 Sep 2022 20:25:28 +0000 Subject: [PATCH] Refactor object::erase --- include/boost/json/impl/object.ipp | 85 ++++++++++++++++-------------- include/boost/json/object.hpp | 12 ++++- 2 files changed, 56 insertions(+), 41 deletions(-) diff --git a/include/boost/json/impl/object.ipp b/include/boost/json/impl/object.ipp index 6c89762a2..1e395c0e3 100644 --- a/include/boost/json/impl/object.ipp +++ b/include/boost/json/impl/object.ipp @@ -508,30 +508,17 @@ object:: erase(const_iterator pos) noexcept -> iterator { - auto p = begin() + (pos - begin()); - if(t_->is_small()) - { - p->~value_type(); - --t_->size; - auto const pb = end(); - if(p != end()) - { + return do_erase(pos, + [this](iterator p) { // the casts silence warnings std::memcpy( static_cast(p), - static_cast(pb), + static_cast(end()), sizeof(*p)); - } - return p; - } - remove(t_->bucket(p->key()), *p); - p->~value_type(); - --t_->size; - if(p != end()) - { - reindex_relocate(end(), p); - } - return p; + }, + [this](iterator p) { + reindex_relocate(end(), p); + }); } auto @@ -551,30 +538,20 @@ object:: stable_erase(const_iterator pos) noexcept -> iterator { - auto p = begin() + (pos - begin()); - if(t_->is_small()) - { - p->~value_type(); - --t_->size; - if(p != end()) - { + return do_erase(pos, + [this](iterator p) { // the casts silence warnings std::memmove( static_cast(p), static_cast(p + 1), sizeof(*p) * (end() - p)); - } - return p; - } - remove(t_->bucket(p->key()), *p); - p->~value_type(); - --t_->size; - auto pret = p; - for (; p != end(); ++p) - { - reindex_relocate(p + 1, p); - } - return pret; + }, + [this](iterator p) { + for (; p != end(); ++p) + { + reindex_relocate(p + 1, p); + } + }); } auto @@ -863,6 +840,36 @@ destroy( (--last)->~key_value_pair(); } +template +auto +object:: +do_erase( + const_iterator pos, + FS small_reloc, + FB big_reloc) noexcept + -> iterator +{ + auto p = begin() + (pos - begin()); + if(t_->is_small()) + { + p->~value_type(); + --t_->size; + if(p != end()) + { + small_reloc(p); + } + return p; + } + remove(t_->bucket(p->key()), *p); + p->~value_type(); + --t_->size; + if(p != end()) + { + big_reloc(p); + } + return p; +} + void object:: reindex_relocate( diff --git a/include/boost/json/object.hpp b/include/boost/json/object.hpp index 378f2d9a5..2922079c2 100644 --- a/include/boost/json/object.hpp +++ b/include/boost/json/object.hpp @@ -1176,7 +1176,7 @@ class object References and iterators from `pos` to `end()`, both included, are invalidated. Other iterators and references are not invalidated. - The relative order of non-erased elements is preserved. + The relative order of remaining elements is preserved. @note @@ -1202,7 +1202,7 @@ class object Remove the element which matches `key`, if it exists. All references and iterators are invalidated. - The relative order of non-erased elements is preserved. + The relative order of remaining elements is preserved. @par Complexity Linear in @ref size(). @@ -1621,6 +1621,14 @@ class object key_value_pair* first, key_value_pair* last) noexcept; + template + auto + do_erase( + const_iterator pos, + FS small_reloc, + FB big_reloc) noexcept + -> iterator; + inline void reindex_relocate(