| Differences between
and this patch
- Source/WTF/ChangeLog +18 lines
Lines 1-3 Source/WTF/ChangeLog_sec1
1
2016-08-06  Sam Weinig  <sam@webkit.org>
2
3
        Replace NodeOrString with Variant<Ref<Node>, String>
4
        https://bugs.webkit.org/show_bug.cgi?id=160638
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * wtf/StdLibExtras.h:
9
        (WTF::Overloader::Overloader):
10
        (WTF::Overloader<A>::Overloader):
11
        (WTF::makeOverloader):
12
        Add WTF::makeOverloader() which takes a list of lambdas to use
13
        an an overload set for a visitor object.
14
15
        * wtf/Variant.h:
16
        Make std::experimental::variant work in WebCore and add a type-alias
17
        so it can be used as WTF::Variant.
18
1
2016-08-06  Sam Weinig  <sam@webkit.org>
19
2016-08-06  Sam Weinig  <sam@webkit.org>
2
20
3
        WTF needs a variant implementation
21
        WTF needs a variant implementation
- Source/WTF/wtf/StdLibExtras.h +30 lines
Lines 309-314 bool checkAndSet(T& left, U right) Source/WTF/wtf/StdLibExtras.h_sec1
309
    return true;
309
    return true;
310
}
310
}
311
311
312
// Overloader taken from http://stackoverflow.com/questions/25338795/is-there-a-name-for-this-tuple-creation-idiom
313
314
template <class A, class... B>
315
struct Overloader : Overloader<A>, Overloader<B...> {
316
    Overloader(A a, B... b)
317
        : Overloader<A>(a)
318
        , Overloader<B...>(b...)
319
    {
320
    }
321
322
    using Overloader<A>::operator ();
323
    using Overloader<B...>::operator ();
324
};
325
  
326
template <class A>
327
struct Overloader<A> : A {
328
    Overloader(A a)
329
        : A(a)
330
    {
331
    }
332
333
    using A::operator();
334
};
335
 
336
template <class... F>
337
auto makeOverloader(F... f)
338
{
339
    return Overloader<F...>(f...);
340
}
341
312
} // namespace WTF
342
} // namespace WTF
313
343
314
// This version of placement new omits a 0 check.
344
// This version of placement new omits a 0 check.
- Source/WTF/wtf/Variant.h -4 / +38 lines
Lines 39-44 Source/WTF/wtf/Variant.h_sec1
39
39
40
#pragma once
40
#pragma once
41
41
42
#include <functional>
42
#include <limits.h>
43
#include <limits.h>
43
#include <new>
44
#include <new>
44
#include <stddef.h>
45
#include <stddef.h>
Lines 48-53 Source/WTF/wtf/Variant.h_sec2
48
#include <utility>
49
#include <utility>
49
#include <wtf/Compiler.h>
50
#include <wtf/Compiler.h>
50
51
52
#if COMPILER(MSVC)
53
#pragma warning(push)
54
#pragma warning(disable:4245)
55
#pragma warning(disable:4521)
56
#pragma warning(disable:4522)
57
#pragma warning(disable:4814)
58
#endif
59
60
#if COMPILER(GCC)
61
62
#if !GCC_VERSION_AT_LEAST(5, 5, 0)
63
#error "Using < 5.4.0"
64
#endif
65
66
#if !GCC_VERSION_AT_LEAST(6, 1, 0)
67
#error "Using < 6.1.0"
68
#endif
69
70
#endif
71
51
namespace std {
72
namespace std {
52
namespace experimental {
73
namespace experimental {
53
74
Lines 63-69 namespace experimental { Source/WTF/wtf/Variant.h_sec3
63
84
64
#else
85
#else
65
86
66
static inline void __crash_helper(bool){
87
NO_RETURN_DUE_TO_CRASH static inline void __crash_helper(bool){
67
    CRASH();
88
    CRASH();
68
}
89
}
69
static inline constexpr bool __constexpr_crash_if(bool test){
90
static inline constexpr bool __constexpr_crash_if(bool test){
Lines 1169-1178 struct __backup_storage_ops{ Source/WTF/wtf/Variant.h_sec4
1169
1190
1170
template<ptrdiff_t _Index,typename _Storage>
1191
template<ptrdiff_t _Index,typename _Storage>
1171
struct __backup_storage_ops<_Index,_Index,_Storage>{
1192
struct __backup_storage_ops<_Index,_Index,_Storage>{
1172
    static void __move_construct_func(_Storage * __dest,_Storage& __source){
1193
    static void __move_construct_func(_Storage *,_Storage&){
1173
        __THROW_EXCEPTION(std::bad_alloc());
1194
        __THROW_EXCEPTION(std::bad_alloc());
1174
    };
1195
    };
1175
    static void __destroy_func(_Storage * __obj){
1196
    static void __destroy_func(_Storage *){
1176
        __THROW_EXCEPTION(std::bad_alloc());
1197
        __THROW_EXCEPTION(std::bad_alloc());
1177
    };
1198
    };
1178
};
1199
};
Lines 1938-1944 template<size_t _VariantIndex,ptrdiff_t Source/WTF/wtf/Variant.h_sec5
1938
struct __visit_helper2<-1,_VariantIndex,_Indices...>{
1959
struct __visit_helper2<-1,_VariantIndex,_Indices...>{
1939
    template<typename _Visitor,typename ... _Variants>
1960
    template<typename _Visitor,typename ... _Variants>
1940
    static constexpr typename __multi_visitor_return_type<_Visitor,_Variants...>::__type
1961
    static constexpr typename __multi_visitor_return_type<_Visitor,_Variants...>::__type
1941
    __visit(_Visitor& __visitor,_Variants&& ... __v){
1962
    __visit(_Visitor&,_Variants&& ...){
1942
        __CONST_EXPR_THROW_EXCPETION_IF(true, bad_variant_access("Visiting of empty variant"));
1963
        __CONST_EXPR_THROW_EXCPETION_IF(true, bad_variant_access("Visiting of empty variant"));
1943
    }
1964
    }
1944
};
1965
};
Lines 2054-2056 struct hash<experimental::variant<_Types Source/WTF/wtf/Variant.h_sec6
2054
};
2075
};
2055
2076
2056
} // namespace std
2077
} // namespace std
2078
2079
namespace WTF {
2080
2081
template<typename... Types>
2082
using Variant = std::experimental::variant<Types...>;
2083
2084
}
2085
2086
using WTF::Variant;
2087
2088
#if COMPILER(MSVC)
2089
#pragma warning(pop)
2090
#endif
- Source/WebCore/ChangeLog +30 lines
Lines 1-3 Source/WebCore/ChangeLog_sec1
1
2016-08-06  Sam Weinig  <sam@webkit.org>
2
3
        Replace NodeOrString with Variant<Ref<Node>, String>
4
        https://bugs.webkit.org/show_bug.cgi?id=160638
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * WebCore.xcodeproj/project.pbxproj:
9
        Remove NodeOrString.h/cpp
10
11
        * bindings/js/JSNodeOrString.cpp:
12
        * bindings/js/JSNodeOrString.h:
13
        * dom/ContainerNode.cpp:
14
        (WebCore::ContainerNode::append):
15
        (WebCore::ContainerNode::prepend):
16
        * dom/ContainerNode.h:
17
        * dom/Node.cpp:
18
        (WebCore::nodeSetPreTransformedFromNodeOrStringVector):
19
        (WebCore::firstFollowingSiblingNotInNodeSet):
20
        (WebCore::Node::convertNodesOrStringsIntoNode):
21
        (WebCore::Node::before):
22
        (WebCore::Node::after):
23
        (WebCore::Node::replaceWith):
24
        * dom/Node.h:
25
        Replace NodeOrString with Variant<Ref<Node>, String> and move convertNodesOrStringsIntoNode
26
        into Node.
27
28
        * dom/NodeOrString.cpp: Removed.
29
        * dom/NodeOrString.h: Removed.
30
1
2016-08-06  Darin Adler  <darin@apple.com>
31
2016-08-06  Darin Adler  <darin@apple.com>
2
32
3
        Simplify valueToUSVString
33
        Simplify valueToUSVString
- Source/WebCore/CMakeLists.txt -1 lines
Lines 1487-1493 set(WebCore_SOURCES Source/WebCore/CMakeLists.txt_sec1
1487
    dom/Node.cpp
1487
    dom/Node.cpp
1488
    dom/NodeFilterCondition.cpp
1488
    dom/NodeFilterCondition.cpp
1489
    dom/NodeIterator.cpp
1489
    dom/NodeIterator.cpp
1490
    dom/NodeOrString.cpp
1491
    dom/NodeRareData.cpp
1490
    dom/NodeRareData.cpp
1492
    dom/NodeTraversal.cpp
1491
    dom/NodeTraversal.cpp
1493
    dom/OverflowEvent.cpp
1492
    dom/OverflowEvent.cpp
- Source/WebCore/WebCore.xcodeproj/project.pbxproj -8 lines
Lines 2843-2850 Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec1
2843
		7CE683471921821500F4D928 /* UserMessageHandlerDescriptorTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE683461921821500F4D928 /* UserMessageHandlerDescriptorTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
2843
		7CE683471921821500F4D928 /* UserMessageHandlerDescriptorTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE683461921821500F4D928 /* UserMessageHandlerDescriptorTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
2844
		7CE6CBFB187F370700D46BF5 /* FormatConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE6CBFA187F370700D46BF5 /* FormatConverter.h */; };
2844
		7CE6CBFB187F370700D46BF5 /* FormatConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE6CBFA187F370700D46BF5 /* FormatConverter.h */; };
2845
		7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CE6CBFC187F394900D46BF5 /* FormatConverter.cpp */; };
2845
		7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CE6CBFC187F394900D46BF5 /* FormatConverter.cpp */; };
2846
		7CEAC1071B483D1D00334482 /* NodeOrString.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CEAC1061B483D1D00334482 /* NodeOrString.h */; };
