Use a 1-byte enum class for TextDirection
[WebKit-https.git] / Source / WebCore / dom / ExceptionOr.h
1 /*
2
3 Copyright (C) 2016-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
7 are met:
8 1.  Redistributions of source code must retain the above copyright
9     notice, this list of conditions and the following disclaimer.
10 2.  Redistributions in binary form must reproduce the above copyright
11     notice, this list of conditions and the following disclaimer in the
12     documentation and/or other materials provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
15 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25 */
26
27 #pragma once
28
29 #include "Exception.h"
30 #include <wtf/CrossThreadCopier.h>
31 #include <wtf/Expected.h>
32
33 namespace WebCore {
34
35 template<typename ReturnType> class ExceptionOr {
36 public:
37     ExceptionOr(Exception&&);
38     ExceptionOr(ReturnType&&);
39     template<typename OtherType> ExceptionOr(const OtherType&, typename std::enable_if<std::is_scalar<OtherType>::value && std::is_convertible<OtherType, ReturnType>::value>::type* = nullptr);
40
41     bool hasException() const;
42     const Exception& exception() const;
43     Exception&& releaseException();
44     const ReturnType& returnValue() const;
45     ReturnType&& releaseReturnValue();
46     
47 private:
48     Expected<ReturnType, Exception> m_value;
49 };
50
51 template<typename ReturnReferenceType> class ExceptionOr<ReturnReferenceType&> {
52 public:
53     ExceptionOr(Exception&&);
54     ExceptionOr(ReturnReferenceType&);
55
56     bool hasException() const;
57     const Exception& exception() const;
58     Exception&& releaseException();
59     const ReturnReferenceType& returnValue() const;
60     ReturnReferenceType& releaseReturnValue();
61     
62 private:
63     ExceptionOr<ReturnReferenceType*> m_value;
64 };
65
66 template<> class ExceptionOr<void> {
67 public:
68     ExceptionOr(Exception&&);
69     ExceptionOr() = default;
70
71     bool hasException() const;
72     const Exception& exception() const;
73     Exception&& releaseException();
74
75 private:
76     Expected<void, Exception> m_value;
77 };
78
79 ExceptionOr<void> isolatedCopy(ExceptionOr<void>&&);
80
81 template<typename ReturnType> inline ExceptionOr<ReturnType>::ExceptionOr(Exception&& exception)
82     : m_value(makeUnexpected(WTFMove(exception)))
83 {
84 }
85
86 template<typename ReturnType> inline ExceptionOr<ReturnType>::ExceptionOr(ReturnType&& returnValue)
87     : m_value(WTFMove(returnValue))
88 {
89 }
90
91 template<typename ReturnType> template<typename OtherType> inline ExceptionOr<ReturnType>::ExceptionOr(const OtherType& returnValue, typename std::enable_if<std::is_scalar<OtherType>::value && std::is_convertible<OtherType, ReturnType>::value>::type*)
92     : m_value(static_cast<ReturnType>(returnValue))
93 {
94 }
95
96 template<typename ReturnType> inline bool ExceptionOr<ReturnType>::hasException() const
97 {
98     return !m_value.has_value();
99 }
100
101 template<typename ReturnType> inline const Exception& ExceptionOr<ReturnType>::exception() const
102 {
103     return m_value.error();
104 }
105
106 template<typename ReturnType> inline Exception&& ExceptionOr<ReturnType>::releaseException()
107 {
108     return WTFMove(m_value.error());
109 }
110
111 template<typename ReturnType> inline const ReturnType& ExceptionOr<ReturnType>::returnValue() const
112 {
113     return m_value.value();
114 }
115
116 template<typename ReturnType> inline ReturnType&& ExceptionOr<ReturnType>::releaseReturnValue()
117 {
118     return WTFMove(m_value.value());
119 }
120
121 template<typename ReturnReferenceType> inline ExceptionOr<ReturnReferenceType&>::ExceptionOr(Exception&& exception)
122     : m_value(WTFMove(exception))
123 {
124 }
125
126 template<typename ReturnReferenceType> inline ExceptionOr<ReturnReferenceType&>::ExceptionOr(ReturnReferenceType& returnValue)
127     : m_value(&returnValue)
128 {
129 }
130
131 template<typename ReturnReferenceType> inline bool ExceptionOr<ReturnReferenceType&>::hasException() const
132 {
133     return m_value.hasException();
134 }
135
136 template<typename ReturnReferenceType> inline const Exception& ExceptionOr<ReturnReferenceType&>::exception() const
137 {
138     return m_value.exception();
139 }
140
141 template<typename ReturnReferenceType> inline Exception&& ExceptionOr<ReturnReferenceType&>::releaseException()
142 {
143     return m_value.releaseException();
144 }
145
146 template<typename ReturnReferenceType> inline const ReturnReferenceType& ExceptionOr<ReturnReferenceType&>::returnValue() const
147 {
148     return *m_value.returnValue();
149 }
150
151 template<typename ReturnReferenceType> inline ReturnReferenceType& ExceptionOr<ReturnReferenceType&>::releaseReturnValue()
152 {
153     return *m_value.releaseReturnValue();
154 }
155
156 inline ExceptionOr<void>::ExceptionOr(Exception&& exception)
157     : m_value(makeUnexpected(WTFMove(exception)))
158 {
159 }
160
161 inline bool ExceptionOr<void>::hasException() const
162 {
163     return !m_value.has_value();
164 }
165
166 inline const Exception& ExceptionOr<void>::exception() const
167 {
168     return m_value.error();
169 }
170
171 inline Exception&& ExceptionOr<void>::releaseException()
172 {
173     return WTFMove(m_value.error());
174 }
175
176 inline ExceptionOr<void> isolatedCopy(ExceptionOr<void>&& value)
177 {
178     if (value.hasException())
179         return isolatedCopy(value.releaseException());
180     return { };
181 }
182
183 }
184
185 namespace WTF {
186 template<typename T> struct CrossThreadCopierBase<false, false, WebCore::ExceptionOr<T> > {
187     typedef WebCore::ExceptionOr<T> Type;
188     static Type copy(const Type& source)
189     {
190         if (source.hasException())
191             return crossThreadCopy(source.exception());
192         return crossThreadCopy(source.returnValue());
193     }
194 };
195 }