ServiceWorker registration should store any script fetched through importScripts
[WebKit-https.git] / Source / WTF / wtf / CrossThreadCopier.h
1 /*
2  * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
3  * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #pragma once
33
34 #include <wtf/Assertions.h>
35 #include <wtf/Forward.h>
36 #include <wtf/HashSet.h>
37 #include <wtf/RefPtr.h>
38 #include <wtf/ThreadSafeRefCounted.h>
39 #include <wtf/text/WTFString.h>
40
41 namespace WTF {
42
43 struct CrossThreadCopierBaseHelper {
44     template<typename T> struct RemovePointer {
45         typedef T Type;
46     };
47     template<typename T> struct RemovePointer<T*> {
48         typedef T Type;
49     };
50
51     template<typename T> struct RemovePointer<RefPtr<T>> {
52         typedef T Type;
53     };
54
55     template<typename T> struct IsEnumOrConvertibleToInteger {
56         static const bool value = std::is_integral<T>::value || std::is_enum<T>::value || std::is_convertible<T, long double>::value;
57     };
58
59     template<typename T> struct IsThreadSafeRefCountedPointer {
60         static const bool value = std::is_convertible<typename RemovePointer<T>::Type*, ThreadSafeRefCounted<typename RemovePointer<T>::Type>*>::value;
61     };
62 };
63
64 template<typename T> struct CrossThreadCopierPassThrough {
65     typedef T Type;
66     static Type copy(const T& parameter)
67     {
68         return parameter;
69     }
70 };
71
72 template<bool isEnumOrConvertibleToInteger, bool isThreadSafeRefCounted, typename T> struct CrossThreadCopierBase;
73
74 // Integers get passed through without any changes.
75 template<typename T> struct CrossThreadCopierBase<true, false, T> : public CrossThreadCopierPassThrough<T> {
76 };
77
78 // Classes that have an isolatedCopy() method get a default specialization.
79 template<class T> struct CrossThreadCopierBase<false, false, T> {
80     static T copy(const T& value)
81     {
82         return value.isolatedCopy();
83     }
84 };
85
86 // Custom copy methods.
87 template<typename T> struct CrossThreadCopierBase<false, true, T> {
88     typedef typename CrossThreadCopierBaseHelper::RemovePointer<T>::Type RefCountedType;
89     static_assert(std::is_convertible<RefCountedType*, ThreadSafeRefCounted<RefCountedType>*>::value, "T is not convertible to ThreadSafeRefCounted!");
90
91     typedef RefPtr<RefCountedType> Type;
92     static Type copy(const T& refPtr)
93     {
94         return refPtr;
95     }
96 };
97
98 template<> struct CrossThreadCopierBase<false, false, WTF::ASCIILiteral> {
99     typedef WTF::ASCIILiteral Type;
100     static Type copy(const Type& source)
101     {
102         return source;
103     }
104 };
105
106 template<typename T>
107 struct CrossThreadCopier : public CrossThreadCopierBase<CrossThreadCopierBaseHelper::IsEnumOrConvertibleToInteger<T>::value, CrossThreadCopierBaseHelper::IsThreadSafeRefCountedPointer<T>::value, T> {
108 };
109
110 // Default specialization for Vectors of CrossThreadCopyable classes.
111 template<typename T> struct CrossThreadCopierBase<false, false, Vector<T>> {
112     typedef Vector<T> Type;
113     static Type copy(const Type& source)
114     {
115         Type destination;
116         destination.reserveInitialCapacity(source.size());
117         for (auto& object : source)
118             destination.uncheckedAppend(CrossThreadCopier<T>::copy(object));
119         return destination;
120     }
121 };
122     
123 // Default specialization for HashSets of CrossThreadCopyable classes
124 template<typename T> struct CrossThreadCopierBase<false, false, HashSet<T> > {
125     typedef HashSet<T> Type;
126     static Type copy(const Type& source)
127     {
128         Type destination;
129         for (auto& object : source)
130             destination.add(CrossThreadCopier<T>::copy(object));
131         return destination;
132     }
133 };
134
135 // Default specialization for HashMaps of CrossThreadCopyable classes
136 template<typename K, typename V> struct CrossThreadCopierBase<false, false, HashMap<K, V> > {
137     typedef HashMap<K, V> Type;
138     static Type copy(const Type& source)
139     {
140         Type destination;
141         for (auto& keyValue : source)
142             destination.add(CrossThreadCopier<K>::copy(keyValue.key), CrossThreadCopier<V>::copy(keyValue.value));
143         return destination;
144     }
145 };
146
147 // Default specialization for std::optional of CrossThreadCopyable class.
148 template<typename T> struct CrossThreadCopierBase<false, false, std::optional<T>> {
149     typedef std::optional<T> Type;
150     static Type copy(const Type& source)
151     {
152         if (!source)
153             return std::nullopt;
154         return CrossThreadCopier<T>::copy(*source);
155     }
156 };
157
158 template<typename T> T crossThreadCopy(const T& source)
159 {
160     return CrossThreadCopier<T>::copy(source);
161 }
162     
163 } // namespace WTF
164
165 using WTF::CrossThreadCopierBaseHelper;
166 using WTF::CrossThreadCopierBase;
167 using WTF::CrossThreadCopier;
168 using WTF::crossThreadCopy;