gecko-dev/xpcom/ds/nsBaseHashtable.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

710 строки
22 KiB
C
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
2012-05-21 15:12:37 +04:00
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsBaseHashtable_h__
#define nsBaseHashtable_h__
#include <utility>
Bug 1609996 - Reorder some includes affected by the previous patches. r=froydnj This was done by: This was done by applying: ``` diff --git a/python/mozbuild/mozbuild/code-analysis/mach_commands.py b/python/mozbuild/mozbuild/code-analysis/mach_commands.py index 789affde7bbf..fe33c4c7d4d1 100644 --- a/python/mozbuild/mozbuild/code-analysis/mach_commands.py +++ b/python/mozbuild/mozbuild/code-analysis/mach_commands.py @@ -2007,7 +2007,7 @@ class StaticAnalysis(MachCommandBase): from subprocess import Popen, PIPE, check_output, CalledProcessError diff_process = Popen(self._get_clang_format_diff_command(commit), stdout=PIPE) - args = [sys.executable, clang_format_diff, "-p1", "-binary=%s" % clang_format] + args = [sys.executable, clang_format_diff, "-p1", "-binary=%s" % clang_format, '-sort-includes'] if not output_file: args.append("-i") ``` Then running `./mach clang-format -c <commit-hash>` Then undoing that patch. Then running check_spidermonkey_style.py --fixup Then running `./mach clang-format` I had to fix four things: * I needed to move <utility> back down in GuardObjects.h because I was hitting obscure problems with our system include wrappers like this: 0:03.94 /usr/include/stdlib.h:550:14: error: exception specification in declaration does not match previous declaration 0:03.94 extern void *realloc (void *__ptr, size_t __size) 0:03.94 ^ 0:03.94 /home/emilio/src/moz/gecko-2/obj-debug/dist/include/malloc_decls.h:53:1: note: previous declaration is here 0:03.94 MALLOC_DECL(realloc, void*, void*, size_t) 0:03.94 ^ 0:03.94 /home/emilio/src/moz/gecko-2/obj-debug/dist/include/mozilla/mozalloc.h:22:32: note: expanded from macro 'MALLOC_DECL' 0:03.94 MOZ_MEMORY_API return_type name##_impl(__VA_ARGS__); 0:03.94 ^ 0:03.94 <scratch space>:178:1: note: expanded from here 0:03.94 realloc_impl 0:03.94 ^ 0:03.94 /home/emilio/src/moz/gecko-2/obj-debug/dist/include/mozmemory_wrap.h:142:41: note: expanded from macro 'realloc_impl' 0:03.94 #define realloc_impl mozmem_malloc_impl(realloc) Which I really didn't feel like digging into. * I had to restore the order of TrustOverrideUtils.h and related files in nss because the .inc files depend on TrustOverrideUtils.h being included earlier. * I had to add a missing include to RollingNumber.h * Also had to partially restore include order in JsepSessionImpl.cpp to avoid some -WError issues due to some static inline functions being defined in a header but not used in the rest of the compilation unit. Differential Revision: https://phabricator.services.mozilla.com/D60327 --HG-- extra : moz-landing-system : lando
2020-01-20 19:19:48 +03:00
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
#include "mozilla/Maybe.h"
Bug 1609996 - Reorder some includes affected by the previous patches. r=froydnj This was done by: This was done by applying: ``` diff --git a/python/mozbuild/mozbuild/code-analysis/mach_commands.py b/python/mozbuild/mozbuild/code-analysis/mach_commands.py index 789affde7bbf..fe33c4c7d4d1 100644 --- a/python/mozbuild/mozbuild/code-analysis/mach_commands.py +++ b/python/mozbuild/mozbuild/code-analysis/mach_commands.py @@ -2007,7 +2007,7 @@ class StaticAnalysis(MachCommandBase): from subprocess import Popen, PIPE, check_output, CalledProcessError diff_process = Popen(self._get_clang_format_diff_command(commit), stdout=PIPE) - args = [sys.executable, clang_format_diff, "-p1", "-binary=%s" % clang_format] + args = [sys.executable, clang_format_diff, "-p1", "-binary=%s" % clang_format, '-sort-includes'] if not output_file: args.append("-i") ``` Then running `./mach clang-format -c <commit-hash>` Then undoing that patch. Then running check_spidermonkey_style.py --fixup Then running `./mach clang-format` I had to fix four things: * I needed to move <utility> back down in GuardObjects.h because I was hitting obscure problems with our system include wrappers like this: 0:03.94 /usr/include/stdlib.h:550:14: error: exception specification in declaration does not match previous declaration 0:03.94 extern void *realloc (void *__ptr, size_t __size) 0:03.94 ^ 0:03.94 /home/emilio/src/moz/gecko-2/obj-debug/dist/include/malloc_decls.h:53:1: note: previous declaration is here 0:03.94 MALLOC_DECL(realloc, void*, void*, size_t) 0:03.94 ^ 0:03.94 /home/emilio/src/moz/gecko-2/obj-debug/dist/include/mozilla/mozalloc.h:22:32: note: expanded from macro 'MALLOC_DECL' 0:03.94 MOZ_MEMORY_API return_type name##_impl(__VA_ARGS__); 0:03.94 ^ 0:03.94 <scratch space>:178:1: note: expanded from here 0:03.94 realloc_impl 0:03.94 ^ 0:03.94 /home/emilio/src/moz/gecko-2/obj-debug/dist/include/mozmemory_wrap.h:142:41: note: expanded from macro 'realloc_impl' 0:03.94 #define realloc_impl mozmem_malloc_impl(realloc) Which I really didn't feel like digging into. * I had to restore the order of TrustOverrideUtils.h and related files in nss because the .inc files depend on TrustOverrideUtils.h being included earlier. * I had to add a missing include to RollingNumber.h * Also had to partially restore include order in JsepSessionImpl.cpp to avoid some -WError issues due to some static inline functions being defined in a header but not used in the rest of the compilation unit. Differential Revision: https://phabricator.services.mozilla.com/D60327 --HG-- extra : moz-landing-system : lando
2020-01-20 19:19:48 +03:00
#include "mozilla/MemoryReporting.h"
#include "nsDebug.h"
Bug 1609996 - Reorder some includes affected by the previous patches. r=froydnj This was done by: This was done by applying: ``` diff --git a/python/mozbuild/mozbuild/code-analysis/mach_commands.py b/python/mozbuild/mozbuild/code-analysis/mach_commands.py index 789affde7bbf..fe33c4c7d4d1 100644 --- a/python/mozbuild/mozbuild/code-analysis/mach_commands.py +++ b/python/mozbuild/mozbuild/code-analysis/mach_commands.py @@ -2007,7 +2007,7 @@ class StaticAnalysis(MachCommandBase): from subprocess import Popen, PIPE, check_output, CalledProcessError diff_process = Popen(self._get_clang_format_diff_command(commit), stdout=PIPE) - args = [sys.executable, clang_format_diff, "-p1", "-binary=%s" % clang_format] + args = [sys.executable, clang_format_diff, "-p1", "-binary=%s" % clang_format, '-sort-includes'] if not output_file: args.append("-i") ``` Then running `./mach clang-format -c <commit-hash>` Then undoing that patch. Then running check_spidermonkey_style.py --fixup Then running `./mach clang-format` I had to fix four things: * I needed to move <utility> back down in GuardObjects.h because I was hitting obscure problems with our system include wrappers like this: 0:03.94 /usr/include/stdlib.h:550:14: error: exception specification in declaration does not match previous declaration 0:03.94 extern void *realloc (void *__ptr, size_t __size) 0:03.94 ^ 0:03.94 /home/emilio/src/moz/gecko-2/obj-debug/dist/include/malloc_decls.h:53:1: note: previous declaration is here 0:03.94 MALLOC_DECL(realloc, void*, void*, size_t) 0:03.94 ^ 0:03.94 /home/emilio/src/moz/gecko-2/obj-debug/dist/include/mozilla/mozalloc.h:22:32: note: expanded from macro 'MALLOC_DECL' 0:03.94 MOZ_MEMORY_API return_type name##_impl(__VA_ARGS__); 0:03.94 ^ 0:03.94 <scratch space>:178:1: note: expanded from here 0:03.94 realloc_impl 0:03.94 ^ 0:03.94 /home/emilio/src/moz/gecko-2/obj-debug/dist/include/mozmemory_wrap.h:142:41: note: expanded from macro 'realloc_impl' 0:03.94 #define realloc_impl mozmem_malloc_impl(realloc) Which I really didn't feel like digging into. * I had to restore the order of TrustOverrideUtils.h and related files in nss because the .inc files depend on TrustOverrideUtils.h being included earlier. * I had to add a missing include to RollingNumber.h * Also had to partially restore include order in JsepSessionImpl.cpp to avoid some -WError issues due to some static inline functions being defined in a header but not used in the rest of the compilation unit. Differential Revision: https://phabricator.services.mozilla.com/D60327 --HG-- extra : moz-landing-system : lando
2020-01-20 19:19:48 +03:00
#include "nsTHashtable.h"
template <class KeyClass, class DataType, class UserDataType, class Converter>
class nsBaseHashtable; // forward declaration
/**
* Data type conversion helper that is used to wrap and unwrap the specified
* DataType.
*/
template <class DataType, class UserDataType>
class nsDefaultConverter {
public:
/**
* Maps the storage DataType to the exposed UserDataType.
*/
static UserDataType Unwrap(DataType& src) { return UserDataType(src); }
/**
* Const ref variant used for example with nsCOMPtr wrappers.
*/
static DataType Wrap(const UserDataType& src) { return DataType(src); }
/**
* Generic conversion, this is useful for things like already_AddRefed.
*/
template <typename U>
static DataType Wrap(U&& src) {
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
return std::forward<U>(src);
}
template <typename U>
static UserDataType Unwrap(U&& src) {
return std::forward<U>(src);
}
};
/**
* the private nsTHashtable::EntryType class used by nsBaseHashtable
* @see nsTHashtable for the specification of this class
* @see nsBaseHashtable for template parameters
*/
template <class KeyClass, class DataType>
class nsBaseHashtableET : public KeyClass {
public:
const DataType& GetData() const { return mData; }
DataType* GetModifiableData() { return &mData; }
template <typename U>
void SetData(U&& aData) {
mData = std::forward<U>(aData);
}
private:
DataType mData;
friend class nsTHashtable<nsBaseHashtableET<KeyClass, DataType>>;
template <typename KeyClassX, typename DataTypeX, typename UserDataTypeX,
typename ConverterX>
friend class nsBaseHashtable;
typedef typename KeyClass::KeyType KeyType;
typedef typename KeyClass::KeyTypePointer KeyTypePointer;
explicit nsBaseHashtableET(KeyTypePointer aKey);
nsBaseHashtableET(KeyTypePointer aKey, const DataType& aData);
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
nsBaseHashtableET(KeyTypePointer aKey, DataType&& aData);
nsBaseHashtableET(nsBaseHashtableET<KeyClass, DataType>&& aToMove);
~nsBaseHashtableET() = default;
};
/**
* templated hashtable for simple data types
* This class manages simple data types that do not need construction or
* destruction.
*
* @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
* for a complete specification.
* @param DataType the datatype stored in the hashtable,
* for example, uint32_t or nsCOMPtr.
* @param UserDataType the user sees, for example uint32_t or nsISupports*
* @param Converter that can be used to map from DataType to UserDataType. A
* default converter is provided that assumes implicit conversion is an
* option.
*/
template <class KeyClass, class DataType, class UserDataType,
class Converter = nsDefaultConverter<DataType, UserDataType>>
class nsBaseHashtable
: protected nsTHashtable<nsBaseHashtableET<KeyClass, DataType>> {
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
using Base = nsTHashtable<nsBaseHashtableET<KeyClass, DataType>>;
typedef mozilla::fallible_t fallible_t;
public:
typedef typename KeyClass::KeyType KeyType;
typedef nsBaseHashtableET<KeyClass, DataType> EntryType;
using nsTHashtable<EntryType>::Contains;
using nsTHashtable<EntryType>::GetGeneration;
using nsTHashtable<EntryType>::SizeOfExcludingThis;
using nsTHashtable<EntryType>::SizeOfIncludingThis;
nsBaseHashtable() = default;
explicit nsBaseHashtable(uint32_t aInitLength)
: nsTHashtable<EntryType>(aInitLength) {}
/**
* Return the number of entries in the table.
* @return number of entries
*/
uint32_t Count() const { return nsTHashtable<EntryType>::Count(); }
/**
* Return whether the table is empty.
* @return whether empty
*/
bool IsEmpty() const { return nsTHashtable<EntryType>::IsEmpty(); }
/**
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
* Get the value, returning a flag indicating the presence of the entry in
* the table.
*
* @param aKey the key to retrieve
* @param aData data associated with this key will be placed at this pointer.
* If you only need to check if the key exists, aData may be null.
* @return true if the key exists. If key does not exist, aData is not
* modified.
*/
bool Get(KeyType aKey, UserDataType* aData) const {
EntryType* ent = this->GetEntry(aKey);
if (!ent) {
return false;
}
if (aData) {
*aData = Converter::Unwrap(ent->mData);
}
return true;
}
/**
* Get the value, returning a zero-initialized POD or a default-initialized
* object if the entry is not present in the table.
*
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
* This overload can only be used if UserDataType is default-constructible.
* Use the double-argument Get or MaybeGet with non-default-constructible
* UserDataType.
*
* @param aKey the key to retrieve
* @return The found value, or UserDataType{} if no entry was found with the
* given key.
* @note If zero/default-initialized values are stored in the table, it is
* not possible to distinguish between such a value and a missing entry.
*/
UserDataType Get(KeyType aKey) const {
EntryType* ent = this->GetEntry(aKey);
if (!ent) {
return UserDataType{};
}
return Converter::Unwrap(ent->mData);
}
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
/**
* Get the value, returning Nothing if the entry is not present in the table.
*
* @param aKey the key to retrieve
* @return The found value wrapped in a Maybe, or Nothing if no entry was
* found with the given key.
*/
mozilla::Maybe<UserDataType> MaybeGet(KeyType aKey) const {
EntryType* ent = this->GetEntry(aKey);
if (!ent) {
return mozilla::Nothing();
}
return mozilla::Some(Converter::Unwrap(ent->mData));
}
/**
* Add aKey to the table if not already present, and return a reference to its
* value. If aKey is not already in the table then the a default-constructed
* or the provided value aData is used.
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
*
* If the arguments are non-trivial to provide, consider using GetOrInsertWith
* instead.
*/
template <typename... Args>
DataType& GetOrInsert(const KeyType& aKey, Args&&... aArgs) {
return WithEntryHandle(aKey, [&](auto entryHandle) -> DataType& {
return entryHandle.OrInsert(std::forward<Args>(aArgs)...);
});
}
/**
* Add aKey to the table if not already present, and return a reference to its
* value. If aKey is not already in the table then the value is
* constructed using the given factory.
*/
template <typename F>
DataType& GetOrInsertWith(const KeyType& aKey, F&& aFunc) {
return WithEntryHandle(aKey, [&aFunc](auto entryHandle) -> DataType& {
return entryHandle.OrInsertWith(std::forward<F>(aFunc));
});
}
/**
* Put a new value for the associated key
* @param aKey the key to put
* @param aData the new data
*/
void Put(KeyType aKey, const UserDataType& aData) {
WithEntryHandle(aKey, [&aData](auto entryHandle) {
entryHandle.InsertOrUpdate(Converter::Wrap(aData));
});
}
[[nodiscard]] bool Put(KeyType aKey, const UserDataType& aData,
const fallible_t& aFallible) {
return WithEntryHandle(aKey, aFallible, [&aData](auto maybeEntryHandle) {
if (!maybeEntryHandle) {
return false;
}
maybeEntryHandle->InsertOrUpdate(Converter::Wrap(aData));
return true;
});
}
/**
* Put a new value for the associated key
* @param aKey the key to put
* @param aData the new data
*/
void Put(KeyType aKey, UserDataType&& aData) {
WithEntryHandle(aKey, [&aData](auto entryHandle) {
entryHandle.InsertOrUpdate(Converter::Wrap(std::move(aData)));
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
});
}
[[nodiscard]] bool Put(KeyType aKey, UserDataType&& aData,
const fallible_t& aFallible) {
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
return WithEntryHandle(aKey, aFallible, [&aData](auto maybeEntryHandle) {
if (!maybeEntryHandle) {
return false;
}
maybeEntryHandle->InsertOrUpdate(Converter::Wrap(std::move(aData)));
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
return true;
});
}
/**
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
* Remove the entry associated with aKey (if any), _moving_ its current value
* into *aData. Return true if found.
*
* This overload can only be used if DataType is default-constructible. Use
* the single-argument Remove or GetAndRemove with non-default-constructible
* DataType.
*
* @param aKey the key to remove from the hashtable
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
* @param aData where to move the value. If an entry is not found, *aData
* will be assigned a default-constructed value (i.e. reset to
* zero or nullptr for primitive types).
* @return true if an entry for aKey was found (and removed)
*/
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
bool Remove(KeyType aKey, DataType* aData) {
if (auto* ent = this->GetEntry(aKey)) {
if (aData) {
*aData = std::move(ent->mData);
}
this->RemoveEntry(ent);
return true;
}
if (aData) {
*aData = std::move(DataType());
}
return false;
}
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
/**
* Remove the entry associated with aKey (if any). Return true if found.
*
* @param aKey the key to remove from the hashtable
* @return true if an entry for aKey was found (and removed)
*/
bool Remove(KeyType aKey) {
if (auto* ent = this->GetEntry(aKey)) {
this->RemoveEntry(ent);
return true;
}
return false;
}
/**
* Retrieve the value for a key and remove the corresponding entry at
* the same time.
*
* @param aKey the key to retrieve and remove
* @return the found value, or Nothing if no entry was found with the
* given key.
*/
[[nodiscard]] mozilla::Maybe<DataType> GetAndRemove(KeyType aKey) {
mozilla::Maybe<DataType> value;
if (EntryType* ent = this->GetEntry(aKey)) {
value.emplace(std::move(ent->mData));
this->RemoveEntry(ent);
}
return value;
}
struct LookupResult {
private:
EntryType* mEntry;
nsBaseHashtable& mTable;
#ifdef DEBUG
uint32_t mTableGeneration;
#endif
public:
LookupResult(EntryType* aEntry, nsBaseHashtable& aTable)
: mEntry(aEntry),
mTable(aTable)
#ifdef DEBUG
,
mTableGeneration(aTable.GetGeneration())
#endif
{
}
// Is there something stored in the table?
explicit operator bool() const {
MOZ_ASSERT(mTableGeneration == mTable.GetGeneration());
return mEntry;
}
void Remove() {
if (!*this) {
return;
}
mTable.RemoveEntry(mEntry);
mEntry = nullptr;
}
[[nodiscard]] DataType& Data() {
MOZ_ASSERT(!!*this, "must have an entry to access its value");
return mEntry->mData;
}
};
/**
* Removes all entries matching a predicate.
*
* The predicate must be compatible with signature bool (const Iterator &).
*/
template <typename Pred>
void RemoveIf(Pred&& aPred) {
for (auto iter = Iter(); !iter.Done(); iter.Next()) {
if (aPred(const_cast<std::add_const_t<decltype(iter)>&>(iter))) {
iter.Remove();
}
}
}
/**
* Looks up aKey in the hashtable and returns an object that allows you to
* read/modify the value of the entry, or remove the entry (if found).
*
* A typical usage of this API looks like this:
*
* if (auto entry = hashtable.Lookup(key)) {
* DoSomething(entry.Data());
* if (entry.Data() > 42) {
* entry.Remove();
* }
* } // else - an entry with the given key doesn't exist
*
* This is useful for cases where you want to read/write the value of an entry
* and (optionally) remove the entry without having to do multiple hashtable
* lookups. If you want to insert a new entry if one does not exist, then use
* WithEntryHandle instead, see below.
*/
[[nodiscard]] LookupResult Lookup(KeyType aKey) {
return LookupResult(this->GetEntry(aKey), *this);
}
/**
* Used by WithEntryHandle as the argument type to its functor. It is
* associated with the Key passed to WithEntryHandle and manages only the
* potential entry with that key. Note that in case no modifying operations
* are called on the handle, the state of the hashtable remains unchanged,
* i.e. WithEntryHandle does not modify the hashtable itself.
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
*
* Provides query functions (Key, HasEntry/operator bool, Data) and
* modifying operations for inserting new entries (Insert), updating existing
* entries (Update) and removing existing entries (Remove). They have
* debug-only assertion that fail when the state of the entry doesn't match
* the expectation. There are variants prefixed with "Or" (OrInsert, OrUpdate,
* OrRemove) that are a no-op in case the entry does already exist resp. does
* not exist. There are also variants OrInsertWith and OrUpdateWith that don't
* accept a value, but a functor, which is only called if the operation takes
* place, which should be used if the provision of the value is not trivial
* (e.g. allocates a heap object). Finally, there's InsertOrUpdate that
* handles both existing and non-existing entries.
*
* Note that all functions of EntryHandle only deal with DataType, not with
* UserDataType.
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
*/
class EntryHandle : protected nsTHashtable<EntryType>::EntryHandle {
public:
using Base = typename nsTHashtable<EntryType>::EntryHandle;
EntryHandle(EntryHandle&& aOther) = default;
~EntryHandle() = default;
EntryHandle(const EntryHandle&) = delete;
EntryHandle& operator=(const EntryHandle&) = delete;
EntryHandle& operator=(const EntryHandle&&) = delete;
using Base::Key;
using Base::HasEntry;
using Base::operator bool;
using Base::Entry;
/**
* Inserts a new entry with the handle's key and the value passed to this
* function.
*
* \tparam Args DataType must be constructible from Args
* \pre !HasEntry()
* \post HasEntry()
*/
template <typename... Args>
DataType& Insert(Args&&... aArgs) {
Base::InsertInternal(std::forward<Args>(aArgs)...);
return Data();
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
}
/**
* If it doesn't yet exist, inserts a new entry with the handle's key and
* the value passed to this function. The value is not consumed if no insert
* takes place.
*
* \tparam Args DataType must be constructible from Args
* \post HasEntry()
*/
template <typename... Args>
DataType& OrInsert(Args&&... aArgs) {
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
if (!HasEntry()) {
return Insert(std::forward<Args>(aArgs)...);
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
}
return Data();
}
/**
* If it doesn't yet exist, inserts a new entry with the handle's key and
* the result of the functor passed to this function. The functor is not
* called if no insert takes place.
*
* \tparam F must return a value that DataType is constructible from
* \post HasEntry()
*/
template <typename F>
DataType& OrInsertWith(F&& aFunc) {
if (!HasEntry()) {
return Insert(std::forward<F>(aFunc)());
}
return Data();
}
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
/**
* Updates the entry with the handle's key by the value passed to this
* function.
*
* \tparam U DataType must be assignable from U
* \pre HasEntry()
*/
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
template <typename U>
DataType& Update(U&& aData) {
MOZ_RELEASE_ASSERT(HasEntry());
Data() = std::forward<U>(aData);
return Data();
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
}
/**
* If an entry with the handle's key already exists, updates its value by
* the value passed to this function. The value is not consumed if no update
* takes place.
*
* \tparam U DataType must be assignable from U
*/
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
template <typename U>
void OrUpdate(U&& aData) {
if (HasEntry()) {
Update(std::forward<U>(aData));
}
}
/**
* If an entry with the handle's key already exists, updates its value by
* the the result of the functor passed to this function. The functor is not
* called if no update takes place.
*
* \tparam F must return a value that DataType is assignable from
*/
template <typename F>
void OrUpdateWith(F&& aFunc) {
if (HasEntry()) {
Update(std::forward<F>(aFunc)());
}
}
/**
* If it does not yet, inserts a new entry with the handle's key and the
* value passed to this function. Otherwise, it updates the entry by the
* value passed to this function.
*
* \tparam U DataType must be constructible and assignable from U
* \post HasEntry()
*/
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
template <typename U>
DataType& InsertOrUpdate(U&& aData) {
if (!HasEntry()) {
Insert(std::forward<U>(aData));
} else {
Update(std::forward<U>(aData));
}
return Data();
}
using Base::Remove;
using Base::OrRemove;
/**
* Returns a reference to the value of the entry.
*
* \pre HasEntry()
*/
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
DataType& Data() { return Entry()->mData; }
private:
friend class nsBaseHashtable;
explicit EntryHandle(Base&& aBase) : Base(std::move(aBase)) {}
};
/**
* Performs a scoped operation on the entry for aKey, which may or may not
* exist when the function is called. It calls aFunc with an EntryHandle. The
* result of aFunc is returned as the result of this function. Its return type
* may be void. See the documentation of EntryHandle for the query and
* modifying operations it offers.
*
* A simple use of this function is, e.g.,
*
* hashtable.WithEntryHandle(key, [](auto&& entry) { entry.OrInsert(42); });
*
* \attention It is not safe to perform modifying operations on the hashtable
* other than through the EntryHandle within aFunc, and trying to do so will
* trigger debug assertions, and result in undefined behaviour otherwise.
*/
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
template <class F>
auto WithEntryHandle(KeyType aKey, F&& aFunc)
-> std::invoke_result_t<F, EntryHandle&&> {
return Base::WithEntryHandle(
aKey, [&aFunc](auto entryHandle) -> decltype(auto) {
return std::forward<F>(aFunc)(EntryHandle{std::move(entryHandle)});
});
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
}
/**
* Fallible variant of WithEntryHandle, with the following differences:
* - The functor aFunc must accept a Maybe<EntryHandle> (instead of an
* EntryHandle).
* - In case allocation of the slot for the entry fails, Nothing is passed to
* the functor.
*
* For more details, see the explanation on the non-fallible overload above.
*/
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
template <class F>
auto WithEntryHandle(KeyType aKey, const fallible_t& aFallible, F&& aFunc)
-> std::invoke_result_t<F, mozilla::Maybe<EntryHandle>&&> {
return Base::WithEntryHandle(
aKey, aFallible, [&aFunc](auto maybeEntryHandle) {
return std::forward<F>(aFunc)(
maybeEntryHandle
? mozilla::Some(EntryHandle{maybeEntryHandle.extract()})
: mozilla::Nothing());
});
}
public:
// This is an iterator that also allows entry removal. Example usage:
//
// for (auto iter = table.Iter(); !iter.Done(); iter.Next()) {
// const KeyType key = iter.Key();
// const UserDataType data = iter.UserData();
// // or
// const DataType& data = iter.Data();
// // ... do stuff with |key| and/or |data| ...
// // ... possibly call iter.Remove() once ...
// }
//
class Iterator : public PLDHashTable::Iterator {
public:
typedef PLDHashTable::Iterator Base;
explicit Iterator(nsBaseHashtable* aTable) : Base(&aTable->mTable) {}
Iterator(Iterator&& aOther) : Base(aOther.mTable) {}
~Iterator() = default;
KeyType Key() const { return static_cast<EntryType*>(Get())->GetKey(); }
UserDataType UserData() const {
return Converter::Unwrap(static_cast<EntryType*>(Get())->mData);
}
DataType& Data() const { return static_cast<EntryType*>(Get())->mData; }
private:
Iterator() = delete;
Iterator(const Iterator&) = delete;
Iterator& operator=(const Iterator&) = delete;
Iterator& operator=(const Iterator&&) = delete;
};
Iterator Iter() { return Iterator(this); }
Iterator ConstIter() const {
return Iterator(const_cast<nsBaseHashtable*>(this));
}
using typename nsTHashtable<EntryType>::iterator;
using typename nsTHashtable<EntryType>::const_iterator;
using nsTHashtable<EntryType>::begin;
using nsTHashtable<EntryType>::end;
using nsTHashtable<EntryType>::cbegin;
using nsTHashtable<EntryType>::cend;
/**
* reset the hashtable, removing all entries
*/
void Clear() { nsTHashtable<EntryType>::Clear(); }
/**
* Measure the size of the table's entry storage. The size of things pointed
* to by entries must be measured separately; hence the "Shallow" prefix.
*
* @param aMallocSizeOf the function used to measure heap-allocated blocks
* @return the summed size of the table's storage
*/
size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
return this->mTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
}
/**
* Like ShallowSizeOfExcludingThis, but includes sizeof(*this).
*/
size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) + ShallowSizeOfExcludingThis(aMallocSizeOf);
}
/**
* Swap the elements in this hashtable with the elements in aOther.
*/
void SwapElements(nsBaseHashtable& aOther) {
nsTHashtable<EntryType>::SwapElements(aOther);
}
using nsTHashtable<EntryType>::MarkImmutable;
};
//
// nsBaseHashtableET definitions
//
template <class KeyClass, class DataType>
nsBaseHashtableET<KeyClass, DataType>::nsBaseHashtableET(KeyTypePointer aKey)
: KeyClass(aKey), mData() {}
template <class KeyClass, class DataType>
nsBaseHashtableET<KeyClass, DataType>::nsBaseHashtableET(KeyTypePointer aKey,
const DataType& aData)
: KeyClass(aKey), mData(aData) {}
Bug 1681469 - Allow nsBaseHashtable to work with a non-default-constructible/non-movable DataType; r=nika nsBaseHashtable now supports non-default-constructible DataType and UserDataType, however not all methods can be instantiated. All methods which can't be instantiated with non-default-constructible DataType or UserDataType are now described as such in method definitions. The public API of PLDHashTable and nsBaseHashtable/nsDataHashtable was changed: - A new method PLDHashTable::WithEntryHandle has been added. It allows to use a custom function for entry initialization (instead of the global hook). - A new method nsBaseHashtable::MaybeGet has been added. - A new overload nsBaseHashtable::Remove has been added. - The nsDataHashtable::GetAndRemove method has been pulled up to nsBaseHashtable. In addition, the following implementation details have changed: PLDHashTable: - The code from the Add method has been split into MakeEntryHandle and a helper object called EntryHandle. The Add method is now implemented on top of that. nsTHashtable: - A new (non-public) API for WithEntryHandle has been added. - The InitEntry hook is no longer used. Instead of using the hook, PutEntry methods now use nsTHashtable::WithEntryHandle instead of PLDHashTable::Add. This change allows to do custom initialization in derived classes. nsBaseHashtable: - A new (non-public) API for WithEntryHandle has been added. - Put methods no longer use nsTHashtable::PutEntry, they now use the new method nsBaseHashtable::WithEntryHandle. Differential Revision: https://phabricator.services.mozilla.com/D99428
2021-01-29 11:39:40 +03:00
template <class KeyClass, class DataType>
nsBaseHashtableET<KeyClass, DataType>::nsBaseHashtableET(KeyTypePointer aKey,
DataType&& aData)
: KeyClass(aKey), mData(std::move(aData)) {}
template <class KeyClass, class DataType>
nsBaseHashtableET<KeyClass, DataType>::nsBaseHashtableET(
nsBaseHashtableET<KeyClass, DataType>&& aToMove)
: KeyClass(std::move(aToMove)), mData(std::move(aToMove.mData)) {}
#endif // nsBaseHashtable_h__