// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_VALUE_ITERATORS_H_ #define BASE_VALUE_ITERATORS_H_ #include #include #include #include "base/base_export.h" #include "base/containers/flat_map.h" #include "base/memory/raw_ptr.h" namespace base { class Value; namespace detail { using DictStorage = base::flat_map>; // This iterator closely resembles DictStorage::iterator, with one // important exception. It abstracts the underlying unique_ptr away, meaning its // value_type is std::pair. It's reference type is a // std::pair, so that callers have read-write // access without incurring a copy. class BASE_EXPORT dict_iterator { public: using difference_type = DictStorage::iterator::difference_type; using value_type = std::pair; using reference = std::pair; using iterator_category = std::bidirectional_iterator_tag; class pointer { public: explicit pointer(const reference& ref); pointer(const pointer& ptr); pointer& operator=(const pointer& ptr) = delete; reference* operator->() { return &ref_; } private: reference ref_; }; explicit dict_iterator(DictStorage::iterator dict_iter); dict_iterator(const dict_iterator& dict_iter); dict_iterator& operator=(const dict_iterator& dict_iter); ~dict_iterator(); reference operator*(); pointer operator->(); dict_iterator& operator++(); dict_iterator operator++(int); dict_iterator& operator--(); dict_iterator operator--(int); BASE_EXPORT friend bool operator==(const dict_iterator& lhs, const dict_iterator& rhs); BASE_EXPORT friend bool operator!=(const dict_iterator& lhs, const dict_iterator& rhs); // Currently, there is no easy way to friend Value::Dict. Once dictionary // storage is updated to not require a proxy iterator, the implementation can // be folded into //base/values.h and a standard friend declaration can be // used instead. const DictStorage::iterator& GetUnderlyingIteratorDoNotUse() { return dict_iter_; } private: DictStorage::iterator dict_iter_; }; // This iterator closely resembles DictStorage::const_iterator, with one // important exception. It abstracts the underlying unique_ptr away, meaning its // value_type is std::pair. It's reference type is a // std::pair, so that callers have read-only // access without incurring a copy. class BASE_EXPORT const_dict_iterator { public: using difference_type = DictStorage::const_iterator::difference_type; using value_type = std::pair; using reference = std::pair; using iterator_category = std::bidirectional_iterator_tag; class pointer { public: explicit pointer(const reference& ref); pointer(const pointer& ptr); pointer& operator=(const pointer& ptr) = delete; const reference* operator->() const { return &ref_; } private: const reference ref_; }; explicit const_dict_iterator(DictStorage::const_iterator dict_iter); const_dict_iterator(const const_dict_iterator& dict_iter); const_dict_iterator& operator=(const const_dict_iterator& dict_iter); ~const_dict_iterator(); reference operator*() const; pointer operator->() const; const_dict_iterator& operator++(); const_dict_iterator operator++(int); const_dict_iterator& operator--(); const_dict_iterator operator--(int); BASE_EXPORT friend bool operator==(const const_dict_iterator& lhs, const const_dict_iterator& rhs); BASE_EXPORT friend bool operator!=(const const_dict_iterator& lhs, const const_dict_iterator& rhs); // Currently, there is no easy way to friend Value::Dict. Once dictionary // storage is updated to not require a proxy iterator, the implementation can // be folded into //base/values.h and a standard friend declaration can be // used instead. const DictStorage::const_iterator& GetUnderlyingIteratorDoNotUse() { return dict_iter_; } private: DictStorage::const_iterator dict_iter_; }; } // namespace detail } // namespace base #endif // BASE_VALUE_ITERATORS_H_