| // Copyright 2017 The Chromium Authors. All rights reserved. | |
| // 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 <memory> | |
| #include <string> | |
| #include <utility> | |
| #include "base/containers/flat_map.h" | |
| namespace base { | |
| class Value; | |
| namespace detail { | |
| using DictStorage = base::flat_map<std::string, std::unique_ptr<Value>>; | |
| // This iterator closely resembles DictStorage::iterator, with one | |
| // important exception. It abstracts the underlying unique_ptr away, meaning its | |
| // value_type is std::pair<const std::string, Value>. It's reference type is a | |
| // std::pair<const std::string&, Value&>, so that callers have read-write | |
| // access without incurring a copy. | |
| class dict_iterator { | |
| public: | |
| using difference_type = DictStorage::iterator::difference_type; | |
| using value_type = std::pair<const std::string, Value>; | |
| using reference = std::pair<const std::string&, Value&>; | |
| 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); | |
| friend bool operator==(const dict_iterator& lhs, const dict_iterator& rhs); | |
| friend bool operator!=(const dict_iterator& lhs, const dict_iterator& rhs); | |
| 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<const std::string, Value>. It's reference type is a | |
| // std::pair<const std::string&, const Value&>, so that callers have read-only | |
| // access without incurring a copy. | |
| class const_dict_iterator { | |
| public: | |
| using difference_type = DictStorage::const_iterator::difference_type; | |
| using value_type = std::pair<const std::string, Value>; | |
| using reference = std::pair<const std::string&, const Value&>; | |
| 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); | |
| friend bool operator==(const const_dict_iterator& lhs, | |
| const const_dict_iterator& rhs); | |
| friend bool operator!=(const const_dict_iterator& lhs, | |
| const const_dict_iterator& rhs); | |
| private: | |
| DictStorage::const_iterator dict_iter_; | |
| }; | |
| // This class wraps the various |begin| and |end| methods of the underlying | |
| // DictStorage in dict_iterators and const_dict_iterators. This allows callers | |
| // to use this class for easy iteration over the underlying values, granting | |
| // them either read-only or read-write access, depending on the | |
| // const-qualification. | |
| class dict_iterator_proxy { | |
| public: | |
| using key_type = DictStorage::key_type; | |
| using mapped_type = DictStorage::mapped_type::element_type; | |
| using value_type = std::pair<key_type, mapped_type>; | |
| using key_compare = DictStorage::key_compare; | |
| using size_type = DictStorage::size_type; | |
| using difference_type = DictStorage::difference_type; | |
| using iterator = dict_iterator; | |
| using const_iterator = const_dict_iterator; | |
| using reverse_iterator = std::reverse_iterator<iterator>; | |
| using const_reverse_iterator = std::reverse_iterator<const_iterator>; | |
| explicit dict_iterator_proxy(DictStorage* storage); | |
| iterator begin(); | |
| const_iterator begin() const; | |
| iterator end(); | |
| const_iterator end() const; | |
| reverse_iterator rbegin(); | |
| const_reverse_iterator rbegin() const; | |
| reverse_iterator rend(); | |
| const_reverse_iterator rend() const; | |
| const_dict_iterator cbegin() const; | |
| const_dict_iterator cend() const; | |
| const_reverse_iterator crbegin() const; | |
| const_reverse_iterator crend() const; | |
| private: | |
| DictStorage* storage_; | |
| }; | |
| // This class wraps the various const |begin| and |end| methods of the | |
| // underlying DictStorage in const_dict_iterators. This allows callers to use | |
| // this class for easy iteration over the underlying values, granting them | |
| // either read-only access. | |
| class const_dict_iterator_proxy { | |
| public: | |
| using key_type = const DictStorage::key_type; | |
| using mapped_type = const DictStorage::mapped_type::element_type; | |
| using value_type = std::pair<key_type, mapped_type>; | |
| using key_compare = DictStorage::key_compare; | |
| using size_type = DictStorage::size_type; | |
| using difference_type = DictStorage::difference_type; | |
| using iterator = const_dict_iterator; | |
| using const_iterator = const_dict_iterator; | |
| using reverse_iterator = std::reverse_iterator<iterator>; | |
| using const_reverse_iterator = std::reverse_iterator<const_iterator>; | |
| explicit const_dict_iterator_proxy(const DictStorage* storage); | |
| const_iterator begin() const; | |
| const_iterator end() const; | |
| const_reverse_iterator rbegin() const; | |
| const_reverse_iterator rend() const; | |
| const_iterator cbegin() const; | |
| const_iterator cend() const; | |
| const_reverse_iterator crbegin() const; | |
| const_reverse_iterator crend() const; | |
| private: | |
| const DictStorage* storage_; | |
| }; | |
| } // namespace detail | |
| } // namespace base | |
| #endif // BASE_VALUE_ITERATORS_H_ |