scnlib  0.1.2
FormattedinputformodernC++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
result.h
Go to the documentation of this file.
1 // Copyright 2017-2019 Elias Kosunen
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // This file is a part of scnlib:
16 // https://github.com/eliaskosunen/scnlib
17 
18 #ifndef SCN_DETAIL_RESULT_H
19 #define SCN_DETAIL_RESULT_H
20 
21 #include "util.h"
22 
23 namespace scn {
26  SCN_CLANG_IGNORE("-Wpadded")
27 
28 
33  public:
35  enum code : char {
62 
64 
65  max_error
66  };
67 
68  struct success_tag_t {
69  };
71  {
72  return {};
73  }
74 
75  SCN_CONSTEXPR error() noexcept = default;
76  SCN_CONSTEXPR error(success_tag_t) noexcept : error() {}
77  SCN_CONSTEXPR error(enum code c, const char* m) noexcept
78  : m_msg(m), m_code(c)
79  {
80  }
81 
83  SCN_CONSTEXPR explicit operator bool() const noexcept
84  {
85  return m_code == good;
86  }
87  SCN_CONSTEXPR bool operator!() const noexcept
88  {
89  return !(operator bool());
90  }
91 
92  SCN_CONSTEXPR operator enum code() const noexcept { return m_code; }
93 
95  SCN_CONSTEXPR enum code code() const noexcept
96  {
97  return m_code;
98  }
99  SCN_CONSTEXPR const char* msg() const noexcept
100  {
101  return m_msg;
102  }
103 
105  SCN_CONSTEXPR bool is_recoverable() const noexcept
106  {
107  return !(m_code == unrecoverable_stream_error ||
108  m_code == unrecoverable_stream_source_error ||
109  m_code == unrecoverable_internal_error);
110  }
111 
112  private:
113  const char* m_msg{nullptr};
114  enum code m_code { good };
115  };
116 
117  SCN_CONSTEXPR inline bool operator==(error a, error b) noexcept
118  {
119  return a.code() == b.code();
120  }
121  SCN_CONSTEXPR inline bool operator!=(error a, error b) noexcept
122  {
123  return !(a == b);
124  }
125 
126  template <typename T, typename Error = ::scn::error>
127  class result {
128  public:
129  using success_type = T;
130  using error_type = Error;
131 
132  SCN_CONSTEXPR result(success_type val) : m_value(std::move(val)) {}
134  : m_value(std::move(val)), m_error(std::move(err))
135  {
136  }
137 
139  {
140  return m_value;
141  }
142  SCN_CONSTEXPR const success_type& value() const& noexcept
143  {
144  return m_value;
145  }
147  {
148  return m_value;
149  }
150 
152  {
153  return m_error;
154  }
155  SCN_CONSTEXPR const error_type& error() const& noexcept
156  {
157  return m_error;
158  }
160  {
161  return m_error;
162  }
163 
164  SCN_CONSTEXPR explicit operator bool() const noexcept
165  {
166  return m_error.operator bool();
167  }
168  SCN_CONSTEXPR bool has_error() const noexcept
169  {
170  return !(operator bool());
171  }
172 
173  private:
174  success_type m_value;
175  Error m_error{Error::success_tag()};
176  };
177 
179 
185  template <typename T, typename Error = ::scn::error, typename Enable = void>
186  class expected;
187 
194  template <typename T, typename Error>
195  class expected<T,
196  Error,
197  typename std::enable_if<
198  std::is_default_constructible<T>::value>::type> {
199  public:
200  using success_type = T;
201  using error_type = Error;
202 
205 
206  SCN_CONSTEXPR bool has_value() const noexcept
207  {
208  return m_e == error::good;
209  }
210  SCN_CONSTEXPR explicit operator bool() const noexcept
211  {
212  return has_value();
213  }
214  SCN_CONSTEXPR bool operator!() const noexcept
215  {
216  return !operator bool();
217  }
218 
220  {
221  return m_s;
222  }
223  SCN_CONSTEXPR success_type value() const& noexcept
224  {
225  return m_s;
226  }
228  {
229  return std::move(m_s);
230  }
231 
233  {
234  return m_e;
235  }
236  SCN_CONSTEXPR error_type error() const noexcept
237  {
238  return m_e;
239  }
240 
241  private:
242  success_type m_s{};
243  error_type m_e{error_type::success_tag()};
244  };
245 
251  template <typename T, typename Error>
252  class expected<T,
253  Error,
254  typename std::enable_if<
255  !std::is_default_constructible<T>::value>::type> {
256  public:
257  using success_type = T;
259  using error_type = Error;
260 
261  expected(success_type s) : m_s(std::move(s)) {}
263 
264  SCN_CONSTEXPR bool has_value() const noexcept
265  {
266  return m_e == error::good;
267  }
268  SCN_CONSTEXPR explicit operator bool() const noexcept
269  {
270  return has_value();
271  }
272  SCN_CONSTEXPR bool operator!() const noexcept
273  {
274  return !operator bool();
275  }
276 
278  {
279  return *m_s;
280  }
281  SCN_CONSTEXPR const success_type& value() const noexcept
282  {
283  return *m_s;
284  }
285 
287  {
288  return m_e;
289  }
290  SCN_CONSTEXPR error_type error() const noexcept
291  {
292  return m_e;
293  }
294 
295  private:
296  success_storage m_s{};
297  error_type m_e{error_type::success_tag()};
298  };
299 
300  // -Wpadded
302 
303  template <typename T,
304  typename U = typename std::remove_cv<
307  {
308  return expected<U>(std::forward<T>(val));
309  }
310 
311  namespace detail {
312  struct error_handler {
313  SCN_CONSTEXPR error_handler() = default;
314 
315  void on_error(error e);
316  void on_error(const char* msg);
317  };
318  } // namespace detail
319 
321 } // namespace scn
322 
323 #endif // SCN_DETAIL_RESULT_H
T success_type
Definition: result.h:129
Scanned value was invalid for given type.
Definition: result.h:44
SCN_CONSTEXPR result(success_type val, error_type err)
Definition: result.h:133
SCN_CONSTEXPR enum code code() const noexcept
Get error code.
Definition: result.h:95
#define SCN_END_NAMESPACE
Definition: config.h:376
SCN_CONSTEXPR bool has_error() const noexcept
Definition: result.h:168
SCN_CONSTEXPR bool is_recoverable() const noexcept
Can the stream be used again.
Definition: result.h:105
SCN_CONSTEXPR bool operator==(error a, error b) noexcept
Definition: result.h:117
This operation is only possible with exceptions enabled.
Definition: result.h:53
The stream source emitted an error.
Definition: result.h:58
SCN_CONSTEXPR error(enum code c, const char *m) noexcept
Definition: result.h:77
No error.
Definition: result.h:37
Scanned value was out of range for the desired type.
Definition: result.h:49
#define SCN_CLANG_IGNORE(x)
Definition: config.h:128
SCN_CONSTEXPR const success_type & value() const &noexcept
Definition: result.h:142
SCN_CONSTEXPR result(success_type val)
Definition: result.h:132
Format string was invalid.
Definition: result.h:41
expected-like type.
Definition: result.h:186
#define SCN_CLANG_POP
Definition: config.h:127
SCN_CLANG_POP expected< U > make_expected(T &&val)
Definition: result.h:306
SCN_CONSTEXPR bool operator!=(error a, error b) noexcept
Definition: result.h:121
SCN_CONSTEXPR error_handler()=default
#define SCN_TRIVIAL_ABI
Definition: config.h:246
SCN_CONSTEXPR14 error_type & error()&noexcept
Definition: result.h:151
Error error_type
Definition: result.h:130
Stream does not support the performed operation.
Definition: result.h:46
The stream has encountered an error that cannot be recovered from.
Definition: result.h:56
SCN_CONSTEXPR14 success_type & value()&noexcept
Definition: result.h:138
Error class.
Definition: result.h:32
#define SCN_BEGIN_NAMESPACE
Definition: config.h:375
SCN_CONSTEXPR bool operator!() const noexcept
Definition: result.h:87
SCN_CONSTEXPR const error_type & error() const &noexcept
Definition: result.h:155
Invalid argument given to operation.
Definition: result.h:51
static SCN_CONSTEXPR success_tag_t success_tag()
Definition: result.h:70
The stream source emitted an error that cannot be recovered from.
Definition: result.h:61
SCN_CONSTEXPR14 error_type error()&&noexcept
Definition: result.h:159
SCN_CONSTEXPR14 success_type value()&&noexcept
Definition: result.h:146
SCN_CONSTEXPR const char * msg() const noexcept
Definition: result.h:99
#define SCN_CONSTEXPR
Definition: config.h:226
code
Error code.
Definition: result.h:35
#define SCN_CLANG_PUSH
Definition: config.h:126
#define SCN_CONSTEXPR14
Definition: config.h:227