From 05569463f7bc4ace9644734286268766ccf7dcf4 Mon Sep 17 00:00:00 2001 From: liuyongkai2 Date: Fri, 25 Jul 2025 11:31:01 +0800 Subject: [PATCH] iterator check Signed-off-by: liuyongkai2 --- frameworks/base/container/list.h | 200 +++++++++++---------- frameworks/base/container/map.h | 246 ++++++++++++++------------ test/unittest/base/container_test.cpp | 198 +++++++++++++++++++++ 3 files changed, 438 insertions(+), 206 deletions(-) diff --git a/frameworks/base/container/list.h b/frameworks/base/container/list.h index 7d1fbab43e0..87498e60edd 100644 --- a/frameworks/base/container/list.h +++ b/frameworks/base/container/list.h @@ -34,6 +34,7 @@ template class SafeList { public: class iterator; + class reverse_iterator; struct list_head { list_head *prev, *next; list_head() : prev(this), next(this) {} @@ -54,7 +55,7 @@ public: next->prev = prev; prev = next = nullptr; } - void add(list_head* head) + void add_to(list_head* head) { prev->next = next; next->prev = prev; @@ -64,16 +65,17 @@ public: head->next = this; } }; - + private: struct TrackedElement { T value; mutable list_head iterator_head; - TrackedElement(const T& val={}) : value(val) {} + TrackedElement(const T& val = {}) : value(val) {} TrackedElement(T&& val) : value(std::forward(val)) {} - TrackedElement(const TrackedElement& rhs): value(rhs.value) {} - TrackedElement& operator=(const TrackedElement& rhs) { + TrackedElement(const TrackedElement& rhs) : value(rhs.value) {} + TrackedElement& operator=(const TrackedElement& rhs) + { if (&rhs != this) { this->value = rhs.value; } @@ -148,9 +150,9 @@ public: class iterator { private: using ListIter = typename std::list::iterator; + list_head node; SafeList* container_ = nullptr; ListIter inner_iter; - list_head node; friend SafeList; ListIter get_end() const { @@ -158,9 +160,9 @@ public: } explicit iterator(SafeList* container, ListIter it = ListIter {}) - : container_(container), inner_iter(it), - node(container_ ? (inner_iter != get_end() ? &inner_iter->iterator_head : &container_->end_iterator_head) - : nullptr) + : node(container ? (it != container->elements.end() ? &it->iterator_head : &container->end_iterator_head) + : nullptr), + container_(container), inner_iter(it) {} public: @@ -169,19 +171,19 @@ public: using value_type = T; using pointer = T*; using reference = T&; - explicit iterator() : container_(nullptr), inner_iter(), node() {} + explicit iterator() : node(), container_(nullptr), inner_iter() {} iterator(const iterator& other) : container_(other.container_), inner_iter(other.inner_iter) { if (container_) { if (inner_iter != get_end()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } - + T& operator*() const { if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && @@ -208,9 +210,9 @@ public: if (container_) { if (inner_iter != get_end()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -224,9 +226,9 @@ public: } ++inner_iter; if (inner_iter != get_end()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -245,9 +247,9 @@ public: } --inner_iter; if (inner_iter != get_end()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -276,9 +278,9 @@ public: class const_iterator { private: using ListIter = typename std::list::const_iterator; + list_head node; const SafeList* container_ = nullptr; ListIter inner_iter; - list_head node; friend SafeList; ListIter get_cend() const { @@ -286,21 +288,26 @@ public: } explicit const_iterator(const SafeList* container, ListIter it = ListIter {}) - : container_(container), inner_iter(it), - node(container_ ? (inner_iter != get_cend() ? &inner_iter->iterator_head : &container_->end_iterator_head) - : nullptr) + : node(container ? (it != container->elements.cend() ? &it->iterator_head : &container->end_iterator_head) + : nullptr), + container_(container), inner_iter(it) {} public: - explicit const_iterator() : container_(nullptr), inner_iter(), node() {} + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using value_type = T; + using pointer = T*; + using reference = T&; + explicit const_iterator() : node(), container_(nullptr), inner_iter() {} const_iterator(const iterator& other) : container_(other.container_), inner_iter(other.inner_iter) { if (container_) { if (inner_iter != get_cend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -309,9 +316,9 @@ public: { if (container_) { if (inner_iter != get_cend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -341,9 +348,9 @@ public: inner_iter = other.inner_iter; if (container_) { if (inner_iter != get_cend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -357,9 +364,9 @@ public: } ++inner_iter; if (inner_iter != get_cend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -374,13 +381,13 @@ public: const_iterator& operator--() { if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { - LOGF_ABORT("Dereferencing invalid iterator"); + LOGF_ABORT("Decrementing invalid const_iterator"); } --inner_iter; if (inner_iter != get_cend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -409,9 +416,9 @@ public: class reverse_iterator { private: using ListIter = typename std::list::reverse_iterator; + list_head node; SafeList* container_ = nullptr; ListIter inner_iter; - list_head node; friend SafeList; ListIter get_rend() const @@ -420,21 +427,26 @@ public: } explicit reverse_iterator(SafeList* container, ListIter it = ListIter {}) - : container_(container), inner_iter(it), - node(container_ ? (inner_iter != get_rend() ? &inner_iter->iterator_head : &container_->end_iterator_head) - : nullptr) + : node(container ? (it != container->elements.rend() ? &it->iterator_head : &container->end_iterator_head) + : nullptr), + container_(container), inner_iter(it) {} public: - explicit reverse_iterator() : container_(nullptr), inner_iter(), node() {} + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using value_type = T; + using pointer = T*; + using reference = T&; + explicit reverse_iterator() : node(), container_(nullptr), inner_iter() {} reverse_iterator(const reverse_iterator& other) : container_(other.container_), inner_iter(other.inner_iter) { if (container_) { if (inner_iter != get_rend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -464,9 +476,9 @@ public: inner_iter = other.inner_iter; if (container_) { if (inner_iter != get_rend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -480,9 +492,9 @@ public: } ++inner_iter; if (inner_iter != get_rend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -497,13 +509,13 @@ public: reverse_iterator& operator--() { if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { - LOGF_ABORT("Decrementing invalid iterator"); + LOGF_ABORT("Decrementing invalid reverse iterator"); } --inner_iter; if (inner_iter != get_rend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -532,9 +544,9 @@ public: class const_reverse_iterator { private: using ListIter = typename std::list::const_reverse_iterator; + list_head node; const SafeList* container_ = nullptr; ListIter inner_iter; - list_head node; friend SafeList; ListIter get_crend() const @@ -543,22 +555,27 @@ public: } explicit const_reverse_iterator(const SafeList* container, ListIter it = ListIter {}) - : container_(container), inner_iter(it), - node(container_ ? (inner_iter != get_crend() ? &inner_iter->iterator_head : &container_->end_iterator_head) - : nullptr) + : node(container ? (it != container->elements.crend() ? &it->iterator_head : &container->end_iterator_head) + : nullptr), + container_(container), inner_iter(it) {} public: - explicit const_reverse_iterator() : container_(nullptr), inner_iter(), node() {} + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; + using value_type = T; + using pointer = T*; + using reference = T&; + explicit const_reverse_iterator() : node(), container_(nullptr), inner_iter() {} const_reverse_iterator(const reverse_iterator& other) : container_(other.container_), inner_iter(other.inner_iter) { if (container_) { if (inner_iter != get_crend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -568,9 +585,9 @@ public: { if (container_) { if (inner_iter != get_crend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -600,9 +617,9 @@ public: inner_iter = other.inner_iter; if (container_) { if (inner_iter != get_crend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -616,9 +633,9 @@ public: } ++inner_iter; if (inner_iter != get_crend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -637,9 +654,9 @@ public: } --inner_iter; if (inner_iter != get_crend()) { - node.add(&inner_iter->iterator_head); + node.add_to(&inner_iter->iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -672,7 +689,7 @@ public: push_back(val); } } - SafeList(const SafeList& other):elements(other.elements){} + SafeList(const SafeList& other) : elements(other.elements) {} SafeList(SafeList&& other) : elements(std::forward>(other.elements)) {} ~SafeList() @@ -750,14 +767,14 @@ public: } return iterator(this, elements.insert(pos.inner_iter, value)); } - iterator insert( const_iterator pos, T&& value ) + iterator insert(const_iterator pos, T&& value) { if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) { LOGF_ABORT("Inserting with invalid iterator"); } return iterator(this, elements.insert(pos.inner_iter, std::forward(value))); } - iterator insert(const_iterator pos, size_t count, const T& value) + iterator insert(const_iterator pos, size_t count, const T& value) { if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) { LOGF_ABORT("Inserting with invalid iterator"); @@ -793,7 +810,8 @@ public: return insert_impl(pos, first, last); } - decltype(auto) get_allocator() const noexcept { + decltype(auto) get_allocator() const noexcept + { return elements.get_allocator(); } @@ -811,8 +829,7 @@ public: } template - auto assign(InputIt first, InputIt last) - -> typename std::enable_if::value>::type + auto assign(InputIt first, InputIt last) -> typename std::enable_if::value>::type { clear(); for (; first != last; ++first) { @@ -823,7 +840,7 @@ public: template iterator emplace(const_iterator pos, Args&&... args) { - auto iter = elements.emplace(pos.inner_iter,T(std::forward(args)...)); + auto iter = elements.emplace(pos.inner_iter, T(std::forward(args)...)); return iterator(this, iter); } @@ -881,35 +898,32 @@ public: return elements.empty(); } - int size() const + size_t size() const { return elements.size(); } - int max_size() const + size_t max_size() const { return elements.max_size(); } - void sort() { + void sort() + { elements.sort(); } template void sort(Compare comp) { - auto adapted_comp = [comp](const TrackedElement& a, const TrackedElement& b) { - return comp(a.value, b.value); - }; + auto adapted_comp = [comp](const TrackedElement& a, const TrackedElement& b) { return comp(a.value, b.value); }; elements.sort(adapted_comp); } template void unique(BinaryPredicate pred) { - auto adapted_pred = [pred](const TrackedElement& a, const TrackedElement& b) { - return pred(a.value, b.value); - }; + auto adapted_pred = [pred](const TrackedElement& a, const TrackedElement& b) { return pred(a.value, b.value); }; elements.unique(adapted_pred); } @@ -918,7 +932,8 @@ public: elements.unique(); } - void reverse() noexcept { + void reverse() noexcept + { elements.reverse(); } @@ -937,7 +952,7 @@ public: { if (other.empty()) { return; - } + } elements.splice(pos.inner_iter, other.elements); } @@ -959,13 +974,12 @@ public: template void merge(SafeList& other, Compare comp) { - auto adapted_comp = [comp](const TrackedElement& a, const TrackedElement& b) { - return comp(a.value, b.value); - }; + auto adapted_comp = [comp](const TrackedElement& a, const TrackedElement& b) { return comp(a.value, b.value); }; elements.merge(other.elements, adapted_comp); } - void swap(SafeList& other) noexcept { + void swap(SafeList& other) noexcept + { elements.swap(other.elements); } @@ -976,7 +990,7 @@ public: void resize(size_t count, const T& value) { - elements.resize(count,value); + elements.resize(count, value); } iterator begin() @@ -1012,16 +1026,20 @@ public: { return reverse_iterator(this, elements.rend()); } - const_reverse_iterator rbegin() const { + const_reverse_iterator rbegin() const + { return crbegin(); } - const_reverse_iterator rend() const { + const_reverse_iterator rend() const + { return crend(); } - const_reverse_iterator crbegin() const { + const_reverse_iterator crbegin() const + { return const_reverse_iterator(this, elements.crbegin()); } - const_reverse_iterator crend() const { + const_reverse_iterator crend() const + { return const_reverse_iterator(this, elements.crend()); } }; diff --git a/frameworks/base/container/map.h b/frameworks/base/container/map.h index 833515ca1e6..bd8d13b0339 100644 --- a/frameworks/base/container/map.h +++ b/frameworks/base/container/map.h @@ -54,7 +54,7 @@ public: next->prev = prev; prev = next = nullptr; } - void add(list_head* head) + void add_to(list_head* head) { prev->next = next; next->prev = prev; @@ -69,22 +69,24 @@ public: private: struct TrackedElement { - T value; + value_type value; mutable list_head iterator_head; - TrackedElement(const T& val) : value(val) {} - TrackedElement(T&& val) : value(std::move(val)) {} + TrackedElement(const Key& key) : value(key, T{}) {} + TrackedElement(const Key& key, const T& val) : value(key, val) {} + TrackedElement(const Key& key, T&& val) : value(key, std::move(val)) {} + TrackedElement(const value_type& val) : value(val) {} + TrackedElement(value_type&& val) : value(val.first, std::move(val.second)) {} TrackedElement(const TrackedElement& rhs) : value(rhs.value) {} TrackedElement& operator=(const TrackedElement& rhs) { if (&rhs != this) { - this->value = rhs.value; + this->value.second = rhs.value.second; } return *this; } - template - TrackedElement(Args&&... args) : value(std::forward(args)...) - {} + template + TrackedElement(const Key& key, Args&&... args) : value(key, std::forward(args)...) {} ~TrackedElement() { @@ -132,35 +134,36 @@ public: class iterator { private: using MapIter = typename std::map::iterator; + list_head node; SafeMap* container_ = nullptr; MapIter inner_iter; - list_head node; friend SafeMap; + MapIter get_end() const { return container_ ? container_->elements.end() : MapIter {}; } explicit iterator(SafeMap* container, MapIter it = MapIter {}) - : container_(container), inner_iter(it), - node(container_ - ? (inner_iter != get_end() ? &inner_iter->second.iterator_head : &container_->end_iterator_head) - : nullptr) + : node(container + ? (it != container->elements.end() ? &it->second.iterator_head : &container->end_iterator_head) + : nullptr), + container_(container), inner_iter(it) {} public: using iterator_category = std::bidirectional_iterator_tag; using difference_type = std::ptrdiff_t; - iterator() : container_(nullptr), inner_iter(), node() {} + iterator() : node(), container_(nullptr), inner_iter() {} iterator(const iterator& other) : container_(other.container_), inner_iter(other.inner_iter) { if (container_) { if (inner_iter != get_end()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -172,9 +175,9 @@ public: inner_iter = other.inner_iter; if (container_) { if (inner_iter != get_end()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -187,7 +190,7 @@ public: (!container_ || inner_iter == get_end()))) { LOGF_ABORT("Dereferencing invalid iterator"); } - return *reinterpret_cast(&*inner_iter); + return inner_iter->second.value; } value_type* operator->() const @@ -196,7 +199,7 @@ public: (!container_ || inner_iter == get_end()))) { LOGF_ABORT("Dereferencing invalid iterator"); } - return reinterpret_cast(&*inner_iter); + return &inner_iter->second.value; } iterator& operator++() @@ -206,9 +209,9 @@ public: } ++inner_iter; if (inner_iter != get_end()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -227,9 +230,9 @@ public: } --inner_iter; if (inner_iter != get_end()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -258,9 +261,9 @@ public: class const_iterator { private: using MapIter = typename std::map::const_iterator; + list_head node; const SafeMap* container_ = nullptr; MapIter inner_iter; - list_head node; friend SafeMap; MapIter get_cend() const { @@ -268,24 +271,24 @@ public: } explicit const_iterator(const SafeMap* container, MapIter it = MapIter {}) - : container_(container), inner_iter(it), - node(container_ - ? (inner_iter != get_cend() ? &inner_iter->second.iterator_head : &container_->end_iterator_head) - : nullptr) + : node(container + ? (it != container->elements.cend() ? &it->second.iterator_head : &container->end_iterator_head) + : nullptr), + container_(container), inner_iter(it) {} public: using iterator_category = std::bidirectional_iterator_tag; using difference_type = std::ptrdiff_t; - const_iterator() : container_(nullptr), inner_iter(), node() {} + const_iterator() : node(), container_(nullptr), inner_iter() {} const_iterator(const iterator& other) : container_(other.container_), inner_iter(other.inner_iter) { if (container_) { if (inner_iter != get_cend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -294,9 +297,9 @@ public: { if (container_) { if (inner_iter != get_cend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -308,9 +311,9 @@ public: inner_iter = other.inner_iter; if (container_) { if (inner_iter != get_cend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -323,7 +326,7 @@ public: (!container_ || inner_iter == get_cend()))) { LOGF_ABORT("Dereferencing invalid const_iterator"); } - return *reinterpret_cast(&*inner_iter); + return inner_iter->second.value; } const value_type* operator->() const @@ -332,7 +335,7 @@ public: (!container_ || inner_iter == get_cend()))) { LOGF_ABORT("Dereferencing invalid const_iterator"); } - return reinterpret_cast(&*inner_iter); + return &inner_iter->second.value; } const_iterator& operator++() @@ -342,9 +345,9 @@ public: } ++inner_iter; if (inner_iter != get_cend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -359,13 +362,13 @@ public: const_iterator& operator--() { if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { - LOGF_ABORT("Dereferencing invalid iterator"); + LOGF_ABORT("Decrementing invalid const_iterator"); } --inner_iter; if (inner_iter != get_cend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -394,35 +397,33 @@ public: class reverse_iterator { private: using MapIter = typename std::map::reverse_iterator; + list_head node; SafeMap* container_ = nullptr; MapIter inner_iter; - list_head node; friend SafeMap; MapIter get_rend() const { return container_ ? container_->elements.rend() : MapIter {}; } - explicit reverse_iterator(SafeMap* container, MapIter it = MapIter {}) - : container_(container), inner_iter(it), - node(container_ - ? (inner_iter != get_rend() ? &inner_iter->second.iterator_head : &container_->end_iterator_head) - : nullptr) + : node(container + ? (it != container->elements.rend() ? &it->second.iterator_head : &container->end_iterator_head) + : nullptr), + container_(container), inner_iter(it) {} public: using iterator_category = std::bidirectional_iterator_tag; using difference_type = std::ptrdiff_t; - reverse_iterator() : container_(nullptr), inner_iter(), node() {} - + reverse_iterator() : node(), container_(nullptr), inner_iter() {} reverse_iterator(const reverse_iterator& other) : container_(other.container_), inner_iter(other.inner_iter) { if (container_) { if (inner_iter != get_rend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -434,9 +435,9 @@ public: inner_iter = other.inner_iter; if (container_) { if (inner_iter != get_rend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -449,7 +450,7 @@ public: (!container_ || inner_iter == get_rend()))) { LOGF_ABORT("Dereferencing invalid reverse iterator"); } - return *reinterpret_cast(&*inner_iter); + return inner_iter->second.value; } value_type* operator->() const @@ -458,7 +459,7 @@ public: (!container_ || inner_iter == get_rend()))) { LOGF_ABORT("Dereferencing invalid reverse iterator"); } - return reinterpret_cast(&*inner_iter); + return &inner_iter->second.value; } reverse_iterator& operator++() @@ -468,9 +469,9 @@ public: } ++inner_iter; if (inner_iter != get_rend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -485,13 +486,13 @@ public: reverse_iterator& operator--() { if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { - LOGF_ABORT("Decrementing invalid iterator"); + LOGF_ABORT("Decrementing invalid reverse iterator"); } --inner_iter; if (inner_iter != get_rend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -517,36 +518,35 @@ public: class const_reverse_iterator { private: using MapIter = typename std::map::const_reverse_iterator; + list_head node; const SafeMap* container_ = nullptr; MapIter inner_iter; - list_head node; friend SafeMap; MapIter get_crend() const { return container_ ? container_->elements.crend() : MapIter {}; } - explicit const_reverse_iterator(const SafeMap* container, MapIter it = MapIter {}) - : container_(container), inner_iter(it), - node(container_ ? (inner_iter != get_crend() ? &inner_iter->second.iterator_head - : &container_->end_iterator_head) - : nullptr) + : node(container + ? (it != container->elements.crend() ? &it->second.iterator_head : &container->end_iterator_head) + : nullptr), + container_(container), inner_iter(it) {} public: using iterator_category = std::bidirectional_iterator_tag; using difference_type = std::ptrdiff_t; - const_reverse_iterator() : container_(nullptr), inner_iter(), node() {} + const_reverse_iterator() : node(), container_(nullptr), inner_iter() {} const_reverse_iterator(const reverse_iterator& other) : container_(other.container_), inner_iter(other.inner_iter) { if (container_) { if (inner_iter != get_crend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -556,9 +556,9 @@ public: { if (container_) { if (inner_iter != get_crend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -570,9 +570,9 @@ public: inner_iter = other.inner_iter; if (container_) { if (inner_iter != get_crend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } } } @@ -585,7 +585,7 @@ public: (!container_ || inner_iter == get_crend()))) { LOGF_ABORT("Dereferencing invalid const_reverse iterator"); } - return *reinterpret_cast(&*inner_iter); + return inner_iter->second.value; } const value_type* operator->() const @@ -594,7 +594,7 @@ public: (!container_ || inner_iter == get_crend()))) { LOGF_ABORT("Dereferencing invalid const_reverse iterator"); } - return reinterpret_cast(&*inner_iter); + return &inner_iter->second.value; } const_reverse_iterator& operator++() @@ -604,9 +604,9 @@ public: } ++inner_iter; if (inner_iter != get_crend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -625,9 +625,9 @@ public: } --inner_iter; if (inner_iter != get_crend()) { - node.add(&inner_iter->second.iterator_head); + node.add_to(&inner_iter->second.iterator_head); } else { - node.add(&container_->end_iterator_head); + node.add_to(&container_->end_iterator_head); } return *this; } @@ -655,7 +655,7 @@ public: SafeMap(std::initializer_list> ilist) { for (const auto& val : ilist) { - elements.emplace(val.first, val.second); + elements.emplace(val.first, val); } } SafeMap(const SafeMap& other) : elements(other.elements) {} @@ -671,20 +671,23 @@ public: std::pair insert(const value_type& value) { - auto [it, inserted] = elements.insert(value); + auto [it, inserted] = elements.emplace(value.first, value); return { iterator(this, it), inserted }; } std::pair insert(value_type&& value) { - auto [it, inserted] = elements.insert(std::forward(value)); + auto [it, inserted] = elements.emplace(value.first, std::move(value)); return { iterator(this, it), inserted }; } template std::pair insert(P&& value) { - auto [it, inserted] = elements.insert(std::forward

(value)); + auto [it, inserted] = elements.emplace( + value.first, + TrackedElement(value.first, std::forward

(value).second) + ); return { iterator(this, it), inserted }; } @@ -693,7 +696,8 @@ public: if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) { LOGF_ABORT("Inserting with invalid iterator"); } - return iterator(this, elements.insert(pos.inner_iter, value)); + return iterator(this, elements.insert(pos.inner_iter, + std::make_pair(value.first, TrackedElement(value.first, value.second)))); } iterator insert(const_iterator pos, value_type&& value) @@ -701,7 +705,9 @@ public: if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) { LOGF_ABORT("Inserting with invalid iterator"); } - return iterator(this, elements.insert(pos.inner_iter, std::forward(value))); + return iterator(this, elements.insert(pos.inner_iter, + std::make_pair(std::move(value.first), + TrackedElement(value.first, std::move(value.second))))); } template @@ -710,78 +716,89 @@ public: if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) { LOGF_ABORT("Inserting with invalid iterator"); } - return iterator(this, elements.insert(pos.inner_iter, std::forward

(value))); + return iterator(this, elements.insert(pos.inner_iter, + std::make_pair(value.first, + TrackedElement(value.first, std::forward

(value).second)))); } template void insert(InputIt first, InputIt last) { - elements.insert(first, last); + for (auto it = first; it != last; ++it) { + elements.emplace(it->first, TrackedElement(it->first, it->second)); + } } void insert(std::initializer_list ilist) { - elements.insert(ilist.begin(), ilist.end()); + for (const auto& val : ilist) { + elements.emplace(val.first, val); + } } + template std::pair emplace(Args&&... args) { - auto [it, inserted] = elements.emplace(std::forward(args)...); + auto temp = value_type(std::forward(args)...); + auto [it, inserted] = elements.emplace(temp.first, temp); return { iterator(this, it), inserted }; } template std::pair insert_or_assign(const Key& k, M&& obj) { - auto [it, inserted] = elements.insert_or_assign(k, std::forward(obj)); + auto [it, inserted] = elements.insert_or_assign(k, TrackedElement(k, std::forward(obj))); return { iterator(this, it), inserted }; } template std::pair insert_or_assign(Key&& k, M&& obj) { - auto [it, inserted] = elements.insert_or_assign(std::forward(k), std::forward(obj)); + auto [it, inserted] = elements.insert_or_assign(std::forward(k), TrackedElement(k, std::forward(obj))); return { iterator(this, it), inserted }; } template iterator insert_or_assign(const_iterator hint, const Key& k, M&& obj) { - return iterator(this, elements.insert_or_assign(hint.inner_iter, k, std::forward(obj))); + return iterator(this, elements.insert_or_assign(hint.inner_iter, k, TrackedElement(k, std::forward(obj)))); } template iterator insert_or_assign(const_iterator hint, Key&& k, M&& obj) { - return iterator(this, elements.insert_or_assign(hint.inner_iter, std::forward(k), std::forward(obj))); + return iterator(this, elements.insert_or_assign(hint.inner_iter, std::forward(k), TrackedElement(k, std::forward(obj)))); } template iterator emplace_hint(const_iterator hint, Args&&... args) { - return iterator(this, elements.emplace_hint(hint.inner_iter, std::forward(args)...)); + auto temp = value_type(std::forward(args)...); + return iterator(this, elements.emplace_hint(hint.inner_iter, + std::make_pair(temp.first, + TrackedElement(temp.first, std::move(temp.second))))); } template std::pair try_emplace(const Key& k, Args&&... args) { - auto [it, inserted] = elements.try_emplace(k, std::forward(args)...); + auto [it, inserted] = elements.try_emplace(k, k, std::forward(args)...); return { iterator(this, it), inserted }; } template std::pair try_emplace(Key&& k, Args&&... args) { - auto [it, inserted] = elements.try_emplace(std::forward(k), std::forward(args)...); + auto [it, inserted] = elements.try_emplace(std::forward(k), k, std::forward(args)...); return { iterator(this, it), inserted }; } template iterator try_emplace(const_iterator hint, Key&& k, Args&&... args) { - auto result = elements.try_emplace(hint.inner_iter, std::forward(k), std::forward(args)...); + auto result = elements.try_emplace(hint.inner_iter, std::forward(k), k, std::forward(args)...); return iterator(this, result); } template iterator try_emplace(const_iterator hint, const Key& k, Args&&... args) { - auto result = elements.try_emplace(hint.inner_iter, k, std::forward(args)...); + auto result = elements.try_emplace(hint.inner_iter, k, k, std::forward(args)...); return iterator(this, result); } @@ -847,16 +864,6 @@ public: return const_iterator(this, elements.upper_bound(k)); } - typename std::map::key_compare key_comp() const - { - return elements.key_comp(); - } - - typename std::map::value_compare value_comp() const - { - return elements.value_comp(); - } - decltype(auto) get_allocator() const noexcept { return elements.get_allocator(); @@ -864,19 +871,28 @@ public: T& operator[](const Key& key) { - return elements[key].value; + auto it = elements.find(key); + if (it == elements.end()) { + it = elements.emplace(key, key).first; + } + return it->second.value.second; } T& operator[](Key&& key) { - return elements[key].value; + auto it = elements.find(key); + if (it == elements.end()) { + it = elements.emplace(key, key).first; + } + return it->second.value.second; } + T& at(const Key& k) { if (elements.find(k) == elements.end()) { LOGF_ABORT("SafeMap::at: key not found"); } - return elements.at(k).value; + return elements.at(k).value.second; } const T& at(const Key& k) const @@ -884,7 +900,7 @@ public: if (elements.find(k) == elements.end()) { LOGF_ABORT("SafeMap::at: key not found"); } - return elements.at(k).value; + return elements.at(k).value.second; } iterator erase(iterator pos) @@ -951,7 +967,7 @@ public: return elements.empty(); } - int max_size() const + size_t max_size() const { return elements.max_size(); } diff --git a/test/unittest/base/container_test.cpp b/test/unittest/base/container_test.cpp index cacc980b8c6..2ad908157cf 100644 --- a/test/unittest/base/container_test.cpp +++ b/test/unittest/base/container_test.cpp @@ -409,4 +409,202 @@ HWTEST_F(SafeContainerTest, SafeMapTest010, TestSize.Level1) m.insert({ 2, Point { 30, 40 } }); EXPECT_EQ(m[2].y, 40); } + +/** + * @tc.name: SafeMapTest011 + * @tc.desc: Test basic map operations and element access + * @tc.type: FUNC + */ +HWTEST_F(SafeContainerTest, SafeMapTest011, TestSize.Level1) +{ + SafeMap map { { 1, "one1" }, { 2, "one2" }, { 3, "one3" } }; + auto it1 = map.begin(); + EXPECT_EQ(it1, map.begin()); + EXPECT_NE(it1, map.end()); + EXPECT_EQ((*it1).second, "one1"); + EXPECT_EQ(it1->second, "one1"); + EXPECT_EQ(it1->first, 1); + ++it1; + EXPECT_EQ(it1->first, 2); + EXPECT_EQ(it1->second, "one2"); + --it1; + EXPECT_EQ((*it1).second, "one1"); + { + SafeMap m { { 1, "one1" }, { 2, "one2" }, { 3, "one3" } }; + m[1] = "one"; + EXPECT_EQ(m.begin()->second, "one"); + m[1] = "new_one"; + EXPECT_EQ(m[1], "new_one"); + m[4] = "two"; + m[4] = "updated_two"; + EXPECT_EQ(m.at(4), "updated_two"); + EXPECT_EQ(m[4], "updated_two"); + int key = 5; + m[std::move(key)] = "three"; + int key2 = 5; + EXPECT_EQ(m.at(key2), "three"); + EXPECT_EQ(m[5], "three"); +} + +/** + * @tc.name: SafeMapTest012 + * @tc.desc: Test basic map operations and element access + * @tc.type: FUNC + */ +HWTEST_F(SafeContainerTest, SafeMapTest012, TestSize.Level1) +{ + SafeMap m2; + std::pair movable_pair { 2, "two" }; + auto [it, inserted] = m2.insert(std::move(movable_pair)); + EXPECT_TRUE(inserted); + EXPECT_EQ(it->second, "two"); + EXPECT_TRUE(movable_pair.second.empty()); +} + +/** + * @tc.name: SafeMapTest013 + * @tc.desc: Test map instert operations + * @tc.type: FUNC + */ +HWTEST_F(SafeContainerTest, SafeMapTest013, TestSize.Level1) +{ + SafeMap map { { 1, "one" } }; + auto iter1 = map.insert(map.begin(), { 2, "two" }); + EXPECT_EQ(iter1->first, 2); + EXPECT_EQ(iter1->second, "two"); + EXPECT_EQ(map.size(), 2); + auto iter2 = map.insert(map.begin(), { 3, "three" }); + EXPECT_EQ(iter2->first, 3); + EXPECT_EQ(iter2->second, "three"); + EXPECT_EQ(map.size(), 3); + map.insert({ { 4, "four" }, { 5, "five" }, { 6, "six" }, { 7, "seven" } }); + EXPECT_EQ(map.size(), 7); + SafeMap map2; + map2.insert(map.begin(), map.end()); + EXPECT_EQ(map2.size(), 7); +} + +/** + * @tc.name: SafeMapTest014 + * @tc.desc: Test map erase operations + * @tc.type: FUNC + */ +HWTEST_F(SafeContainerTest, SafeMapTest014, TestSize.Level1) +{ + SafeMap m { { 1, "one1" }, { 2, "one2" }, { 3, "one3" }, { 4, "four" }, { 5, "five" } }; + EXPECT_EQ(m.size(), 5); + m.erase(m.begin()); + EXPECT_EQ(m.begin()->first, 2); + m.erase(m.cbegin()); + EXPECT_EQ(m.begin()->first, 3); + m.erase(3); + EXPECT_EQ(m.begin()->first, 4); + m.erase(m.begin(), m.end()); + EXPECT_EQ(m.size(), 0); + EXPECT_TRUE(m.empty()); + SafeMap m2 { { 1, "one" }, { 2, "two" }, { 3, "three" }, { 4, "four" }, { 5, "five" } }; + EXPECT_EQ(m2.find(3)->second, "three"); + SafeMap::const_iterator const_it = m2.find(5); + EXPECT_EQ(const_it->second, "five"); + m2.clear(); + EXPECT_EQ(m2.size(), 0); +} + +/** + * @tc.name: SafeMapTest015 + * @tc.desc: Test map lower_bound operations + * @tc.type: FUNC + */ +HWTEST_F(SafeContainerTest, SafeMapTest015, TestSize.Level1) +{ + const std::map map0; + auto it0 = map0.lower_bound(1); + EXPECT_EQ(it0, map0.end()); + std::map map; + map.insert({ 1, "value1" }); + map.insert({ 3, "value3" }); + auto it1 = map.lower_bound(1); + EXPECT_NE(it1, map.end()); + EXPECT_EQ(it1->first, 1); + EXPECT_EQ(it1->second, "value1"); + auto it2 = map.lower_bound(2); + EXPECT_NE(it2, map.end()); + EXPECT_EQ(it2->first, 3); + EXPECT_EQ(it2->second, "value3"); + auto it3 = map.lower_bound(3); + EXPECT_NE(it3, map.end()); + EXPECT_EQ(it3->first, 3); + EXPECT_EQ(it3->second, "value3"); + auto it4 = map.lower_bound(4); + EXPECT_EQ(it4, map.end()); +} + +/** + * @tc.name: SafeMapTest016 + * @tc.desc: Test map lower_bound operations + * @tc.type: FUNC + */ +HWTEST_F(SafeContainerTest, SafeMapTest016, TestSize.Level1) +{ + SafeMap map0; + auto it0 = map0.lower_bound(1); + EXPECT_EQ(it0, map0.end()); + SafeMap map; + map.insert({ 1, "value1" }); + map.insert({ 3, "value3" }); + auto it1 = map.lower_bound(1); + EXPECT_NE(it1, map.end()); + EXPECT_EQ(it1->first, 1); + EXPECT_EQ(it1->second, "value1"); + auto it2 = map.lower_bound(2); + EXPECT_NE(it2, map.end()); + EXPECT_EQ(it2->first, 3); + EXPECT_EQ(it2->second, "value3"); + auto it3 = map.lower_bound(3); + EXPECT_NE(it3, map.end()); + EXPECT_EQ(it3->first, 3); + EXPECT_EQ(it3->second, "value3"); + auto it4 = map.lower_bound(4); + EXPECT_EQ(it4, map.end()); +} + +/** + * @tc.name: SafeMapTest017 + * @tc.desc: Test map insert_or_assign operations + * @tc.type: FUNC + */ +HWTEST_F(SafeContainerTest, SafeMapTest017, TestSize.Level1) +{ + SafeMap m; + int key = 1; + auto [it1, inserted1] = m.insert_or_assign(key, "one"); + EXPECT_TRUE(inserted1); + EXPECT_EQ(it1->first, 1); + EXPECT_EQ(it1->second, "one"); + auto [it2, inserted2] = m.insert_or_assign(key, "new_one"); + EXPECT_FALSE(inserted2); + EXPECT_EQ(it2->second, "new_one"); +} + +/** + * @tc.name: SafeMapTest019 + * @tc.desc: Test map lower_bound swap + * @tc.type: FUNC + */ +HWTEST_F(SafeContainerTest, SafeMapTest019, TestSize.Level1) +{ + std::map m1 { { 1, "one" }, { 2, "two" }, { 3, "three" } }; + std::map m2 { { 4, "four" }, { 5, "five" } }; + auto mit1 = m1.begin(); + auto mit2 = m2.begin(); + auto mend1 = m1.end(); + auto mend2 = m2.end(); + m1.swap(m2); + EXPECT_EQ(mit1->second, "one"); + EXPECT_EQ(m2.begin()->second, "one"); + EXPECT_EQ(mit2->second, "four"); + EXPECT_EQ(m1.begin()->second, "four"); + EXPECT_EQ(mend1, m1.end()); + EXPECT_EQ(mend2, m2.end()); +} } // namespace OHOS::Ace \ No newline at end of file -- Gitee