1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_VALUE_ITERATORS_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_VALUE_ITERATORS_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <memory> 9*6777b538SAndroid Build Coastguard Worker #include <string> 10*6777b538SAndroid Build Coastguard Worker #include <utility> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/containers/flat_map.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker namespace base { 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker class Value; 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard Worker namespace detail { 21*6777b538SAndroid Build Coastguard Worker 22*6777b538SAndroid Build Coastguard Worker using DictStorage = base::flat_map<std::string, std::unique_ptr<Value>>; 23*6777b538SAndroid Build Coastguard Worker 24*6777b538SAndroid Build Coastguard Worker // This iterator closely resembles DictStorage::iterator, with one 25*6777b538SAndroid Build Coastguard Worker // important exception. It abstracts the underlying unique_ptr away, meaning its 26*6777b538SAndroid Build Coastguard Worker // value_type is std::pair<const std::string, Value>. It's reference type is a 27*6777b538SAndroid Build Coastguard Worker // std::pair<const std::string&, Value&>, so that callers have read-write 28*6777b538SAndroid Build Coastguard Worker // access without incurring a copy. 29*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT dict_iterator { 30*6777b538SAndroid Build Coastguard Worker public: 31*6777b538SAndroid Build Coastguard Worker using difference_type = DictStorage::iterator::difference_type; 32*6777b538SAndroid Build Coastguard Worker using value_type = std::pair<const std::string, Value>; 33*6777b538SAndroid Build Coastguard Worker using reference = std::pair<const std::string&, Value&>; 34*6777b538SAndroid Build Coastguard Worker using iterator_category = std::bidirectional_iterator_tag; 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard Worker class pointer { 37*6777b538SAndroid Build Coastguard Worker public: 38*6777b538SAndroid Build Coastguard Worker explicit pointer(const reference& ref); 39*6777b538SAndroid Build Coastguard Worker pointer(const pointer& ptr); 40*6777b538SAndroid Build Coastguard Worker pointer& operator=(const pointer& ptr) = delete; 41*6777b538SAndroid Build Coastguard Worker 42*6777b538SAndroid Build Coastguard Worker reference* operator->() { return &ref_; } 43*6777b538SAndroid Build Coastguard Worker 44*6777b538SAndroid Build Coastguard Worker private: 45*6777b538SAndroid Build Coastguard Worker reference ref_; 46*6777b538SAndroid Build Coastguard Worker }; 47*6777b538SAndroid Build Coastguard Worker 48*6777b538SAndroid Build Coastguard Worker explicit dict_iterator(DictStorage::iterator dict_iter); 49*6777b538SAndroid Build Coastguard Worker dict_iterator(const dict_iterator& dict_iter); 50*6777b538SAndroid Build Coastguard Worker dict_iterator& operator=(const dict_iterator& dict_iter); 51*6777b538SAndroid Build Coastguard Worker ~dict_iterator(); 52*6777b538SAndroid Build Coastguard Worker 53*6777b538SAndroid Build Coastguard Worker reference operator*(); 54*6777b538SAndroid Build Coastguard Worker pointer operator->(); 55*6777b538SAndroid Build Coastguard Worker 56*6777b538SAndroid Build Coastguard Worker dict_iterator& operator++(); 57*6777b538SAndroid Build Coastguard Worker dict_iterator operator++(int); 58*6777b538SAndroid Build Coastguard Worker dict_iterator& operator--(); 59*6777b538SAndroid Build Coastguard Worker dict_iterator operator--(int); 60*6777b538SAndroid Build Coastguard Worker 61*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator==(const dict_iterator& lhs, 62*6777b538SAndroid Build Coastguard Worker const dict_iterator& rhs); 63*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator!=(const dict_iterator& lhs, 64*6777b538SAndroid Build Coastguard Worker const dict_iterator& rhs); 65*6777b538SAndroid Build Coastguard Worker 66*6777b538SAndroid Build Coastguard Worker // Currently, there is no easy way to friend Value::Dict. Once dictionary 67*6777b538SAndroid Build Coastguard Worker // storage is updated to not require a proxy iterator, the implementation can 68*6777b538SAndroid Build Coastguard Worker // be folded into //base/values.h and a standard friend declaration can be 69*6777b538SAndroid Build Coastguard Worker // used instead. GetUnderlyingIteratorDoNotUse()70*6777b538SAndroid Build Coastguard Worker const DictStorage::iterator& GetUnderlyingIteratorDoNotUse() { 71*6777b538SAndroid Build Coastguard Worker return dict_iter_; 72*6777b538SAndroid Build Coastguard Worker } 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard Worker private: 75*6777b538SAndroid Build Coastguard Worker DictStorage::iterator dict_iter_; 76*6777b538SAndroid Build Coastguard Worker }; 77*6777b538SAndroid Build Coastguard Worker 78*6777b538SAndroid Build Coastguard Worker // This iterator closely resembles DictStorage::const_iterator, with one 79*6777b538SAndroid Build Coastguard Worker // important exception. It abstracts the underlying unique_ptr away, meaning its 80*6777b538SAndroid Build Coastguard Worker // value_type is std::pair<const std::string, Value>. It's reference type is a 81*6777b538SAndroid Build Coastguard Worker // std::pair<const std::string&, const Value&>, so that callers have read-only 82*6777b538SAndroid Build Coastguard Worker // access without incurring a copy. 83*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT const_dict_iterator { 84*6777b538SAndroid Build Coastguard Worker public: 85*6777b538SAndroid Build Coastguard Worker using difference_type = DictStorage::const_iterator::difference_type; 86*6777b538SAndroid Build Coastguard Worker using value_type = std::pair<const std::string, Value>; 87*6777b538SAndroid Build Coastguard Worker using reference = std::pair<const std::string&, const Value&>; 88*6777b538SAndroid Build Coastguard Worker using iterator_category = std::bidirectional_iterator_tag; 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Worker class pointer { 91*6777b538SAndroid Build Coastguard Worker public: 92*6777b538SAndroid Build Coastguard Worker explicit pointer(const reference& ref); 93*6777b538SAndroid Build Coastguard Worker pointer(const pointer& ptr); 94*6777b538SAndroid Build Coastguard Worker pointer& operator=(const pointer& ptr) = delete; 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker const reference* operator->() const { return &ref_; } 97*6777b538SAndroid Build Coastguard Worker 98*6777b538SAndroid Build Coastguard Worker private: 99*6777b538SAndroid Build Coastguard Worker const reference ref_; 100*6777b538SAndroid Build Coastguard Worker }; 101*6777b538SAndroid Build Coastguard Worker 102*6777b538SAndroid Build Coastguard Worker explicit const_dict_iterator(DictStorage::const_iterator dict_iter); 103*6777b538SAndroid Build Coastguard Worker const_dict_iterator(const const_dict_iterator& dict_iter); 104*6777b538SAndroid Build Coastguard Worker const_dict_iterator& operator=(const const_dict_iterator& dict_iter); 105*6777b538SAndroid Build Coastguard Worker ~const_dict_iterator(); 106*6777b538SAndroid Build Coastguard Worker 107*6777b538SAndroid Build Coastguard Worker reference operator*() const; 108*6777b538SAndroid Build Coastguard Worker pointer operator->() const; 109*6777b538SAndroid Build Coastguard Worker 110*6777b538SAndroid Build Coastguard Worker const_dict_iterator& operator++(); 111*6777b538SAndroid Build Coastguard Worker const_dict_iterator operator++(int); 112*6777b538SAndroid Build Coastguard Worker const_dict_iterator& operator--(); 113*6777b538SAndroid Build Coastguard Worker const_dict_iterator operator--(int); 114*6777b538SAndroid Build Coastguard Worker 115*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator==(const const_dict_iterator& lhs, 116*6777b538SAndroid Build Coastguard Worker const const_dict_iterator& rhs); 117*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator!=(const const_dict_iterator& lhs, 118*6777b538SAndroid Build Coastguard Worker const const_dict_iterator& rhs); 119*6777b538SAndroid Build Coastguard Worker 120*6777b538SAndroid Build Coastguard Worker // Currently, there is no easy way to friend Value::Dict. Once dictionary 121*6777b538SAndroid Build Coastguard Worker // storage is updated to not require a proxy iterator, the implementation can 122*6777b538SAndroid Build Coastguard Worker // be folded into //base/values.h and a standard friend declaration can be 123*6777b538SAndroid Build Coastguard Worker // used instead. GetUnderlyingIteratorDoNotUse()124*6777b538SAndroid Build Coastguard Worker const DictStorage::const_iterator& GetUnderlyingIteratorDoNotUse() { 125*6777b538SAndroid Build Coastguard Worker return dict_iter_; 126*6777b538SAndroid Build Coastguard Worker } 127*6777b538SAndroid Build Coastguard Worker 128*6777b538SAndroid Build Coastguard Worker private: 129*6777b538SAndroid Build Coastguard Worker DictStorage::const_iterator dict_iter_; 130*6777b538SAndroid Build Coastguard Worker }; 131*6777b538SAndroid Build Coastguard Worker 132*6777b538SAndroid Build Coastguard Worker } // namespace detail 133*6777b538SAndroid Build Coastguard Worker 134*6777b538SAndroid Build Coastguard Worker } // namespace base 135*6777b538SAndroid Build Coastguard Worker 136*6777b538SAndroid Build Coastguard Worker #endif // BASE_VALUE_ITERATORS_H_ 137