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