xref: /aosp_15_r20/external/cronet/base/win/map.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2019 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_WIN_MAP_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_WIN_MAP_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <windows.foundation.collections.h>
9*6777b538SAndroid Build Coastguard Worker #include <wrl/implements.h>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include <map>
12*6777b538SAndroid Build Coastguard Worker #include <utility>
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/containers/contains.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/notimplemented.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/win/vector.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/win/winrt_foundation_helpers.h"
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker namespace base {
21*6777b538SAndroid Build Coastguard Worker namespace win {
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker template <typename K, typename V>
24*6777b538SAndroid Build Coastguard Worker class Map;
25*6777b538SAndroid Build Coastguard Worker 
26*6777b538SAndroid Build Coastguard Worker namespace internal {
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker // Template tricks needed to dispatch to the correct implementation.
29*6777b538SAndroid Build Coastguard Worker // See base/win/winrt_foundation_helpers.h for explanation.
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker template <typename K, typename V>
32*6777b538SAndroid Build Coastguard Worker using ComplexK =
33*6777b538SAndroid Build Coastguard Worker     typename ABI::Windows::Foundation::Collections::IMap<K, V>::K_complex;
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker template <typename K, typename V>
36*6777b538SAndroid Build Coastguard Worker using ComplexV =
37*6777b538SAndroid Build Coastguard Worker     typename ABI::Windows::Foundation::Collections::IMap<K, V>::V_complex;
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker template <typename K, typename V>
40*6777b538SAndroid Build Coastguard Worker using LogicalK = LogicalType<ComplexK<K, V>>;
41*6777b538SAndroid Build Coastguard Worker 
42*6777b538SAndroid Build Coastguard Worker template <typename K, typename V>
43*6777b538SAndroid Build Coastguard Worker using LogicalV = LogicalType<ComplexV<K, V>>;
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker template <typename K, typename V>
46*6777b538SAndroid Build Coastguard Worker using AbiK = AbiType<ComplexK<K, V>>;
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker template <typename K, typename V>
49*6777b538SAndroid Build Coastguard Worker using AbiV = AbiType<ComplexV<K, V>>;
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker template <typename K, typename V>
52*6777b538SAndroid Build Coastguard Worker using StorageK = StorageType<ComplexK<K, V>>;
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker template <typename K, typename V>
55*6777b538SAndroid Build Coastguard Worker using StorageV = StorageType<ComplexV<K, V>>;
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker template <typename K, typename V>
58*6777b538SAndroid Build Coastguard Worker class KeyValuePair : public Microsoft::WRL::RuntimeClass<
59*6777b538SAndroid Build Coastguard Worker                          Microsoft::WRL::RuntimeClassFlags<
60*6777b538SAndroid Build Coastguard Worker                              Microsoft::WRL::WinRtClassicComMix |
61*6777b538SAndroid Build Coastguard Worker                              Microsoft::WRL::InhibitRoOriginateError>,
62*6777b538SAndroid Build Coastguard Worker                          ABI::Windows::Foundation::Collections::
63*6777b538SAndroid Build Coastguard Worker                              IKeyValuePair<LogicalK<K, V>, LogicalV<K, V>>> {
64*6777b538SAndroid Build Coastguard Worker  public:
65*6777b538SAndroid Build Coastguard Worker   using AbiK = AbiK<K, V>;
66*6777b538SAndroid Build Coastguard Worker   using AbiV = AbiV<K, V>;
67*6777b538SAndroid Build Coastguard Worker   using StorageK = StorageK<K, V>;
68*6777b538SAndroid Build Coastguard Worker   using StorageV = StorageV<K, V>;
69*6777b538SAndroid Build Coastguard Worker 
KeyValuePair(StorageK key,StorageV value)70*6777b538SAndroid Build Coastguard Worker   KeyValuePair(StorageK key, StorageV value)
71*6777b538SAndroid Build Coastguard Worker       : key_(std::move(key)), value_(std::move(value)) {}
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker   // ABI::Windows::Foundation::Collections::IKeyValuePair:
get_Key(AbiK * key)74*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP get_Key(AbiK* key) { return CopyTo(key_, key); }
75*6777b538SAndroid Build Coastguard Worker 
get_Value(AbiV * value)76*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP get_Value(AbiV* value) { return CopyTo(value_, value); }
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker  private:
79*6777b538SAndroid Build Coastguard Worker   StorageK key_;
80*6777b538SAndroid Build Coastguard Worker   StorageV value_;
81*6777b538SAndroid Build Coastguard Worker };
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker template <typename K>
84*6777b538SAndroid Build Coastguard Worker class MapChangedEventArgs
85*6777b538SAndroid Build Coastguard Worker     : public Microsoft::WRL::RuntimeClass<
86*6777b538SAndroid Build Coastguard Worker           Microsoft::WRL::RuntimeClassFlags<
87*6777b538SAndroid Build Coastguard Worker               Microsoft::WRL::WinRtClassicComMix |
88*6777b538SAndroid Build Coastguard Worker               Microsoft::WRL::InhibitRoOriginateError>,
89*6777b538SAndroid Build Coastguard Worker           ABI::Windows::Foundation::Collections::IMapChangedEventArgs<K>> {
90*6777b538SAndroid Build Coastguard Worker  public:
MapChangedEventArgs(ABI::Windows::Foundation::Collections::CollectionChange change,K key)91*6777b538SAndroid Build Coastguard Worker   MapChangedEventArgs(
92*6777b538SAndroid Build Coastguard Worker       ABI::Windows::Foundation::Collections::CollectionChange change,
93*6777b538SAndroid Build Coastguard Worker       K key)
94*6777b538SAndroid Build Coastguard Worker       : change_(change), key_(std::move(key)) {}
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker   ~MapChangedEventArgs() override = default;
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker   // ABI::Windows::Foundation::Collections::IMapChangedEventArgs:
get_CollectionChange(ABI::Windows::Foundation::Collections::CollectionChange * value)99*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP get_CollectionChange(
100*6777b538SAndroid Build Coastguard Worker       ABI::Windows::Foundation::Collections::CollectionChange* value) override {
101*6777b538SAndroid Build Coastguard Worker     *value = change_;
102*6777b538SAndroid Build Coastguard Worker     return S_OK;
103*6777b538SAndroid Build Coastguard Worker   }
104*6777b538SAndroid Build Coastguard Worker 
get_Key(K * value)105*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP get_Key(K* value) override {
106*6777b538SAndroid Build Coastguard Worker     *value = key_;
107*6777b538SAndroid Build Coastguard Worker     return S_OK;
108*6777b538SAndroid Build Coastguard Worker   }
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker  private:
111*6777b538SAndroid Build Coastguard Worker   const ABI::Windows::Foundation::Collections::CollectionChange change_;
112*6777b538SAndroid Build Coastguard Worker   K key_;
113*6777b538SAndroid Build Coastguard Worker };
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker }  // namespace internal
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker // This file provides an implementation of Windows::Foundation::IMap. It
118*6777b538SAndroid Build Coastguard Worker // functions as a thin wrapper around an std::map, and dispatches
119*6777b538SAndroid Build Coastguard Worker // method calls to either the corresponding std::map API or
120*6777b538SAndroid Build Coastguard Worker // appropriate std algorithms. Furthermore, it notifies its observers whenever
121*6777b538SAndroid Build Coastguard Worker // its observable state changes, and is iterable. Please notice also that if the
122*6777b538SAndroid Build Coastguard Worker // map is modified while iterating over it, iterator methods will return
123*6777b538SAndroid Build Coastguard Worker // E_CHANGED_STATE. A base::win::Map can be constructed for any types <K,V>, and
124*6777b538SAndroid Build Coastguard Worker // is implicitly constructible from a std::map. In the case where K or V is a
125*6777b538SAndroid Build Coastguard Worker // pointer derived from IUnknown, the std::map needs to be of type
126*6777b538SAndroid Build Coastguard Worker // Microsoft::WRL::ComPtr<K> or Microsoft::WRL::ComPtr<V>. This enforces proper
127*6777b538SAndroid Build Coastguard Worker // reference counting and improves safety.
128*6777b538SAndroid Build Coastguard Worker template <typename K, typename V>
129*6777b538SAndroid Build Coastguard Worker class Map
130*6777b538SAndroid Build Coastguard Worker     : public Microsoft::WRL::RuntimeClass<
131*6777b538SAndroid Build Coastguard Worker           Microsoft::WRL::RuntimeClassFlags<
132*6777b538SAndroid Build Coastguard Worker               Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
133*6777b538SAndroid Build Coastguard Worker           ABI::Windows::Foundation::Collections::IMap<internal::LogicalK<K, V>,
134*6777b538SAndroid Build Coastguard Worker                                                       internal::LogicalV<K, V>>,
135*6777b538SAndroid Build Coastguard Worker           ABI::Windows::Foundation::Collections::IObservableMap<
136*6777b538SAndroid Build Coastguard Worker               internal::LogicalK<K, V>,
137*6777b538SAndroid Build Coastguard Worker               internal::LogicalV<K, V>>,
138*6777b538SAndroid Build Coastguard Worker           ABI::Windows::Foundation::Collections::IIterable<
139*6777b538SAndroid Build Coastguard Worker               ABI::Windows::Foundation::Collections::IKeyValuePair<
140*6777b538SAndroid Build Coastguard Worker                   internal::LogicalK<K, V>,
141*6777b538SAndroid Build Coastguard Worker                   internal::LogicalV<K, V>>*>> {
142*6777b538SAndroid Build Coastguard Worker  public:
143*6777b538SAndroid Build Coastguard Worker   using LogicalK = internal::LogicalK<K, V>;
144*6777b538SAndroid Build Coastguard Worker   using LogicalV = internal::LogicalV<K, V>;
145*6777b538SAndroid Build Coastguard Worker   using AbiK = internal::AbiK<K, V>;
146*6777b538SAndroid Build Coastguard Worker   using AbiV = internal::AbiV<K, V>;
147*6777b538SAndroid Build Coastguard Worker   using StorageK = internal::StorageK<K, V>;
148*6777b538SAndroid Build Coastguard Worker   using StorageV = internal::StorageV<K, V>;
149*6777b538SAndroid Build Coastguard Worker 
150*6777b538SAndroid Build Coastguard Worker  private:
151*6777b538SAndroid Build Coastguard Worker   class MapView;
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker   // Iterates over base::win::Map.
154*6777b538SAndroid Build Coastguard Worker   // Its methods return E_CHANGED_STATE is the map is modified.
155*6777b538SAndroid Build Coastguard Worker   // TODO(https://crbug.com/987533): Refactor MapIterator to leverage
156*6777b538SAndroid Build Coastguard Worker   // std::map::iterator.
157*6777b538SAndroid Build Coastguard Worker   class MapIterator
158*6777b538SAndroid Build Coastguard Worker       : public Microsoft::WRL::RuntimeClass<
159*6777b538SAndroid Build Coastguard Worker             Microsoft::WRL::RuntimeClassFlags<
160*6777b538SAndroid Build Coastguard Worker                 Microsoft::WRL::WinRtClassicComMix |
161*6777b538SAndroid Build Coastguard Worker                 Microsoft::WRL::InhibitRoOriginateError>,
162*6777b538SAndroid Build Coastguard Worker             ABI::Windows::Foundation::Collections::IIterator<
163*6777b538SAndroid Build Coastguard Worker                 ABI::Windows::Foundation::Collections::IKeyValuePair<
164*6777b538SAndroid Build Coastguard Worker                     internal::LogicalK<K, V>,
165*6777b538SAndroid Build Coastguard Worker                     internal::LogicalV<K, V>>*>> {
166*6777b538SAndroid Build Coastguard Worker    public:
MapIterator(Microsoft::WRL::ComPtr<MapView> view)167*6777b538SAndroid Build Coastguard Worker     explicit MapIterator(Microsoft::WRL::ComPtr<MapView> view)
168*6777b538SAndroid Build Coastguard Worker         : view_(std::move(view)) {
169*6777b538SAndroid Build Coastguard Worker       DCHECK(view_->ValidState());
170*6777b538SAndroid Build Coastguard Worker       ConvertMapToVectorIterator();
171*6777b538SAndroid Build Coastguard Worker     }
172*6777b538SAndroid Build Coastguard Worker 
173*6777b538SAndroid Build Coastguard Worker     // ABI::Windows::Foundation::Collections::IIterator:
get_Current(ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK,LogicalV> ** current)174*6777b538SAndroid Build Coastguard Worker     IFACEMETHODIMP get_Current(
175*6777b538SAndroid Build Coastguard Worker         ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK,
176*6777b538SAndroid Build Coastguard Worker                                                              LogicalV>**
177*6777b538SAndroid Build Coastguard Worker             current) override {
178*6777b538SAndroid Build Coastguard Worker       return view_->ValidState() ? iterator_->get_Current(current)
179*6777b538SAndroid Build Coastguard Worker                                  : E_CHANGED_STATE;
180*6777b538SAndroid Build Coastguard Worker     }
181*6777b538SAndroid Build Coastguard Worker 
get_HasCurrent(boolean * has_current)182*6777b538SAndroid Build Coastguard Worker     IFACEMETHODIMP get_HasCurrent(boolean* has_current) override {
183*6777b538SAndroid Build Coastguard Worker       return view_->ValidState() ? iterator_->get_HasCurrent(has_current)
184*6777b538SAndroid Build Coastguard Worker                                  : E_CHANGED_STATE;
185*6777b538SAndroid Build Coastguard Worker     }
186*6777b538SAndroid Build Coastguard Worker 
MoveNext(boolean * has_current)187*6777b538SAndroid Build Coastguard Worker     IFACEMETHODIMP MoveNext(boolean* has_current) override {
188*6777b538SAndroid Build Coastguard Worker       return view_->ValidState() ? iterator_->MoveNext(has_current)
189*6777b538SAndroid Build Coastguard Worker                                  : E_CHANGED_STATE;
190*6777b538SAndroid Build Coastguard Worker     }
191*6777b538SAndroid Build Coastguard Worker 
GetMany(unsigned capacity,ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK,LogicalV> ** value,unsigned * actual)192*6777b538SAndroid Build Coastguard Worker     IFACEMETHODIMP GetMany(
193*6777b538SAndroid Build Coastguard Worker         unsigned capacity,
194*6777b538SAndroid Build Coastguard Worker         ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK,
195*6777b538SAndroid Build Coastguard Worker                                                              LogicalV>** value,
196*6777b538SAndroid Build Coastguard Worker         unsigned* actual) override {
197*6777b538SAndroid Build Coastguard Worker       return view_->ValidState() ? iterator_->GetMany(capacity, value, actual)
198*6777b538SAndroid Build Coastguard Worker                                  : E_CHANGED_STATE;
199*6777b538SAndroid Build Coastguard Worker     }
200*6777b538SAndroid Build Coastguard Worker 
201*6777b538SAndroid Build Coastguard Worker    private:
202*6777b538SAndroid Build Coastguard Worker     // Helper for iteration:
ConvertMapToVectorIterator()203*6777b538SAndroid Build Coastguard Worker     void ConvertMapToVectorIterator() {
204*6777b538SAndroid Build Coastguard Worker       // Create a vector that will hold Map's key-value pairs.
205*6777b538SAndroid Build Coastguard Worker       auto vector = Microsoft::WRL::Make<
206*6777b538SAndroid Build Coastguard Worker           Vector<ABI::Windows::Foundation::Collections::IKeyValuePair<
207*6777b538SAndroid Build Coastguard Worker               LogicalK, LogicalV>*>>();
208*6777b538SAndroid Build Coastguard Worker 
209*6777b538SAndroid Build Coastguard Worker       // Fill the vector with container data.
210*6777b538SAndroid Build Coastguard Worker       for (const auto& pair : view_->get_map()) {
211*6777b538SAndroid Build Coastguard Worker         auto key_value_pair =
212*6777b538SAndroid Build Coastguard Worker             Microsoft::WRL::Make<internal::KeyValuePair<AbiK, AbiV>>(
213*6777b538SAndroid Build Coastguard Worker                 pair.first, pair.second);
214*6777b538SAndroid Build Coastguard Worker         vector->Append(key_value_pair.Get());
215*6777b538SAndroid Build Coastguard Worker       }
216*6777b538SAndroid Build Coastguard Worker 
217*6777b538SAndroid Build Coastguard Worker       // Return an iterator to that vector.
218*6777b538SAndroid Build Coastguard Worker       // Iterator is immutable (wraps an IVectorView) and Vector's lifecycle is
219*6777b538SAndroid Build Coastguard Worker       // ensured cause the view holds a reference to the vector, and iterator
220*6777b538SAndroid Build Coastguard Worker       // holds a reference to the view.
221*6777b538SAndroid Build Coastguard Worker       HRESULT hr = vector->First(&iterator_);
222*6777b538SAndroid Build Coastguard Worker       DCHECK(SUCCEEDED(hr));
223*6777b538SAndroid Build Coastguard Worker     }
224*6777b538SAndroid Build Coastguard Worker 
225*6777b538SAndroid Build Coastguard Worker     Microsoft::WRL::ComPtr<MapView> view_;
226*6777b538SAndroid Build Coastguard Worker     Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IIterator<
227*6777b538SAndroid Build Coastguard Worker         ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK,
228*6777b538SAndroid Build Coastguard Worker                                                              LogicalV>*>>
229*6777b538SAndroid Build Coastguard Worker         iterator_;
230*6777b538SAndroid Build Coastguard Worker   };
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker   class MapView
233*6777b538SAndroid Build Coastguard Worker       : public Microsoft::WRL::RuntimeClass<
234*6777b538SAndroid Build Coastguard Worker             Microsoft::WRL::RuntimeClassFlags<
235*6777b538SAndroid Build Coastguard Worker                 Microsoft::WRL::WinRtClassicComMix |
236*6777b538SAndroid Build Coastguard Worker                 Microsoft::WRL::InhibitRoOriginateError>,
237*6777b538SAndroid Build Coastguard Worker             ABI::Windows::Foundation::Collections::
238*6777b538SAndroid Build Coastguard Worker                 IMapView<internal::LogicalK<K, V>, internal::LogicalV<K, V>>,
239*6777b538SAndroid Build Coastguard Worker             ABI::Windows::Foundation::Collections::IIterable<
240*6777b538SAndroid Build Coastguard Worker                 ABI::Windows::Foundation::Collections::IKeyValuePair<
241*6777b538SAndroid Build Coastguard Worker                     internal::LogicalK<K, V>,
242*6777b538SAndroid Build Coastguard Worker                     internal::LogicalV<K, V>>*>,
243*6777b538SAndroid Build Coastguard Worker             ABI::Windows::Foundation::Collections::MapChangedEventHandler<
244*6777b538SAndroid Build Coastguard Worker                 internal::LogicalK<K, V>,
245*6777b538SAndroid Build Coastguard Worker                 internal::LogicalV<K, V>>> {
246*6777b538SAndroid Build Coastguard Worker    public:
MapView(Microsoft::WRL::ComPtr<Map<LogicalK,LogicalV>> map)247*6777b538SAndroid Build Coastguard Worker     explicit MapView(Microsoft::WRL::ComPtr<Map<LogicalK, LogicalV>> map)
248*6777b538SAndroid Build Coastguard Worker         : map_(std::move(map)) {
249*6777b538SAndroid Build Coastguard Worker       map_->add_MapChanged(this, &map_changed_token_);
250*6777b538SAndroid Build Coastguard Worker     }
251*6777b538SAndroid Build Coastguard Worker 
~MapView()252*6777b538SAndroid Build Coastguard Worker     ~MapView() override {
253*6777b538SAndroid Build Coastguard Worker       if (map_)
254*6777b538SAndroid Build Coastguard Worker         map_->remove_MapChanged(map_changed_token_);
255*6777b538SAndroid Build Coastguard Worker     }
256*6777b538SAndroid Build Coastguard Worker 
257*6777b538SAndroid Build Coastguard Worker     // ABI::Windows::Foundation::Collections::IMapView:
Lookup(AbiK key,AbiV * value)258*6777b538SAndroid Build Coastguard Worker     IFACEMETHODIMP Lookup(AbiK key, AbiV* value) override {
259*6777b538SAndroid Build Coastguard Worker       return map_ ? map_->Lookup(key, value) : E_CHANGED_STATE;
260*6777b538SAndroid Build Coastguard Worker     }
261*6777b538SAndroid Build Coastguard Worker 
get_Size(unsigned int * size)262*6777b538SAndroid Build Coastguard Worker     IFACEMETHODIMP get_Size(unsigned int* size) override {
263*6777b538SAndroid Build Coastguard Worker       return map_ ? map_->get_Size(size) : E_CHANGED_STATE;
264*6777b538SAndroid Build Coastguard Worker     }
265*6777b538SAndroid Build Coastguard Worker 
HasKey(AbiK key,boolean * found)266*6777b538SAndroid Build Coastguard Worker     IFACEMETHODIMP HasKey(AbiK key, boolean* found) override {
267*6777b538SAndroid Build Coastguard Worker       return map_ ? map_->HasKey(key, found) : E_CHANGED_STATE;
268*6777b538SAndroid Build Coastguard Worker     }
269*6777b538SAndroid Build Coastguard Worker 
Split(ABI::Windows::Foundation::Collections::IMapView<LogicalK,LogicalV> ** first_partition,ABI::Windows::Foundation::Collections::IMapView<LogicalK,LogicalV> ** second_partition)270*6777b538SAndroid Build Coastguard Worker     IFACEMETHODIMP Split(
271*6777b538SAndroid Build Coastguard Worker         ABI::Windows::Foundation::Collections::IMapView<LogicalK, LogicalV>**
272*6777b538SAndroid Build Coastguard Worker             first_partition,
273*6777b538SAndroid Build Coastguard Worker         ABI::Windows::Foundation::Collections::IMapView<LogicalK, LogicalV>**
274*6777b538SAndroid Build Coastguard Worker             second_partition) override {
275*6777b538SAndroid Build Coastguard Worker       NOTIMPLEMENTED();
276*6777b538SAndroid Build Coastguard Worker       return E_NOTIMPL;
277*6777b538SAndroid Build Coastguard Worker     }
278*6777b538SAndroid Build Coastguard Worker 
279*6777b538SAndroid Build Coastguard Worker     // ABI::Windows::Foundation::Collections::IIterable:
First(ABI::Windows::Foundation::Collections::IIterator<ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK,LogicalV> * > ** first)280*6777b538SAndroid Build Coastguard Worker     IFACEMETHODIMP First(
281*6777b538SAndroid Build Coastguard Worker         ABI::Windows::Foundation::Collections::IIterator<
282*6777b538SAndroid Build Coastguard Worker             ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK,
283*6777b538SAndroid Build Coastguard Worker                                                                  LogicalV>*>**
284*6777b538SAndroid Build Coastguard Worker             first) override {
285*6777b538SAndroid Build Coastguard Worker       return map_ ? map_->First(first) : E_CHANGED_STATE;
286*6777b538SAndroid Build Coastguard Worker     }
287*6777b538SAndroid Build Coastguard Worker 
288*6777b538SAndroid Build Coastguard Worker     // ABI::Windows::Foundation::Collections::MapChangedEventHandler:
Invoke(ABI::Windows::Foundation::Collections::IObservableMap<LogicalK,LogicalV> * sender,ABI::Windows::Foundation::Collections::IMapChangedEventArgs<LogicalK> * e)289*6777b538SAndroid Build Coastguard Worker     IFACEMETHODIMP Invoke(
290*6777b538SAndroid Build Coastguard Worker         ABI::Windows::Foundation::Collections::IObservableMap<LogicalK,
291*6777b538SAndroid Build Coastguard Worker                                                               LogicalV>* sender,
292*6777b538SAndroid Build Coastguard Worker         ABI::Windows::Foundation::Collections::IMapChangedEventArgs<LogicalK>*
293*6777b538SAndroid Build Coastguard Worker             e) override {
294*6777b538SAndroid Build Coastguard Worker       DCHECK_EQ(map_.Get(), sender);
295*6777b538SAndroid Build Coastguard Worker       map_.Reset();
296*6777b538SAndroid Build Coastguard Worker       sender->remove_MapChanged(map_changed_token_);
297*6777b538SAndroid Build Coastguard Worker       return S_OK;
298*6777b538SAndroid Build Coastguard Worker     }
299*6777b538SAndroid Build Coastguard Worker 
300*6777b538SAndroid Build Coastguard Worker     // Accessor used in MapIterator for iterating over Map's container.
301*6777b538SAndroid Build Coastguard Worker     // Will remain valid during the entire iteration.
get_map()302*6777b538SAndroid Build Coastguard Worker     const std::map<StorageK, StorageV, internal::Less>& get_map() {
303*6777b538SAndroid Build Coastguard Worker       DCHECK(map_);
304*6777b538SAndroid Build Coastguard Worker       return map_->map_;
305*6777b538SAndroid Build Coastguard Worker     }
306*6777b538SAndroid Build Coastguard Worker 
ValidState()307*6777b538SAndroid Build Coastguard Worker     bool ValidState() const { return map_; }
308*6777b538SAndroid Build Coastguard Worker 
309*6777b538SAndroid Build Coastguard Worker    private:
310*6777b538SAndroid Build Coastguard Worker     Microsoft::WRL::ComPtr<Map<LogicalK, LogicalV>> map_;
311*6777b538SAndroid Build Coastguard Worker     EventRegistrationToken map_changed_token_;
312*6777b538SAndroid Build Coastguard Worker   };
313*6777b538SAndroid Build Coastguard Worker 
314*6777b538SAndroid Build Coastguard Worker  public:
315*6777b538SAndroid Build Coastguard Worker   Map() = default;
Map(const std::map<StorageK,StorageV,internal::Less> & map)316*6777b538SAndroid Build Coastguard Worker   explicit Map(const std::map<StorageK, StorageV, internal::Less>& map)
317*6777b538SAndroid Build Coastguard Worker       : map_(map) {}
Map(std::map<StorageK,StorageV,internal::Less> && map)318*6777b538SAndroid Build Coastguard Worker   explicit Map(std::map<StorageK, StorageV, internal::Less>&& map)
319*6777b538SAndroid Build Coastguard Worker       : map_(std::move(map)) {}
320*6777b538SAndroid Build Coastguard Worker 
321*6777b538SAndroid Build Coastguard Worker   // ABI::Windows::Foundation::Collections::IMap:
Lookup(AbiK key,AbiV * value)322*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP Lookup(AbiK key, AbiV* value) override {
323*6777b538SAndroid Build Coastguard Worker     auto it = map_.find(key);
324*6777b538SAndroid Build Coastguard Worker     if (it == map_.cend())
325*6777b538SAndroid Build Coastguard Worker       return E_BOUNDS;
326*6777b538SAndroid Build Coastguard Worker 
327*6777b538SAndroid Build Coastguard Worker     return internal::CopyTo(it->second, value);
328*6777b538SAndroid Build Coastguard Worker   }
329*6777b538SAndroid Build Coastguard Worker 
get_Size(unsigned int * size)330*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP get_Size(unsigned int* size) override {
331*6777b538SAndroid Build Coastguard Worker     *size = map_.size();
332*6777b538SAndroid Build Coastguard Worker     return S_OK;
333*6777b538SAndroid Build Coastguard Worker   }
334*6777b538SAndroid Build Coastguard Worker 
HasKey(AbiK key,boolean * found)335*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP HasKey(AbiK key, boolean* found) override {
336*6777b538SAndroid Build Coastguard Worker     *found = Contains(map_, key);
337*6777b538SAndroid Build Coastguard Worker     return S_OK;
338*6777b538SAndroid Build Coastguard Worker   }
339*6777b538SAndroid Build Coastguard Worker 
GetView(ABI::Windows::Foundation::Collections::IMapView<LogicalK,LogicalV> ** view)340*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP GetView(
341*6777b538SAndroid Build Coastguard Worker       ABI::Windows::Foundation::Collections::IMapView<LogicalK, LogicalV>**
342*6777b538SAndroid Build Coastguard Worker           view) override {
343*6777b538SAndroid Build Coastguard Worker     return Microsoft::WRL::Make<MapView>(this).CopyTo(view);
344*6777b538SAndroid Build Coastguard Worker   }
345*6777b538SAndroid Build Coastguard Worker 
Insert(AbiK key,AbiV value,boolean * replaced)346*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP Insert(AbiK key, AbiV value, boolean* replaced) override {
347*6777b538SAndroid Build Coastguard Worker     auto [it, inserted] = map_.insert_or_assign(key, std::move(value));
348*6777b538SAndroid Build Coastguard Worker     *replaced = !inserted;
349*6777b538SAndroid Build Coastguard Worker     NotifyMapChanged(*replaced ? ABI::Windows::Foundation::Collections::
350*6777b538SAndroid Build Coastguard Worker                                      CollectionChange_ItemChanged
351*6777b538SAndroid Build Coastguard Worker                                : ABI::Windows::Foundation::Collections::
352*6777b538SAndroid Build Coastguard Worker                                      CollectionChange_ItemInserted,
353*6777b538SAndroid Build Coastguard Worker                      key);
354*6777b538SAndroid Build Coastguard Worker     return S_OK;
355*6777b538SAndroid Build Coastguard Worker   }
356*6777b538SAndroid Build Coastguard Worker 
Remove(AbiK key)357*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP Remove(AbiK key) override {
358*6777b538SAndroid Build Coastguard Worker     if (!map_.erase(key))
359*6777b538SAndroid Build Coastguard Worker       return E_BOUNDS;
360*6777b538SAndroid Build Coastguard Worker 
361*6777b538SAndroid Build Coastguard Worker     NotifyMapChanged(
362*6777b538SAndroid Build Coastguard Worker         ABI::Windows::Foundation::Collections::CollectionChange_ItemRemoved,
363*6777b538SAndroid Build Coastguard Worker         key);
364*6777b538SAndroid Build Coastguard Worker     return S_OK;
365*6777b538SAndroid Build Coastguard Worker   }
366*6777b538SAndroid Build Coastguard Worker 
Clear()367*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP Clear() override {
368*6777b538SAndroid Build Coastguard Worker     map_.clear();
369*6777b538SAndroid Build Coastguard Worker     NotifyMapChanged(
370*6777b538SAndroid Build Coastguard Worker         ABI::Windows::Foundation::Collections::CollectionChange_Reset, 0);
371*6777b538SAndroid Build Coastguard Worker     return S_OK;
372*6777b538SAndroid Build Coastguard Worker   }
373*6777b538SAndroid Build Coastguard Worker 
374*6777b538SAndroid Build Coastguard Worker   // ABI::Windows::Foundation::Collections::IObservableMap:
add_MapChanged(ABI::Windows::Foundation::Collections::MapChangedEventHandler<LogicalK,LogicalV> * handler,EventRegistrationToken * token)375*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP add_MapChanged(
376*6777b538SAndroid Build Coastguard Worker       ABI::Windows::Foundation::Collections::MapChangedEventHandler<LogicalK,
377*6777b538SAndroid Build Coastguard Worker                                                                     LogicalV>*
378*6777b538SAndroid Build Coastguard Worker           handler,
379*6777b538SAndroid Build Coastguard Worker       EventRegistrationToken* token) override {
380*6777b538SAndroid Build Coastguard Worker     token->value = handler_id_++;
381*6777b538SAndroid Build Coastguard Worker     handlers_.emplace_hint(handlers_.end(), token->value, handler);
382*6777b538SAndroid Build Coastguard Worker     return S_OK;
383*6777b538SAndroid Build Coastguard Worker   }
384*6777b538SAndroid Build Coastguard Worker 
remove_MapChanged(EventRegistrationToken token)385*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP remove_MapChanged(EventRegistrationToken token) override {
386*6777b538SAndroid Build Coastguard Worker     return handlers_.erase(token.value) ? S_OK : E_BOUNDS;
387*6777b538SAndroid Build Coastguard Worker   }
388*6777b538SAndroid Build Coastguard Worker 
389*6777b538SAndroid Build Coastguard Worker   // ABI::Windows::Foundation::Collections::IIterable:
First(ABI::Windows::Foundation::Collections::IIterator<ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK,LogicalV> * > ** first)390*6777b538SAndroid Build Coastguard Worker   IFACEMETHODIMP First(
391*6777b538SAndroid Build Coastguard Worker       ABI::Windows::Foundation::Collections::IIterator<
392*6777b538SAndroid Build Coastguard Worker           ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK,
393*6777b538SAndroid Build Coastguard Worker                                                                LogicalV>*>**
394*6777b538SAndroid Build Coastguard Worker           first) override {
395*6777b538SAndroid Build Coastguard Worker     return Microsoft::WRL::Make<MapIterator>(
396*6777b538SAndroid Build Coastguard Worker                Microsoft::WRL::Make<MapView>(this))
397*6777b538SAndroid Build Coastguard Worker         .CopyTo(first);
398*6777b538SAndroid Build Coastguard Worker   }
399*6777b538SAndroid Build Coastguard Worker 
400*6777b538SAndroid Build Coastguard Worker  private:
~Map()401*6777b538SAndroid Build Coastguard Worker   ~Map() override {
402*6777b538SAndroid Build Coastguard Worker     // Handlers should not outlive the Map. Furthermore, they must ensure
403*6777b538SAndroid Build Coastguard Worker     // they are unregistered before the handler is destroyed. This implies
404*6777b538SAndroid Build Coastguard Worker     // there should be no handlers left when the Map is destructed.
405*6777b538SAndroid Build Coastguard Worker     DCHECK(handlers_.empty());
406*6777b538SAndroid Build Coastguard Worker   }
407*6777b538SAndroid Build Coastguard Worker 
NotifyMapChanged(ABI::Windows::Foundation::Collections::CollectionChange change,AbiK key)408*6777b538SAndroid Build Coastguard Worker   void NotifyMapChanged(
409*6777b538SAndroid Build Coastguard Worker       ABI::Windows::Foundation::Collections::CollectionChange change,
410*6777b538SAndroid Build Coastguard Worker       AbiK key) {
411*6777b538SAndroid Build Coastguard Worker     auto args =
412*6777b538SAndroid Build Coastguard Worker         Microsoft::WRL::Make<internal::MapChangedEventArgs<AbiK>>(change, key);
413*6777b538SAndroid Build Coastguard Worker 
414*6777b538SAndroid Build Coastguard Worker     // Invoking the handlers could result in mutations to the map, thus we make
415*6777b538SAndroid Build Coastguard Worker     // a copy beforehand.
416*6777b538SAndroid Build Coastguard Worker     auto handlers = handlers_;
417*6777b538SAndroid Build Coastguard Worker     for (auto& handler : handlers)
418*6777b538SAndroid Build Coastguard Worker       handler.second->Invoke(this, args.Get());
419*6777b538SAndroid Build Coastguard Worker   }
420*6777b538SAndroid Build Coastguard Worker 
421*6777b538SAndroid Build Coastguard Worker   std::map<StorageK, StorageV, internal::Less> map_;
422*6777b538SAndroid Build Coastguard Worker   base::flat_map<int64_t,
423*6777b538SAndroid Build Coastguard Worker                  ABI::Windows::Foundation::Collections::
424*6777b538SAndroid Build Coastguard Worker                      MapChangedEventHandler<LogicalK, LogicalV>*>
425*6777b538SAndroid Build Coastguard Worker       handlers_;
426*6777b538SAndroid Build Coastguard Worker   int64_t handler_id_ = 0;
427*6777b538SAndroid Build Coastguard Worker };
428*6777b538SAndroid Build Coastguard Worker 
429*6777b538SAndroid Build Coastguard Worker }  // namespace win
430*6777b538SAndroid Build Coastguard Worker }  // namespace base
431*6777b538SAndroid Build Coastguard Worker 
432*6777b538SAndroid Build Coastguard Worker #endif  // BASE_WIN_MAP_H_
433