2847
		7CEAC1091B483D7F00334482 /* NodeOrString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEAC1081B483D7F00334482 /* NodeOrString.cpp */; };
2848
		7CFDC57C1AC1D80500E24A57 /* ContentExtensionError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CFDC57A1AC1D80500E24A57 /* ContentExtensionError.cpp */; };
2846
		7CFDC57C1AC1D80500E24A57 /* ContentExtensionError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CFDC57A1AC1D80500E24A57 /* ContentExtensionError.cpp */; };
2849
		7CFDC57D1AC1D80500E24A57 /* ContentExtensionError.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CFDC57B1AC1D80500E24A57 /* ContentExtensionError.h */; settings = {ATTRIBUTES = (Private, ); }; };
2847
		7CFDC57D1AC1D80500E24A57 /* ContentExtensionError.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CFDC57B1AC1D80500E24A57 /* ContentExtensionError.h */; settings = {ATTRIBUTES = (Private, ); }; };
2850
		7D4C96DC1AD4483500365A50 /* JSFetchHeaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7D4C96D81AD4483500365A50 /* JSFetchHeaders.cpp */; };
2848
		7D4C96DC1AD4483500365A50 /* JSFetchHeaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7D4C96D81AD4483500365A50 /* JSFetchHeaders.cpp */; };
