Add OptionSet::operator& and operator bool
https://bugs.webkit.org/show_bug.cgi?id=185306

Reviewed by Anders Carlsson.

Source/WebCore:

Use it in a few places.

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::reload):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::logReasonsForCompositing):
(WebCore::RenderLayerCompositor::updateScrollCoordinatedLayer):

Source/WTF:

This is primarily to allow writing

    if (options & Option:A)

instead of

    if (options.contains(Option:A))

This is consistent with other OptionSet operators.

* wtf/OptionSet.h:
(WTF::OptionSet::operator bool):
(WTF::OptionSet::operator&):

Also remove T versions of operator| and operator-, they are not needed due to
implicit conversion from T to OptionSet<T>.

Tools:

* TestWebKitAPI/Tests/WTF/OptionSet.cpp:
(TestWebKitAPI::TEST):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@231548 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index 89dc436..747567e 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,27 @@
+2018-05-09  Antti Koivisto  <antti@apple.com>
+
+        Add OptionSet::operator& and operator bool
+        https://bugs.webkit.org/show_bug.cgi?id=185306
+
+        Reviewed by Anders Carlsson.
+
+        This is primarily to allow writing
+
+            if (options & Option:A)
+
+        instead of
+
+            if (options.contains(Option:A))
+
+        This is consistent with other OptionSet operators.
+
+        * wtf/OptionSet.h:
+        (WTF::OptionSet::operator bool):
+        (WTF::OptionSet::operator&):
+
+        Also remove T versions of operator| and operator-, they are not needed due to
+        implicit conversion from T to OptionSet<T>.
+
 2018-05-06  Filip Pizlo  <fpizlo@apple.com>
 
         InPlaceAbstractState::beginBasicBlock shouldn't have to clear any abstract values
diff --git a/Source/WTF/wtf/OptionSet.h b/Source/WTF/wtf/OptionSet.h
index a1f1231..b171751 100644
--- a/Source/WTF/wtf/OptionSet.h
+++ b/Source/WTF/wtf/OptionSet.h
@@ -107,6 +107,8 @@
     constexpr iterator begin() const { return m_storage; }
     constexpr iterator end() const { return 0; }
 
+    constexpr explicit operator bool() { return !isEmpty(); }
+
     constexpr bool contains(OptionSet optionSet) const
     {
         return m_storage & optionSet.m_storage;
@@ -139,9 +141,9 @@
         return fromRaw(lhs.m_storage | rhs.m_storage);
     }
 
-    constexpr friend OptionSet operator|(OptionSet lhs, T rhs)
+    constexpr friend OptionSet operator&(OptionSet lhs, OptionSet rhs)
     {
-        return lhs | OptionSet { rhs };
+        return fromRaw(lhs.m_storage & rhs.m_storage);
     }
 
     constexpr friend OptionSet operator-(OptionSet lhs, OptionSet rhs)
@@ -149,11 +151,6 @@
         return fromRaw(lhs.m_storage & ~rhs.m_storage);
     }
 
