iceoryx2
C++ Language Bindings
Loading...
Searching...
No Matches
expected.hpp
Go to the documentation of this file.
1// Copyright (c) 2025 Contributors to the Eclipse Foundation
2//
3// See the NOTICE file(s) distributed with this work for additional
4// information regarding copyright ownership.
5//
6// This program and the accompanying materials are made available under the
7// terms of the Apache Software License 2.0 which is available at
8// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9// which is available at https://opensource.org/licenses/MIT.
10//
11// SPDX-License-Identifier: Apache-2.0 OR MIT
12
13#ifndef IOX2_INCLUDE_GUARD_BB_STL_EXPECTED_HPP
14#define IOX2_INCLUDE_GUARD_BB_STL_EXPECTED_HPP
15
20#include <type_traits>
21
22namespace iox2 {
23namespace bb {
24namespace stl {
25
26struct InPlaceT { };
27constexpr InPlaceT IN_PLACE {};
28struct UnexpectT { };
29constexpr UnexpectT UNEXPECT {};
30
31
32template <typename E>
34 private:
35 E m_error;
36
37 public:
38 constexpr Unexpected(const Unexpected&) = default;
39 constexpr Unexpected(Unexpected&&) = default;
40 ~Unexpected() = default;
41
42 auto operator=(const Unexpected&) -> Unexpected& = default;
43 auto operator=(Unexpected&&) -> Unexpected& = default;
44
45 template <typename Err = E>
46 // NOLINTNEXTLINE(bugprone-forwarding-reference-overload), for consistency with C++23 code using std::unexpected
47 constexpr explicit Unexpected(Err&& err)
48 : m_error(std::forward<Err>(err)) {
49 }
50
51 template <class... Args>
52 constexpr explicit Unexpected(InPlaceT /* unused */, Args&&... args)
53 : m_error(std::forward<Args>(args)...) {
54 }
55
56 constexpr auto error() & noexcept -> E& {
57 return m_error;
58 }
59
60 constexpr auto error() const& noexcept -> const E& {
61 return m_error;
62 }
63
64 constexpr auto error() && noexcept -> E&& {
65 return std::move(m_error);
66 }
67
68 constexpr auto error() const&& noexcept -> const E&& {
69 return std::move(m_error);
70 }
71};
72
73#if __cplusplus >= 201703L
74template <typename E>
76#endif
77
78template <typename T, typename E>
80 private:
82
83 public:
84 // BEGIN ctors
85 constexpr Expected()
86 : m_value(iox2::legacy::in_place) {
87 }
88
89 template <typename U,
90 typename V = std::remove_cv_t<T>,
91 std::enable_if_t<std::is_convertible<U, V>::value && std::is_same<U, V>::value, bool> = true>
92 // NOLINTNEXTLINE(hicpp-explicit-conversions), as specified in ISO14882:2024 [expected]
93 constexpr Expected(U&& value)
94 : m_value(iox2::legacy::in_place_t {}, std::forward<U>(value)) {
95 }
96
97 template <typename U,
98 typename V = std::remove_cv_t<T>,
99 std::enable_if_t<std::is_convertible<U, V>::value && !std::is_same<U, V>::value, bool> = true>
100 constexpr explicit Expected(U&& value)
101 : m_value(iox2::legacy::in_place_t {}, std::forward<U>(value)) {
102 }
103
104 // NOLINTNEXTLINE(hicpp-explicit-conversions), as specified in ISO14882:2024 [expected]
105 constexpr Expected(const Unexpected<E>& error)
106 : m_value(iox2::legacy::unexpect_t {}, error.error()) {
107 }
108
109 // NOLINTNEXTLINE(hicpp-explicit-conversions), as specified in ISO14882:2024 [expected]
110 constexpr Expected(Unexpected<E>&& error)
111 : m_value(iox2::legacy::unexpect_t {}, std::forward<E>(error.error())) {
112 }
113
114 template <typename... Args>
115 // NOLINTNEXTLINE(hicpp-explicit-conversions), as specified in ISO14882:2024 [expected]
116 constexpr Expected(InPlaceT /* unused */, Args&&... args)
117 : m_value(iox2::legacy::in_place_t {}, std::forward<Args>(args)...) {
118 }
119
120 template <typename... Args>
121 // NOLINTNEXTLINE(hicpp-explicit-conversions), as specified in ISO14882:2024 [expected]
122 constexpr Expected(UnexpectT /* unused */, Args&&... args)
123 : m_value(iox2::legacy::unexpect_t {}, std::forward<Args>(args)...) {
124 }
125
126 constexpr Expected(const Expected&) = default;
127 constexpr Expected(Expected&& rhs) noexcept = default;
128 // END ctors
129
130 ~Expected() = default;
131
132 constexpr auto operator=(const Expected&) -> Expected& = default;
133
134 constexpr auto operator=(Expected&& rhs) noexcept -> Expected& = default;
135
136 constexpr auto has_value() const noexcept -> bool {
137 return m_value.has_value();
138 }
139
140 constexpr explicit operator bool() const noexcept {
141 return has_value();
142 }
143
144 // BEGIN value method
145 template <typename U = T, std::enable_if_t<std::is_void<U>::value, bool> = true>
146 constexpr auto value() const& noexcept -> void {
147 }
148
149 template <typename U = T, std::enable_if_t<std::is_void<U>::value, bool> = true>
150 constexpr auto value() && noexcept -> void {
151 }
152
153 template <typename U = T, std::enable_if_t<!std::is_void<U>::value, bool> = true>
154 constexpr auto value(bb::detail::SourceLocation location = bb::detail::SourceLocation::current()) & noexcept -> U& {
155 return m_value.value(location);
156 }
157
158 template <typename U = T, std::enable_if_t<!std::is_void<U>::value, bool> = true>
159 constexpr auto value(bb::detail::SourceLocation location = bb::detail::SourceLocation::current()) const& noexcept
160 -> const U& {
161 return m_value.value(location);
162 }
163
164 template <typename U = T, std::enable_if_t<!std::is_void<U>::value, bool> = true>
165 constexpr auto value(bb::detail::SourceLocation location = bb::detail::SourceLocation::current()) && noexcept
166 -> U&& {
167 return std::move(m_value).value(location);
168 }
169
170 template <typename U = T, std::enable_if_t<!std::is_void<U>::value, bool> = true>
171 constexpr auto value(bb::detail::SourceLocation location = bb::detail::SourceLocation::current()) const&& noexcept
172 -> const U&& {
173 return std::move(m_value).value(location);
174 }
175 // END value method
176
177 // BEGIN operator*
178 template <typename U = T, std::enable_if_t<std::is_void<U>::value, bool> = true>
179 constexpr auto operator*() const noexcept -> U {
180 }
181
182 template <typename U = T, std::enable_if_t<!std::is_void<U>::value, bool> = true>
183 constexpr auto operator*() & noexcept -> U& {
184 return value();
185 }
186
187 template <typename U = T, std::enable_if_t<!std::is_void<U>::value, bool> = true>
188 constexpr auto operator*() const& noexcept -> const U& {
189 return value();
190 }
191
192 template <typename U = T, std::enable_if_t<!std::is_void<U>::value, bool> = true>
193 constexpr auto operator*() && noexcept -> U&& {
194 return std::move(*this).value();
195 }
196
197 template <typename U = T, std::enable_if_t<!std::is_void<U>::value, bool> = true>
198 constexpr auto operator*() const&& noexcept -> const U&& {
199 return std::move(*this).value();
200 }
201 // END operator*
202
203 // BEGIN operator->
204 template <typename U = T, std::enable_if_t<!std::is_void<U>::value, bool> = true>
205 constexpr auto operator->() noexcept -> U* {
206 return &value();
207 }
208
209 template <typename U = T, std::enable_if_t<!std::is_void<U>::value, bool> = true>
210 constexpr auto operator->() const noexcept -> const U* {
211 return &value();
212 }
213 // END operator->
214
215 // BEGIN error method
216 constexpr auto error(bb::detail::SourceLocation location = bb::detail::SourceLocation::current()) & noexcept -> E& {
217 return m_value.error(location);
218 }
219
220 constexpr auto error(bb::detail::SourceLocation location = bb::detail::SourceLocation::current()) const& noexcept
221 -> const E& {
222 return m_value.error(location);
223 }
224
225 constexpr auto error(bb::detail::SourceLocation location = bb::detail::SourceLocation::current()) && noexcept
226 -> E&& {
227 return std::move(m_value).error(location);
228 }
229
230 constexpr auto error(bb::detail::SourceLocation location = bb::detail::SourceLocation::current()) const&& noexcept
231 -> const E&& {
232 return std::move(m_value).error(location);
233 }
234 // END error method
235};
236
237} // namespace stl
238} // namespace bb
239} // namespace iox2
240
241#endif // IOX2_INCLUDE_GUARD_CONTAINER_EXPECTED_HPP
#define IOX2_NO_DISCARD
IOX2_NO_DISCARD adds the [[nodiscard]] keyword if it is available for the current compiler.
constexpr auto operator*() &noexcept -> U &
Definition expected.hpp:183
constexpr Expected(const Expected &)=default
constexpr auto operator=(Expected &&rhs) noexcept -> Expected &=default
constexpr Expected(Expected &&rhs) noexcept=default
constexpr Expected(const Unexpected< E > &error)
Definition expected.hpp:105
constexpr Expected(UnexpectT, Args &&... args)
Definition expected.hpp:122
constexpr Expected(Unexpected< E > &&error)
Definition expected.hpp:110
constexpr auto error(bb::detail::SourceLocation location=bb::detail::SourceLocation::current()) &noexcept -> E &
Definition expected.hpp:216
constexpr auto operator->() noexcept -> U *
Definition expected.hpp:205
constexpr auto operator*() const &noexcept -> const U &
Definition expected.hpp:188
constexpr auto operator*() const noexcept -> U
Definition expected.hpp:179
constexpr auto value(bb::detail::SourceLocation location=bb::detail::SourceLocation::current()) const &noexcept -> const U &
Definition expected.hpp:159
constexpr auto value(bb::detail::SourceLocation location=bb::detail::SourceLocation::current()) &&noexcept -> U &&
Definition expected.hpp:165
constexpr auto error(bb::detail::SourceLocation location=bb::detail::SourceLocation::current()) const &noexcept -> const E &
Definition expected.hpp:220
constexpr auto operator*() const &&noexcept -> const U &&
Definition expected.hpp:198
constexpr auto operator=(const Expected &) -> Expected &=default
constexpr auto operator->() const noexcept -> const U *
Definition expected.hpp:210
constexpr auto value() const &noexcept -> void
Definition expected.hpp:146
constexpr auto error(bb::detail::SourceLocation location=bb::detail::SourceLocation::current()) &&noexcept -> E &&
Definition expected.hpp:225
constexpr auto value() &&noexcept -> void
Definition expected.hpp:150
constexpr Expected(InPlaceT, Args &&... args)
Definition expected.hpp:116
constexpr auto error(bb::detail::SourceLocation location=bb::detail::SourceLocation::current()) const &&noexcept -> const E &&
Definition expected.hpp:230
constexpr Expected(U &&value)
Definition expected.hpp:93
constexpr auto value(bb::detail::SourceLocation location=bb::detail::SourceLocation::current()) &noexcept -> U &
Definition expected.hpp:154
constexpr auto value(bb::detail::SourceLocation location=bb::detail::SourceLocation::current()) const &&noexcept -> const U &&
Definition expected.hpp:171
constexpr auto has_value() const noexcept -> bool
Definition expected.hpp:136
constexpr auto operator*() &&noexcept -> U &&
Definition expected.hpp:193
constexpr auto error() &&noexcept -> E &&
Definition expected.hpp:64
constexpr auto error() const &noexcept -> const E &
Definition expected.hpp:60
constexpr Unexpected(const Unexpected &)=default
auto operator=(const Unexpected &) -> Unexpected &=default
constexpr Unexpected(Err &&err)
Definition expected.hpp:47
auto operator=(Unexpected &&) -> Unexpected &=default
constexpr Unexpected(InPlaceT, Args &&... args)
Definition expected.hpp:52
constexpr auto error() &noexcept -> E &
Definition expected.hpp:56
constexpr auto error() const &&noexcept -> const E &&
Definition expected.hpp:68
constexpr Unexpected(Unexpected &&)=default
Implementation of the C++23 expected class which can contain an error or a success value.
Definition expected.hpp:150
enable_if_non_void_t< U > & value(bb::detail::SourceLocation location=bb::detail::SourceLocation::current()) &noexcept
returns a lvalue reference to the contained success value, if the expected does not contain a success...
bool has_value() const noexcept
returns true if the expected contains a value type and false if it is an error type
ErrorType & error(bb::detail::SourceLocation location=bb::detail::SourceLocation::current()) &noexcept
returns a lvalue reference to the contained error value, if the expected does not contain an error th...
constexpr InPlaceT IN_PLACE
Definition expected.hpp:27
constexpr UnexpectT UNEXPECT
Definition expected.hpp:29
iox2::bb::variation::Unexpected< E > Unexpected
Definition expected.hpp:24
constexpr auto err(const E &error) -> Unexpected< E >
Definition expected.hpp:33