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