@@ -119,19 +119,19 @@ class Result {
119119
120120 // / Monadic operation - F must be a function of type T -> Result<U>.
121121 template <class F >
122- auto and_then (const F& _f) {
122+ auto and_then (F&& _f) && {
123123 // / Result_U is expected to be of type Result<U>.
124124 using Result_U = typename std::invoke_result<F, T>::type;
125125 if (success_) {
126- return Result_U (_f (std::forward<T>( get_t () )));
126+ return Result_U (_f (std::move (* this ). get_t ()));
127127 } else {
128- return Result_U (std::forward<Error>( get_err () ));
128+ return Result_U (std::move (* this ). get_err ());
129129 }
130130 }
131131
132132 // / Monadic operation - F must be a function of type T -> Result<U>.
133133 template <class F >
134- auto and_then (const F& _f) const {
134+ auto and_then (const F& _f) const & {
135135 // / Result_U is expected to be of type Result<U>.
136136 using Result_U = typename std::invoke_result<F, T>::type;
137137 if (success_) {
@@ -146,11 +146,15 @@ class Result {
146146
147147 // / Allows access to the underlying value. Careful: Will result in undefined
148148 // / behavior, if the result contains an error.
149- T& operator *() noexcept { return get_t (); }
149+ T&& operator *() && noexcept { return std::move (*this ).get_t (); }
150+
151+ // / Allows access to the underlying value. Careful: Will result in undefined
152+ // / behavior, if the result contains an error.
153+ T& operator *() & noexcept { return get_t (); }
150154
151155 // / Allows read access to the underlying value. Careful: Will result in
152156 // / undefined behavior, if the result contains an error.
153- const T& operator *() const noexcept { return get_t (); }
157+ const T& operator *() const & noexcept { return get_t (); }
154158
155159 // / Assigns the underlying object.
156160 Result<T>& operator =(const Result<T>& _other) {
@@ -180,6 +184,7 @@ class Result {
180184 new (&get_err ()) Error (_err.error ());
181185 return *this ;
182186 }
187+
183188 Result<T>& operator =(const Unexpected<Error>& _err) noexcept {
184189 destroy ();
185190 success_ = false ;
@@ -199,18 +204,18 @@ class Result {
199204 // / Expects a function that takes of type Error -> Result<T> and returns
200205 // / Result<T>.
201206 template <class F >
202- Result<T> or_else (const F& _f) {
207+ Result<T> or_else (const F& _f) && {
203208 if (success_) {
204- return std::forward<T>( get_t () );
209+ return std::move (* this ). get_t ();
205210 } else {
206- return _f (std::forward<Error>( get_err () ));
211+ return _f (std::move (* this ). get_err ());
207212 }
208213 }
209214
210215 // / Expects a function that takes of type Error -> Result<T> and returns
211216 // / Result<T>.
212217 template <class F >
213- Result<T> or_else (const F& _f) const {
218+ Result<T> or_else (const F& _f) const & {
214219 if (success_) {
215220 return get_t ();
216221 } else {
@@ -220,19 +225,19 @@ class Result {
220225
221226 // / Functor operation - F must be a function of type T -> U.
222227 template <class F >
223- auto transform (const F& _f) {
228+ auto transform (const F& _f) && {
224229 // / Result_U is expected to be of type Result<U>.
225- using U = typename std::invoke_result <F, T>::type ;
230+ using U = std::invoke_result_t <F, T>;
226231 if (success_) {
227- return rfl::Result<U>(_f (std::forward<T>( get_t () )));
232+ return rfl::Result<U>(_f (std::move (* this ). get_t ()));
228233 } else {
229- return rfl::Result<U>(rfl::Unexpected (std::forward<Error>( get_err () )));
234+ return rfl::Result<U>(rfl::Unexpected (std::move (* this ). get_err ()));
230235 }
231236 }
232237
233238 // / Functor operation - F must be a function of type T -> U.
234239 template <class F >
235- auto transform (const F& _f) const {
240+ auto transform (const F& _f) const & {
236241 // / Result_U is expected to be of type Result<U>.
237242 using U = typename std::invoke_result<F, T>::type;
238243 if (success_) {
@@ -244,17 +249,17 @@ class Result {
244249
245250 // / Returns the value if the result does not contain an error, throws an
246251 // / exceptions if not. Similar to .unwrap() in Rust.
247- T& value () {
252+ T&& value() && {
248253 if (success_) {
249- return get_t ();
254+ return std::move (* this ). get_t ();
250255 } else {
251256 throw std::runtime_error (get_err ().what ());
252257 }
253258 }
254259
255260 // / Returns the value if the result does not contain an error, throws an
256261 // / exceptions if not. Similar to .unwrap() in Rust.
257- const T& value () const {
262+ const T& value () const & {
258263 if (success_) {
259264 return get_t ();
260265 } else {
@@ -263,64 +268,72 @@ class Result {
263268 }
264269
265270 // / Returns the value or a default.
266- T value_or (T&& _default) noexcept {
271+ T&& value_or(T&& _default) && noexcept {
267272 if (success_) {
268- return std::forward<T>( get_t () );
273+ return std::move (* this ). get_t ();
269274 } else {
270275 return std::forward<T>(_default);
271276 }
272277 }
273278
274279 // / Returns the value or a default.
275- T value_or (const T& _default) const noexcept {
280+ T value_or (const T& _default) const & noexcept {
276281 if (success_) {
277282 return get_t ();
278283 } else {
279284 return _default;
280285 }
281286 }
282287
283- // As specified by the standard :
284- // https://en.cppreference.com/w/cpp/utility/expected
285- // Observers
286288 template <class G = rfl::Error>
287- rfl::Error error_or (G&& _default) const & {
289+ rfl::Error error_or (G&& _default) & & {
288290 if (success_) {
289- return _default;
291+ return std::forward<G>( _default) ;
290292 } else {
291- return get_err ();
293+ return std::move (* this ). get_err ();
292294 }
293295 }
296+
297+ // As specified by the standard :
298+ // https://en.cppreference.com/w/cpp/utility/expected
299+ // Observers
294300 template <class G = rfl::Error>
295- rfl::Error error_or (G&& _default) & & {
301+ rfl::Error error_or (G&& _default) const & {
296302 if (success_) {
297- return _default;
303+ return std::forward<G>( _default) ;
298304 } else {
299305 return get_err ();
300306 }
301307 }
308+
302309 bool has_value () const noexcept { return success_; }
310+
303311 const Error& error () const & {
304312 if (success_) throw std::runtime_error (" Expected does not contain value" );
305313 return get_err ();
306314 }
307- Error& error () & {
315+
316+ Error& error () && {
308317 if (success_) throw std::runtime_error (" Expected does not contain value" );
309- return get_err ();
318+ return std::move (* this ). get_err ();
310319 }
320+
311321 T* operator ->() noexcept { return &get_t (); }
322+
312323 const T* operator ->() const noexcept { return &get_t (); }
324+
313325 template <class F >
314326 rfl::Result<T> transform_error (F&& f) && {
315327 static_assert (
316328 std::is_same<std::invoke_result_t <F, rfl::Error>, rfl::Error>(),
317329 " A function passed to transform_error must return an error." );
318330 if (!has_value ()) {
319- return rfl::Result<T>{std::invoke (f, std::move (get_err () ))};
331+ return rfl::Result<T>{std::invoke (f, std::move (* this ). get_err ())};
320332 } else {
321- return rfl::Result<T>{std::move (value () )};
333+ return rfl::Result<T>{std::move (* this ). value ()};
322334 }
323335 }
336+
324337 template <class F >
325338 rfl::Result<T> transform_error (F&& f) const & {
326339 static_assert (
@@ -352,19 +365,27 @@ class Result {
352365 }
353366 }
354367
355- T& get_t () noexcept {
368+ T&& get_t () && noexcept {
369+ return std::move (*std::launder (reinterpret_cast <T*>(t_or_err_.data ())));
370+ }
371+
372+ T& get_t () & noexcept {
356373 return *std::launder (reinterpret_cast <T*>(t_or_err_.data ()));
357374 }
358375
359- const T& get_t () const noexcept {
376+ const T& get_t () const & noexcept {
360377 return *std::launder (reinterpret_cast <const T*>(t_or_err_.data ()));
361378 }
362379
363- Error& get_err () noexcept {
380+ Error&& get_err() && noexcept {
381+ return std::move (*std::launder (reinterpret_cast <Error*>(t_or_err_.data ())));
382+ }
383+
384+ Error& get_err () & noexcept {
364385 return *std::launder (reinterpret_cast <Error*>(t_or_err_.data ()));
365386 }
366387
367- const Error& get_err () const noexcept {
388+ const Error& get_err () const & noexcept {
368389 return *std::launder (reinterpret_cast <const Error*>(t_or_err_.data ()));
369390 }
370391
0 commit comments