aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/ExceptionOr.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/bindings/ExceptionOr.h')
-rw-r--r--src/bun.js/bindings/ExceptionOr.h239
1 files changed, 239 insertions, 0 deletions
diff --git a/src/bun.js/bindings/ExceptionOr.h b/src/bun.js/bindings/ExceptionOr.h
new file mode 100644
index 000000000..f3378466e
--- /dev/null
+++ b/src/bun.js/bindings/ExceptionOr.h
@@ -0,0 +1,239 @@
+/*
+
+Copyright (C) 2016-2017 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.
+
+*/
+
+#pragma once
+
+#include "root.h"
+
+#include "Exception.h"
+#include "wtf/CrossThreadCopier.h"
+#include "wtf/Expected.h"
+#include "wtf/StdLibExtras.h"
+
+namespace WebCore {
+
+template<typename T> class ExceptionOr {
+public:
+ using ReturnType = T;
+
+ ExceptionOr(Exception&&);
+ ExceptionOr(ReturnType&&);
+ template<typename OtherType> ExceptionOr(const OtherType&, typename std::enable_if<std::is_scalar<OtherType>::value && std::is_convertible<OtherType, ReturnType>::value>::type* = nullptr);
+
+ bool hasException() const;
+ const Exception& exception() const;
+ Exception releaseException();
+ const ReturnType& returnValue() const;
+ ReturnType releaseReturnValue();
+
+private:
+ Expected<ReturnType, Exception> m_value;
+#if ASSERT_ENABLED
+ bool m_wasReleased { false };
+#endif
+};
+
+template<typename T> class ExceptionOr<T&> {
+public:
+ using ReturnType = T&;
+ using ReturnReferenceType = T;
+
+ ExceptionOr(Exception&&);
+ ExceptionOr(ReturnReferenceType&);
+
+ bool hasException() const;
+ const Exception& exception() const;
+ Exception releaseException();
+ const ReturnReferenceType& returnValue() const;
+ ReturnReferenceType& releaseReturnValue();
+
+private:
+ ExceptionOr<ReturnReferenceType*> m_value;
+};
+
+template<> class ExceptionOr<void> {
+public:
+ using ReturnType = void;
+
+ ExceptionOr(Exception&&);
+ ExceptionOr() = default;
+
+ bool hasException() const;
+ const Exception& exception() const;
+ Exception releaseException();
+
+private:
+ Expected<void, Exception> m_value;
+#if ASSERT_ENABLED
+ bool m_wasReleased { false };
+#endif
+};
+
+ExceptionOr<void> isolatedCopy(ExceptionOr<void>&&);
+
+template<typename ReturnType> inline ExceptionOr<ReturnType>::ExceptionOr(Exception&& exception)
+ : m_value(makeUnexpected(WTFMove(exception)))
+{
+}
+
+template<typename ReturnType> inline ExceptionOr<ReturnType>::ExceptionOr(ReturnType&& returnValue)
+ : m_value(WTFMove(returnValue))
+{
+}
+
+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*)
+ : m_value(static_cast<ReturnType>(returnValue))
+{
+}
+
+template<typename ReturnType> inline bool ExceptionOr<ReturnType>::hasException() const
+{
+ return !m_value.has_value();
+}
+
+template<typename ReturnType> inline const Exception& ExceptionOr<ReturnType>::exception() const
+{
+ ASSERT(!m_wasReleased);
+ return m_value.error();
+}
+
+template<typename ReturnType> inline Exception ExceptionOr<ReturnType>::releaseException()
+{
+ ASSERT(!std::exchange(m_wasReleased, true));
+ return WTFMove(m_value.error());
+}
+
+template<typename ReturnType> inline const ReturnType& ExceptionOr<ReturnType>::returnValue() const
+{
+ ASSERT(!m_wasReleased);
+ return m_value.value();
+}
+
+template<typename ReturnType> inline ReturnType ExceptionOr<ReturnType>::releaseReturnValue()
+{
+ ASSERT(!std::exchange(m_wasReleased, true));
+ return WTFMove(m_value.value());
+}
+
+template<typename ReturnReferenceType> inline ExceptionOr<ReturnReferenceType&>::ExceptionOr(Exception&& exception)
+ : m_value(WTFMove(exception))
+{
+}
+
+template<typename ReturnReferenceType> inline ExceptionOr<ReturnReferenceType&>::ExceptionOr(ReturnReferenceType& returnValue)
+ : m_value(&returnValue)
+{
+}
+
+template<typename ReturnReferenceType> inline bool ExceptionOr<ReturnReferenceType&>::hasException() const
+{
+ return m_value.hasException();
+}
+
+template<typename ReturnReferenceType> inline const Exception& ExceptionOr<ReturnReferenceType&>::exception() const
+{
+ return m_value.exception();
+}
+
+template<typename ReturnReferenceType> inline Exception ExceptionOr<ReturnReferenceType&>::releaseException()
+{
+ return m_value.releaseException();
+}
+
+template<typename ReturnReferenceType> inline const ReturnReferenceType& ExceptionOr<ReturnReferenceType&>::returnValue() const
+{
+ return *m_value.returnValue();
+}
+
+template<typename ReturnReferenceType> inline ReturnReferenceType& ExceptionOr<ReturnReferenceType&>::releaseReturnValue()
+{
+ return *m_value.releaseReturnValue();
+}
+
+inline ExceptionOr<void>::ExceptionOr(Exception&& exception)
+ : m_value(makeUnexpected(WTFMove(exception)))
+{
+}
+
+inline bool ExceptionOr<void>::hasException() const
+{
+ return !m_value.has_value();
+}
+
+inline const Exception& ExceptionOr<void>::exception() const
+{
+ ASSERT(!m_wasReleased);
+ return m_value.error();
+}
+
+inline Exception ExceptionOr<void>::releaseException()
+{
+ ASSERT(!std::exchange(m_wasReleased, true));
+ return WTFMove(m_value.error());
+}
+
+inline ExceptionOr<void> isolatedCopy(ExceptionOr<void>&& value)
+{
+ if (value.hasException())
+ return isolatedCopy(value.releaseException());
+ return {};
+}
+
+template<typename T> inline constexpr bool IsExceptionOr = WTF::IsTemplate<std::decay_t<T>, ExceptionOr>::value;
+
+template<typename T, bool isExceptionOr = IsExceptionOr<T>> struct TypeOrExceptionOrUnderlyingTypeImpl;
+template<typename T> struct TypeOrExceptionOrUnderlyingTypeImpl<T, true> {
+ using Type = typename T::ReturnType;
+};
+template<typename T> struct TypeOrExceptionOrUnderlyingTypeImpl<T, false> {
+ using Type = T;
+};
+template<typename T> using TypeOrExceptionOrUnderlyingType = typename TypeOrExceptionOrUnderlyingTypeImpl<T>::Type;
+
+}
+
+namespace WTF {
+template<typename T> struct CrossThreadCopierBase<false, false, WebCore::ExceptionOr<T>> {
+ typedef WebCore::ExceptionOr<T> Type;
+ static Type copy(const Type& source)
+ {
+ if (source.hasException())
+ return crossThreadCopy(source.exception());
+ return crossThreadCopy(source.returnValue());
+ }
+};
+
+template<> struct CrossThreadCopierBase<false, false, WebCore::ExceptionOr<void>> {
+ typedef WebCore::ExceptionOr<void> Type;
+ static Type copy(const Type& source)
+ {
+ if (source.hasException())
+ return crossThreadCopy(source.exception());
+ return {};
+ }
+};
+
+}