Lines 10265-10272 Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec2
10265
		7CE683461921821500F4D928 /* UserMessageHandlerDescriptorTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMessageHandlerDescriptorTypes.h; sourceTree = "<group>"; };
10263
		7CE683461921821500F4D928 /* UserMessageHandlerDescriptorTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMessageHandlerDescriptorTypes.h; sourceTree = "<group>"; };
10266
		7CE6CBFA187F370700D46BF5 /* FormatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatConverter.h; sourceTree = "<group>"; };
10264
		7CE6CBFA187F370700D46BF5 /* FormatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatConverter.h; sourceTree = "<group>"; };
10267
		7CE6CBFC187F394900D46BF5 /* FormatConverter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormatConverter.cpp; sourceTree = "<group>"; };
10265
		7CE6CBFC187F394900D46BF5 /* FormatConverter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormatConverter.cpp; sourceTree = "<group>"; };
10268
		7CEAC1061B483D1D00334482 /* NodeOrString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NodeOrString.h; sourceTree = "<group>"; };
10269
		7CEAC1081B483D7F00334482 /* NodeOrString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NodeOrString.cpp; sourceTree = "<group>"; };
10270
		7CFDC57A1AC1D80500E24A57 /* ContentExtensionError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContentExtensionError.cpp; sourceTree = "<group>"; };
10266
		7CFDC57A1AC1D80500E24A57 /* ContentExtensionError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContentExtensionError.cpp; sourceTree = "<group>"; };
10271
		7CFDC57B1AC1D80500E24A57 /* ContentExtensionError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentExtensionError.h; sourceTree = "<group>"; };
10267
		7CFDC57B1AC1D80500E24A57 /* ContentExtensionError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentExtensionError.h; sourceTree = "<group>"; };
10272
		7D4C96D81AD4483500365A50 /* JSFetchHeaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFetchHeaders.cpp; sourceTree = "<group>"; };
10268
		7D4C96D81AD4483500365A50 /* JSFetchHeaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFetchHeaders.cpp; sourceTree = "<group>"; };
Lines 24142-24149 Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec3
24142
				1A750D870A90E394000FF215 /* NodeIterator.idl */,
24138
				1A750D870A90E394000FF215 /* NodeIterator.idl */,
24143
				A81872100977D3C0005826D9 /* NodeList.h */,
24139
				A81872100977D3C0005826D9 /* NodeList.h */,
24144
				85ACA9FA0A9B631000671E90 /* NodeList.idl */,
24140
				85ACA9FA0A9B631000671E90 /* NodeList.idl */,
24145
				7CEAC1081B483D7F00334482 /* NodeOrString.cpp */,
24146
				7CEAC1061B483D1D00334482 /* NodeOrString.h */,
24147
				4FAB48661643A67E00F70C07 /* NodeRareData.cpp */,
24141
				4FAB48661643A67E00F70C07 /* NodeRareData.cpp */,
24148
				63189AE20E83A33300012E41 /* NodeRareData.h */,
24142
				63189AE20E83A33300012E41 /* NodeRareData.h */,
24149
				63D7B32C0E78CD3F00F7617C /* NodeRenderStyle.h */,
24143
				63D7B32C0E78CD3F00F7617C /* NodeRenderStyle.h */,
Lines 26904-26910 Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec4
26904
				854FE7330A2297BE0058D7AD /* NodeFilterCondition.h in Headers */,
26898
				854FE7330A2297BE0058D7AD /* NodeFilterCondition.h in Headers */,
26905
				854FE7350A2297BE0058D7AD /* NodeIterator.h in Headers */,
26899
				854FE7350A2297BE0058D7AD /* NodeIterator.h in Headers */,
26906
				A818721B0977D3C0005826D9 /* NodeList.h in Headers */,
26900
				A818721B0977D3C0005826D9 /* NodeList.h in Headers */,
26907
				7CEAC1071B483D1D00334482 /* NodeOrString.h in Headers */,
26908
				63189AE30E83A33300012E41 /* NodeRareData.h in Headers */,
26901
				63189AE30E83A33300012E41 /* NodeRareData.h in Headers */,
26909
				63D7B32D0E78CD3F00F7617C /* NodeRenderStyle.h in Headers */,
26902
				63D7B32D0E78CD3F00F7617C /* NodeRenderStyle.h in Headers */,
26910
				E43105BB16750F1600DB2FB8 /* NodeTraversal.h in Headers */,
26903
				E43105BB16750F1600DB2FB8 /* NodeTraversal.h in Headers */,
Lines 30706-30712 Source/WebCore/WebCore.xcodeproj/project.pbxproj_sec5
30706
				A8C4A80009D563270003AC8D /* Node.cpp in Sources */,
30699
				A8C4A80009D563270003AC8D /* Node.cpp in Sources */,
30707
				854FE7320A2297BE0058D7AD /* NodeFilterCondition.cpp in Sources */,
30700
				854FE7320A2297BE0058D7AD /* NodeFilterCondition.cpp in Sources */,
30708
				854FE7340A2297BE0058D7AD /* NodeIterator.cpp in Sources */,
30701
				854FE7340A2297BE0058D7AD /* NodeIterator.cpp in Sources */,
30709
				7CEAC1091B483D7F00334482 /* NodeOrString.cpp in Sources */,
30710
				4FFC022B1643B710004E1638 /* NodeRareData.cpp in Sources */,
30702
				4FFC022B1643B710004E1638 /* NodeRareData.cpp in Sources */,
30711
				E43105B816750F0C00DB2FB8 /* NodeTraversal.cpp in Sources */,
30703
				E43105B816750F0C00DB2FB8 /* NodeTraversal.cpp in Sources */,
30712
				33503CC71017A1B1003B47E1 /* Notification.cpp in Sources */,
30704
				33503CC71017A1B1003B47E1 /* Notification.cpp in Sources */,
