blob: 2e05127bf5eafba950ec01f20e48a8e1471691fb [file] [log] [blame]
jdoerrie44efa9d2017-07-14 14:47:201// Copyright 2017 The Chromium Authors. All rights reserved.
2// 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"
14#include "base/macros.h"
15
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
66 private:
67 DictStorage::iterator dict_iter_;
68};
69
70// This iterator closely resembles DictStorage::const_iterator, with one
71// important exception. It abstracts the underlying unique_ptr away, meaning its
72// value_type is std::pair<const std::string, Value>. It's reference type is a
73// std::pair<const std::string&, const Value&>, so that callers have read-only
74// access without incurring a copy.
75class BASE_EXPORT const_dict_iterator {
76 public:
77 using difference_type = DictStorage::const_iterator::difference_type;
78 using value_type = std::pair<const std::string, Value>;
79 using reference = std::pair<const std::string&, const Value&>;
80 using iterator_category = std::bidirectional_iterator_tag;
81
82 class pointer {
83 public:
84 explicit pointer(const reference& ref);
85 pointer(const pointer& ptr);
86 pointer& operator=(const pointer& ptr) = delete;
87
88 const reference* operator->() const { return &ref_; }
89
90 private:
91 const reference ref_;
92 };
93
94 explicit const_dict_iterator(DictStorage::const_iterator dict_iter);
95 const_dict_iterator(const const_dict_iterator& dict_iter);
96 const_dict_iterator& operator=(const const_dict_iterator& dict_iter);
97 ~const_dict_iterator();
98
99 reference operator*() const;
100 pointer operator->() const;
101
102 const_dict_iterator& operator++();
103 const_dict_iterator operator++(int);
104 const_dict_iterator& operator--();
105 const_dict_iterator operator--(int);
106
107 BASE_EXPORT friend bool operator==(const const_dict_iterator& lhs,
108 const const_dict_iterator& rhs);
109 BASE_EXPORT friend bool operator!=(const const_dict_iterator& lhs,
110 const const_dict_iterator& rhs);
111
112 private:
113 DictStorage::const_iterator dict_iter_;
114};
115
116// This class wraps the various |begin| and |end| methods of the underlying
117// DictStorage in dict_iterators and const_dict_iterators. This allows callers
118// to use this class for easy iteration over the underlying values, granting
119// them either read-only or read-write access, depending on the
120// const-qualification.
121class BASE_EXPORT dict_iterator_proxy {
122 public:
123 using key_type = DictStorage::key_type;
124 using mapped_type = DictStorage::mapped_type::element_type;
125 using value_type = std::pair<key_type, mapped_type>;
126 using key_compare = DictStorage::key_compare;
127 using size_type = DictStorage::size_type;
128 using difference_type = DictStorage::difference_type;
129
130 using iterator = dict_iterator;
131 using const_iterator = const_dict_iterator;
132 using reverse_iterator = std::reverse_iterator<iterator>;
133 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
134
135 explicit dict_iterator_proxy(DictStorage* storage);
136
137 iterator begin();
138 const_iterator begin() const;
139 iterator end();
140 const_iterator end() const;
141
142 reverse_iterator rbegin();
143 const_reverse_iterator rbegin() const;
144 reverse_iterator rend();
145 const_reverse_iterator rend() const;
146
147 const_dict_iterator cbegin() const;
148 const_dict_iterator cend() const;
149 const_reverse_iterator crbegin() const;
150 const_reverse_iterator crend() const;
151
152 private:
153 DictStorage* storage_;
154};
155
156// This class wraps the various const |begin| and |end| methods of the
157// underlying DictStorage in const_dict_iterators. This allows callers to use
158// this class for easy iteration over the underlying values, granting them
159// either read-only access.
160class BASE_EXPORT const_dict_iterator_proxy {
161 public:
162 using key_type = const DictStorage::key_type;
163 using mapped_type = const DictStorage::mapped_type::element_type;
164 using value_type = std::pair<key_type, mapped_type>;
165 using key_compare = DictStorage::key_compare;
166 using size_type = DictStorage::size_type;
167 using difference_type = DictStorage::difference_type;
168
169 using iterator = const_dict_iterator;
170 using const_iterator = const_dict_iterator;
171 using reverse_iterator = std::reverse_iterator<iterator>;
172 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
173
174 explicit const_dict_iterator_proxy(const DictStorage* storage);
175
176 const_iterator begin() const;
177 const_iterator end() const;
178
179 const_reverse_iterator rbegin() const;
180 const_reverse_iterator rend() const;
181
182 const_iterator cbegin() const;
183 const_iterator cend() const;
184 const_reverse_iterator crbegin() const;
185 const_reverse_iterator crend() const;
186
187 private:
188 const DictStorage* storage_;
189};
190} // namespace detail
191
192} // namespace base
193
194#endif // BASE_VALUE_ITERATORS_H_