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 {
76public:
77 unexpected() = delete;
78 template <class U = E>
79 constexpr explicit unexpected(U&& u) : val(std::forward<U>(u)) { }
80 constexpr const E& value() const & { return val; }
81 constexpr E& value() & { return val; }
82 constexpr E&& value() && { return WTFMove(val); }
83 constexpr const E&& value() const && { return WTFMove(val); }
84
85private:
86 E val;
87};
88
89template<class E> constexpr bool operator==(const unexpected<E>& lhs, const unexpected<E>& rhs) { return lhs.value() == rhs.value(); }
90template<class E> constexpr bool operator!=(const unexpected<E>& lhs, const unexpected<E>& rhs) { return lhs.value() != rhs.value(); }
91
92}}} // namespace std::experimental::fundamentals_v3
93
94template<class E> using Unexpected = std::experimental::unexpected<E>;
95
96// Not in the std::expected spec, but useful to work around lack of C++17 deduction guides.
97template<class E> constexpr Unexpected<std::decay_t<E>> makeUnexpected(E&& v) { return Unexpected<typename std::decay<E>::type>(std::forward<E>(v)); }
98