1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef BASE_VALUE_ITERATORS_H_
6 #define BASE_VALUE_ITERATORS_H_
12 #include "base/base_export.h"
13 #include "base/containers/flat_map.h"
14 #include "base/memory/raw_ptr.h"
22 using DictStorage = base::flat_map<std::string, std::unique_ptr<Value>>;
24 // This iterator closely resembles DictStorage::iterator, with one
25 // important exception. It abstracts the underlying unique_ptr away, meaning its
26 // value_type is std::pair<const std::string, Value>. It's reference type is a
27 // std::pair<const std::string&, Value&>, so that callers have read-write
28 // access without incurring a copy.
29 class BASE_EXPORT dict_iterator {
31 using difference_type = DictStorage::iterator::difference_type;
32 using value_type = std::pair<const std::string, Value>;
33 using reference = std::pair<const std::string&, Value&>;
34 using iterator_category = std::bidirectional_iterator_tag;
38 explicit pointer(const reference& ref);
39 pointer(const pointer& ptr);
40 pointer& operator=(const pointer& ptr) = delete;
42 reference* operator->() { return &ref_; }
48 explicit dict_iterator(DictStorage::iterator dict_iter);
49 dict_iterator(const dict_iterator& dict_iter);
50 dict_iterator& operator=(const dict_iterator& dict_iter);
53 reference operator*();
56 dict_iterator& operator++();
57 dict_iterator operator++(int);
58 dict_iterator& operator--();
59 dict_iterator operator--(int);
61 BASE_EXPORT friend bool operator==(const dict_iterator& lhs,
62 const dict_iterator& rhs);
63 BASE_EXPORT friend bool operator!=(const dict_iterator& lhs,
64 const dict_iterator& rhs);
66 // Currently, there is no easy way to friend Value::Dict. Once dictionary
67 // storage is updated to not require a proxy iterator, the implementation can
68 // be folded into //base/values.h and a standard friend declaration can be
70 const DictStorage::iterator& GetUnderlyingIteratorDoNotUse() {
75 DictStorage::iterator dict_iter_;
78 // This iterator closely resembles DictStorage::const_iterator, with one
79 // important exception. It abstracts the underlying unique_ptr away, meaning its
80 // value_type is std::pair<const std::string, Value>. It's reference type is a
81 // std::pair<const std::string&, const Value&>, so that callers have read-only
82 // access without incurring a copy.
83 class BASE_EXPORT const_dict_iterator {
85 using difference_type = DictStorage::const_iterator::difference_type;
86 using value_type = std::pair<const std::string, Value>;
87 using reference = std::pair<const std::string&, const Value&>;
88 using iterator_category = std::bidirectional_iterator_tag;
92 explicit pointer(const reference& ref);
93 pointer(const pointer& ptr);
94 pointer& operator=(const pointer& ptr) = delete;
96 const reference* operator->() const { return &ref_; }
102 explicit const_dict_iterator(DictStorage::const_iterator dict_iter);
103 const_dict_iterator(const const_dict_iterator& dict_iter);
104 const_dict_iterator& operator=(const const_dict_iterator& dict_iter);
105 ~const_dict_iterator();
107 reference operator*() const;
108 pointer operator->() const;
110 const_dict_iterator& operator++();
111 const_dict_iterator operator++(int);
112 const_dict_iterator& operator--();
113 const_dict_iterator operator--(int);
115 BASE_EXPORT friend bool operator==(const const_dict_iterator& lhs,
116 const const_dict_iterator& rhs);
117 BASE_EXPORT friend bool operator!=(const const_dict_iterator& lhs,
118 const const_dict_iterator& rhs);
120 // Currently, there is no easy way to friend Value::Dict. Once dictionary
121 // storage is updated to not require a proxy iterator, the implementation can
122 // be folded into //base/values.h and a standard friend declaration can be
124 const DictStorage::const_iterator& GetUnderlyingIteratorDoNotUse() {
129 DictStorage::const_iterator dict_iter_;
132 } // namespace detail
136 #endif // BASE_VALUE_ITERATORS_H_