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