Line data Source code
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 : #ifndef nsClassHashtable_h__
8 : #define nsClassHashtable_h__
9 :
10 : #include "mozilla/Move.h"
11 : #include "nsBaseHashtable.h"
12 : #include "nsHashKeys.h"
13 : #include "nsAutoPtr.h"
14 :
15 : /**
16 : * templated hashtable class maps keys to C++ object pointers.
17 : * See nsBaseHashtable for complete declaration.
18 : * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
19 : * for a complete specification.
20 : * @param Class the class-type being wrapped
21 : * @see nsInterfaceHashtable, nsClassHashtable
22 : */
23 : template<class KeyClass, class T>
24 106 : class nsClassHashtable
25 : : public nsBaseHashtable<KeyClass, nsAutoPtr<T>, T*>
26 : {
27 : public:
28 : typedef typename KeyClass::KeyType KeyType;
29 : typedef T* UserDataType;
30 : typedef nsBaseHashtable<KeyClass, nsAutoPtr<T>, T*> base_type;
31 :
32 : using base_type::IsEmpty;
33 : using base_type::Remove;
34 :
35 621 : nsClassHashtable() {}
36 140 : explicit nsClassHashtable(uint32_t aInitLength)
37 140 : : nsBaseHashtable<KeyClass, nsAutoPtr<T>, T*>(aInitLength)
38 : {
39 140 : }
40 :
41 : /**
42 : * Looks up aKey in the hash table. If it doesn't exist a new object of
43 : * KeyClass will be created (using the arguments provided) and then returned.
44 : */
45 : template<typename... Args>
46 : UserDataType LookupOrAdd(KeyType aKey, Args&&... aConstructionArgs);
47 :
48 : /**
49 : * @copydoc nsBaseHashtable::Get
50 : * @param aData if the key doesn't exist, pData will be set to nullptr.
51 : */
52 : bool Get(KeyType aKey, UserDataType* aData) const;
53 :
54 : /**
55 : * @copydoc nsBaseHashtable::Get
56 : * @returns nullptr if the key is not present.
57 : */
58 : UserDataType Get(KeyType aKey) const;
59 : };
60 :
61 : //
62 : // nsClassHashtable definitions
63 : //
64 :
65 : template<class KeyClass, class T>
66 : template<typename... Args>
67 : T*
68 667 : nsClassHashtable<KeyClass, T>::LookupOrAdd(KeyType aKey,
69 : Args&&... aConstructionArgs)
70 : {
71 667 : auto count = this->Count();
72 667 : typename base_type::EntryType* ent = this->PutEntry(aKey);
73 667 : if (count != this->Count()) {
74 358 : ent->mData = new T(mozilla::Forward<Args>(aConstructionArgs)...);
75 : }
76 667 : return ent->mData;
77 : }
78 :
79 : template<class KeyClass, class T>
80 : bool
81 6744 : nsClassHashtable<KeyClass, T>::Get(KeyType aKey, T** aRetVal) const
82 : {
83 6744 : typename base_type::EntryType* ent = this->GetEntry(aKey);
84 :
85 6744 : if (ent) {
86 4858 : if (aRetVal) {
87 4858 : *aRetVal = ent->mData;
88 : }
89 :
90 4858 : return true;
91 : }
92 :
93 1886 : if (aRetVal) {
94 1886 : *aRetVal = nullptr;
95 : }
96 :
97 1886 : return false;
98 : }
99 :
100 : template<class KeyClass, class T>
101 : T*
102 29220 : nsClassHashtable<KeyClass, T>::Get(KeyType aKey) const
103 : {
104 29220 : typename base_type::EntryType* ent = this->GetEntry(aKey);
105 29220 : if (!ent) {
106 4976 : return nullptr;
107 : }
108 :
109 24244 : return ent->mData;
110 : }
111 :
112 : #endif // nsClassHashtable_h__
|