• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_CONTAINER_MAP_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_CONTAINER_MAP_H
18 
19 #include <initializer_list>
20 #include <iostream>
21 #include <list>
22 #include <map>
23 #include <memory>
24 #include <stdexcept>
25 #include <utility>
26 
27 #include "base/log/log_wrapper.h"
28 
29 #define list_entry(ptr, type, member) \
30     reinterpret_cast<type*>(reinterpret_cast<char*>(ptr) - offsetof(type, member))
31 
32 namespace OHOS::Ace {
33 template<typename Key, typename T>
34 class SafeMap {
35 public:
36     class iterator;
37     struct list_head {
38         list_head *prev, *next;
list_headlist_head39         list_head() : prev(this), next(this) {}
list_headlist_head40         list_head(list_head* head)
41         {
42             if (head) {
43                 prev = head;
44                 next = head->next;
45                 head->next->prev = this;
46                 head->next = this;
47             } else {
48                 prev = next = this;
49             }
50         }
~list_headlist_head51         ~list_head()
52         {
53             prev->next = next;
54             next->prev = prev;
55             prev = next = nullptr;
56         }
addlist_head57         void add(list_head* head)
58         {
59             prev->next = next;
60             next->prev = prev;
61             prev = head;
62             next = head->next;
63             head->next->prev = this;
64             head->next = this;
65         }
66     };
67 
68     using value_type = std::pair<const Key, T>;
69 
70 private:
71     struct TrackedElement {
72         T value;
73         mutable list_head iterator_head;
74 
TrackedElementTrackedElement75         TrackedElement(const T& val) : value(val) {}
TrackedElementTrackedElement76         TrackedElement(T&& val) : value(std::move(val)) {}
TrackedElementTrackedElement77         TrackedElement(const TrackedElement& rhs) : value(rhs.value) {}
78         TrackedElement& operator=(const TrackedElement& rhs)
79         {
80             if (&rhs != this) {
81                 this->value = rhs.value;
82             }
83             return *this;
84         }
85         template<typename... Args>
TrackedElementTrackedElement86         TrackedElement(Args&&... args) : value(std::forward<Args>(args)...)
87         {}
88 
~TrackedElementTrackedElement89         ~TrackedElement()
90         {
91             invalidate_iterators();
92         }
93 
invalidate_iteratorsTrackedElement94         void invalidate_iterators()
95         {
96             list_head* pos = iterator_head.next;
97             while (pos != &iterator_head) {
98                 list_head* next = pos->next;
99                 auto iter = list_entry(pos, iterator, node);
100                 iter->container_ = nullptr;
101                 pos = next;
102             }
103         }
104 
invalidate_iteratorsTrackedElement105         void invalidate_iterators() const
106         {
107             list_head* pos = iterator_head.next;
108             while (pos != &iterator_head) {
109                 list_head* next = pos->next;
110                 auto iter = list_entry(pos, iterator, node);
111                 iter->container_ = nullptr;
112                 pos = next;
113             }
114         }
115     };
116 
117     std::map<Key, TrackedElement, std::less<>> elements;
118     mutable list_head end_iterator_head;
119 
invalidate_end_iterators()120     void invalidate_end_iterators()
121     {
122         list_head* pos = end_iterator_head.next;
123         while (pos != &end_iterator_head) {
124             list_head* next = pos->next;
125             auto iter = list_entry(pos, iterator, node);
126             iter->container_ = nullptr;
127             pos = next;
128         }
129     }
130 
131 public:
132     class iterator {
133     private:
134         using MapIter = typename std::map<Key, TrackedElement>::iterator;
135         SafeMap* container_ = nullptr;
136         MapIter inner_iter;
137         list_head node;
138         friend SafeMap;
get_end()139         MapIter get_end() const
140         {
141             return container_ ? container_->elements.end() : MapIter {};
142         }
143 
144         explicit iterator(SafeMap* container, MapIter it = MapIter {})
container_(container)145             : container_(container), inner_iter(it),
146               node(container_
147                        ? (inner_iter != get_end() ? &inner_iter->second.iterator_head : &container_->end_iterator_head)
148                        : nullptr)
149         {}
150 
151     public:
152         using iterator_category = std::bidirectional_iterator_tag;
153         using difference_type = std::ptrdiff_t;
154 
iterator()155         iterator() : container_(nullptr), inner_iter(), node() {}
156 
iterator(const iterator & other)157         iterator(const iterator& other) : container_(other.container_), inner_iter(other.inner_iter)
158         {
159             if (container_) {
160                 if (inner_iter != get_end()) {
161                     node.add(&inner_iter->second.iterator_head);
162                 } else {
163                     node.add(&container_->end_iterator_head);
164                 }
165             }
166         }
167 
168         iterator& operator=(const iterator& other)
169         {
170             if (this != &other) {
171                 container_ = other.container_;
172                 inner_iter = other.inner_iter;
173                 if (container_) {
174                     if (inner_iter != get_end()) {
175                         node.add(&inner_iter->second.iterator_head);
176                     } else {
177                         node.add(&container_->end_iterator_head);
178                     }
179                 }
180             }
181             return *this;
182         }
183 
184         value_type& operator*() const
185         {
186             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
187                              (!container_ || inner_iter == get_end()))) {
188                 LOGF_ABORT("Dereferencing invalid iterator");
189             }
190             return *reinterpret_cast<value_type*>(&*inner_iter);
191         }
192 
193         value_type* operator->() const
194         {
195             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
196                              (!container_ || inner_iter == get_end()))) {
197                 LOGF_ABORT("Dereferencing invalid iterator");
198             }
199             return reinterpret_cast<value_type*>(&*inner_iter);
200         }
201 
202         iterator& operator++()
203         {
204             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) {
205                 LOGF_ABORT("Incrementing invalid iterator");
206             }
207             ++inner_iter;
208             if (inner_iter != get_end()) {
209                 node.add(&inner_iter->second.iterator_head);
210             } else {
211                 node.add(&container_->end_iterator_head);
212             }
213             return *this;
214         }
215 
216         iterator operator++(int)
217         {
218             iterator tmp = *this;
219             ++(*this);
220             return tmp;
221         }
222 
223         iterator& operator--()
224         {
225             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) {
226                 LOGF_ABORT("Decrementing invalid iterator");
227             }
228             --inner_iter;
229             if (inner_iter != get_end()) {
230                 node.add(&inner_iter->second.iterator_head);
231             } else {
232                 node.add(&container_->end_iterator_head);
233             }
234             return *this;
235         }
236 
237         iterator operator--(int)
238         {
239             iterator tmp = *this;
240             --(*this);
241             return tmp;
242         }
243 
244         bool operator==(const iterator& other) const
245         {
246             if (!container_ || !other.container_) {
247                 return false;
248             }
249             return inner_iter == other.inner_iter;
250         }
251 
252         bool operator!=(const iterator& other) const
253         {
254             return !(*this == other);
255         }
256     };
257 
258     class const_iterator {
259     private:
260         using MapIter = typename std::map<Key, TrackedElement>::const_iterator;
261         const SafeMap* container_ = nullptr;
262         MapIter inner_iter;
263         list_head node;
264         friend SafeMap;
get_cend()265         MapIter get_cend() const
266         {
267             return container_ ? container_->elements.cend() : MapIter {};
268         }
269 
270         explicit const_iterator(const SafeMap* container, MapIter it = MapIter {})
container_(container)271             : container_(container), inner_iter(it),
272               node(container_
273                        ? (inner_iter != get_cend() ? &inner_iter->second.iterator_head : &container_->end_iterator_head)
274                        : nullptr)
275         {}
276 
277     public:
278         using iterator_category = std::bidirectional_iterator_tag;
279         using difference_type = std::ptrdiff_t;
280 
const_iterator()281         const_iterator() : container_(nullptr), inner_iter(), node() {}
const_iterator(const iterator & other)282         const_iterator(const iterator& other) : container_(other.container_), inner_iter(other.inner_iter)
283         {
284             if (container_) {
285                 if (inner_iter != get_cend()) {
286                     node.add(&inner_iter->second.iterator_head);
287                 } else {
288                     node.add(&container_->end_iterator_head);
289                 }
290             }
291         }
292 
const_iterator(const const_iterator & other)293         const_iterator(const const_iterator& other) : container_(other.container_), inner_iter(other.inner_iter)
294         {
295             if (container_) {
296                 if (inner_iter != get_cend()) {
297                     node.add(&inner_iter->second.iterator_head);
298                 } else {
299                     node.add(&container_->end_iterator_head);
300                 }
301             }
302         }
303 
304         const_iterator& operator=(const const_iterator& other)
305         {
306             if (this != &other) {
307                 container_ = other.container_;
308                 inner_iter = other.inner_iter;
309                 if (container_) {
310                     if (inner_iter != get_cend()) {
311                         node.add(&inner_iter->second.iterator_head);
312                     } else {
313                         node.add(&container_->end_iterator_head);
314                     }
315                 }
316             }
317             return *this;
318         }
319 
320         const value_type& operator*() const
321         {
322             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
323                              (!container_ || inner_iter == get_cend()))) {
324                 LOGF_ABORT("Dereferencing invalid const_iterator");
325             }
326             return *reinterpret_cast<const value_type*>(&*inner_iter);
327         }
328 
329         const value_type* operator->() const
330         {
331             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
332                              (!container_ || inner_iter == get_cend()))) {
333                 LOGF_ABORT("Dereferencing invalid const_iterator");
334             }
335             return reinterpret_cast<const value_type*>(&*inner_iter);
336         }
337 
338         const_iterator& operator++()
339         {
340             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) {
341                 LOGF_ABORT("Incrementing invalid const_iterator");
342             }
343             ++inner_iter;
344             if (inner_iter != get_cend()) {
345                 node.add(&inner_iter->second.iterator_head);
346             } else {
347                 node.add(&container_->end_iterator_head);
348             }
349             return *this;
350         }
351 
352         const_iterator operator++(int)
353         {
354             const_iterator tmp = *this;
355             ++(*this);
356             return tmp;
357         }
358 
359         const_iterator& operator--()
360         {
361             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) {
362                 LOGF_ABORT("Dereferencing invalid iterator");
363             }
364             --inner_iter;
365             if (inner_iter != get_cend()) {
366                 node.add(&inner_iter->second.iterator_head);
367             } else {
368                 node.add(&container_->end_iterator_head);
369             }
370             return *this;
371         }
372 
373         const_iterator operator--(int)
374         {
375             const_iterator tmp = *this;
376             --(*this);
377             return tmp;
378         }
379 
380         bool operator==(const const_iterator& other) const
381         {
382             if (!container_ || !other.container_) {
383                 return false;
384             }
385             return inner_iter == other.inner_iter;
386         }
387 
388         bool operator!=(const const_iterator& other) const
389         {
390             return !(*this == other);
391         }
392     };
393 
394     class reverse_iterator {
395     private:
396         using MapIter = typename std::map<Key, TrackedElement>::reverse_iterator;
397         SafeMap* container_ = nullptr;
398         MapIter inner_iter;
399         list_head node;
400         friend SafeMap;
get_rend()401         MapIter get_rend() const
402         {
403             return container_ ? container_->elements.rend() : MapIter {};
404         }
405 
406         explicit reverse_iterator(SafeMap* container, MapIter it = MapIter {})
container_(container)407             : container_(container), inner_iter(it),
408               node(container_
409                        ? (inner_iter != get_rend() ? &inner_iter->second.iterator_head : &container_->end_iterator_head)
410                        : nullptr)
411         {}
412 
413     public:
414         using iterator_category = std::bidirectional_iterator_tag;
415         using difference_type = std::ptrdiff_t;
416 
reverse_iterator()417         reverse_iterator() : container_(nullptr), inner_iter(), node() {}
418 
reverse_iterator(const reverse_iterator & other)419         reverse_iterator(const reverse_iterator& other) : container_(other.container_), inner_iter(other.inner_iter)
420         {
421             if (container_) {
422                 if (inner_iter != get_rend()) {
423                     node.add(&inner_iter->second.iterator_head);
424                 } else {
425                     node.add(&container_->end_iterator_head);
426                 }
427             }
428         }
429 
430         reverse_iterator& operator=(const reverse_iterator& other)
431         {
432             if (this != &other) {
433                 container_ = other.container_;
434                 inner_iter = other.inner_iter;
435                 if (container_) {
436                     if (inner_iter != get_rend()) {
437                         node.add(&inner_iter->second.iterator_head);
438                     } else {
439                         node.add(&container_->end_iterator_head);
440                     }
441                 }
442             }
443             return *this;
444         }
445 
446         value_type& operator*() const
447         {
448             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
449                              (!container_ || inner_iter == get_rend()))) {
450                 LOGF_ABORT("Dereferencing invalid reverse iterator");
451             }
452             return *reinterpret_cast<value_type*>(&*inner_iter);
453         }
454 
455         value_type* operator->() const
456         {
457             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
458                              (!container_ || inner_iter == get_rend()))) {
459                 LOGF_ABORT("Dereferencing invalid reverse iterator");
460             }
461             return reinterpret_cast<value_type*>(&*inner_iter);
462         }
463 
464         reverse_iterator& operator++()
465         {
466             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) {
467                 LOGF_ABORT("Incrementing invalid reverse iterator");
468             }
469             ++inner_iter;
470             if (inner_iter != get_rend()) {
471                 node.add(&inner_iter->second.iterator_head);
472             } else {
473                 node.add(&container_->end_iterator_head);
474             }
475             return *this;
476         }
477 
478         reverse_iterator operator++(int)
479         {
480             reverse_iterator tmp = *this;
481             ++(*this);
482             return tmp;
483         }
484 
485         reverse_iterator& operator--()
486         {
487             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) {
488                 LOGF_ABORT("Decrementing invalid iterator");
489             }
490             --inner_iter;
491             if (inner_iter != get_rend()) {
492                 node.add(&inner_iter->second.iterator_head);
493             } else {
494                 node.add(&container_->end_iterator_head);
495             }
496             return *this;
497         }
498 
499         reverse_iterator operator--(int)
500         {
501             reverse_iterator tmp = *this;
502             --(*this);
503             return tmp;
504         }
505 
506         bool operator==(const reverse_iterator& other) const
507         {
508             return inner_iter == other.inner_iter;
509         }
510 
511         bool operator!=(const reverse_iterator& other) const
512         {
513             return !(*this == other);
514         }
515     };
516 
517     class const_reverse_iterator {
518     private:
519         using MapIter = typename std::map<Key, TrackedElement>::const_reverse_iterator;
520         const SafeMap* container_ = nullptr;
521         MapIter inner_iter;
522         list_head node;
523         friend SafeMap;
get_crend()524         MapIter get_crend() const
525         {
526             return container_ ? container_->elements.crend() : MapIter {};
527         }
528 
529         explicit const_reverse_iterator(const SafeMap* container, MapIter it = MapIter {})
container_(container)530             : container_(container), inner_iter(it),
531               node(container_ ? (inner_iter != get_crend() ? &inner_iter->second.iterator_head
532                                                            : &container_->end_iterator_head)
533                               : nullptr)
534         {}
535 
536     public:
537         using iterator_category = std::bidirectional_iterator_tag;
538         using difference_type = std::ptrdiff_t;
539 
const_reverse_iterator()540         const_reverse_iterator() : container_(nullptr), inner_iter(), node() {}
541 
const_reverse_iterator(const reverse_iterator & other)542         const_reverse_iterator(const reverse_iterator& other)
543             : container_(other.container_), inner_iter(other.inner_iter)
544         {
545             if (container_) {
546                 if (inner_iter != get_crend()) {
547                     node.add(&inner_iter->second.iterator_head);
548                 } else {
549                     node.add(&container_->end_iterator_head);
550                 }
551             }
552         }
553 
const_reverse_iterator(const const_reverse_iterator & other)554         const_reverse_iterator(const const_reverse_iterator& other)
555             : container_(other.container_), inner_iter(other.inner_iter)
556         {
557             if (container_) {
558                 if (inner_iter != get_crend()) {
559                     node.add(&inner_iter->second.iterator_head);
560                 } else {
561                     node.add(&container_->end_iterator_head);
562                 }
563             }
564         }
565 
566         const_reverse_iterator& operator=(const const_reverse_iterator& other)
567         {
568             if (this != &other) {
569                 container_ = other.container_;
570                 inner_iter = other.inner_iter;
571                 if (container_) {
572                     if (inner_iter != get_crend()) {
573                         node.add(&inner_iter->second.iterator_head);
574                     } else {
575                         node.add(&container_->end_iterator_head);
576                     }
577                 }
578             }
579             return *this;
580         }
581 
582         const value_type& operator*() const
583         {
584             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
585                              (!container_ || inner_iter == get_crend()))) {
586                 LOGF_ABORT("Dereferencing invalid const_reverse iterator");
587             }
588             return *reinterpret_cast<const value_type*>(&*inner_iter);
589         }
590 
591         const value_type* operator->() const
592         {
593             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
594                              (!container_ || inner_iter == get_crend()))) {
595                 LOGF_ABORT("Dereferencing invalid const_reverse iterator");
596             }
597             return reinterpret_cast<const value_type*>(&*inner_iter);
598         }
599 
600         const_reverse_iterator& operator++()
601         {
602             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) {
603                 LOGF_ABORT("Incrementing invalid const_reverse iterator");
604             }
605             ++inner_iter;
606             if (inner_iter != get_crend()) {
607                 node.add(&inner_iter->second.iterator_head);
608             } else {
609                 node.add(&container_->end_iterator_head);
610             }
611             return *this;
612         }
613 
614         const_reverse_iterator operator++(int)
615         {
616             const_reverse_iterator tmp = *this;
617             ++(*this);
618             return tmp;
619         }
620 
621         const_reverse_iterator& operator--()
622         {
623             if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) {
624                 LOGF_ABORT("Decrementing invalid const_reverse iterator");
625             }
626             --inner_iter;
627             if (inner_iter != get_crend()) {
628                 node.add(&inner_iter->second.iterator_head);
629             } else {
630                 node.add(&container_->end_iterator_head);
631             }
632             return *this;
633         }
634 
635         const_reverse_iterator operator--(int)
636         {
637             const_reverse_iterator tmp = *this;
638             --(*this);
639             return tmp;
640         }
641 
642         bool operator==(const const_reverse_iterator& other) const
643         {
644             return inner_iter == other.inner_iter;
645         }
646 
647         bool operator!=(const const_reverse_iterator& other) const
648         {
649             return !(*this == other);
650         }
651     };
652 
653     SafeMap() = default;
654 
SafeMap(std::initializer_list<std::pair<const Key,T>> ilist)655     SafeMap(std::initializer_list<std::pair<const Key, T>> ilist)
656     {
657         for (const auto& val : ilist) {
658             elements.emplace(val.first, val.second);
659         }
660     }
SafeMap(const SafeMap & other)661     SafeMap(const SafeMap& other) : elements(other.elements) {}
662 
SafeMap(SafeMap && other)663     SafeMap(SafeMap&& other) noexcept
664     {
665         elements = std::move(other.elements);
666     }
~SafeMap()667     ~SafeMap()
668     {
669         invalidate_end_iterators();
670     }
671 
insert(const value_type & value)672     std::pair<iterator, bool> insert(const value_type& value)
673     {
674         auto [it, inserted] = elements.insert(value);
675         return { iterator(this, it), inserted };
676     }
677 
insert(value_type && value)678     std::pair<iterator, bool> insert(value_type&& value)
679     {
680         auto [it, inserted] = elements.insert(std::forward<value_type>(value));
681         return { iterator(this, it), inserted };
682     }
683 
684     template<class P>
insert(P && value)685     std::pair<iterator, bool> insert(P&& value)
686     {
687         auto [it, inserted] = elements.insert(std::forward<P>(value));
688         return { iterator(this, it), inserted };
689     }
690 
insert(const_iterator pos,const value_type & value)691     iterator insert(const_iterator pos, const value_type& value)
692     {
693         if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) {
694             LOGF_ABORT("Inserting with invalid iterator");
695         }
696         return iterator(this, elements.insert(pos.inner_iter, value));
697     }
698 
insert(const_iterator pos,value_type && value)699     iterator insert(const_iterator pos, value_type&& value)
700     {
701         if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) {
702             LOGF_ABORT("Inserting with invalid iterator");
703         }
704         return iterator(this, elements.insert(pos.inner_iter, std::forward<value_type>(value)));
705     }
706 
707     template<class P>
insert(const_iterator pos,P && value)708     iterator insert(const_iterator pos, P&& value)
709     {
710         if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) {
711             LOGF_ABORT("Inserting with invalid iterator");
712         }
713         return iterator(this, elements.insert(pos.inner_iter, std::forward<P>(value)));
714     }
715 
716     template<class InputIt>
insert(InputIt first,InputIt last)717     void insert(InputIt first, InputIt last)
718     {
719         elements.insert(first, last);
720     }
721 
insert(std::initializer_list<value_type> ilist)722     void insert(std::initializer_list<value_type> ilist)
723     {
724         elements.insert(ilist.begin(), ilist.end());
725     }
726 
727     template<class... Args>
emplace(Args &&...args)728     std::pair<iterator, bool> emplace(Args&&... args)
729     {
730         auto [it, inserted] = elements.emplace(std::forward<Args>(args)...);
731         return { iterator(this, it), inserted };
732     }
733 
734     template<typename M>
insert_or_assign(const Key & k,M && obj)735     std::pair<iterator, bool> insert_or_assign(const Key& k, M&& obj)
736     {
737         auto [it, inserted] = elements.insert_or_assign(k, std::forward<M>(obj));
738         return { iterator(this, it), inserted };
739     }
740     template<class M>
insert_or_assign(Key && k,M && obj)741     std::pair<iterator, bool> insert_or_assign(Key&& k, M&& obj)
742     {
743         auto [it, inserted] = elements.insert_or_assign(std::forward<Key>(k), std::forward<M>(obj));
744         return { iterator(this, it), inserted };
745     }
746     template<class M>
insert_or_assign(const_iterator hint,const Key & k,M && obj)747     iterator insert_or_assign(const_iterator hint, const Key& k, M&& obj)
748     {
749         return iterator(this, elements.insert_or_assign(hint.inner_iter, k, std::forward<M>(obj)));
750     }
751     template<class M>
insert_or_assign(const_iterator hint,Key && k,M && obj)752     iterator insert_or_assign(const_iterator hint, Key&& k, M&& obj)
753     {
754         return iterator(this, elements.insert_or_assign(hint.inner_iter, std::forward<Key>(k), std::forward<M>(obj)));
755     }
756 
757     template<typename... Args>
emplace_hint(const_iterator hint,Args &&...args)758     iterator emplace_hint(const_iterator hint, Args&&... args)
759     {
760         return iterator(this, elements.emplace_hint(hint.inner_iter, std::forward<Args>(args)...));
761     }
762 
763     template<typename... Args>
try_emplace(const Key & k,Args &&...args)764     std::pair<iterator, bool> try_emplace(const Key& k, Args&&... args)
765     {
766         auto [it, inserted] = elements.try_emplace(k, std::forward<Args>(args)...);
767         return { iterator(this, it), inserted };
768     }
769     template<class... Args>
try_emplace(Key && k,Args &&...args)770     std::pair<iterator, bool> try_emplace(Key&& k, Args&&... args)
771     {
772         auto [it, inserted] = elements.try_emplace(std::forward<Key>(k), std::forward<Args>(args)...);
773         return { iterator(this, it), inserted };
774     }
775     template<class... Args>
try_emplace(const_iterator hint,Key && k,Args &&...args)776     iterator try_emplace(const_iterator hint, Key&& k, Args&&... args)
777     {
778         auto result = elements.try_emplace(hint.inner_iter, std::forward<Key>(k), std::forward<Args>(args)...);
779         return iterator(this, result);
780     }
781     template<class... Args>
try_emplace(const_iterator hint,const Key & k,Args &&...args)782     iterator try_emplace(const_iterator hint, const Key& k, Args&&... args)
783     {
784         auto result = elements.try_emplace(hint.inner_iter, k, std::forward<Args>(args)...);
785         return iterator(this, result);
786     }
787 
swap(SafeMap & other)788     void swap(SafeMap& other) noexcept
789     {
790         elements.swap(other.elements);
791     }
792 
extract(const_iterator pos)793     auto extract(const_iterator pos)
794     {
795         if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
796                          (!pos.container_ || pos.inner_iter == elements.end()))) {
797             LOGF_ABORT("extract with invalid iterator");
798         }
799         auto node = elements.extract(pos.inner_iter);
800         if (!node.empty()) {
801             node.mapped().invalidate_iterators();
802         }
803         return node;
804     }
extract(const Key & k)805     auto extract(const Key& k)
806     {
807         auto node = elements.extract(k);
808         if (!node.empty()) {
809             node.mapped().invalidate_iterators();
810         }
811         return node;
812     }
813 
merge(SafeMap & other)814     void merge(SafeMap& other)
815     {
816         elements.merge(other.elements);
817     }
818 
count(const Key & k)819     size_t count(const Key& k) const
820     {
821         return elements.count(k);
822     }
823 
equal_range(const Key & k)824     std::pair<iterator, iterator> equal_range(const Key& k)
825     {
826         auto [first, last] = elements.equal_range(k);
827         return { iterator(this, first), iterator(this, last) };
828     }
829 
lower_bound(const Key & k)830     iterator lower_bound(const Key& k)
831     {
832         return iterator(this, elements.lower_bound(k));
833     }
834 
lower_bound(const Key & k)835     const_iterator lower_bound(const Key& k) const
836     {
837         return const_iterator(this, elements.lower_bound(k));
838     }
839 
upper_bound(const Key & k)840     iterator upper_bound(const Key& k)
841     {
842         return iterator(this, elements.upper_bound(k));
843     }
844 
upper_bound(const Key & k)845     const_iterator upper_bound(const Key& k) const
846     {
847         return const_iterator(this, elements.upper_bound(k));
848     }
849 
key_comp()850     typename std::map<Key, TrackedElement>::key_compare key_comp() const
851     {
852         return elements.key_comp();
853     }
854 
value_comp()855     typename std::map<Key, TrackedElement>::value_compare value_comp() const
856     {
857         return elements.value_comp();
858     }
859 
get_allocator()860     decltype(auto) get_allocator() const noexcept
861     {
862         return elements.get_allocator();
863     }
864 
865     T& operator[](const Key& key)
866     {
867         return elements[key].value;
868     }
869 
870     T& operator[](Key&& key)
871     {
872         return elements[key].value;
873     }
at(const Key & k)874     T& at(const Key& k)
875     {
876         if (elements.find(k) == elements.end()) {
877             LOGF_ABORT("SafeMap::at: key not found");
878         }
879         return elements.at(k).value;
880     }
881 
at(const Key & k)882     const T& at(const Key& k) const
883     {
884         if (elements.find(k) == elements.end()) {
885             LOGF_ABORT("SafeMap::at: key not found");
886         }
887         return elements.at(k).value;
888     }
889 
erase(iterator pos)890     iterator erase(iterator pos)
891     {
892         if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
893                          (!pos.container_ || pos.inner_iter == elements.end()))) {
894             LOGF_ABORT("Erasing with invalid iterator");
895         }
896         return iterator(this, elements.erase(pos.inner_iter));
897     }
898 
erase(const_iterator pos)899     iterator erase(const_iterator pos)
900     {
901         if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
902                          (!pos.container_ || pos.inner_iter == elements.end()))) {
903             LOGF_ABORT("Erasing with invalid iterator");
904         }
905         return iterator(this, elements.erase(pos.inner_iter));
906     }
907 
erase(const_iterator first,const_iterator last)908     iterator erase(const_iterator first, const_iterator last)
909     {
910         if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() &&
911                          (!first.container_ || !last.container_ || first.inner_iter == elements.end()))) {
912             LOGF_ABORT("Erasing with invalid iterator");
913         }
914         return iterator(this, elements.erase(first.inner_iter, last.inner_iter));
915     }
916 
erase(Key key)917     size_t erase(Key key)
918     {
919         return elements.erase(key);
920     }
921 
find(const Key & key)922     iterator find(const Key& key)
923     {
924         return iterator(this, elements.find(key));
925     }
926 
find(const Key & key)927     const_iterator find(const Key& key) const
928     {
929         return const_iterator(this, elements.find(key));
930     }
931 
932     template<typename K>
find(const K & x)933     iterator find(const K& x)
934     {
935         return iterator(this, elements.find(x));
936     }
937 
938     template<typename K>
find(const K & x)939     const_iterator find(const K& x) const
940     {
941         return const_iterator(this, elements.find(x));
942     }
943 
size()944     size_t size() const
945     {
946         return elements.size();
947     }
948 
empty()949     bool empty() const
950     {
951         return elements.empty();
952     }
953 
max_size()954     int max_size() const
955     {
956         return elements.max_size();
957     }
958 
clear()959     void clear()
960     {
961         elements.clear();
962     }
963 
begin()964     iterator begin()
965     {
966         return iterator(this, elements.begin());
967     }
begin()968     const_iterator begin() const
969     {
970         return const_iterator(this, elements.begin());
971     }
end()972     iterator end()
973     {
974         return iterator(this, elements.end());
975     }
end()976     const_iterator end() const
977     {
978         return const_iterator(this, elements.end());
979     }
cbegin()980     const_iterator cbegin() const
981     {
982         return const_iterator(this, elements.begin());
983     }
cend()984     const_iterator cend()
985     {
986         return const_iterator(this, elements.end());
987     }
rbegin()988     reverse_iterator rbegin()
989     {
990         return reverse_iterator(this, elements.rbegin());
991     }
rend()992     reverse_iterator rend()
993     {
994         return reverse_iterator(this, elements.rend());
995     }
rbegin()996     const_reverse_iterator rbegin() const
997     {
998         return crbegin();
999     }
rend()1000     const_reverse_iterator rend() const
1001     {
1002         return crend();
1003     }
crbegin()1004     const_reverse_iterator crbegin() const
1005     {
1006         return const_reverse_iterator(this, elements.crbegin());
1007     }
crend()1008     const_reverse_iterator crend() const
1009     {
1010         return const_reverse_iterator(this, elements.crend());
1011     }
1012 };
1013 
1014 } // namespace OHOS::Ace
1015 
1016 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_CONTAINER_MAP_H