Skip to content
Permalink
Browse files
Add EnumeratedArray type
https://bugs.webkit.org/show_bug.cgi?id=241451

Reviewed by Cameron McCormack.

This is an std::array where the indices of the array are values of an enum (rather than a size_t).
This assumes the values of the enum start at 0 and monotonically increase by 1
(so the conversion function between size_t and the enum is just a simple static_cast).

EnumeratedArray includes almost all of the functions from std::array, except for a few which I
intentionally omitted.

* Source/WTF/WTF.xcodeproj/project.pbxproj:
* Source/WTF/wtf/EnumeratedArray.h: Added.
(WTF::EnumeratedArray::EnumeratedArray):
(WTF::EnumeratedArray::operator=):
(WTF::EnumeratedArray::at):
(WTF::EnumeratedArray::at const):
(WTF::EnumeratedArray::operator[]):
(WTF::EnumeratedArray::operator[] const):
(WTF::EnumeratedArray::front):
(WTF::EnumeratedArray::front const):
(WTF::EnumeratedArray::back):
(WTF::EnumeratedArray::back const):
(WTF::EnumeratedArray::fill):
(WTF::EnumeratedArray::operator== const):
(WTF::EnumeratedArray::operator!= const):
(WTF::EnumeratedArray::operator< const):
(WTF::EnumeratedArray::operator<= const):
(WTF::EnumeratedArray::operator> const):
(WTF::EnumeratedArray::operator>= const):
(WTF::EnumeratedArray::index):
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/WTF/EnumeratedArray.cpp: Added.
(TestWebKitAPI::TEST):