- Source/WebCore/bindings/js/JSNodeOrString.cpp -3 / +3 lines
Lines 33-49 using namespace JSC; Source/WebCore/bindings/js/JSNodeOrString.cpp_sec1
33
33
34
namespace WebCore {
34
namespace WebCore {
35
35
36
Vector<NodeOrString> toNodeOrStringVector(ExecState& state)
36
Vector<Variant<Ref<Node>, String>> toNodeOrStringVector(ExecState& state)
37
{
37
{
38
    size_t argumentCount = state.argumentCount();
38
    size_t argumentCount = state.argumentCount();
39
39
40
    Vector<NodeOrString> result;
40
    Vector<Variant<Ref<Node>, String>> result;
41
    result.reserveInitialCapacity(argumentCount);
41
    result.reserveInitialCapacity(argumentCount);
42
42
43
    for (size_t i = 0; i < argumentCount; ++i) {
43
    for (size_t i = 0; i < argumentCount; ++i) {
44
        JSValue value = state.uncheckedArgument(i);
44
        JSValue value = state.uncheckedArgument(i);
45
        if (auto* node = jsDynamicCast<JSNode*>(value))
45
        if (auto* node = jsDynamicCast<JSNode*>(value))
46
            result.uncheckedAppend(&node->wrapped());
46
            result.uncheckedAppend(node->wrapped());
47
        else {
47
        else {
48
            String string = value.toWTFString(&state);
48
            String string = value.toWTFString(&state);
49
            if (state.hadException())
49
            if (state.hadException())
- Source/WebCore/bindings/js/JSNodeOrString.h -2 / +5 lines
Lines 26-32 Source/WebCore/bindings/js/JSNodeOrString.h_sec1
26
#ifndef JSNodeOrString_h
26
#ifndef JSNodeOrString_h
27
#define JSNodeOrString_h
27
#define JSNodeOrString_h
28
28
29
#include "NodeOrString.h"
29
#include <wtf/Forward.h>
30
#include <wtf/Variant.h>
30
#include <wtf/Vector.h>
31
#include <wtf/Vector.h>
31
32
32
namespace JSC {
33
namespace JSC {
Lines 35-41 class ExecState; Source/WebCore/bindings/js/JSNodeOrString.h_sec2
35
36
36
namespace WebCore {
37
namespace WebCore {
37
38
38
Vector<NodeOrString> toNodeOrStringVector(JSC::ExecState&);
39
class Node;
40
41
Vector<Variant<Ref<Node>, String>> toNodeOrStringVector(JSC::ExecState&);
39
42
40
} // namespace WebCore
43
} // namespace WebCore
41
44
- Source/WebCore/dom/ContainerNode.cpp -5 / +4 lines
Lines 44-50 Source/WebCore/dom/ContainerNode.cpp_sec1
44
#include "MutationEvent.h"
44
#include "MutationEvent.h"
45
#include "NameNodeList.h"
45
#include "NameNodeList.h"
46
#include "NoEventDispatchAssertion.h"
46
#include "NoEventDispatchAssertion.h"
47
#include "NodeOrString.h"
48
#include "NodeRareData.h"
47
#include "NodeRareData.h"
49
#include "NodeRenderStyle.h"
48
#include "NodeRenderStyle.h"
50
#include "RadioNodeList.h"
49
#include "RadioNodeList.h"
Lines 873-890 unsigned ContainerNode::childElementCoun Source/WebCore/dom/ContainerNode.cpp_sec2
873
    return std::distance(children.begin(), children.end());
872
    return std::distance(children.begin(), children.end());
874
}
873
}
875
874
876
void ContainerNode::append(Vector<NodeOrString>&& nodeOrStringVector, ExceptionCode& ec)
875
void ContainerNode::append(Vector<Variant<Ref<Node>, String>>&& nodeOrStringVector, ExceptionCode& ec)
877
{
876
{
878
    RefPtr<Node> node = convertNodesOrStringsIntoNode(*this, WTFMove(nodeOrStringVector), ec);
877
    RefPtr<Node> node = convertNodesOrStringsIntoNode(WTFMove(nodeOrStringVector), ec);
879
    if (ec || !node)
878
    if (ec || !node)
880
        return;
879
        return;
881
880
882
    appendChild(*node, ec);
881
    appendChild(*node, ec);
883
}
882
}
884
883
885
void ContainerNode::prepend(Vector<NodeOrString>&& nodeOrStringVector, ExceptionCode& ec)
884
void ContainerNode::prepend(Vector<Variant<Ref<Node>, String>>&& nodeOrStringVector, ExceptionCode& ec)
886
{
885
{
887
    RefPtr<Node> node = convertNodesOrStringsIntoNode(*this, WTFMove(nodeOrStringVector), ec);
886
    RefPtr<Node> node = convertNodesOrStringsIntoNode(WTFMove(nodeOrStringVector), ec);
888
    if (ec || !node)
887
    if (ec || !node)
889
        return;
888
        return;
890
889
- Source/WebCore/dom/ContainerNode.h -2 / +2 lines
Lines 99-106 public: Source/WebCore/dom/ContainerNode.h_sec1
99
    Element* firstElementChild() const;
99
    Element* firstElementChild() const;
100
    Element* lastElementChild() const;
100
    Element* lastElementChild() const;
101
    unsigned childElementCount() const;
101
    unsigned childElementCount() const;
102
    void append(Vector<NodeOrString>&&, ExceptionCode&);
102
    void append(Vector<Variant<Ref<Node>, String>>&&, ExceptionCode&);
103
    void prepend(Vector<NodeOrString>&&, ExceptionCode&);
103
    void prepend(Vector<Variant<Ref<Node>, String>>&&, ExceptionCode&);
104
104
105
    bool ensurePreInsertionValidity(Node& newChild, Node* refChild, ExceptionCode&);
105
    bool ensurePreInsertionValidity(Node& newChild, Node* refChild, ExceptionCode&);
106
106
- Source/WebCore/dom/DOMAllInOne.cpp -1 lines
Lines 112-118 Source/WebCore/dom/DOMAllInOne.cpp_sec1
112
#include "Node.cpp"
112
#include "Node.cpp"
113
#include "NodeFilterCondition.cpp"
113
#include "NodeFilterCondition.cpp"
114
#include "NodeIterator.cpp"
114
#include "NodeIterator.cpp"
115
#include "NodeOrString.cpp"
116
#include "NodeRareData.cpp"
115
#include "NodeRareData.cpp"
117
#include "NodeTraversal.cpp"
116
#include "NodeTraversal.cpp"
118
#include "OverflowEvent.cpp"
117
#include "OverflowEvent.cpp"
- Source/WebCore/dom/Node.cpp -17 / +42 lines
Lines 53-59 Source/WebCore/dom/Node.cpp_sec1
53
#include "Logging.h"
53
#include "Logging.h"
54
#include "MutationEvent.h"
54
#include "MutationEvent.h"
55
#include "NoEventDispatchAssertion.h"
55
#include "NoEventDispatchAssertion.h"
56
#include "NodeOrString.h"
57
#include "NodeRenderStyle.h"
56
#include "NodeRenderStyle.h"
58
#include "ProcessingInstruction.h"
57
#include "ProcessingInstruction.h"
59
#include "ProgressEvent.h"
58
#include "ProgressEvent.h"
Lines 438-455 bool Node::appendChild(Node& newChild, E Source/WebCore/dom/Node.cpp_sec2
438
    return downcast<ContainerNode>(*this).appendChild(newChild, ec);
437
    return downcast<ContainerNode>(*this).appendChild(newChild, ec);
439
}
438
}
440
439
441
static HashSet<RefPtr<Node>> nodeSetPreTransformedFromNodeOrStringVector(const Vector<NodeOrString>& nodeOrStringVector)
440
static HashSet<RefPtr<Node>> nodeSetPreTransformedFromNodeOrStringVector(const Vector<Variant<Ref<Node>, String>>& vector)
442
{
441
{
443
    HashSet<RefPtr<Node>> nodeSet;
442
    HashSet<RefPtr<Node>> nodeSet;
444
    for (auto& nodeOrString : nodeOrStringVector) {
443
445
        switch (nodeOrString.type()) {
444
    auto visitor = WTF::makeOverloader(
446
        case NodeOrString::Type::String:
445
        [&](const Ref<Node>& node) { nodeSet.add(const_cast<Node*>(node.ptr())); },
447
            break;
446
        [](const String&) { }
448
        case NodeOrString::Type::Node:
447
    );
449
            nodeSet.add(&nodeOrString.node());
448
450
            break;
449
    for (const auto& variant : vector)
451
        }
450
        std::experimental::visit(visitor, variant);
452
    }
453
451
454
    return nodeSet;
452
    return nodeSet;
455
}
453
}
Lines 472-478 static RefPtr<Node> firstFollowingSiblin Source/WebCore/dom/Node.cpp_sec3
472
    return nullptr;
470
    return nullptr;
473
}
471
}
474
472
475
void Node::before(Vector<NodeOrString>&& nodeOrStringVector, ExceptionCode& ec)
473
RefPtr<Node> Node::convertNodesOrStringsIntoNode(Vector<Variant<Ref<Node>, String>>&& nodeOrStringVector, ExceptionCode& ec)
474
{
475
    if (nodeOrStringVector.isEmpty())
476
        return nullptr;
477
478
    Vector<Ref<Node>> nodes;
479
    nodes.reserveInitialCapacity(nodeOrStringVector.size());
480
481
    auto visitor = WTF::makeOverloader(
482
        [&](Ref<Node>& node) { nodes.uncheckedAppend(node.copyRef()); },
483
        [&](String& string) { nodes.uncheckedAppend(Text::create(document(), string)); }
484
    );
485
486
    for (auto& variant : nodeOrStringVector)
487
        std::experimental::visit(visitor, variant);
488
489
    if (nodes.size() == 1)
490
        return WTFMove(nodes.first());
491
492
    auto nodeToReturn = DocumentFragment::create(document());
493
    for (auto& node : nodes) {
494
        if (!nodeToReturn->appendChild(node, ec))
495
            return nullptr;
496
    }
497
    return WTFMove(nodeToReturn);
498
}
499
500
void Node::before(Vector<Variant<Ref<Node>, String>>&& nodeOrStringVector, ExceptionCode& ec)
476
{
501
{
477
    RefPtr<ContainerNode> parent = parentNode();
502
    RefPtr<ContainerNode> parent = parentNode();
478
    if (!parent)
503
    if (!parent)
Lines 481-487 void Node::before(Vector<NodeOrString>&& Source/WebCore/dom/Node.cpp_sec4
481
    auto nodeSet = nodeSetPreTransformedFromNodeOrStringVector(nodeOrStringVector);
506
    auto nodeSet = nodeSetPreTransformedFromNodeOrStringVector(nodeOrStringVector);
482
    auto viablePreviousSibling = firstPrecedingSiblingNotInNodeSet(*this, nodeSet);
507
    auto viablePreviousSibling = firstPrecedingSiblingNotInNodeSet(*this, nodeSet);
483
508
484
    auto node = convertNodesOrStringsIntoNode(*this, WTFMove(nodeOrStringVector), ec);
509
    auto node = convertNodesOrStringsIntoNode(WTFMove(nodeOrStringVector), ec);
485
    if (ec || !node)
510
    if (ec || !node)
486
        return;
511
        return;
487
512
Lines 493-499 void Node::before(Vector<NodeOrString>&& Source/WebCore/dom/Node.cpp_sec5
493
    parent->insertBefore(*node, viablePreviousSibling.get(), ec);
518
    parent->insertBefore(*node, viablePreviousSibling.get(), ec);
494
}
519
}
495
520
496
void Node::after(Vector<NodeOrString>&& nodeOrStringVector, ExceptionCode& ec)
521
void Node::after(Vector<Variant<Ref<Node>, String>>&& nodeOrStringVector, ExceptionCode& ec)
497
{
522
{
498
    RefPtr<ContainerNode> parent = parentNode();
523
    RefPtr<ContainerNode> parent = parentNode();
499
    if (!parent)
524
    if (!parent)
Lines 502-515 void Node::after(Vector<NodeOrString>&& Source/WebCore/dom/Node.cpp_sec6
502
    auto nodeSet = nodeSetPreTransformedFromNodeOrStringVector(nodeOrStringVector);
527
    auto nodeSet = nodeSetPreTransformedFromNodeOrStringVector(nodeOrStringVector);
503
    auto viableNextSibling = firstFollowingSiblingNotInNodeSet(*this, nodeSet);
528
    auto viableNextSibling = firstFollowingSiblingNotInNodeSet(*this, nodeSet);
504
529
505
    auto node = convertNodesOrStringsIntoNode(*this, WTFMove(nodeOrStringVector), ec);
530
    auto node = convertNodesOrStringsIntoNode(WTFMove(nodeOrStringVector), ec);
506
    if (ec || !node)
531
    if (ec || !node)
507
        return;
532
        return;
508
533
509
    parent->insertBefore(*node, viableNextSibling.get(), ec);
534
    parent->insertBefore(*node, viableNextSibling.get(), ec);
510
}
535
}
511
536
512
void Node::replaceWith(Vector<NodeOrString>&& nodeOrStringVector, ExceptionCode& ec)
537
void Node::replaceWith(Vector<Variant<Ref<Node>, String>>&& nodeOrStringVector, ExceptionCode& ec)
513
{
538
{
514
    RefPtr<ContainerNode> parent = parentNode();
539
    RefPtr<ContainerNode> parent = parentNode();
515
    if (!parent)
540
    if (!parent)
Lines 518-524 void Node::replaceWith(Vector<NodeOrStri Source/WebCore/dom/Node.cpp_sec7
518
    auto nodeSet = nodeSetPreTransformedFromNodeOrStringVector(nodeOrStringVector);
543
    auto nodeSet = nodeSetPreTransformedFromNodeOrStringVector(nodeOrStringVector);
519
    auto viableNextSibling = firstFollowingSiblingNotInNodeSet(*this, nodeSet);
544
    auto viableNextSibling = firstFollowingSiblingNotInNodeSet(*this, nodeSet);
520
545
521
    auto node = convertNodesOrStringsIntoNode(*this, WTFMove(nodeOrStringVector), ec);
546
    auto node = convertNodesOrStringsIntoNode(WTFMove(nodeOrStringVector), ec);
522
    if (ec)
547
    if (ec)
523
        return;
548
        return;
524
549
- Source/WebCore/dom/Node.h -4 / +6 lines
Lines 35-40 Source/WebCore/dom/Node.h_sec1
35
#include <wtf/ListHashSet.h>
35
#include <wtf/ListHashSet.h>
36
#include <wtf/MainThread.h>
36
#include <wtf/MainThread.h>
37
#include <wtf/TypeCasts.h>
37
#include <wtf/TypeCasts.h>
38
#include <wtf/Variant.h>
38
39
39
// This needs to be here because Document.h also depends on it.
40
// This needs to be here because Document.h also depends on it.
40
#define DUMP_NODE_STATISTICS 0
41
#define DUMP_NODE_STATISTICS 0
Lines 51-57 class MathMLQualifiedName; Source/WebCore/dom/Node.h_sec2
51
class NamedNodeMap;
52
class NamedNodeMap;
52
class NodeList;
53
class NodeList;
53
class NodeListsNodeData;
54
class NodeListsNodeData;
54
class NodeOrString;
55
class NodeRareData;
55
class NodeRareData;
56
class QualifiedName;
56
class QualifiedName;
57
class RenderBox;
57
class RenderBox;
Lines 208-216 public: Source/WebCore/dom/Node.h_sec3
208
    Element* nextElementSibling() const;
208
    Element* nextElementSibling() const;
209
209
210
    // From the ChildNode - https://dom.spec.whatwg.org/#childnode
210
    // From the ChildNode - https://dom.spec.whatwg.org/#childnode
211
    void before(Vector<NodeOrString>&&, ExceptionCode&);
211
    void before(Vector<Variant<Ref<Node>, String>>&&, ExceptionCode&);
212
    void after(Vector<NodeOrString>&&, ExceptionCode&);
212
    void after(Vector<Variant<Ref<Node>, String>>&&, ExceptionCode&);
213
    void replaceWith(Vector<NodeOrString>&&, ExceptionCode&);
213
    void replaceWith(Vector<Variant<Ref<Node>, String>>&&, ExceptionCode&);
214
    WEBCORE_EXPORT void remove(ExceptionCode&);
214
    WEBCORE_EXPORT void remove(ExceptionCode&);
215
215
216
    // Other methods (not part of DOM)
216
    // Other methods (not part of DOM)
Lines 661-666 protected: Source/WebCore/dom/Node.h_sec4
661
    void setStyleChange(StyleChangeType changeType) { m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType; }
661
    void setStyleChange(StyleChangeType changeType) { m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType; }
662
    void updateAncestorsForStyleRecalc();
662
    void updateAncestorsForStyleRecalc();
663
663
664
    RefPtr<Node> convertNodesOrStringsIntoNode(Vector<Variant<Ref<Node>, String>>&&, ExceptionCode&);
665
664
private:
666
private:
665
    virtual PseudoId customPseudoId() const
667
    virtual PseudoId customPseudoId() const
666
    {
668
    {
- Source/WebCore/dom/NodeOrString.cpp -63 lines
Lines 1-63 Source/WebCore/dom/NodeOrString.cpp_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
 * THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#include "config.h"
27
#include "NodeOrString.h"
28
29
#include "DocumentFragment.h"
30
#include "Text.h"
31
32
namespace WebCore {
33
34
RefPtr<Node> convertNodesOrStringsIntoNode(Node& context, Vector<NodeOrString>&& nodeOrStringVector, ExceptionCode& ec)
35
{
36
    if (nodeOrStringVector.isEmpty())
37
        return nullptr;
38
39
    Vector<Ref<Node>> nodes;
40
    nodes.reserveInitialCapacity(nodeOrStringVector.size());
41
    for (auto& nodeOrString : nodeOrStringVector) {
42
        switch (nodeOrString.type()) {
43
        case NodeOrString::Type::String:
44
            nodes.uncheckedAppend(Text::create(context.document(), nodeOrString.string()));
45
            break;
46
        case NodeOrString::Type::Node:
47
            nodes.uncheckedAppend(nodeOrString.node());
48
            break;
49
        }
50
    }
51
52
    if (nodes.size() == 1)
53
        return WTFMove(nodes.first());
54
55
    auto nodeToReturn = DocumentFragment::create(context.document());
56
    for (auto& node : nodes) {
57
        if (!nodeToReturn->appendChild(node, ec))
58
            return nullptr;
59
    }
60
    return WTFMove(nodeToReturn);
61
}
62
63
} // namespace WebCore
- Source/WebCore/dom/NodeOrString.h -163 lines
Lines 1-163 Source/WebCore/dom/NodeOrString.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
 * THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#ifndef NodeOrString_h
27
#define NodeOrString_h
28
29
#include "Node.h"
30
#include <wtf/StdLibExtras.h>
31
#include <wtf/Vector.h>
32
#include <wtf/text/WTFString.h>
33
34
namespace WebCore {
35
36
class NodeOrString {
37
public:
38
    enum class Type {
39
        String,
40
        Node
41
    };
42
43
    NodeOrString(const String& string)
44
        : m_type(Type::String)
45
    {
46
        m_data.string = string.impl();
47
        m_data.string->ref();
48
    }
49
50
    NodeOrString(Node* node)
51
        : m_type(Type::Node)
52
    {
53
        m_data.node = node;
54
        m_data.node->ref();
55
    }
56
57
    NodeOrString(const NodeOrString& other)
58
        : m_type(other.m_type)
59
    {
60
        switch (m_type) {
61
        case Type::String:
62
            m_data.string = other.m_data.string;
63
            m_data.string->ref();
64
            break;
65
        case Type::Node:
66
            m_data.node = other.m_data.node;
67
            m_data.node->ref();
68
            break;
69
        }
70
    }
71
72
    NodeOrString(NodeOrString&& other)
73
        : m_type(other.m_type)
74
    {
75
        switch (m_type) {
76
        case Type::String:
77
            m_data.string = std::exchange(other.m_data.string, nullptr);
78
            break;
79
        case Type::Node:
80
            m_data.node = std::exchange(other.m_data.node, nullptr);
81
            break;
82
        }
83
    }
84
85
    NodeOrString& operator=(const NodeOrString& other)
86
    {
87
        if (this == &other)
88
            return *this;
89
90
        derefData();
91
92
        m_type = other.m_type;
93
        switch (m_type) {
94
        case Type::String:
95
            m_data.string = other.m_data.string;
96
            m_data.string->ref();
97
            break;
98
        case Type::Node:
99
            m_data.node = other.m_data.node;
100
            m_data.node->ref();
101
            break;
102
        }
103
104
        return *this;
105
    }
106
107
    NodeOrString& operator=(NodeOrString&& other)
108
    {
109
        if (this == &other)
110
            return *this;
111
112
        derefData();
113
114
        m_type = other.m_type;
115
        switch (m_type) {
116
        case Type::String:
117
            m_data.string = std::exchange(other.m_data.string, nullptr);
118
            break;
119
        case Type::Node:
120
            m_data.node = std::exchange(other.m_data.node, nullptr);
121
            break;
122
        }
123
124
        return *this;
125
    }
126
127
    ~NodeOrString()
128
    {
129
        derefData();
130
    }
131
132
    Type type() const { return m_type; }
133
134
    Node& node() const { ASSERT(m_type == Type::Node); ASSERT(m_data.node); return *m_data.node; }
135
    StringImpl& string() const { ASSERT(m_type == Type::String); ASSERT(m_data.string); return *m_data.string; }
136
    
137
private:
138
    void derefData()
139
    {
140
        switch (m_type) {
141
        case Type::String:
142
            if (m_data.string)
143
                m_data.string->deref();
144
            break;
145
        case Type::Node:
146
            if (m_data.node)
147
                m_data.node->deref();
148
            break;
149
        }
150
    }
151
152
    Type m_type;
153
    union {
154
        StringImpl* string;
155
        Node* node;
156
    } m_data;
157
};
158
159
RefPtr<Node> convertNodesOrStringsIntoNode(Node& context, Vector<NodeOrString>&&, ExceptionCode&);
160
161
} // namespace WebCore
162
163
#endif // NodeOrString_h
- Tools/ChangeLog +11 lines
Lines 1-3 Tools/ChangeLog_sec1
1
2016-08-06  Sam Weinig  <sam@webkit.org>
2
3
        Replace NodeOrString with Variant<Ref<Node>, String>
4
        https://bugs.webkit.org/show_bug.cgi?id=160638
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * TestWebKitAPI/Tests/WTF/Variant.cpp:
9
        Add additional tests for the initial state of Variant and using
10
        makeOverloader for visiting.
11
1
2016-08-06  Aakash Jain  <aakash_jain@apple.com>
12
2016-08-06  Aakash Jain  <aakash_jain@apple.com>
2
13
3
        EWS Style Queue fails to process patches which fails validation
14
        EWS Style Queue fails to process patches which fails validation
- Tools/TestWebKitAPI/Tests/WTF/Variant.cpp -14 / +78 lines
Lines 26-51 Tools/TestWebKitAPI/Tests/WTF/Variant.cpp_sec1
26
#include "config.h"
26
#include "config.h"
27
27
28
#include "Counters.h"
28
#include "Counters.h"
29
#include "MoveOnly.h"
30
#include "RefLogger.h"
29
#include "RefLogger.h"
31
#include <wtf/Ref.h>
30
#include <wtf/Ref.h>
32
#include <wtf/RefPtr.h>
31
#include <wtf/RefPtr.h>
32
#include <wtf/StdLibExtras.h>
33
#include <wtf/Variant.h>
33
#include <wtf/Variant.h>
34
#include <wtf/text/WTFString.h>
34
#include <wtf/text/WTFString.h>
35
35
36
namespace TestWebKitAPI {
36
namespace TestWebKitAPI {
37
37
38
TEST(WTF_Variant, Initial)
39
{
40
    Variant<int, double> v1;
41
    EXPECT_TRUE(v1.index() == 0);
42
    EXPECT_TRUE(std::experimental::get<int>(v1) == 0);
43
44
    struct T {
45
        T() : value(15) { }
46
        int value;
47
    };
48
49
    Variant<T, int> v2;
50
    EXPECT_TRUE(v2.index() == 0);
51
    EXPECT_TRUE(std::experimental::get<T>(v2).value == 15);
52
}
53
38
TEST(WTF_Variant, Basic)
54
TEST(WTF_Variant, Basic)
39
{
55
{
40
    std::experimental::variant<int, double> variant = 1;
56
    Variant<int, double> variant = 1;
41
    EXPECT_TRUE(variant.index() == 0);
57
    EXPECT_TRUE(variant.index() == 0);
42
    EXPECT_TRUE(std::experimental::get<int>(variant) == 1);
58
    EXPECT_TRUE(std::experimental::get<int>(variant) == 1);
59
    EXPECT_TRUE(*std::experimental::get_if<int>(variant) == 1);
60
    EXPECT_TRUE(std::experimental::get_if<double>(variant) == nullptr);
61
    EXPECT_TRUE(std::experimental::holds_alternative<int>(variant));
62
    EXPECT_FALSE(std::experimental::holds_alternative<double>(variant));
63
64
    variant = 1.0;
65
    EXPECT_TRUE(variant.index() == 1);
66
    EXPECT_TRUE(std::experimental::get<double>(variant) == 1);
67
    EXPECT_TRUE(*std::experimental::get_if<double>(variant) == 1.0);
68
    EXPECT_TRUE(std::experimental::get_if<int>(variant) == nullptr);
69
    EXPECT_TRUE(std::experimental::holds_alternative<double>(variant));
70
    EXPECT_FALSE(std::experimental::holds_alternative<int>(variant));
43
}
71
}
44
72
45
TEST(WTF_Variant, BasicVisitor)
73
TEST(WTF_Variant, BasicVisitor)
46
{
74
{
47
    typedef std::experimental::variant<int, float, String> Variant;
48
49
    enum class Type {
75
    enum class Type {
50
        None,
76
        None,
51
        Int,
77
        Int,
Lines 53-59 TEST(WTF_Variant, BasicVisitor) Tools/TestWebKitAPI/Tests/WTF/Variant.cpp_sec2
53
        String,
79
        String,
54
    };
80
    };
55
81
56
57
    struct Visitor {
82
    struct Visitor {
58
        Visitor(Type& t)
83
        Visitor(Type& t)
59
            : type(t)
84
            : type(t)
Lines 69-75 TEST(WTF_Variant, BasicVisitor) Tools/TestWebKitAPI/Tests/WTF/Variant.cpp_sec3
69
94
70
    Type type = Type::None;
95
    Type type = Type::None;
71
96
72
    Variant variant = 8;
97
    Variant<int, float, String> variant = 8;
73
    std::experimental::visit(Visitor(type), variant);
98
    std::experimental::visit(Visitor(type), variant);
74
    EXPECT_TRUE(Type::Int == type);
99
    EXPECT_TRUE(Type::Int == type);
75
100
Lines 84-98 TEST(WTF_Variant, BasicVisitor) Tools/TestWebKitAPI/Tests/WTF/Variant.cpp_sec4
84
    EXPECT_TRUE(Type::String == type);
109
    EXPECT_TRUE(Type::String == type);
85
}
110
}
86
111
112
TEST(WTF_Variant, VisitorUsingMakeOverloader)
113
{
114
    enum class Type {
115
        None,
116
        Int,
117
        Float,
118
        String,
119
    };
120
121
    Type type = Type::None;
122
123
    auto visitor = WTF::makeOverloader(
124
        [&](int) { type = Type::Int; },
125
        [&](float) { type = Type::Float; },
126
        [&](String) { type = Type::String; }
127
    );
128
129
    Variant<int, float, String> variant = 8;
130
    std::experimental::visit(visitor, variant);
131
    EXPECT_TRUE(Type::Int == type);
132
133
134
    variant = 1.0f;
135
    std::experimental::visit(visitor, variant);
136
    EXPECT_TRUE(Type::Float == type);
137
138
139
    variant = "hello";
140
    std::experimental::visit(visitor, variant);
141
    EXPECT_TRUE(Type::String == type);
142
}
143
87
TEST(WTF_Variant, ConstructorDestructor)
144
TEST(WTF_Variant, ConstructorDestructor)
88
{
145
{
89
    typedef std::experimental::variant<std::unique_ptr<ConstructorDestructorCounter>, int> Variant;
90
 
91
    ConstructorDestructorCounter::TestingScope scope;
146
    ConstructorDestructorCounter::TestingScope scope;
92
147
93
    {
148
    {
94
        auto uniquePtr = std::make_unique<ConstructorDestructorCounter>();
149
        auto uniquePtr = std::make_unique<ConstructorDestructorCounter>();
95
        Variant v = WTFMove(uniquePtr);
150
        Variant<std::unique_ptr<ConstructorDestructorCounter>, int> v = WTFMove(uniquePtr);
96
151
97
        EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
152
        EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
98
        EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
153
        EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
Lines 102-115 TEST(WTF_Variant, ConstructorDestructor) Tools/TestWebKitAPI/Tests/WTF/Variant.cpp_sec5
102
    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
157
    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
103
}
158
}
104
159
105
TEST(WTF_Variant, RefCounting)
160
TEST(WTF_Variant, RefPtr)
106
{
161
{
107
    typedef std::experimental::variant<RefPtr<RefLogger>, int> Variant;
108
109
    {
162
    {
110
        RefLogger a("a");
163
        RefLogger a("a");
111
        RefPtr<RefLogger> ref(&a);
164
        RefPtr<RefLogger> ref(&a);
112
        Variant v = ref;
165
        Variant<RefPtr<RefLogger>, int> v = ref;
113
    }
166
    }
114
167
115
    ASSERT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str());
168
    ASSERT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str());
Lines 117-123 TEST(WTF_Variant, RefCounting) Tools/TestWebKitAPI/Tests/WTF/Variant.cpp_sec6
117
    {
170
    {
118
        RefLogger a("a");
171
        RefLogger a("a");
119
        RefPtr<RefLogger> ref(&a);
172
        RefPtr<RefLogger> ref(&a);
120
        Variant v = WTFMove(ref);
173
        Variant<RefPtr<RefLogger>, int> v = WTFMove(ref);
174
    }
175
176
    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
177
}
178
179
TEST(WTF_Variant, Ref)
180
{
181
    {
182
        RefLogger a("a");
183
        Ref<RefLogger> ref(a);
184
        Variant<Ref<RefLogger>, int> v = WTFMove(ref);
121
    }
185
    }
122
186
123
    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
187
    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

Return to Bug 160638