dom/bindings/MozMap.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:9046d6f33891
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 /**
8 * Class for representing MozMap arguments. This is an nsTHashtable
9 * under the hood, but we don't want to leak that implementation
10 * detail.
11 */
12
13 #ifndef mozilla_dom_MozMap_h
14 #define mozilla_dom_MozMap_h
15
16 #include "nsTHashtable.h"
17 #include "nsHashKeys.h"
18 #include "nsStringGlue.h"
19 #include "nsTArray.h"
20 #include "mozilla/Move.h"
21
22 namespace mozilla {
23 namespace dom {
24
25 namespace binding_detail {
26 template<typename DataType>
27 class MozMapEntry : public nsStringHashKey
28 {
29 public:
30 MozMapEntry(const nsAString* aKeyTypePointer)
31 : nsStringHashKey(aKeyTypePointer)
32 {
33 }
34
35 // Move constructor so we can do MozMaps of MozMaps.
36 MozMapEntry(MozMapEntry<DataType>&& aOther)
37 : nsStringHashKey(aOther),
38 mData(Move(aOther.mData))
39 {
40 }
41
42 DataType mData;
43 };
44 } // namespace binding_detail
45
46 template<typename DataType>
47 class MozMap : protected nsTHashtable<binding_detail::MozMapEntry<DataType>>
48 {
49 public:
50 typedef typename binding_detail::MozMapEntry<DataType> EntryType;
51 typedef nsTHashtable<EntryType> Base;
52 typedef MozMap<DataType> SelfType;
53
54 MozMap()
55 {
56 }
57
58 // Move constructor so we can do MozMap of MozMap.
59 MozMap(SelfType&& aOther) :
60 Base(Move(aOther))
61 {
62 }
63
64 // The return value is only safe to use until an AddEntry call.
65 const DataType& Get(const nsAString& aKey) const
66 {
67 const EntryType* ent = this->GetEntry(aKey);
68 MOZ_ASSERT(ent, "Why are you using a key we didn't claim to have?");
69 return ent->mData;
70 }
71
72 // The return value is only safe to use until an AddEntry call.
73 const DataType* GetIfExists(const nsAString& aKey) const
74 {
75 const EntryType* ent = this->GetEntry(aKey);
76 if (!ent) {
77 return nullptr;
78 }
79 return &ent->mData;
80 }
81
82 void GetKeys(nsTArray<nsString>& aKeys) const {
83 // Sadly, EnumerateEntries is not a const method
84 const_cast<SelfType*>(this)->EnumerateEntries(KeyEnumerator, &aKeys);
85 }
86
87 // XXXbz we expose this generic enumerator for tracing. Otherwise we'd end up
88 // with a dependency on BindingUtils.h here for the SequenceTracer bits.
89 typedef PLDHashOperator (* Enumerator)(DataType* aValue, void* aClosure);
90 void EnumerateValues(Enumerator aEnumerator, void *aClosure)
91 {
92 ValueEnumClosure args = { aEnumerator, aClosure };
93 this->EnumerateEntries(ValueEnumerator, &args);
94 }
95
96 DataType* AddEntry(const nsAString& aKey) NS_WARN_UNUSED_RESULT
97 {
98 // XXXbz can't just use fallible_t() because our superclass has a
99 // private typedef by that name.
100 EntryType* ent = this->PutEntry(aKey, mozilla::fallible_t());
101 if (!ent) {
102 return nullptr;
103 }
104 return &ent->mData;
105 }
106
107 private:
108 static PLDHashOperator
109 KeyEnumerator(EntryType* aEntry, void* aClosure)
110 {
111 nsTArray<nsString>& keys = *static_cast<nsTArray<nsString>*>(aClosure);
112 keys.AppendElement(aEntry->GetKey());
113 return PL_DHASH_NEXT;
114 }
115
116 struct ValueEnumClosure {
117 Enumerator mEnumerator;
118 void* mClosure;
119 };
120
121 static PLDHashOperator
122 ValueEnumerator(EntryType* aEntry, void* aClosure)
123 {
124 ValueEnumClosure* enumClosure = static_cast<ValueEnumClosure*>(aClosure);
125 return enumClosure->mEnumerator(&aEntry->mData, enumClosure->mClosure);
126 }
127 };
128
129 } // namespace dom
130 } // namespace mozilla
131
132 #endif // mozilla_dom_MozMap_h

mercurial