Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
result.hpp
Go to the documentation of this file.
1/*
2 RESULT.hpp - intermediary token representing the result of an operation
3
4 Copyright (C)
5 2010, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
38#ifndef LIB_RESULT_H
39#define LIB_RESULT_H
40
41#include "lib/error.hpp"
42#include "lib/item-wrapper.hpp"
43#include "lib/meta/util.hpp"
44
45#include <type_traits>
46#include <exception>
47#include <utility>
48
49
50
51namespace lib {
52
53 namespace error = lumiera::error;
54
55
66 template<typename RES>
67 class Result;
68
69
74 template<>
75 class Result<void>
76 {
77 protected:
78 std::exception_ptr failure_;
79
80 public:
82 Result (bool success =false)
83 : failure_{success? nullptr: std::make_exception_ptr (error::State{"operation failed"})}
84 { }
85
87 Result (lumiera::Error const& reason)
88 : failure_{std::make_exception_ptr (reason)}
89 { }
90
92 template<class FUN, typename...ARGS, typename=lib::meta::enable_if<std::is_invocable<FUN,ARGS...>>>
93 Result (FUN&& callable, ARGS&& ...args) noexcept
94 : failure_{}
95 {
96 try {
97 static_assert (std::is_invocable_v<FUN,ARGS...>);
98 std::invoke (std::forward<FUN>(callable)
99 ,std::forward<ARGS>(args)...
100 );
101 }
102 catch(...)
103 {
104 failure_ = std::current_exception();
105 }
106 }
107
108 explicit
109 operator bool() const { return isValid(); }
110 bool isValid() const { return not failure_; }
111
112 void
114 {
115 if (failure_)
116 std::rethrow_exception(failure_);
117 }
118 };
119
120
130 template<typename RES>
131 class Result
132 : public Result<void>
133 {
135
136 public:
138 Result (lumiera::Error const& reason)
139 : Result<void>{reason}
140 { }
141
143 template< typename=lib::meta::disable_if<std::is_invocable<RES>>>
144 Result (RES&& value)
145 : Result<void>{true}
146 , value_{std::forward<RES> (value)}
147 { }
148
150 template<class FUN, typename...ARGS, typename=lib::meta::enable_if<std::is_invocable<FUN,ARGS...>>>
151 Result (FUN&& callable, ARGS&& ...args) noexcept
152 : Result<void>{true}
153 , value_{}
154 {
155 try {
156 static_assert (std::is_invocable_r_v<RES,FUN,ARGS...>);
157 value_ = std::invoke_r<RES> (std::forward<FUN>(callable)
158 ,std::forward<ARGS>(args)...
159 );
160 }
161 catch(...)
162 {
163 failure_ = std::current_exception();
164 }
165 }
166
167 // is or is not copyable depending on RES
168
169
170 operator RES() const
171 {
172 maybeThrow();
173 return *value_;
174 }
175
176 template<typename TY =RES>
177 TY
178 get() const
179 {
180 maybeThrow();
181 return static_cast<TY> (*value_);
182 }
183
184 template<typename O>
185 RES
186 value_or (O&& defaultVal)
187 {
188 return isValid()? *value_ : std::forward<O> (defaultVal);
189 }
190
191 template<typename MAKE, typename...ARGS>
192 RES
193 or_else (MAKE&& producer, ARGS ...args)
194 {
195 if (isValid())
196 return *value_;
197 else
198 return std::invoke(std::forward<MAKE> (producer), std::forward<ARGS> (args)...);
199 }
200 };
201
203 template<typename VAL, typename=lib::meta::disable_if<std::is_invocable<VAL>>>
204 Result (VAL&&) -> Result<VAL>;
205
207 template<typename FUN, typename...ARGS>
208 Result (FUN&&, ARGS&&...) -> Result<std::invoke_result_t<FUN,ARGS...>>;
209
210
211
212} // namespace lib
213#endif
Result(lumiera::Error const &reason)
failed result, with reason given.
Definition result.hpp:87
bool isValid() const
Definition result.hpp:110
std::exception_ptr failure_
Definition result.hpp:78
void maybeThrow() const
Definition result.hpp:113
Result(bool success=false)
mark either failure (default) or success
Definition result.hpp:82
Result(FUN &&callable, ARGS &&...args) noexcept
invoke a callable and mark success or failure
Definition result.hpp:93
Representation of the result of some operation, EITHER a value or a failure.
Definition result.hpp:133
TY get() const
Definition result.hpp:178
Result(lumiera::Error const &reason)
mark failed result, with reason given.
Definition result.hpp:138
RES value_or(O &&defaultVal)
Definition result.hpp:186
Result(RES &&value)
standard case: valid result
Definition result.hpp:144
RES or_else(MAKE &&producer, ARGS ...args)
Definition result.hpp:193
wrapper::ItemWrapper< RES > value_
Definition result.hpp:134
Result(FUN &&callable, ARGS &&...args) noexcept
invoke a callable and capture result in one shot
Definition result.hpp:151
Universal value/ref wrapper accessible similar to a pointer.
Interface and Base definition for all Lumiera Exceptions.
Definition error.hpp:65
Lumiera error handling (C++ interface).
Adapter to store and hold an element of arbitrary type in local storage.
Simple and lightweight helpers for metaprogramming and type detection.
enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition meta/util.hpp:87
Implementation namespace for support and library code.
Result(VAL &&) -> Result< VAL >
deduction guide: allow perfect forwarding of a any result into the ctor call.
STL namespace.