blob: adcaebce244175fb2f557f59ad0509fdec291ab9 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2017 The Chromium Authors
jdoerrie44efa9d2017-07-14 14:47:202// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_VALUE_ITERATORS_H_
6#define BASE_VALUE_ITERATORS_H_
7
8#include <memory>
9#include <string>
10#include <utility>
11
12#include "base/base_export.h"
13#include "base/containers/flat_map.h"
Keishi Hattorie175ac52022-06-07 06:24:5714#include "base/memory/raw_ptr.h"
jdoerrie44efa9d2017-07-14 14:47:2015
16namespace base {
17
18class Value;
19
20namespace detail {
21
22using DictStorage = base::flat_map<std::string, std::unique_ptr<Value>>;
23
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.
29class BASE_EXPORT dict_iterator {
30 public:
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;
35
36 class pointer {
37 public:
38 explicit pointer(const reference& ref);
39 pointer(const pointer& ptr);
40 pointer& operator=(const pointer& ptr) = delete;
41
42 reference* operator->() { return &ref_; }
43
44 private:
45 reference ref_;
46 };
47
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);
51 ~dict_iterator();
52
53 reference operator*();
54 pointer operator->();
55
56 dict_iterator& operator++();
57 dict_iterator operator++(int);
58 dict_iterator& operator--();
59 dict_iterator operator--(int);
60
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);
65
Daniel Chenga367fe52022-02-15 18:08:4866 // 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
69 // used instead.
70 const DictStorage::iterator& GetUnderlyingIteratorDoNotUse() {
71 return dict_iter_;
72 }
73
jdoerrie44efa9d2017-07-14 14:47:2074 private:
75 DictStorage::iterator dict_iter_;
76};
77
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.
83class BASE_EXPORT const_dict_iterator {
84 public:
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;
89
90 class pointer {
91 public:
92 explicit pointer(const reference& ref);
93 pointer(const pointer& ptr);
94 pointer& operator=(const pointer& ptr) = delete;
95
96 const reference* operator->() const { return &ref_; }
97
98 private:
99 const reference ref_;
100 };
101
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();
106
107 reference operator*() const;
108 pointer operator->() const;
109
110 const_dict_iterator& operator++();
111 const_dict_iterator operator++(int);
112 const_dict_iterator& operator--();
113 const_dict_iterator operator--(int);
114
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);
119
Daniel Chenga367fe52022-02-15 18:08:48120 // 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
123 // used instead.
124 const DictStorage::const_iterator& GetUnderlyingIteratorDoNotUse() {
125 return dict_iter_;
126 }
127
jdoerrie44efa9d2017-07-14 14:47:20128 private:
129 DictStorage::const_iterator dict_iter_;
130};
131
132// This class wraps the various |begin| and |end| methods of the underlying
133// DictStorage in dict_iterators and const_dict_iterators. This allows callers
134// to use this class for easy iteration over the underlying values, granting
135// them either read-only or read-write access, depending on the
136// const-qualification.
137class BASE_EXPORT dict_iterator_proxy {
138 public:
139 using key_type = DictStorage::key_type;
140 using mapped_type = DictStorage::mapped_type::element_type;
141 using value_type = std::pair<key_type, mapped_type>;
142 using key_compare = DictStorage::key_compare;
143 using size_type = DictStorage::size_type;
144 using difference_type = DictStorage::difference_type;
145
146 using iterator = dict_iterator;
147 using const_iterator = const_dict_iterator;
148 using reverse_iterator = std::reverse_iterator<iterator>;
149 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
150
151 explicit dict_iterator_proxy(DictStorage* storage);
152
Christoph Schweringb96b7052021-11-03 15:04:04153 size_type size() const;
154
jdoerrie44efa9d2017-07-14 14:47:20155 iterator begin();
156 const_iterator begin() const;
157 iterator end();
158 const_iterator end() const;
159
160 reverse_iterator rbegin();
161 const_reverse_iterator rbegin() const;
162 reverse_iterator rend();
163 const_reverse_iterator rend() const;
164
165 const_dict_iterator cbegin() const;
166 const_dict_iterator cend() const;
167 const_reverse_iterator crbegin() const;
168 const_reverse_iterator crend() const;
169
170 private:
Keishi Hattorie175ac52022-06-07 06:24:57171 raw_ptr<DictStorage> storage_;
jdoerrie44efa9d2017-07-14 14:47:20172};
173
174// This class wraps the various const |begin| and |end| methods of the
175// underlying DictStorage in const_dict_iterators. This allows callers to use
176// this class for easy iteration over the underlying values, granting them
177// either read-only access.
178class BASE_EXPORT const_dict_iterator_proxy {
179 public:
180 using key_type = const DictStorage::key_type;
181 using mapped_type = const DictStorage::mapped_type::element_type;
182 using value_type = std::pair<key_type, mapped_type>;
183 using key_compare = DictStorage::key_compare;
184 using size_type = DictStorage::size_type;
185 using difference_type = DictStorage::difference_type;
186
187 using iterator = const_dict_iterator;
188 using const_iterator = const_dict_iterator;
189 using reverse_iterator = std::reverse_iterator<iterator>;
190 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
191
192 explicit const_dict_iterator_proxy(const DictStorage* storage);
193
Christoph Schweringb96b7052021-11-03 15:04:04194 size_type size() const;
195
jdoerrie44efa9d2017-07-14 14:47:20196 const_iterator begin() const;
197 const_iterator end() const;
198
199 const_reverse_iterator rbegin() const;
200 const_reverse_iterator rend() const;
201
202 const_iterator cbegin() const;
203 const_iterator cend() const;
204 const_reverse_iterator crbegin() const;
205 const_reverse_iterator crend() const;
206
207 private:
Keishi Hattorie175ac52022-06-07 06:24:57208 raw_ptr<const DictStorage> storage_;
jdoerrie44efa9d2017-07-14 14:47:20209};
210} // namespace detail
211
212} // namespace base
213
214#endif // BASE_VALUE_ITERATORS_H_