-    constexpr friend OptionSet operator-(OptionSet lhs, T rhs)
-    {
-        return lhs - OptionSet { rhs };
-    }
-
 private:
     enum InitializationTag { FromRawValue };
     constexpr OptionSet(T t, InitializationTag)
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 6c07404..5420106 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,18 @@
+2018-05-09  Antti Koivisto  <antti@apple.com>
+
+        Add OptionSet::operator& and operator bool
+        https://bugs.webkit.org/show_bug.cgi?id=185306
+
+        Reviewed by Anders Carlsson.
+
+        Use it in a few places.
+
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::reload):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::logReasonsForCompositing):
+        (WebCore::RenderLayerCompositor::updateScrollCoordinatedLayer):
+
 2018-05-08  Dean Jackson  <dino@apple.com>
 
         Disable system preview link fetching
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index 0cf6bcb..000b9a4 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -1701,9 +1701,9 @@
     loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
 
     auto frameLoadTypeForReloadOptions = [] (auto options) {
-        if (options.contains(ReloadOption::FromOrigin))
+        if (options & ReloadOption::FromOrigin)
             return FrameLoadType::ReloadFromOrigin;
-        if (options.contains(ReloadOption::ExpiredOnly))
+        if (options & ReloadOption::ExpiredOnly)
             return FrameLoadType::ReloadExpiredOnly;
         return FrameLoadType::Reload;
     };
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 0e90888..2fb72bd 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -2210,81 +2210,81 @@
 {
     OptionSet<CompositingReason> reasons = reasonsForCompositing(layer);
 
-    if (reasons.contains(CompositingReason::Transform3D))
+    if (reasons & CompositingReason::Transform3D)
         return "3D transform";
 
-    if (reasons.contains(CompositingReason::Video))
+    if (reasons & CompositingReason::Video)
         return "video";
 
-    if (reasons.contains(CompositingReason::Canvas))
+    if (reasons & CompositingReason::Canvas)
         return "canvas";
 
-    if (reasons.contains(CompositingReason::Plugin))
+    if (reasons & CompositingReason::Plugin)
         return "plugin";
 
-    if (reasons.contains(CompositingReason::IFrame))
+    if (reasons & CompositingReason::IFrame)
         return "iframe";
 
-    if (reasons.contains(CompositingReason::BackfaceVisibilityHidden))
+    if (reasons & CompositingReason::BackfaceVisibilityHidden)
         return "backface-visibility: hidden";
 
-    if (reasons.contains(CompositingReason::ClipsCompositingDescendants))
+    if (reasons & CompositingReason::ClipsCompositingDescendants)
         return "clips compositing descendants";
 
-    if (reasons.contains(CompositingReason::Animation))
+    if (reasons & CompositingReason::Animation)
         return "animation";
 
-    if (reasons.contains(CompositingReason::Filters))
+    if (reasons & CompositingReason::Filters)
         return "filters";
 
-    if (reasons.contains(CompositingReason::PositionFixed))
+    if (reasons & CompositingReason::PositionFixed)
         return "position: fixed";
 
-    if (reasons.contains(CompositingReason::PositionSticky))
+    if (reasons & CompositingReason::PositionSticky)
         return "position: sticky";
 
-    if (reasons.contains(CompositingReason::OverflowScrollingTouch))
+    if (reasons & CompositingReason::OverflowScrollingTouch)
         return "-webkit-overflow-scrolling: touch";
 
-    if (reasons.contains(CompositingReason::Stacking))
+    if (reasons & CompositingReason::Stacking)
         return "stacking";
 
-    if (reasons.contains(CompositingReason::Overlap))
+    if (reasons & CompositingReason::Overlap)
         return "overlap";
 
-    if (reasons.contains(CompositingReason::NegativeZIndexChildren))
+    if (reasons & CompositingReason::NegativeZIndexChildren)
         return "negative z-index children";
 
-    if (reasons.contains(CompositingReason::TransformWithCompositedDescendants))
+    if (reasons & CompositingReason::TransformWithCompositedDescendants)
         return "transform with composited descendants";
 
-    if (reasons.contains(CompositingReason::OpacityWithCompositedDescendants))
+    if (reasons & CompositingReason::OpacityWithCompositedDescendants)
         return "opacity with composited descendants";
 
-    if (reasons.contains(CompositingReason::MaskWithCompositedDescendants))
+    if (reasons & CompositingReason::MaskWithCompositedDescendants)
         return "mask with composited descendants";
 
-    if (reasons.contains(CompositingReason::ReflectionWithCompositedDescendants))
+    if (reasons & CompositingReason::ReflectionWithCompositedDescendants)
         return "reflection with composited descendants";
 
-    if (reasons.contains(CompositingReason::FilterWithCompositedDescendants))
+    if (reasons & CompositingReason::FilterWithCompositedDescendants)
         return "filter with composited descendants";
 
 #if ENABLE(CSS_COMPOSITING)
-    if (reasons.contains(CompositingReason::BlendingWithCompositedDescendants))
+    if (reasons & CompositingReason::BlendingWithCompositedDescendants)
         return "blending with composited descendants";
 
-    if (reasons.contains(CompositingReason::IsolatesCompositedBlendingDescendants))
+    if (reasons & CompositingReason::IsolatesCompositedBlendingDescendants)
         return "isolates composited blending descendants";
 #endif
 
-    if (reasons.contains(CompositingReason::Perspective))
+    if (reasons & CompositingReason::Perspective)
         return "perspective";
 
-    if (reasons.contains(CompositingReason::Preserve3D))
+    if (reasons & CompositingReason::Preserve3D)
         return "preserve-3d";
 
-    if (reasons.contains(CompositingReason::Root))
+    if (reasons & CompositingReason::Root)
         return "root";
 
     return "";
@@ -3798,10 +3798,10 @@
             
         LOG_WITH_STREAM(Compositing, stream << "Registering ViewportConstrained " << nodeType << " node " << nodeID << " (layer " << backing->graphicsLayer()->primaryLayerID() << ") as child of " << parentNodeID);
 
-        if (changes.contains(ScrollingNodeChangeFlags::Layer))
+        if (changes & ScrollingNodeChangeFlags::Layer)
             scrollingCoordinator->updateNodeLayer(nodeID, backing->graphicsLayer());
 
-        if (changes.contains(ScrollingNodeChangeFlags::LayerGeometry)) {
+        if (changes & ScrollingNodeChangeFlags::LayerGeometry) {
             switch (nodeType) {
             case FixedNode:
                 scrollingCoordinator->updateNodeViewportConstraints(nodeID, computeFixedViewportConstraints(layer));
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index 2f5e347..91f9f8a 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,13 @@
+2018-05-09  Antti Koivisto  <antti@apple.com>
+
+        Add OptionSet::operator& and operator bool
+        https://bugs.webkit.org/show_bug.cgi?id=185306
+
+        Reviewed by Anders Carlsson.
+
+        * TestWebKitAPI/Tests/WTF/OptionSet.cpp:
+        (TestWebKitAPI::TEST):
+
 2018-05-08  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Consolidate WebContentReaderIOS and WebContentReaderMac into WebContentReaderCocoa
diff --git a/Tools/TestWebKitAPI/Tests/WTF/OptionSet.cpp b/Tools/TestWebKitAPI/Tests/WTF/OptionSet.cpp
index 3241943..13e03de 100644
--- a/Tools/TestWebKitAPI/Tests/WTF/OptionSet.cpp
+++ b/Tools/TestWebKitAPI/Tests/WTF/OptionSet.cpp
@@ -316,4 +316,67 @@
     EXPECT_TRUE(*it1 == *it2);
 }
 
+TEST(WTF_OptionSet, OperatorAnd)
+{
+    OptionSet<ExampleFlags> a { ExampleFlags::A };
+    OptionSet<ExampleFlags> ac { ExampleFlags::A, ExampleFlags::C };
+    OptionSet<ExampleFlags> bc { ExampleFlags::B, ExampleFlags::C };
+    {
+        auto set = a & ac;
+        EXPECT_TRUE(!!set);
+        EXPECT_FALSE(set.isEmpty());
+        EXPECT_TRUE(set.contains(ExampleFlags::A));
+        EXPECT_FALSE(set.contains(ExampleFlags::B));
+        EXPECT_FALSE(set.contains(ExampleFlags::C));
+    }
+    {
+        auto set = a & bc;
+        EXPECT_FALSE(!!set);
+        EXPECT_TRUE(set.isEmpty());
+        EXPECT_FALSE(set.contains(ExampleFlags::A));
+        EXPECT_FALSE(set.contains(ExampleFlags::B));
+        EXPECT_FALSE(set.contains(ExampleFlags::C));
+    }
+    {
+        auto set = ac & bc;
+        EXPECT_TRUE(!!set);
+        EXPECT_FALSE(set.isEmpty());
+        EXPECT_FALSE(set.contains(ExampleFlags::A));
+        EXPECT_FALSE(set.contains(ExampleFlags::B));
+        EXPECT_TRUE(set.contains(ExampleFlags::C));
+    }
+    {
+        auto set = ExampleFlags::A & bc;
+        EXPECT_FALSE(!!set);
+        EXPECT_TRUE(set.isEmpty());
+        EXPECT_FALSE(set.contains(ExampleFlags::A));
+        EXPECT_FALSE(set.contains(ExampleFlags::B));
+        EXPECT_FALSE(set.contains(ExampleFlags::C));
+    }
+    {
+        auto set = ExampleFlags::A & ac;
+        EXPECT_TRUE(!!set);
+        EXPECT_FALSE(set.isEmpty());
+        EXPECT_TRUE(set.contains(ExampleFlags::A));
+        EXPECT_FALSE(set.contains(ExampleFlags::B));
+        EXPECT_FALSE(set.contains(ExampleFlags::C));
+    }
+    {
+        auto set = bc & ExampleFlags::A;
+        EXPECT_FALSE(!!set);
+        EXPECT_TRUE(set.isEmpty());
+        EXPECT_FALSE(set.contains(ExampleFlags::A));
+        EXPECT_FALSE(set.contains(ExampleFlags::B));
+        EXPECT_FALSE(set.contains(ExampleFlags::C));
+    }
+    {
+        auto set = ac & ExampleFlags::A;
+        EXPECT_TRUE(!!set);
+        EXPECT_FALSE(set.isEmpty());
+        EXPECT_TRUE(set.contains(ExampleFlags::A));
+        EXPECT_FALSE(set.contains(ExampleFlags::B));
+        EXPECT_FALSE(set.contains(ExampleFlags::C));
+    }
+}
+
 } // namespace TestWebKitAPI