1/*
2 * Copyright (C) 2016-2017 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// Implementation of Library Fundamentals v3's std::expected, as described here: http://wg21.link/p0323r4
27
28#pragma once
29
30/*
31 unexpected synopsis
32
33namespace std {
34namespace experimental {
35inline namespace fundamentals_v3 {
36 // ?.?.3, Unexpected object type
37 template <class E>
38 class unexpected;
39
40 // ?.?.4, Unexpected relational operators
41 template <class E>
42 constexpr bool
43 operator==(const unexpected<E>&, const unexpected<E>&);
44 template <class E>
45 constexpr bool
46 operator!=(const unexpected<E>&, const unexpected<E>&);
47
48 template <class E>
49 class unexpected {
50 public:
51 unexpected() = delete;
52 template <class U = E>
53 constexpr explicit unexpected(E&&);
54 constexpr const E& value() const &;
55 constexpr E& value() &;
56 constexpr E&& value() &&;
57 constexpr E const&& value() const&&;
58 private:
59 E val; // exposition only
60 };
61
62}}}
63
64*/
65
66#include <cstdlib>
67#include <utility>
68#include <wtf/StdLibExtras.h>
69
70namespace std {
71namespace experimental {
72inline namespace fundamentals_v3 {
73
74template<class E>
75class unexpected {
76 WTF_MAKE_FAST_ALLOCATED;
77public:
78 unexpected() = delete;
79 template <class U = E>
80 constexpr explicit unexpected(U&& u) : val(std::forward<U>(u)) { }
81 constexpr const E& value() const & { return val; }
82 constexpr E& value() & { return val; }
83 constexpr E&& value() && { return WTFMove(val); }
84 constexpr const E&& value() const && { return WTFMove(val); }
85
86private:
87 E val;
88};
89
90template<class E> constexpr bool operator==(const unexpected<E>& lhs, const unexpected<E>& rhs) { return lhs.value() == rhs.value(); }
91template<class E> constexpr bool operator!=(const unexpected<E>& lhs, const unexpected<E>& rhs) { return lhs.value() != rhs.value(); }
92
93}}} // namespace std::experimental::fundamentals_v3
94
95template<class E> using Unexpected = std::experimental::unexpected<E>;
96
97// Not in the std::expected spec, but useful to work around lack of C++17 deduction guides.
98template<class E> constexpr Unexpected<std::decay_t<E>> makeUnexpected(E&& v) { return Unexpected<typename std::decay<E>::type>(std::forward<E>(v)); }
99