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 | |
33 | namespace std { |
34 | namespace experimental { |
35 | inline 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 | |
70 | namespace std { |
71 | namespace experimental { |
72 | inline namespace fundamentals_v3 { |
73 | |
74 | template<class E> |
75 | class unexpected { |
76 | WTF_MAKE_FAST_ALLOCATED; |
77 | public: |
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 | |
86 | private: |
87 | E val; |
88 | }; |
89 | |
90 | template<class E> constexpr bool operator==(const unexpected<E>& lhs, const unexpected<E>& rhs) { return lhs.value() == rhs.value(); } |
91 | template<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 | |
95 | template<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. |
98 | template<class E> constexpr Unexpected<std::decay_t<E>> makeUnexpected(E&& v) { return Unexpected<typename std::decay<E>::type>(std::forward<E>(v)); } |
99 | |