Update std::expected to match libc++ coding style
[WebKit-https.git] / Source / WTF / wtf / Unexpected.h
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         constexpr explicit unexpected(const 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 public:
77     unexpected() = delete;
78     constexpr explicit unexpected(const E& e) : val(e) { }
79     constexpr explicit unexpected(E&& e) : val(std::forward<E>(e)) { }
80     constexpr const E& value() const & { return val; }
81     RELAXED_CONSTEXPR E& value() & { return val; }
82     RELAXED_CONSTEXPR E&& value() && { return WTFMove(val); }
83     RELAXED_CONSTEXPR const E&& value() const && { return WTFMove(val); }
84
85 private:
86     E val;
87 };
88
89 template<class E> constexpr bool operator==(const unexpected<E>& lhs, const unexpected<E>& rhs) { return lhs.value() == rhs.value(); }
90 template<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
94 template<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.
97 template<class E> constexpr Unexpected<std::decay_t<E>> makeUnexpected(E&& v) { return Unexpected<typename std::decay<E>::type>(std::forward<E>(v)); }