L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
result
1// vi:set ft=cpp: -*- Mode: C++ -*-
2
3#pragma once
4
5#include <assert.h>
6#include <stdlib.h>
7
8#include "type_traits"
9#include "utils"
10
11namespace cxx {
12
19class Error
20{
21 int _err;
22
23public:
24 constexpr explicit Error(int err) noexcept : _err(err) {}
25 constexpr Error(Error const &) noexcept = default;
26 constexpr Error(Error &&) noexcept = default;
27
28 constexpr int error() const noexcept
29 { return _err; }
30};
31
38template <typename T>
39class Result
40{
41 // Wrapper providing a placement-new operator. Avoids depending on a global
42 // placement-new overload (which is not available without <new>).
43 struct Holder
44 {
45 T value;
46
47 void *operator new (size_t, void *p) noexcept { return p; }
48 void operator delete (void *) {}
49
50 template<typename... Args>
51 Holder(Args&&... args)
52 noexcept(noexcept(T(cxx::forward<Args>(args)...)))
53 : value(cxx::forward<Args>(args)...) {}
54 };
55
56 union
57 {
58 Holder _res;
59 int _err;
60 };
61 bool _has_result;
62
63public:
70 Result() = delete;
71
72 Result(Error err) noexcept
73 : _err(err.error()), _has_result(false)
74 {}
75
76 template<typename... Args>
77 explicit Result(in_place_t, Args&&... args)
78 noexcept(noexcept(T(cxx::forward<Args>(args)...)))
79 : _res(cxx::forward<Args>(args)...), _has_result(true)
80 {}
81
82 Result(T &&val)
83 noexcept(noexcept(T(cxx::move(val))))
84 : _res(cxx::move(val)), _has_result(true)
85 {}
86
87 Result(Result const &o)
88 noexcept(noexcept(T(o._res.value)))
89 : _has_result(o._has_result)
90 {
91 if (_has_result)
92 new (&_res) Holder(o._res.value);
93 else
94 _err = o._err;
95 }
96
97 Result(Result &&o)
98 noexcept(noexcept(T(cxx::move(o._res.value))))
99 : _has_result(o._has_result)
100 {
101 if (_has_result)
102 new (&_res) Holder(cxx::move(o._res.value));
103 else
104 _err = o._err;
105 }
106
107 ~Result()
108 {
109 if (_has_result)
110 _res.~Holder();
111 }
112
113 Result &operator=(Result const &o)
114 noexcept(noexcept(T(o._res.value)))
115 {
116 if (_has_result)
117 _res.~Holder();
118
119 _has_result = o._has_result;
120 if (_has_result)
121 new (&_res) Holder(o._res.value);
122 else
123 _err = o._err;
124
125 return *this;
126 }
127
128 Result &operator=(Result &&o)
129 {
130 if (_has_result)
131 {
132 if (o._has_result)
133 _res.value = cxx::move(o._res.value);
134 else
135 {
136 _res.~Holder();
137 _has_result = false;
138 _err = o._err;
139 }
140 }
141 else
142 {
143 if (o._has_result)
144 {
145 new (&_res) Holder(cxx::move(o._res.value));
146 _has_result = true;
147 }
148 else
149 _err = o._err;
150 }
151
152 return *this;
153 }
154
155 Result &operator=(Error err) noexcept
156 {
157 if (_has_result)
158 _res.~Holder();
159
160 _has_result = false;
161 _err = err.error();
162
163 return *this;
164 }
165
166 Result &operator=(T &&val)
167 {
168 if (_has_result)
169 _res.value = cxx::move(val);
170 else
171 {
172 new (&_res) Holder(cxx::move(val));
173 _has_result = true;
174 }
175
176 return *this;
177 }
178
179 explicit operator bool() const noexcept
180 { return _has_result; }
181
182 int error() const noexcept
183 { return _has_result ? 0 : _err; }
184
185 T const &result() const & noexcept
186 {
187 assert(_has_result);
188 if (!_has_result) [[unlikely]]
189 abort();
190
191 return _res.value;
192 }
193
194 T&& result() && noexcept
195 {
196 assert(_has_result);
197 if (!_has_result) [[unlikely]]
198 abort();
199
200 return cxx::move(_res.value);
201 }
202};
203
204}
Error value.
Definition result:20
Result()=delete
Prevent default construction.
Our C++ library.
Definition arith:11