xref: /aosp_15_r20/external/libchrome/base/value_iterators.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_VALUE_ITERATORS_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_VALUE_ITERATORS_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <memory>
9*635a8641SAndroid Build Coastguard Worker #include <string>
10*635a8641SAndroid Build Coastguard Worker #include <utility>
11*635a8641SAndroid Build Coastguard Worker 
12*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/containers/flat_map.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
15*635a8641SAndroid Build Coastguard Worker 
16*635a8641SAndroid Build Coastguard Worker namespace base {
17*635a8641SAndroid Build Coastguard Worker 
18*635a8641SAndroid Build Coastguard Worker class Value;
19*635a8641SAndroid Build Coastguard Worker 
20*635a8641SAndroid Build Coastguard Worker namespace detail {
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker using DictStorage = base::flat_map<std::string, std::unique_ptr<Value>>;
23*635a8641SAndroid Build Coastguard Worker 
24*635a8641SAndroid Build Coastguard Worker // This iterator closely resembles DictStorage::iterator, with one
25*635a8641SAndroid Build Coastguard Worker // important exception. It abstracts the underlying unique_ptr away, meaning its
26*635a8641SAndroid Build Coastguard Worker // value_type is std::pair<const std::string, Value>. It's reference type is a
27*635a8641SAndroid Build Coastguard Worker // std::pair<const std::string&, Value&>, so that callers have read-write
28*635a8641SAndroid Build Coastguard Worker // access without incurring a copy.
29*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT dict_iterator {
30*635a8641SAndroid Build Coastguard Worker  public:
31*635a8641SAndroid Build Coastguard Worker   using difference_type = DictStorage::iterator::difference_type;
32*635a8641SAndroid Build Coastguard Worker   using value_type = std::pair<const std::string, Value>;
33*635a8641SAndroid Build Coastguard Worker   using reference = std::pair<const std::string&, Value&>;
34*635a8641SAndroid Build Coastguard Worker   using iterator_category = std::bidirectional_iterator_tag;
35*635a8641SAndroid Build Coastguard Worker 
36*635a8641SAndroid Build Coastguard Worker   class pointer {
37*635a8641SAndroid Build Coastguard Worker    public:
38*635a8641SAndroid Build Coastguard Worker     explicit pointer(const reference& ref);
39*635a8641SAndroid Build Coastguard Worker     pointer(const pointer& ptr);
40*635a8641SAndroid Build Coastguard Worker     pointer& operator=(const pointer& ptr) = delete;
41*635a8641SAndroid Build Coastguard Worker 
42*635a8641SAndroid Build Coastguard Worker     reference* operator->() { return &ref_; }
43*635a8641SAndroid Build Coastguard Worker 
44*635a8641SAndroid Build Coastguard Worker    private:
45*635a8641SAndroid Build Coastguard Worker     reference ref_;
46*635a8641SAndroid Build Coastguard Worker   };
47*635a8641SAndroid Build Coastguard Worker 
48*635a8641SAndroid Build Coastguard Worker   explicit dict_iterator(DictStorage::iterator dict_iter);
49*635a8641SAndroid Build Coastguard Worker   dict_iterator(const dict_iterator& dict_iter);
50*635a8641SAndroid Build Coastguard Worker   dict_iterator& operator=(const dict_iterator& dict_iter);
51*635a8641SAndroid Build Coastguard Worker   ~dict_iterator();
52*635a8641SAndroid Build Coastguard Worker 
53*635a8641SAndroid Build Coastguard Worker   reference operator*();
54*635a8641SAndroid Build Coastguard Worker   pointer operator->();
55*635a8641SAndroid Build Coastguard Worker 
56*635a8641SAndroid Build Coastguard Worker   dict_iterator& operator++();
57*635a8641SAndroid Build Coastguard Worker   dict_iterator operator++(int);
58*635a8641SAndroid Build Coastguard Worker   dict_iterator& operator--();
59*635a8641SAndroid Build Coastguard Worker   dict_iterator operator--(int);
60*635a8641SAndroid Build Coastguard Worker 
61*635a8641SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator==(const dict_iterator& lhs,
62*635a8641SAndroid Build Coastguard Worker                                      const dict_iterator& rhs);
63*635a8641SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator!=(const dict_iterator& lhs,
64*635a8641SAndroid Build Coastguard Worker                                      const dict_iterator& rhs);
65*635a8641SAndroid Build Coastguard Worker 
66*635a8641SAndroid Build Coastguard Worker  private:
67*635a8641SAndroid Build Coastguard Worker   DictStorage::iterator dict_iter_;
68*635a8641SAndroid Build Coastguard Worker };
69*635a8641SAndroid Build Coastguard Worker 
70*635a8641SAndroid Build Coastguard Worker // This iterator closely resembles DictStorage::const_iterator, with one
71*635a8641SAndroid Build Coastguard Worker // important exception. It abstracts the underlying unique_ptr away, meaning its
72*635a8641SAndroid Build Coastguard Worker // value_type is std::pair<const std::string, Value>. It's reference type is a
73*635a8641SAndroid Build Coastguard Worker // std::pair<const std::string&, const Value&>, so that callers have read-only
74*635a8641SAndroid Build Coastguard Worker // access without incurring a copy.
75*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT const_dict_iterator {
76*635a8641SAndroid Build Coastguard Worker  public:
77*635a8641SAndroid Build Coastguard Worker   using difference_type = DictStorage::const_iterator::difference_type;
78*635a8641SAndroid Build Coastguard Worker   using value_type = std::pair<const std::string, Value>;
79*635a8641SAndroid Build Coastguard Worker   using reference = std::pair<const std::string&, const Value&>;
80*635a8641SAndroid Build Coastguard Worker   using iterator_category = std::bidirectional_iterator_tag;
81*635a8641SAndroid Build Coastguard Worker 
82*635a8641SAndroid Build Coastguard Worker   class pointer {
83*635a8641SAndroid Build Coastguard Worker    public:
84*635a8641SAndroid Build Coastguard Worker     explicit pointer(const reference& ref);
85*635a8641SAndroid Build Coastguard Worker     pointer(const pointer& ptr);
86*635a8641SAndroid Build Coastguard Worker     pointer& operator=(const pointer& ptr) = delete;
87*635a8641SAndroid Build Coastguard Worker 
88*635a8641SAndroid Build Coastguard Worker     const reference* operator->() const { return &ref_; }
89*635a8641SAndroid Build Coastguard Worker 
90*635a8641SAndroid Build Coastguard Worker    private:
91*635a8641SAndroid Build Coastguard Worker     const reference ref_;
92*635a8641SAndroid Build Coastguard Worker   };
93*635a8641SAndroid Build Coastguard Worker 
94*635a8641SAndroid Build Coastguard Worker   explicit const_dict_iterator(DictStorage::const_iterator dict_iter);
95*635a8641SAndroid Build Coastguard Worker   const_dict_iterator(const const_dict_iterator& dict_iter);
96*635a8641SAndroid Build Coastguard Worker   const_dict_iterator& operator=(const const_dict_iterator& dict_iter);
97*635a8641SAndroid Build Coastguard Worker   ~const_dict_iterator();
98*635a8641SAndroid Build Coastguard Worker 
99*635a8641SAndroid Build Coastguard Worker   reference operator*() const;
100*635a8641SAndroid Build Coastguard Worker   pointer operator->() const;
101*635a8641SAndroid Build Coastguard Worker 
102*635a8641SAndroid Build Coastguard Worker   const_dict_iterator& operator++();
103*635a8641SAndroid Build Coastguard Worker   const_dict_iterator operator++(int);
104*635a8641SAndroid Build Coastguard Worker   const_dict_iterator& operator--();
105*635a8641SAndroid Build Coastguard Worker   const_dict_iterator operator--(int);
106*635a8641SAndroid Build Coastguard Worker 
107*635a8641SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator==(const const_dict_iterator& lhs,
108*635a8641SAndroid Build Coastguard Worker                                      const const_dict_iterator& rhs);
109*635a8641SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator!=(const const_dict_iterator& lhs,
110*635a8641SAndroid Build Coastguard Worker                                      const const_dict_iterator& rhs);
111*635a8641SAndroid Build Coastguard Worker 
112*635a8641SAndroid Build Coastguard Worker  private:
113*635a8641SAndroid Build Coastguard Worker   DictStorage::const_iterator dict_iter_;
114*635a8641SAndroid Build Coastguard Worker };
115*635a8641SAndroid Build Coastguard Worker 
116*635a8641SAndroid Build Coastguard Worker // This class wraps the various |begin| and |end| methods of the underlying
117*635a8641SAndroid Build Coastguard Worker // DictStorage in dict_iterators and const_dict_iterators. This allows callers
118*635a8641SAndroid Build Coastguard Worker // to use this class for easy iteration over the underlying values, granting
119*635a8641SAndroid Build Coastguard Worker // them either read-only or read-write access, depending on the
120*635a8641SAndroid Build Coastguard Worker // const-qualification.
121*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT dict_iterator_proxy {
122*635a8641SAndroid Build Coastguard Worker  public:
123*635a8641SAndroid Build Coastguard Worker   using key_type = DictStorage::key_type;
124*635a8641SAndroid Build Coastguard Worker   using mapped_type = DictStorage::mapped_type::element_type;
125*635a8641SAndroid Build Coastguard Worker   using value_type = std::pair<key_type, mapped_type>;
126*635a8641SAndroid Build Coastguard Worker   using key_compare = DictStorage::key_compare;
127*635a8641SAndroid Build Coastguard Worker   using size_type = DictStorage::size_type;
128*635a8641SAndroid Build Coastguard Worker   using difference_type = DictStorage::difference_type;
129*635a8641SAndroid Build Coastguard Worker 
130*635a8641SAndroid Build Coastguard Worker   using iterator = dict_iterator;
131*635a8641SAndroid Build Coastguard Worker   using const_iterator = const_dict_iterator;
132*635a8641SAndroid Build Coastguard Worker   using reverse_iterator = std::reverse_iterator<iterator>;
133*635a8641SAndroid Build Coastguard Worker   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
134*635a8641SAndroid Build Coastguard Worker 
135*635a8641SAndroid Build Coastguard Worker   explicit dict_iterator_proxy(DictStorage* storage);
136*635a8641SAndroid Build Coastguard Worker 
137*635a8641SAndroid Build Coastguard Worker   iterator begin();
138*635a8641SAndroid Build Coastguard Worker   const_iterator begin() const;
139*635a8641SAndroid Build Coastguard Worker   iterator end();
140*635a8641SAndroid Build Coastguard Worker   const_iterator end() const;
141*635a8641SAndroid Build Coastguard Worker 
142*635a8641SAndroid Build Coastguard Worker   reverse_iterator rbegin();
143*635a8641SAndroid Build Coastguard Worker   const_reverse_iterator rbegin() const;
144*635a8641SAndroid Build Coastguard Worker   reverse_iterator rend();
145*635a8641SAndroid Build Coastguard Worker   const_reverse_iterator rend() const;
146*635a8641SAndroid Build Coastguard Worker 
147*635a8641SAndroid Build Coastguard Worker   const_dict_iterator cbegin() const;
148*635a8641SAndroid Build Coastguard Worker   const_dict_iterator cend() const;
149*635a8641SAndroid Build Coastguard Worker   const_reverse_iterator crbegin() const;
150*635a8641SAndroid Build Coastguard Worker   const_reverse_iterator crend() const;
151*635a8641SAndroid Build Coastguard Worker 
152*635a8641SAndroid Build Coastguard Worker  private:
153*635a8641SAndroid Build Coastguard Worker   DictStorage* storage_;
154*635a8641SAndroid Build Coastguard Worker };
155*635a8641SAndroid Build Coastguard Worker 
156*635a8641SAndroid Build Coastguard Worker // This class wraps the various const |begin| and |end| methods of the
157*635a8641SAndroid Build Coastguard Worker // underlying DictStorage in const_dict_iterators. This allows callers to use
158*635a8641SAndroid Build Coastguard Worker // this class for easy iteration over the underlying values, granting them
159*635a8641SAndroid Build Coastguard Worker // either read-only access.
160*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT const_dict_iterator_proxy {
161*635a8641SAndroid Build Coastguard Worker  public:
162*635a8641SAndroid Build Coastguard Worker   using key_type = const DictStorage::key_type;
163*635a8641SAndroid Build Coastguard Worker   using mapped_type = const DictStorage::mapped_type::element_type;
164*635a8641SAndroid Build Coastguard Worker   using value_type = std::pair<key_type, mapped_type>;
165*635a8641SAndroid Build Coastguard Worker   using key_compare = DictStorage::key_compare;
166*635a8641SAndroid Build Coastguard Worker   using size_type = DictStorage::size_type;
167*635a8641SAndroid Build Coastguard Worker   using difference_type = DictStorage::difference_type;
168*635a8641SAndroid Build Coastguard Worker 
169*635a8641SAndroid Build Coastguard Worker   using iterator = const_dict_iterator;
170*635a8641SAndroid Build Coastguard Worker   using const_iterator = const_dict_iterator;
171*635a8641SAndroid Build Coastguard Worker   using reverse_iterator = std::reverse_iterator<iterator>;
172*635a8641SAndroid Build Coastguard Worker   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
173*635a8641SAndroid Build Coastguard Worker 
174*635a8641SAndroid Build Coastguard Worker   explicit const_dict_iterator_proxy(const DictStorage* storage);
175*635a8641SAndroid Build Coastguard Worker 
176*635a8641SAndroid Build Coastguard Worker   const_iterator begin() const;
177*635a8641SAndroid Build Coastguard Worker   const_iterator end() const;
178*635a8641SAndroid Build Coastguard Worker 
179*635a8641SAndroid Build Coastguard Worker   const_reverse_iterator rbegin() const;
180*635a8641SAndroid Build Coastguard Worker   const_reverse_iterator rend() const;
181*635a8641SAndroid Build Coastguard Worker 
182*635a8641SAndroid Build Coastguard Worker   const_iterator cbegin() const;
183*635a8641SAndroid Build Coastguard Worker   const_iterator cend() const;
184*635a8641SAndroid Build Coastguard Worker   const_reverse_iterator crbegin() const;
185*635a8641SAndroid Build Coastguard Worker   const_reverse_iterator crend() const;
186*635a8641SAndroid Build Coastguard Worker 
187*635a8641SAndroid Build Coastguard Worker  private:
188*635a8641SAndroid Build Coastguard Worker   const DictStorage* storage_;
189*635a8641SAndroid Build Coastguard Worker };
190*635a8641SAndroid Build Coastguard Worker }  // namespace detail
191*635a8641SAndroid Build Coastguard Worker 
192*635a8641SAndroid Build Coastguard Worker }  // namespace base
193*635a8641SAndroid Build Coastguard Worker 
194*635a8641SAndroid Build Coastguard Worker #endif  // BASE_VALUE_ITERATORS_H_
195