blob: 418390b431f8cf9ce69cd942d367a78069ab3f0d [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2017 The Chromium Authors
jdoerrie44efa9d2017-07-14 14:47:202// 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"
Tom Sepez04e98bf2024-10-25 18:19:3113#include "base/compiler_specific.h"
jdoerrie44efa9d2017-07-14 14:47:2014#include "base/containers/flat_map.h"
jdoerrie44efa9d2017-07-14 14:47:2015
16namespace base {
17
18class Value;
19
20namespace detail {
21
22using 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
Peter Kastingc573e2d2025-01-10 21:00:0026// reference type is a std::pair<const std::string&, Value&>, so that callers
27// have read-write access without incurring a copy.
jdoerrie44efa9d2017-07-14 14:47:2028class BASE_EXPORT dict_iterator {
29 public:
30 using difference_type = DictStorage::iterator::difference_type;
Peter Kastingc573e2d2025-01-10 21:00:0031 using value_type = std::pair<const std::string&, Value&>;
32 using reference = value_type;
jdoerrie44efa9d2017-07-14 14:47:2033 using iterator_category = std::bidirectional_iterator_tag;
34
35 class pointer {
36 public:
37 explicit pointer(const reference& ref);
38 pointer(const pointer& ptr);
39 pointer& operator=(const pointer& ptr) = delete;
40
41 reference* operator->() { return &ref_; }
42
43 private:
44 reference ref_;
45 };
46
Daniel Chengbe3ac3a2024-05-15 17:38:2347 constexpr dict_iterator() = default;
jdoerrie44efa9d2017-07-14 14:47:2048 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
Peter Kastingc573e2d2025-01-10 21:00:0053 reference operator*() const;
54 pointer operator->() const;
jdoerrie44efa9d2017-07-14 14:47:2055
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);
jdoerrie44efa9d2017-07-14 14:47:2063
Daniel Chenga367fe52022-02-15 18:08:4864 // Currently, there is no easy way to friend Value::Dict. Once dictionary
65 // storage is updated to not require a proxy iterator, the implementation can
66 // be folded into //base/values.h and a standard friend declaration can be
67 // used instead.
Tom Sepez04e98bf2024-10-25 18:19:3168 const DictStorage::iterator& GetUnderlyingIteratorDoNotUse() const
69 LIFETIME_BOUND {
Daniel Chenga367fe52022-02-15 18:08:4870 return dict_iter_;
71 }
72
jdoerrie44efa9d2017-07-14 14:47:2073 private:
74 DictStorage::iterator dict_iter_;
75};
76
77// This iterator closely resembles DictStorage::const_iterator, with one
78// important exception. It abstracts the underlying unique_ptr away, meaning its
Peter Kastingc573e2d2025-01-10 21:00:0079// reference type is a std::pair<const std::string&, const Value&>, so that
80// callers have read-only access without incurring a copy.
jdoerrie44efa9d2017-07-14 14:47:2081class BASE_EXPORT const_dict_iterator {
82 public:
83 using difference_type = DictStorage::const_iterator::difference_type;
Peter Kastingc573e2d2025-01-10 21:00:0084 using value_type = std::pair<const std::string&, const Value&>;
85 using reference = value_type;
jdoerrie44efa9d2017-07-14 14:47:2086 using iterator_category = std::bidirectional_iterator_tag;
87
88 class pointer {
89 public:
90 explicit pointer(const reference& ref);
91 pointer(const pointer& ptr);
92 pointer& operator=(const pointer& ptr) = delete;
93
94 const reference* operator->() const { return &ref_; }
95
96 private:
97 const reference ref_;
98 };
99
Daniel Chengbe3ac3a2024-05-15 17:38:23100 constexpr const_dict_iterator() = default;
jdoerrie44efa9d2017-07-14 14:47:20101 explicit const_dict_iterator(DictStorage::const_iterator dict_iter);
102 const_dict_iterator(const const_dict_iterator& dict_iter);
103 const_dict_iterator& operator=(const const_dict_iterator& dict_iter);
104 ~const_dict_iterator();
105
106 reference operator*() const;
107 pointer operator->() const;
108
109 const_dict_iterator& operator++();
110 const_dict_iterator operator++(int);
111 const_dict_iterator& operator--();
112 const_dict_iterator operator--(int);
113
114 BASE_EXPORT friend bool operator==(const const_dict_iterator& lhs,
115 const const_dict_iterator& rhs);
jdoerrie44efa9d2017-07-14 14:47:20116
Daniel Chenga367fe52022-02-15 18:08:48117 // Currently, there is no easy way to friend Value::Dict. Once dictionary
118 // storage is updated to not require a proxy iterator, the implementation can
119 // be folded into //base/values.h and a standard friend declaration can be
120 // used instead.
121 const DictStorage::const_iterator& GetUnderlyingIteratorDoNotUse() {
122 return dict_iter_;
123 }
124
jdoerrie44efa9d2017-07-14 14:47:20125 private:
126 DictStorage::const_iterator dict_iter_;
127};
128
jdoerrie44efa9d2017-07-14 14:47:20129} // namespace detail
130
131} // namespace base
132
133#endif // BASE_VALUE_ITERATORS_H_