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