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