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/. */
7 #ifndef __nsCheapSets_h__
8 #define __nsCheapSets_h__
10 #include "nsTHashtable.h"
13 enum nsCheapSetOperator
15 OpNext
= 0, // enumerator says continue
16 OpRemove
= 1, // enumerator says remove and continue
20 * A set that takes up minimal size when there are 0 or 1 entries in the set.
21 * Use for cases where sizes of 0 and 1 are even slightly common.
23 template<typename EntryType
>
27 typedef typename
EntryType::KeyType KeyType
;
28 typedef nsCheapSetOperator (*Enumerator
)(EntryType
* aEntry
, void* userArg
);
33 mUnion
.table
= nullptr;
35 ~nsCheapSet() { Clear(); }
46 GetSingleEntry()->~EntryType();
52 MOZ_ASSERT_UNREACHABLE("bogus state");
58 void Put(const KeyType aVal
);
60 void Remove(const KeyType aVal
);
62 bool Contains(const KeyType aVal
)
68 return GetSingleEntry()->KeyEquals(EntryType::KeyToPointer(aVal
));
70 return !!mUnion
.table
->GetEntry(aVal
);
72 MOZ_ASSERT_UNREACHABLE("bogus state");
77 uint32_t EnumerateEntries(Enumerator aEnumFunc
, void* aUserArg
)
83 if (aEnumFunc(GetSingleEntry(), aUserArg
) == OpRemove
) {
84 GetSingleEntry()->~EntryType();
89 uint32_t n
= mUnion
.table
->Count();
90 for (auto iter
= mUnion
.table
->Iter(); !iter
.Done(); iter
.Next()) {
91 auto entry
= static_cast<EntryType
*>(iter
.Get());
92 if (aEnumFunc(entry
, aUserArg
) == OpRemove
) {
99 MOZ_ASSERT_UNREACHABLE("bogus state");
105 EntryType
* GetSingleEntry()
107 return reinterpret_cast<EntryType
*>(&mUnion
.singleEntry
[0]);
119 nsTHashtable
<EntryType
>* table
;
120 char singleEntry
[sizeof(EntryType
)];
122 enum SetState mState
;
125 template<typename EntryType
>
127 nsCheapSet
<EntryType
>::Put(const KeyType aVal
)
131 new (GetSingleEntry()) EntryType(EntryType::KeyToPointer(aVal
));
135 nsTHashtable
<EntryType
>* table
= new nsTHashtable
<EntryType
>();
136 EntryType
* entry
= GetSingleEntry();
137 table
->PutEntry(entry
->GetKey());
139 mUnion
.table
= table
;
145 mUnion
.table
->PutEntry(aVal
);
148 MOZ_ASSERT_UNREACHABLE("bogus state");
153 template<typename EntryType
>
155 nsCheapSet
<EntryType
>::Remove(const KeyType aVal
)
161 if (Contains(aVal
)) {
162 GetSingleEntry()->~EntryType();
167 mUnion
.table
->RemoveEntry(aVal
);
170 MOZ_ASSERT_UNREACHABLE("bogus state");