Bug 1640839 - Add some helpers for enums to calculate the size and use it in EnumeratedArray. r=glandium,jgilbert,media-playback-reviewers,padenot

Differential Revision: https://phabricator.services.mozilla.com/D201334
This commit is contained in:
Peter Van der Beken 2024-03-02 07:50:19 +00:00
parent 9c8d00b7fb
commit 2b747df80a
53 changed files with 189 additions and 126 deletions

View File

@ -245,7 +245,7 @@ class EffectCompositor {
// indicate that the style rule on the element is out of date but without
// posting a restyle to update it.
EnumeratedArray<CascadeLevel, nsTHashMap<PseudoElementHashEntry, bool>,
CascadeLevel(kCascadeLevelCount)>
kCascadeLevelCount>
mElementsToRestyle;
bool mIsInPreTraverse = false;

View File

@ -40,7 +40,7 @@ enum class FlushType : uint8_t {
// Flush type strings that will be displayed in the profiler
// clang-format off
const EnumeratedArray<FlushType, const char*, FlushType::Count>
const EnumeratedArray<FlushType, const char*, size_t(FlushType::Count)>
kFlushTypeNames = {
"",
"Event",

View File

@ -1008,9 +1008,11 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal,
RefPtr<nsAtom> fontLanguage;
nsFont fontFont;
EnumeratedArray<Style, RefPtr<CanvasGradient>, Style::MAX> gradientStyles;
EnumeratedArray<Style, RefPtr<CanvasPattern>, Style::MAX> patternStyles;
EnumeratedArray<Style, nscolor, Style::MAX> colorStyles;
EnumeratedArray<Style, RefPtr<CanvasGradient>, size_t(Style::MAX)>
gradientStyles;
EnumeratedArray<Style, RefPtr<CanvasPattern>, size_t(Style::MAX)>
patternStyles;
EnumeratedArray<Style, nscolor, size_t(Style::MAX)> colorStyles;
nsCString font;
CanvasTextAlign textAlign = CanvasTextAlign::Start;

View File

@ -969,7 +969,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
// WebGL extensions (implemented in WebGLContextExtensions.cpp)
EnumeratedArray<WebGLExtensionID, std::unique_ptr<WebGLExtensionBase>,
WebGLExtensionID::Max>
size_t(WebGLExtensionID::Max)>
mExtensions;
public:

View File

@ -51,7 +51,7 @@ using namespace gfx;
// should be launched serially. Protects sLaunchPromise
StaticMutex sLaunchMutex;
static EnumeratedArray<RemoteDecodeIn, StaticRefPtr<GenericNonExclusivePromise>,
RemoteDecodeIn::SENTINEL>
size_t(RemoteDecodeIn::SENTINEL)>
sLaunchPromises MOZ_GUARDED_BY(sLaunchMutex);
// Only modified on the main-thread, read on any thread. While it could be read
@ -62,7 +62,7 @@ static StaticDataMutex<StaticRefPtr<nsIThread>>
// Only accessed from sRemoteDecoderManagerChildThread
static EnumeratedArray<RemoteDecodeIn, StaticRefPtr<RemoteDecoderManagerChild>,
RemoteDecodeIn::SENTINEL>
size_t(RemoteDecodeIn::SENTINEL)>
sRemoteDecoderManagerChildForProcesses;
static StaticAutoPtr<nsTArray<RefPtr<Runnable>>> sRecreateTasks;
@ -71,7 +71,7 @@ static StaticAutoPtr<nsTArray<RefPtr<Runnable>>> sRecreateTasks;
// processes.
StaticMutex sProcessSupportedMutex;
static EnumeratedArray<RemoteDecodeIn, Maybe<media::MediaCodecsSupported>,
RemoteDecodeIn::SENTINEL>
size_t(RemoteDecodeIn::SENTINEL)>
sProcessSupported MOZ_GUARDED_BY(sProcessSupportedMutex);
class ShutdownObserver final : public nsIObserver {

View File

@ -121,7 +121,7 @@ class MediaSession final : public nsIDocumentActivity, public nsWrapperCache {
RefPtr<MediaMetadata> mMediaMetadata;
EnumeratedArray<MediaSessionAction, RefPtr<MediaSessionActionHandler>,
MediaSessionAction::EndGuard_>
size_t(MediaSessionAction::EndGuard_)>
mActionHandlers;
// This is used as is a hint for the user agent to determine whether the

View File

@ -727,7 +727,8 @@ class QuotaManager final : public BackgroundThreadObject {
nsCOMPtr<mozIStorageConnection> mStorageConnection;
EnumeratedArray<Client::Type, nsCString, Client::TYPE_MAX> mShutdownSteps;
EnumeratedArray<Client::Type, nsCString, size_t(Client::TYPE_MAX)>
mShutdownSteps;
LazyInitializedOnce<const TimeStamp> mShutdownStartedAt;
// Accesses to mQuotaManagerShutdownSteps must be protected by mQuotaMutex.

View File

@ -69,8 +69,8 @@ class IOUtils final {
};
template <typename T>
using PhaseArray =
EnumeratedArray<IOUtils::ShutdownPhase, T, IOUtils::ShutdownPhase::Count>;
using PhaseArray = EnumeratedArray<IOUtils::ShutdownPhase, T,
size_t(IOUtils::ShutdownPhase::Count)>;
static already_AddRefed<Promise> Read(GlobalObject& aGlobal,
const nsAString& aPath,

View File

@ -241,7 +241,8 @@ class PathUtils::DirectoryCache final {
void ResolveWithDirectory(Promise* aPromise, const Directory aRequestedDir);
template <typename T>
using DirectoryArray = EnumeratedArray<Directory, T, Directory::Count>;
using DirectoryArray =
EnumeratedArray<Directory, T, size_t(Directory::Count)>;
DirectoryArray<nsString> mDirectories;
DirectoryArray<MozPromiseHolder<PopulateDirectoriesPromise>> mPromises;

View File

@ -190,7 +190,7 @@ struct txEXSLTFunctionDescriptor {
};
static EnumeratedArray<txEXSLTType, txEXSLTFunctionDescriptor,
txEXSLTType::_LIMIT>
size_t(txEXSLTType::_LIMIT)>
descriptTable;
class txEXSLTFunctionCall : public FunctionCall {

View File

@ -192,7 +192,7 @@ class Image {
mozilla::EnumeratedArray<mozilla::layers::LayersBackend,
UniquePtr<ImageBackendData>,
mozilla::layers::LayersBackend::LAYERS_LAST>
size_t(mozilla::layers::LayersBackend::LAYERS_LAST)>
mBackendData;
void* mImplData;

View File

@ -18,7 +18,7 @@ using namespace mozilla::ipc;
using namespace mozilla::gfx;
using VideoBridgeTable = EnumeratedArray<VideoBridgeSource, VideoBridgeParent*,
VideoBridgeSource::_Count>;
size_t(VideoBridgeSource::_Count)>;
static StaticDataMutex<VideoBridgeTable> sVideoBridgeFromProcess(
"VideoBridges");

View File

@ -1011,12 +1011,13 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
// When system-wide font lookup fails for a character, cache it to skip future
// searches. This is an array of bitsets, one for each FontVisibility level.
mozilla::EnumeratedArray<FontVisibility, gfxSparseBitSet,
FontVisibility::Count>
size_t(FontVisibility::Count)>
mCodepointsWithNoFonts MOZ_GUARDED_BY(mLock);
// the family to use for U+FFFD fallback, to avoid expensive search every time
// on pages with lots of problems
mozilla::EnumeratedArray<FontVisibility, FontFamily, FontVisibility::Count>
mozilla::EnumeratedArray<FontVisibility, FontFamily,
size_t(FontVisibility::Count)>
mReplacementCharFallbackFamily MOZ_GUARDED_BY(mLock);
// Sorted array of lowercased family names; use ContainsSorted to test

View File

@ -43,7 +43,7 @@ NS_IMETHODIMP UtilityAudioDecoderChildShutdownObserver::Observe(
NS_IMPL_ISUPPORTS(UtilityAudioDecoderChildShutdownObserver, nsIObserver);
static EnumeratedArray<SandboxingKind, StaticRefPtr<UtilityAudioDecoderChild>,
SandboxingKind::COUNT>
size_t(SandboxingKind::COUNT)>
sAudioDecoderChilds;
UtilityAudioDecoderChild::UtilityAudioDecoderChild(SandboxingKind aKind)

View File

@ -228,7 +228,8 @@ class UtilityProcessManager final : public UtilityProcessHost::Listener {
~ProcessFields() = default;
};
EnumeratedArray<SandboxingKind, RefPtr<ProcessFields>, SandboxingKind::COUNT>
EnumeratedArray<SandboxingKind, RefPtr<ProcessFields>,
size_t(SandboxingKind::COUNT)>
mProcesses;
RefPtr<ProcessFields> GetProcess(SandboxingKind);

View File

@ -981,12 +981,12 @@ enum class AutoGCRooterKind : uint8_t {
Limit
};
using RootedListHeads =
mozilla::EnumeratedArray<RootKind, js::StackRootedBase*, RootKind::Limit>;
using RootedListHeads = mozilla::EnumeratedArray<RootKind, js::StackRootedBase*,
size_t(RootKind::Limit)>;
using AutoRooterListHeads =
mozilla::EnumeratedArray<AutoGCRooterKind, AutoGCRooter*,
AutoGCRooterKind::Limit>;
size_t(AutoGCRooterKind::Limit)>;
// Superclass of JSContext which can be used for rooting data in use by the
// current thread but that does not provide all the functions of a JSContext.

View File

@ -197,13 +197,14 @@ constexpr auto SomeAllocKinds(AllocKind first = AllocKind::FIRST,
// with each index corresponding to a particular alloc kind.
template <typename ValueType>
using AllAllocKindArray =
mozilla::EnumeratedArray<AllocKind, ValueType, AllocKind::LIMIT>;
mozilla::EnumeratedArray<AllocKind, ValueType, size_t(AllocKind::LIMIT)>;
// ObjectAllocKindArray<ValueType> gives an enumerated array of ValueTypes,
// with each index corresponding to a particular object alloc kind.
template <typename ValueType>
using ObjectAllocKindArray =
mozilla::EnumeratedArray<AllocKind, ValueType, AllocKind::OBJECT_LIMIT>;
mozilla::EnumeratedArray<AllocKind, ValueType,
size_t(AllocKind::OBJECT_LIMIT)>;
/*
* Map from C++ type to alloc kind for non-object types. JSObject does not have

View File

@ -382,10 +382,10 @@ class Nursery {
};
using ProfileTimes = mozilla::EnumeratedArray<ProfileKey, mozilla::TimeStamp,
ProfileKey::KeyCount>;
size_t(ProfileKey::KeyCount)>;
using ProfileDurations =
mozilla::EnumeratedArray<ProfileKey, mozilla::TimeDuration,
ProfileKey::KeyCount>;
size_t(ProfileKey::KeyCount)>;
// Calculate the promotion rate of the most recent minor GC.
// The valid_for_tenuring parameter is used to return whether this

View File

@ -154,11 +154,11 @@ struct PhaseInfo {
};
// A table of PhaseInfo indexed by Phase.
using PhaseTable = EnumeratedArray<Phase, PhaseInfo, Phase::LIMIT>;
using PhaseTable = EnumeratedArray<Phase, PhaseInfo, size_t(Phase::LIMIT)>;
// A table of PhaseKindInfo indexed by PhaseKind.
using PhaseKindTable =
EnumeratedArray<PhaseKind, PhaseKindInfo, PhaseKind::LIMIT>;
EnumeratedArray<PhaseKind, PhaseKindInfo, size_t(PhaseKind::LIMIT)>;
#include "gc/StatsPhasesGenerated.inc"

View File

@ -138,7 +138,7 @@ struct Statistics {
template <typename IndexType, typename ValueType, IndexType SizeAsEnumValue>
using EnumeratedArray =
mozilla::EnumeratedArray<IndexType, ValueType, SizeAsEnumValue>;
mozilla::EnumeratedArray<IndexType, ValueType, size_t(SizeAsEnumValue)>;
using TimeDuration = mozilla::TimeDuration;
using TimeStamp = mozilla::TimeStamp;

View File

@ -2167,8 +2167,8 @@ class CreateDependentString {
NotInlineString,
Count
};
mozilla::EnumeratedArray<FallbackKind, Label, FallbackKind::Count> fallbacks_,
joins_;
mozilla::EnumeratedArray<FallbackKind, Label, size_t(FallbackKind::Count)>
fallbacks_, joins_;
public:
CreateDependentString(CharEncoding encoding, Register string, Register temp1,

View File

@ -72,7 +72,8 @@ class ExecutablePool {
bool m_mark : 1;
// Number of bytes currently allocated for each CodeKind.
mozilla::EnumeratedArray<CodeKind, size_t, CodeKind::Count> m_codeBytes;
mozilla::EnumeratedArray<CodeKind, size_t, size_t(CodeKind::Count)>
m_codeBytes;
public:
void release(bool willDestroy = false);

View File

@ -182,7 +182,7 @@ class OptimizationInfo {
class OptimizationLevelInfo {
private:
mozilla::EnumeratedArray<OptimizationLevel, OptimizationInfo,
OptimizationLevel::Count>
size_t(OptimizationLevel::Count)>
infos_;
public:

View File

@ -74,15 +74,16 @@ enum class BailoutReturnKind {
// is stored in JitRuntime and generated when creating the JitRuntime.
class BaselineICFallbackCode {
JitCode* code_ = nullptr;
using OffsetArray = mozilla::EnumeratedArray<BaselineICFallbackKind, uint32_t,
BaselineICFallbackKind::Count>;
using OffsetArray =
mozilla::EnumeratedArray<BaselineICFallbackKind, uint32_t,
size_t(BaselineICFallbackKind::Count)>;
OffsetArray offsets_ = {};
// Keep track of offset into various baseline stubs' code at return
// point from called script.
using BailoutReturnArray =
mozilla::EnumeratedArray<BailoutReturnKind, uint32_t,
BailoutReturnKind::Count>;
size_t(BailoutReturnKind::Count)>;
BailoutReturnArray bailoutReturnOffsets_ = {};
public:
@ -175,12 +176,12 @@ class JitRuntime {
// Thunk to do a generic call from Ion.
mozilla::EnumeratedArray<IonGenericCallKind, WriteOnceData<uint32_t>,
IonGenericCallKind::Count>
size_t(IonGenericCallKind::Count)>
ionGenericCallStubOffset_;
// Thunk used by the debugger for breakpoint and step mode.
mozilla::EnumeratedArray<DebugTrapHandlerKind, WriteOnceData<JitCode*>,
DebugTrapHandlerKind::Count>
size_t(DebugTrapHandlerKind::Count)>
debugTrapHandlers_;
// BaselineInterpreter state.

View File

@ -141,7 +141,8 @@ class JitZone {
Count
};
mozilla::EnumeratedArray<StubIndex, WeakHeapPtr<JitCode*>, StubIndex::Count>
mozilla::EnumeratedArray<StubIndex, WeakHeapPtr<JitCode*>,
size_t(StubIndex::Count)>
stubs_;
mozilla::Maybe<IonCompilationId> currentCompilationId_;

View File

@ -49,7 +49,8 @@ class MOZ_RAII WarpCacheIRTranspiler : public WarpBuilderShared {
// Array mapping call arguments to OperandId.
using ArgumentKindArray =
mozilla::EnumeratedArray<ArgumentKind, OperandId, ArgumentKind::NumKinds>;
mozilla::EnumeratedArray<ArgumentKind, OperandId,
size_t(ArgumentKind::NumKinds)>;
ArgumentKindArray argumentOperandIds_;
void setArgumentId(ArgumentKind kind, OperandId id) {

View File

@ -187,8 +187,8 @@ class StructuredSpewer {
// Globally selected channel.
StructuredSpewFilter selectedChannel_;
using NameArray =
mozilla::EnumeratedArray<SpewChannel, const char*, SpewChannel::Count>;
using NameArray = mozilla::EnumeratedArray<SpewChannel, const char*,
size_t(SpewChannel::Count)>;
// Channel Names
static NameArray const names_;

View File

@ -129,8 +129,8 @@ class GlobalObjectData {
HeapPtr<JSObject*> constructor;
HeapPtr<JSObject*> prototype;
};
using CtorArray =
mozilla::EnumeratedArray<JSProtoKey, ConstructorWithProto, JSProto_LIMIT>;
using CtorArray = mozilla::EnumeratedArray<JSProtoKey, ConstructorWithProto,
size_t(JSProto_LIMIT)>;
CtorArray builtinConstructors;
// Built-in prototypes for this global. Note that this is different from the
@ -154,8 +154,8 @@ class GlobalObjectData {
Limit
};
using ProtoArray =
mozilla::EnumeratedArray<ProtoKind, HeapPtr<JSObject*>, ProtoKind::Limit>;
using ProtoArray = mozilla::EnumeratedArray<ProtoKind, HeapPtr<JSObject*>,
size_t(ProtoKind::Limit)>;
ProtoArray builtinProtos;
HeapPtr<GlobalScope*> emptyGlobalScope;
@ -197,7 +197,7 @@ class GlobalObjectData {
// AllocKind.
using PlainObjectShapeArray =
mozilla::EnumeratedArray<PlainObjectSlotsKind, HeapPtr<SharedShape*>,
PlainObjectSlotsKind::Limit>;
size_t(PlainObjectSlotsKind::Limit)>;
PlainObjectShapeArray plainObjectShapesWithDefaultProto;
// Shape for JSFunction with %Function.prototype% as proto, for both

View File

@ -115,7 +115,8 @@ class GlobalHelperThreadState {
PromiseHelperTaskVector;
// Count of running task by each threadType.
mozilla::EnumeratedArray<ThreadType, size_t, ThreadType::THREAD_TYPE_MAX>
mozilla::EnumeratedArray<ThreadType, size_t,
size_t(ThreadType::THREAD_TYPE_MAX)>
runningTaskCount;
size_t totalCountRunningTasks;

View File

@ -528,7 +528,7 @@ struct JSRuntime {
// Heap GC roots for PersistentRooted pointers.
js::MainThreadData<mozilla::EnumeratedArray<
JS::RootKind, mozilla::LinkedList<js::PersistentRootedBase>,
JS::RootKind::Limit>>
size_t(JS::RootKind::Limit)>>
heapRoots;
void tracePersistentRoots(JSTracer* trc);

View File

@ -102,7 +102,7 @@ class BuiltinModuleFunc {
class BuiltinModuleFuncs {
using Storage =
mozilla::EnumeratedArray<BuiltinModuleFuncId, BuiltinModuleFunc,
BuiltinModuleFuncId::Limit>;
size_t(BuiltinModuleFuncId::Limit)>;
Storage funcs_;
static BuiltinModuleFuncs* singleton_;

View File

@ -1839,7 +1839,7 @@ using TypedNativeToCodeRangeMap =
HashMap<TypedNative, uint32_t, TypedNative, SystemAllocPolicy>;
using SymbolicAddressToCodeRangeArray =
EnumeratedArray<SymbolicAddress, uint32_t, SymbolicAddress::Limit>;
EnumeratedArray<SymbolicAddress, uint32_t, size_t(SymbolicAddress::Limit)>;
struct BuiltinThunks {
uint8_t* codeBase;

View File

@ -117,8 +117,8 @@ struct LinkData : LinkDataCacheablePod {
};
using InternalLinkVector = Vector<InternalLink, 0, SystemAllocPolicy>;
struct SymbolicLinkArray
: EnumeratedArray<SymbolicAddress, Uint32Vector, SymbolicAddress::Limit> {
struct SymbolicLinkArray : EnumeratedArray<SymbolicAddress, Uint32Vector,
size_t(SymbolicAddress::Limit)> {
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
};

View File

@ -273,7 +273,7 @@ WASM_DECLARE_CACHEABLE_POD(TrapSite);
WASM_DECLARE_POD_VECTOR(TrapSite, TrapSiteVector)
struct TrapSiteVectorArray
: EnumeratedArray<Trap, TrapSiteVector, Trap::Limit> {
: EnumeratedArray<Trap, TrapSiteVector, size_t(Trap::Limit)> {
bool empty() const;
void clear();
void swap(TrapSiteVectorArray& rhs);

View File

@ -440,7 +440,7 @@ static bool InRange(uint32_t caller, uint32_t callee) {
using OffsetMap =
HashMap<uint32_t, uint32_t, DefaultHasher<uint32_t>, SystemAllocPolicy>;
using TrapMaybeOffsetArray =
EnumeratedArray<Trap, Maybe<uint32_t>, Trap::Limit>;
EnumeratedArray<Trap, Maybe<uint32_t>, size_t(Trap::Limit)>;
bool ModuleGenerator::linkCallSites() {
AutoCreatedBy acb(masm_, "linkCallSites");

View File

@ -38,9 +38,9 @@ enum class LayoutSubsystem : uint8_t {
};
using LayoutSubsystemDurations =
EnumeratedArray<LayoutSubsystem, double, LayoutSubsystem::Count>;
EnumeratedArray<LayoutSubsystem, double, size_t(LayoutSubsystem::Count)>;
using LayoutFlushCount =
EnumeratedArray<FlushKind, SaturateUint8, FlushKind::Count>;
EnumeratedArray<FlushKind, SaturateUint8, size_t(FlushKind::Count)>;
struct Data {
Data();

View File

@ -1397,7 +1397,8 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
#ifdef DEBUG
private:
friend struct nsAutoLayoutPhase;
mozilla::EnumeratedArray<nsLayoutPhase, uint32_t, nsLayoutPhase::COUNT>
mozilla::EnumeratedArray<nsLayoutPhase, uint32_t,
size_t(nsLayoutPhase::COUNT)>
mLayoutPhaseCount;
public:

View File

@ -106,12 +106,10 @@ class nsGridContainerFrame final : public nsContainerFrame,
using NamedArea = mozilla::StyleNamedArea;
template <typename T>
using PerBaseline = mozilla::EnumeratedArray<BaselineSharingGroup, T,
BaselineSharingGroup(2)>;
using PerBaseline = mozilla::EnumeratedArray<BaselineSharingGroup, T, 2>;
template <typename T>
using PerLogicalAxis =
mozilla::EnumeratedArray<LogicalAxis, T, LogicalAxis(2)>;
using PerLogicalAxis = mozilla::EnumeratedArray<LogicalAxis, T, 2>;
// nsIFrame overrides
void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,

View File

@ -418,7 +418,7 @@ struct StyleIDs {
LookAndFeel::FloatID mLineRelativeSize;
};
EnumeratedArray<nsTextPaintStyle::SelectionStyleIndex, StyleIDs,
nsTextPaintStyle::SelectionStyleIndex::Count>
size_t(nsTextPaintStyle::SelectionStyleIndex::Count)>
SelectionStyleIDs = {
StyleIDs{LookAndFeel::ColorID::IMERawInputForeground,
LookAndFeel::ColorID::IMERawInputBackground,

View File

@ -146,7 +146,7 @@ class MOZ_STACK_CLASS nsTextPaintStyle {
};
mozilla::EnumeratedArray<SelectionStyleIndex,
mozilla::Maybe<nsSelectionStyle>,
SelectionStyleIndex::Count>
size_t(SelectionStyleIndex::Count)>
mSelectionStyle;
// Color initializations

View File

@ -687,7 +687,7 @@ class ServoStyleSet {
// Stores pointers to our cached ComputedStyles for non-inheriting anonymous
// boxes.
EnumeratedArray<nsCSSAnonBoxes::NonInheriting, RefPtr<ComputedStyle>,
nsCSSAnonBoxes::NonInheriting::_Count>
size_t(nsCSSAnonBoxes::NonInheriting::_Count)>
mNonInheritingComputedStyles;
public:

View File

@ -27,7 +27,7 @@ namespace mozilla {
template <typename T, size_t Length>
class Array;
template <typename IndexType, typename ValueType, IndexType SizeAsEnumValue>
template <typename IndexType, typename ValueType, size_t Size>
class EnumeratedArray;
/*
@ -64,9 +64,9 @@ constexpr size_t ArrayLength(const Array<T, N>& aArr) {
return N;
}
template <typename E, typename T, E N>
template <typename E, typename T, size_t N>
constexpr size_t ArrayLength(const EnumeratedArray<E, T, N>& aArr) {
return size_t(N);
return N;
}
/*

View File

@ -61,29 +61,6 @@ struct EnumTypeFitsWithin
"must provide an integral type");
};
/*
* Provides information about highest enum member value.
* Each specialization of struct MaxEnumValue should define
* "static constexpr unsigned int value".
*
* example:
*
* enum ExampleEnum
* {
* CAT = 0,
* DOG,
* HAMSTER
* };
*
* template <>
* struct MaxEnumValue<ExampleEnum>
* {
* static constexpr unsigned int value = static_cast<unsigned int>(HAMSTER);
* };
*/
template <typename T>
struct MaxEnumValue; // no need to define the primary template
/**
* Get the underlying value of an enum, but typesafe.
*
@ -108,6 +85,65 @@ inline constexpr auto UnderlyingValue(const T v) {
return static_cast<typename std::underlying_type<T>::type>(v);
}
/*
* Specialize either MaxContiguousEnumValue or MaxEnumValue to provide the
* highest enum member value for an enum class. Note that specializing
* MaxContiguousEnumValue will make MaxEnumValue just take its value from the
* MaxContiguousEnumValue specialization.
*
* Specialize MinContiguousEnumValue and MaxContiguousEnumValue to provide both
* lowest and highest enum member values for an enum class with contiguous
* values.
*
* Each specialization of these structs should define "static constexpr" member
* variable named "value".
*
* example:
*
* enum ExampleEnum
* {
* CAT = 0,
* DOG,
* HAMSTER
* };
*
* template <>
* struct MaxEnumValue<ExampleEnum>
* {
* static constexpr ExampleEnumvalue = HAMSTER;
* };
*/
template <typename T>
struct MinContiguousEnumValue {
static constexpr T value = static_cast<T>(0);
};
template <typename T>
struct MaxContiguousEnumValue;
template <typename T>
struct MaxEnumValue {
static constexpr auto value = MaxContiguousEnumValue<T>::value;
};
// Provides the min and max values for a contiguous enum (requires at least
// MaxContiguousEnumValue to be defined).
template <typename T>
struct ContiguousEnumValues {
static constexpr auto min = MinContiguousEnumValue<T>::value;
static constexpr auto max = MaxContiguousEnumValue<T>::value;
};
// Provides the total number of values for a contiguous enum (requires at least
// MaxContiguousEnumValue to be defined).
template <typename T>
struct ContiguousEnumSize {
static constexpr size_t value =
UnderlyingValue(ContiguousEnumValues<T>::max) + 1 -
UnderlyingValue(ContiguousEnumValues<T>::min);
};
} // namespace mozilla
#endif /* mozilla_EnumTypeTraits_h */

View File

@ -12,6 +12,7 @@
#include <utility>
#include "mozilla/Array.h"
#include "EnumTypeTraits.h"
namespace mozilla {
@ -38,14 +39,18 @@ namespace mozilla {
* headCount[AnimalSpecies::Cow] = 17;
* headCount[AnimalSpecies::Sheep] = 30;
*
* If the enum class has contiguous values and provides a specialization of
* mozilla::MaxContiguousEnumValue then the size will be calculated as the max
* value + 1.
*/
template <typename IndexType, typename ValueType, IndexType SizeAsEnumValue>
template <typename Enum, typename ValueType,
size_t Size = ContiguousEnumSize<Enum>::value>
class EnumeratedArray {
public:
static const size_t kSize = size_t(SizeAsEnumValue);
private:
typedef Array<ValueType, kSize> ArrayType;
static_assert(UnderlyingValue(MinContiguousEnumValue<Enum>::value) == 0,
"All indexes would need to be corrected if min != 0");
using ArrayType = Array<ValueType, Size>;
ArrayType mArray;
@ -56,16 +61,16 @@ class EnumeratedArray {
MOZ_IMPLICIT constexpr EnumeratedArray(Args&&... aArgs)
: mArray{std::forward<Args>(aArgs)...} {}
ValueType& operator[](IndexType aIndex) { return mArray[size_t(aIndex)]; }
ValueType& operator[](Enum aIndex) { return mArray[size_t(aIndex)]; }
const ValueType& operator[](IndexType aIndex) const {
const ValueType& operator[](Enum aIndex) const {
return mArray[size_t(aIndex)];
}
typedef typename ArrayType::iterator iterator;
typedef typename ArrayType::const_iterator const_iterator;
typedef typename ArrayType::reverse_iterator reverse_iterator;
typedef typename ArrayType::const_reverse_iterator const_reverse_iterator;
using iterator = typename ArrayType::iterator;
using const_iterator = typename ArrayType::const_iterator;
using reverse_iterator = typename ArrayType::reverse_iterator;
using const_reverse_iterator = typename ArrayType::const_reverse_iterator;
// Methods for range-based for loops.
iterator begin() { return mArray.begin(); }

View File

@ -4,17 +4,25 @@
* 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/. */
#include "mozilla/ArrayUtils.h"
#include "mozilla/EnumeratedArray.h"
#include "mozilla/EnumTypeTraits.h"
using mozilla::EnumeratedArray;
enum class AnimalSpecies { Cow, Sheep, Pig, Count };
enum class AnimalSpecies { Cow, Sheep, Pig };
using TestArray = EnumeratedArray<AnimalSpecies, int, AnimalSpecies::Count>;
template <>
struct mozilla::MaxContiguousEnumValue<AnimalSpecies> {
static constexpr AnimalSpecies value = AnimalSpecies::Pig;
};
using TestArray = EnumeratedArray<AnimalSpecies, int>;
void TestInitialValueByConstructor() {
// Style 1
TestArray headCount(1, 2, 3);
MOZ_RELEASE_ASSERT(mozilla::ArrayLength(headCount) == 3);
MOZ_RELEASE_ASSERT(headCount[AnimalSpecies::Cow] == 1);
MOZ_RELEASE_ASSERT(headCount[AnimalSpecies::Sheep] == 2);
MOZ_RELEASE_ASSERT(headCount[AnimalSpecies::Pig] == 3);

View File

@ -200,14 +200,16 @@ enum class CCExpYearParams : uint8_t {
};
struct AutofillParams {
EnumeratedArray<CCNumberParams, double, CCNumberParams::Count>
EnumeratedArray<CCNumberParams, double, size_t(CCNumberParams::Count)>
mCCNumberParams;
EnumeratedArray<CCNameParams, double, CCNameParams::Count> mCCNameParams;
EnumeratedArray<CCTypeParams, double, CCTypeParams::Count> mCCTypeParams;
EnumeratedArray<CCExpParams, double, CCExpParams::Count> mCCExpParams;
EnumeratedArray<CCExpMonthParams, double, CCExpMonthParams::Count>
EnumeratedArray<CCNameParams, double, size_t(CCNameParams::Count)>
mCCNameParams;
EnumeratedArray<CCTypeParams, double, size_t(CCTypeParams::Count)>
mCCTypeParams;
EnumeratedArray<CCExpParams, double, size_t(CCExpParams::Count)> mCCExpParams;
EnumeratedArray<CCExpMonthParams, double, size_t(CCExpMonthParams::Count)>
mCCExpMonthParams;
EnumeratedArray<CCExpYearParams, double, CCExpYearParams::Count>
EnumeratedArray<CCExpYearParams, double, size_t(CCExpYearParams::Count)>
mCCExpYearParams;
};
@ -667,11 +669,11 @@ class FormAutofillImpl {
// Array contains regular expressions to match the corresponding
// field. Ex, CC number, CC type, etc.
using RegexStringArray =
EnumeratedArray<RegexKey, nsCString, RegexKey::Count>;
EnumeratedArray<RegexKey, nsCString, size_t(RegexKey::Count)>;
RegexStringArray mRuleMap;
// Array that holds RegexWrapper that created by regex::ffi::regex_new
using RegexWrapperArray = EnumeratedArray<RegexKey, RustRegex, RegexKey::Count>;
using RegexWrapperArray = EnumeratedArray<RegexKey, RustRegex, size_t(RegexKey::Count)>;
RegexWrapperArray mRegexes;
};

View File

@ -143,7 +143,8 @@ void GetAnnotation(uint32_t childPid, Annotation annotation,
nsACString& outStr);
// Functions for working with minidumps and .extras
typedef mozilla::EnumeratedArray<Annotation, nsCString, Annotation::Count>
typedef mozilla::EnumeratedArray<Annotation, nsCString,
size_t(Annotation::Count)>
AnnotationTable;
void DeleteMinidumpFilesForID(
const nsAString& aId,

View File

@ -176,7 +176,7 @@ struct FileLocationCache {
void Clear() { *this = {}; }
};
EnumeratedArray<FileKind, Entry, FileKind::Count> mEntries;
EnumeratedArray<FileKind, Entry, size_t(FileKind::Count)> mEntries;
static const char* PrefFor(FileKind aKind) {
switch (aKind) {

View File

@ -126,7 +126,7 @@ nsresult nsPrinterBase::AsyncPromiseAttributeGetter(
MOZ_ASSERT(NS_IsMainThread());
static constexpr EnumeratedArray<AsyncAttribute, nsLiteralCString,
AsyncAttribute::Last>
size_t(AsyncAttribute::Last)>
attributeKeys{"SupportsDuplex"_ns, "SupportsColor"_ns,
"SupportsMonochrome"_ns, "SupportsCollation"_ns,
"PrinterInfo"_ns};

View File

@ -105,7 +105,7 @@ class nsPrinterBase : public nsIPrinter {
private:
mozilla::EnumeratedArray<AsyncAttribute, RefPtr<Promise>,
AsyncAttribute::Last>
size_t(AsyncAttribute::Last)>
mAsyncAttributePromises;
// List of built-in, commonly used paper sizes.
const RefPtr<const mozilla::CommonPaperInfoArray> mCommonPaperInfo;

View File

@ -57,7 +57,7 @@ using FontID = mozilla::LookAndFeel::FontID;
template <typename Index, typename Value, Index kEnd>
class EnumeratedCache {
mozilla::EnumeratedArray<Index, Value, kEnd> mEntries;
mozilla::EnumeratedArray<Index, Value, size_t(kEnd)> mEntries;
std::bitset<size_t(kEnd)> mValidity;
public:

View File

@ -888,7 +888,7 @@ class nsWindow final : public nsBaseWidget {
// Client rect for minimize, maximize and close buttons.
mozilla::EnumeratedArray<WindowButtonType, LayoutDeviceIntRect,
WindowButtonType::Count>
size_t(WindowButtonType::Count)>
mWindowBtnRect;
mozilla::DataMutex<Desktop> mDesktopId;

View File

@ -10,21 +10,21 @@
#include "mozilla/EnumeratedArray.h"
#include "nsCycleCollectionTraversalCallback.h"
template <typename IndexType, typename ValueType, IndexType SizeAsEnumValue>
template <typename IndexType, typename ValueType, size_t Size>
inline void ImplCycleCollectionUnlink(
mozilla::EnumeratedArray<IndexType, ValueType, SizeAsEnumValue>& aField) {
for (size_t i = 0; i < size_t(SizeAsEnumValue); ++i) {
mozilla::EnumeratedArray<IndexType, ValueType, Size>& aField) {
for (size_t i = 0; i < Size; ++i) {
aField[IndexType(i)] = nullptr;
}
}
template <typename IndexType, typename ValueType, IndexType SizeAsEnumValue>
template <typename IndexType, typename ValueType, size_t Size>
inline void ImplCycleCollectionTraverse(
nsCycleCollectionTraversalCallback& aCallback,
mozilla::EnumeratedArray<IndexType, ValueType, SizeAsEnumValue>& aField,
mozilla::EnumeratedArray<IndexType, ValueType, Size>& aField,
const char* aName, uint32_t aFlags = 0) {
aFlags |= CycleCollectionEdgeNameArrayFlag;
for (size_t i = 0; i < size_t(SizeAsEnumValue); ++i) {
for (size_t i = 0; i < Size; ++i) {
ImplCycleCollectionTraverse(aCallback, aField[IndexType(i)], aName, aFlags);
}
}