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/base_export.h" 13 #include "base/containers/flat_map.h" 14 #include "base/macros.h" 15 16 namespace base { 17 18 class Value; 19 20 namespace detail { 21 22 using 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. 29 class 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. 75 class 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. 121 class 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. 160 class 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_ 195