Diff
Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (295446 => 295447)
--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2022-06-10 06:25:28 UTC (rev 295446)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2022-06-10 06:29:03 UTC (rev 295447)
@@ -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 */,
Added: trunk/Source/WTF/wtf/EnumeratedArray.h (0 => 295447)
--- trunk/Source/WTF/wtf/EnumeratedArray.h (rev 0)
+++ trunk/Source/WTF/wtf/EnumeratedArray.h 2022-06-10 06:29:03 UTC (rev 295447)
@@ -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;
Modified: trunk/Tools/Scripts/webkitpy/style/checkers/cpp.py (295446 => 295447)
--- trunk/Tools/Scripts/webkitpy/style/checkers/cpp.py 2022-06-10 06:25:28 UTC (rev 295446)
+++ trunk/Tools/Scripts/webkitpy/style/checkers/cpp.py 2022-06-10 06:29:03 UTC (rev 295447)
@@ -3003,7 +3003,7 @@
# 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
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (295446 => 295447)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2022-06-10 06:25:28 UTC (rev 295446)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2022-06-10 06:29:03 UTC (rev 295447)
@@ -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 */,
Added: trunk/Tools/TestWebKitAPI/Tests/WTF/EnumeratedArray.cpp (0 => 295447)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/EnumeratedArray.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/EnumeratedArray.cpp 2022-06-10 06:29:03 UTC (rev 295447)
@@ -0,0 +1,149 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include <wtf/EnumeratedArray.h>
+
+namespace TestWebKitAPI {
+
+enum class Foo {
+ One,
+ Two,
+ Three,
+};
+
+TEST(WTF_EnumeratedArray, Basic)
+{
+ EnumeratedArray<Foo, int, Foo::Three> array;
+ array[Foo::Three] = 17;
+ EXPECT_EQ(array[Foo::Three], 17);
+ EXPECT_EQ(array.at(Foo::Three), 17);
+ array[Foo::One] = 3;
+ EXPECT_EQ(array.front(), 3);
+ EXPECT_EQ(array.back(), 17);
+ auto* data = ""
+ EXPECT_EQ(data[static_cast<size_t>(Foo::One)], 3);
+ EXPECT_EQ(data[static_cast<size_t>(Foo::Three)], 17);
+ array[Foo::Two] = 10;
+ EXPECT_FALSE(array.empty());
+ EnumeratedArray<Foo, int, Foo::Three> array2;
+ array2.fill(4);
+ EXPECT_EQ(array2.at(Foo::One), 4);
+ EXPECT_EQ(array2.at(Foo::Two), 4);
+ EXPECT_EQ(array2.at(Foo::Three), 4);
+ array.swap(array2);
+ EXPECT_EQ(array.at(Foo::One), 4);
+ EXPECT_EQ(array.at(Foo::Two), 4);
+ EXPECT_EQ(array.at(Foo::Three), 4);
+ EXPECT_EQ(array2.at(Foo::One), 3);
+ EXPECT_EQ(array2.at(Foo::Two), 10);
+ EXPECT_EQ(array2.at(Foo::Three), 17);
+ EXPECT_EQ(array.size(), static_cast<size_t>(3));
+ EXPECT_EQ(array.max_size(), static_cast<size_t>(3));
+}
+
+TEST(WTF_EnumeratedArray, Comparison)
+{
+ EnumeratedArray<Foo, int, Foo::Three> array { { 3, 10, 17 } };
+ auto array2 = array;
+ EXPECT_EQ(array, array2);
+ EXPECT_LE(array, array2);
+ EXPECT_GE(array, array2);
+ array[Foo::Three] = 18;
+ EXPECT_GT(array, array2);
+ EXPECT_GE(array, array2);
+ EXPECT_LT(array2, array);
+ EXPECT_LE(array2, array);
+ array[Foo::Three] = 15;
+ EXPECT_LT(array, array2);
+ EXPECT_LE(array, array2);
+ EXPECT_GT(array2, array);
+ EXPECT_GE(array2, array);
+}
+
+TEST(WTF_EnumeratedArray, Construction)
+{
+ EnumeratedArray<Foo, int, Foo::Three> array1 { { 3, 10, 17 } };
+ EXPECT_EQ(array1.front(), 3);
+ EXPECT_EQ(array1.back(), 17);
+ EnumeratedArray<Foo, int, Foo::Three> array2(array1);
+ EXPECT_EQ(array2.front(), 3);
+ EXPECT_EQ(array2.back(), 17);
+ EnumeratedArray<Foo, int, Foo::Three> array3(WTFMove(array1));
+ EXPECT_EQ(array3.front(), 3);
+ EXPECT_EQ(array3.back(), 17);
+ EnumeratedArray<Foo, int, Foo::Three> array4;
+ array4 = array2;
+ EXPECT_EQ(array4.front(), 3);
+ EXPECT_EQ(array4.back(), 17);
+ EnumeratedArray<Foo, int, Foo::Three> array5;
+ array5 = WTFMove(array2);
+ EXPECT_EQ(array5.front(), 3);
+ EXPECT_EQ(array5.back(), 17);
+}
+
+TEST(WTF_EnumeratedArray, Iteration)
+{
+ EnumeratedArray<Foo, int, Foo::Three> array { { 3, 10, 17 } };
+ int index = 0;
+ for (int value : array) {
+ switch (index) {
+ case 0:
+ EXPECT_EQ(value, 3);
+ break;
+ case 1:
+ EXPECT_EQ(value, 10);
+ break;
+ case 2:
+ EXPECT_EQ(value, 17);
+ break;
+ default:
+ FAIL();
+ break;
+ }
+ ++index;
+ }
+ index = 0;
+ for (auto iter = array.rbegin(); iter != array.rend(); ++iter) {
+ int value = *iter;
+ switch (index) {
+ case 0:
+ EXPECT_EQ(value, 17);
+ break;
+ case 1:
+ EXPECT_EQ(value, 10);
+ break;
+ case 2:
+ EXPECT_EQ(value, 3);
+ break;
+ default:
+ FAIL();
+ break;
+ }
+ ++index;
+ }
+}
+
+} // namespace TestWebKitAPI