Canonical link: https://commits.webkit.org/251453@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295447 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
litherum committed Jun 10, 2022
1 parent 5676303 commit 66dcc4e97851c90a6e7d7162a27686a9802ea1a7
Show file tree
Hide file tree
Showing 5 changed files with 433 additions and 1 deletion.
@@ -51,6 +51,7 @@
1C96836926BE76B600A2A2F9 /* LoggingCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C96836826BE76B600A2A2F9 /* LoggingCocoa.mm */; };
1CA85CA9241B0B260071C2F5 /* RuntimeApplicationChecksCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CA85CA8241B0B260071C2F5 /* RuntimeApplicationChecksCocoa.cpp */; };
1CF18F3B26BB579E004B1722 /* LogChannels.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CF18F3926BB579E004B1722 /* LogChannels.cpp */; };
1CFD5D3D2851AB3E00A0E30B /* EnumeratedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CFD5D3B2851AB3E00A0E30B /* EnumeratedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
1FA47C8A152502DA00568D1B /* WebCoreThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FA47C88152502DA00568D1B /* WebCoreThread.cpp */; };
2CCD892A15C0390200285083 /* GregorianDateTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2CCD892915C0390200285083 /* GregorianDateTime.cpp */; };
2CDED0EF18115C38004DBA70 /* RunLoopCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2CDED0EE18115C38004DBA70 /* RunLoopCF.cpp */; };
@@ -1049,6 +1050,7 @@
1CCDB14D1E566898006C73C0 /* TextBreakIteratorICU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextBreakIteratorICU.h; sourceTree = "<group>"; };
1CF18F3926BB579E004B1722 /* LogChannels.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LogChannels.cpp; sourceTree = "<group>"; };
1CF18F3A26BB579E004B1722 /* LogChannels.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogChannels.h; sourceTree = "<group>"; };
1CFD5D3B2851AB3E00A0E30B /* EnumeratedArray.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EnumeratedArray.h; sourceTree = "<group>"; };
1FA47C88152502DA00568D1B /* WebCoreThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebCoreThread.cpp; sourceTree = "<group>"; };
1FA47C89152502DA00568D1B /* WebCoreThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreThread.h; sourceTree = "<group>"; };
24F1B248619F412296D1C19C /* RandomDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomDevice.h; sourceTree = "<group>"; };
@@ -1981,6 +1983,7 @@
A8A47298151A825A004123FF /* dtoa.h */,
E3538D4C276220880075DA50 /* EmbeddedFixedVector.h */,
5338EBA423AB04D100382662 /* EnumClassOperatorOverloads.h */,
1CFD5D3B2851AB3E00A0E30B /* EnumeratedArray.h */,
1AEA88E11D6BBCF400E5AD64 /* EnumTraits.h */,
AD7C434A1DD2A4A70026888B /* Expected.h */,
DF292D55278F9BC600BB2918 /* ExperimentalFeatureNames.h */,
@@ -2911,6 +2914,7 @@
DD3DC94C27A4BF8E007E5B61 /* EmbeddedFixedVector.h in Headers */,
DDF3076327C086CD006A526F /* Entitlements.h in Headers */,
DD3DC97827A4BF8E007E5B61 /* EnumClassOperatorOverloads.h in Headers */,
1CFD5D3D2851AB3E00A0E30B /* EnumeratedArray.h in Headers */,
DD3DC88C27A4BF8E007E5B61 /* EnumTraits.h in Headers */,
DD3DC87C27A4BF8E007E5B61 /* Expected.h in Headers */,
DD3DC8FB27A4BF8E007E5B61 /* ExperimentalFeatureNames.h in Headers */,
@@ -0,0 +1,275 @@
/*
* Copyright (C) 2022 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#include <array>

namespace WTF {

// This is an std::array where the indices of the array are values of an enum (rather than a size_t).
// This assumes the values of the enum start at 0 and monotonically increase by 1
// (so the conversion function between size_t and the enum is just a simple static_cast).
// LastValue is the maximum value of the enum, which determines the size of the array.
template <typename Key, typename T, Key LastValue>
class EnumeratedArray {
WTF_MAKE_FAST_ALLOCATED;
public:
using value_type = T;
using size_type = Key;
using reference = value_type&;
using const_reference = const value_type&;
using pointer = value_type*;
using const_pointer = const value_type*;

private:
// We add 1 to the size because we expect that LastValue is the maximum value of the enum,
// rather than the count of items in the enum.
// We're assuming the values in the enum are zero-indexed.
using UnderlyingType = std::array<T, static_cast<std::size_t>(LastValue) + 1>;

public:
using iterator = typename UnderlyingType::iterator;
using const_iterator = typename UnderlyingType::const_iterator;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;

EnumeratedArray() = default;

EnumeratedArray(const EnumeratedArray& from)
: m_storage(from.m_storage)
{
}

EnumeratedArray(EnumeratedArray&& from)
: m_storage(WTFMove(from.m_storage))
{
}

EnumeratedArray(const UnderlyingType& from)
: m_storage(from)
{
}

EnumeratedArray(UnderlyingType&& from)
: m_storage(WTFMove(from))
{
}

EnumeratedArray& operator=(const EnumeratedArray& from)
{
m_storage = from.m_storage;
return *this;
}

EnumeratedArray& operator=(EnumeratedArray&& from)
{
m_storage = WTFMove(from.m_storage);
return *this;
}

constexpr reference at(size_type pos)
{
return m_storage.at(index(pos));
}

constexpr const_reference at(size_type pos) const
{
return m_storage.at(index(pos));
}

constexpr reference operator[](size_type pos)
{
return m_storage[index(pos)];
}

constexpr const_reference operator[](size_type pos) const
{
return m_storage[index(pos)];
}

constexpr reference front()
{
return m_storage.front();
}

constexpr const_reference front() const
{
return m_storage.front();
}

constexpr reference back()
{
return m_storage.back();
}

constexpr const_reference back() const
{
return m_storage.back();
}

constexpr T* data() noexcept
{
return m_storage.data();
}

constexpr const T* data() const noexcept
{
return m_storage.data();
}

constexpr iterator begin() noexcept
{
return m_storage.begin();
}

constexpr const_iterator begin() const noexcept
{
return m_storage.begin();
}

constexpr const_iterator cbegin() const noexcept
{
return m_storage.cbegin();
}

constexpr iterator end() noexcept
{
return m_storage.end();
}

constexpr const_iterator end() const noexcept
{
return m_storage.end();
}

constexpr const_iterator cend() const noexcept
{
return m_storage.cend();
}

constexpr reverse_iterator rbegin() noexcept
{
return m_storage.rbegin();
}

constexpr const_reverse_iterator rbegin() const noexcept
{
return m_storage.rbegin();
}

constexpr const_reverse_iterator crbegin() const noexcept
{
return m_storage.crbegin();
}

constexpr reverse_iterator rend() noexcept
{
return m_storage.rend();
}

constexpr const_reverse_iterator rend() const noexcept
{
return m_storage.rend();
}

constexpr const_reverse_iterator crend() const noexcept
{
return m_storage.crend();
}

constexpr bool empty() const noexcept
{
return m_storage.empty();
}

constexpr typename UnderlyingType::size_type size() const noexcept
{
return m_storage.size();
}

constexpr typename UnderlyingType::size_type max_size() const noexcept
{
return m_storage.max_size();
}

constexpr void fill(const T& value)
{
m_storage.fill(value);
}

constexpr void swap(EnumeratedArray& other) noexcept
{
return m_storage.swap(other.m_storage);
}

template <typename Key2, typename T2, Key2 LastValue2>
constexpr bool operator==(const EnumeratedArray<Key2, T2, LastValue2>& rhs) const
{
return m_storage == rhs.m_storage;
}

template <typename Key2, typename T2, Key2 LastValue2>
bool operator!=(const EnumeratedArray<Key2, T2, LastValue2>& rhs) const
{
return m_storage != rhs.m_storage;
}

template <typename Key2, typename T2, Key2 LastValue2>
bool operator<(const EnumeratedArray<Key2, T2, LastValue2>& rhs) const
{
return m_storage < rhs.m_storage;
}

template <typename Key2, typename T2, Key2 LastValue2>
bool operator<=(const EnumeratedArray<Key2, T2, LastValue2>& rhs) const
{
return m_storage <= rhs.m_storage;
}

template <typename Key2, typename T2, Key2 LastValue2>
bool operator>(const EnumeratedArray<Key2, T2, LastValue2>& rhs) const
{
return m_storage > rhs.m_storage;
}

template <typename Key2, typename T2, Key2 LastValue2>
bool operator>=(const EnumeratedArray<Key2, T2, LastValue2>& rhs) const
{
return m_storage >= rhs.m_storage;
}

private:
typename UnderlyingType::size_type index(size_type pos)
{
return static_cast<typename UnderlyingType::size_type>(pos);
}

UnderlyingType m_storage;
};

} // namespace WTF

using WTF::EnumeratedArray;
@@ -3003,7 +3003,7 @@ def check_braces(clean_lines, line_number, file_state, error):
# on the previous non-blank line is '{' because it's likely to
# indicate the begining of a nested code block.
previous_line = get_previous_non_blank_line(clean_lines, line_number)[0]
if ((not search(r'[;:}{)=]\s*$|\)\s*((const|override|const override|final|const final)\s*)?(->\s*\S+)?\s*$', previous_line)
if ((not search(r'[;:}{)=]\s*$|\)\s*((const|override|const override|final|const final|noexcept|const noexcept)\s*)?(->\s*\S+)?\s*$', previous_line)
or search(r'\b(if|for|while|switch|else|CF_OPTIONS|NS_ENUM|NS_ERROR_ENUM|NS_OPTIONS)\b', previous_line)
or regex_for_lambdas_and_blocks(previous_line, line_number, file_state, error))
and previous_line.find('#') < 0
@@ -122,6 +122,7 @@
1CF59AE221E68925006E37EC /* ForceLightAppearanceInBundle_Bundle.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1CF59AE021E68925006E37EC /* ForceLightAppearanceInBundle_Bundle.mm */; };
1CF59AE321E68932006E37EC /* ForceLightAppearanceInBundle.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1CF59ADF21E68925006E37EC /* ForceLightAppearanceInBundle.mm */; };
1CF59AE521E6977D006E37EC /* dark-mode.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1CF59AE421E696FB006E37EC /* dark-mode.html */; };
1CFD5D3F2851B62100A0E30B /* EnumeratedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CFD5D3E2851B62100A0E30B /* EnumeratedArray.cpp */; };
1D67BFDC2433E0A7006B5047 /* PreemptVideoFullscreen.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1D67BFDB2433E0A7006B5047 /* PreemptVideoFullscreen.mm */; };
1D67BFDD2433EE66006B5047 /* two-videos.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1D67BFD92433DFD8006B5047 /* two-videos.html */; };
1DAA52CC243BE805001A3159 /* one-video.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1DAA52CB243BE621001A3159 /* one-video.html */; };
@@ -1828,6 +1829,7 @@
1CF59ADF21E68925006E37EC /* ForceLightAppearanceInBundle.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ForceLightAppearanceInBundle.mm; sourceTree = "<group>"; };
1CF59AE021E68925006E37EC /* ForceLightAppearanceInBundle_Bundle.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ForceLightAppearanceInBundle_Bundle.mm; sourceTree = "<group>"; };
1CF59AE421E696FB006E37EC /* dark-mode.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "dark-mode.html"; sourceTree = "<group>"; };
1CFD5D3E2851B62100A0E30B /* EnumeratedArray.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = EnumeratedArray.cpp; sourceTree = "<group>"; };
1D12BEBF245BEF85004C0B7A /* ExitPiPOnSuspendVideoElement.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ExitPiPOnSuspendVideoElement.mm; sourceTree = "<group>"; };
1D5BE6AD2673EC5F00CB0B12 /* audio-buffer-size.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "audio-buffer-size.html"; sourceTree = "<group>"; };
1D67BFD92433DFD8006B5047 /* two-videos.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "two-videos.html"; sourceTree = "<group>"; };
@@ -4679,6 +4681,7 @@
1A3524A91D627BD40031729B /* DeletedAddressOfOperator.h */,
E4A757D3178AEA5B00B5D7A4 /* Deque.cpp */,
E36B87A2276221860059D2F9 /* EmbeddedFixedVector.cpp */,
1CFD5D3E2851B62100A0E30B /* EnumeratedArray.cpp */,
1AF7B21D1D6CD12E008C126C /* EnumTraits.cpp */,
AD7C434C1DD2A5470026888B /* Expected.cpp */,
A310827121F296EC00C28B97 /* FileSystem.cpp */,
@@ -5480,6 +5483,7 @@
7C83DEA91D0A590C00FEBCF3 /* CString.cpp in Sources */,
7C83DEAD1D0A590C00FEBCF3 /* Deque.cpp in Sources */,
E36B87A3276221870059D2F9 /* EmbeddedFixedVector.cpp in Sources */,
1CFD5D3F2851B62100A0E30B /* EnumeratedArray.cpp in Sources */,
1AF7B21F1D6CD14D008C126C /* EnumTraits.cpp in Sources */,
AD7C434D1DD2A54E0026888B /* Expected.cpp in Sources */,
A310827221F296FF00C28B97 /* FileSystem.cpp in Sources */,

0 comments on commit 66dcc4e

Please sign in to comment.