Bug 1634281 - Add nsTHashMap. r=xpcom-reviewers,nika

Differential Revision: https://phabricator.services.mozilla.com/D105962
This commit is contained in:
Simon Giesecke 2021-03-09 11:39:35 +00:00
Родитель 46c22b83c6
Коммит 32b1a38aa7
3 изменённых файлов: 117 добавлений и 0 удалений

Просмотреть файл

@ -76,6 +76,7 @@ EXPORTS += [
"nsTArray-inl.h",
"nsTArray.h",
"nsTArrayForwardDeclare.h",
"nsTHashMap.h",
"nsTHashtable.h",
"nsTObserverArray.h",
"nsTPriorityQueue.h",

Просмотреть файл

@ -33,6 +33,7 @@ class nsClassHashtable;
/**
* templated hashtable class maps keys to simple datatypes.
* See nsBaseHashtable for complete declaration
* @deprecated This is going to be removed. Use nsTHashMap instead.
* @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
* for a complete specification.
* @param DataType the simple datatype being wrapped
@ -47,6 +48,7 @@ class nsRefCountedHashtable;
/**
* templated hashtable class maps keys to interface pointers.
* See nsBaseHashtable for complete declaration.
* @deprecated This is going to be removed. Use nsTHashMap instead.
* @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
* for a complete specification.
* @param Interface the interface-type being wrapped
@ -59,6 +61,7 @@ using nsInterfaceHashtable =
/**
* templated hashtable class maps keys to reference pointers.
* See nsBaseHashtable for complete declaration.
* @deprecated This is going to be removed. Use nsTHashMap instead.
* @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
* for a complete specification.
* @param PtrType the reference-type being wrapped
@ -67,4 +70,30 @@ using nsInterfaceHashtable =
template <class KeyClass, class ClassType>
using nsRefPtrHashtable = nsRefCountedHashtable<KeyClass, RefPtr<ClassType>>;
namespace mozilla::detail {
template <class KeyType>
struct nsKeyClass;
} // namespace mozilla::detail
/**
* A universal hash map that maps some KeyType to some DataType. It can be used
* for any DataType, including RefPtr<T>, nsCOMPtr<T> and UniquePtr<T>.
*
* For the default hash keys types, the appropriate hash key class is determined
* automatically, so you can just specify `nsTHashMap<uint32_t,
* RefPtr<Foo>>`, for example.
*
* If you require custom hash behaviour (e.g. case insensitive string handling),
* you can still specify a hash key class derived from PLDHashEntryHdr
* explicitly.
*
* If you need to use a custom UserDataType, use nsBaseHashtable (or
* nsTHashtable) directly. However, you should double-check if that's really
* necessary.
*/
template <class KeyType, class DataType>
using nsTHashMap =
nsBaseHashtable<typename mozilla::detail::nsKeyClass<KeyType>::type,
DataType, DataType>;
#endif // XPCOM_DS_NSHASHTABLESFWD_H_

87
xpcom/ds/nsTHashMap.h Normal file
Просмотреть файл

@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 XPCOM_DS_NSTHASHMAP_H_
#define XPCOM_DS_NSTHASHMAP_H_
#include "mozilla/Attributes.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsBaseHashtable.h"
#include "nsCOMPtr.h"
#include "nsHashKeys.h"
#include "nsHashtablesFwd.h"
#include <type_traits>
namespace mozilla::detail {
template <class KeyType>
struct nsKeyClass {
// Prevent instantiation with an incomplete KeyType, as std::is_base_of_v
// would have undefined behaviour then.
static_assert(sizeof(KeyType) > 0,
"KeyType must be a complete type (unless there's an explicit "
"specialization for nsKeyClass<KeyType>)");
static_assert(std::is_base_of_v<PLDHashEntryHdr, KeyType>,
"KeyType must inherit from PLDHashEntryHdr (unless there's an "
"explicit specialization for nsKeyClass<KeyType>)");
using type = std::conditional_t<std::is_base_of_v<PLDHashEntryHdr, KeyType>,
KeyType, void>;
};
template <typename KeyType>
struct nsKeyClass<KeyType*> {
using type = nsPtrHashKey<KeyType>;
};
template <>
struct nsKeyClass<nsCString> {
using type = nsCStringHashKey;
};
// This uses the case-sensitive hash key class, if you want the
// case-insensitive hash key, use nsStringCaseInsensitiveHashKey explicitly.
template <>
struct nsKeyClass<nsString> {
using type = nsStringHashKey;
};
template <>
struct nsKeyClass<uint32_t> {
using type = nsUint32HashKey;
};
template <>
struct nsKeyClass<uint64_t> {
using type = nsUint64HashKey;
};
template <>
struct nsKeyClass<intptr_t> {
using type = IntPtrHashKey;
};
template <>
struct nsKeyClass<nsCOMPtr<nsISupports>> {
using type = nsISupportsHashKey;
};
template <typename T>
struct nsKeyClass<RefPtr<T>> {
using type = nsRefPtrHashKey<T>;
};
template <>
struct nsKeyClass<nsID> {
using type = nsIDHashKey;
};
} // namespace mozilla::detail
// The actual definition of nsTHashMap is in nsHashtablesFwd.h, since it is a
// type alias.
#endif // XPCOM_DS_NSTHASHMAP_H_