1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
base / value_iterators.h [blame]
// 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 <memory>
#include <string>
#include <utility>
#include "base/base_export.h"
#include "base/compiler_specific.h"
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.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 BASE_EXPORT 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_;
};
constexpr dict_iterator() = default;
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() const
LIFETIME_BOUND {
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<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 BASE_EXPORT 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_;
};
constexpr const_dict_iterator() = default;
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_