scnlib  0.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 {
59 
61 
62  max_error
63  };
64 
65  struct success_tag_t {
66  };
67  static constexpr success_tag_t success_tag()
68  {
69  return {};
70  }
71 
72  constexpr error() noexcept = default;
73  constexpr error(success_tag_t) noexcept : error() {}
74  constexpr error(enum code c, const char* m) noexcept
75  : m_msg(m), m_code(c)
76  {
77  }
78 
80  constexpr explicit operator bool() const noexcept
81  {
82  return m_code == good;
83  }
84  constexpr bool operator!() const noexcept
85  {
86  return !(operator bool());
87  }
88 
89  constexpr operator enum code() const noexcept { return m_code; }
90 
92  constexpr enum code code() const noexcept
93  {
94  return m_code;
95  }
96  constexpr const char* msg() const noexcept
97  {
98  return m_msg;
99  }
100 
102  constexpr bool is_recoverable() const noexcept
103  {
104  return !(m_code == unrecoverable_source_error ||
105  m_code == unrecoverable_internal_error);
106  }
107 
108  private:
109  const char* m_msg{nullptr};
110  enum code m_code { good };
111  };
112 
113  constexpr inline bool operator==(error a, error b) noexcept
114  {
115  return a.code() == b.code();
116  }
117  constexpr inline bool operator!=(error a, error b) noexcept
118  {
119  return !(a == b);
120  }
121 
122  template <typename T, typename Error = ::scn::error>
123  class result {
124  public:
125  using success_type = T;
126  using error_type = Error;
127 
128  constexpr result(success_type val) : m_value(std::move(val)) {}
129  constexpr result(success_type val, error_type err)
130  : m_value(std::move(val)), m_error(std::move(err))
131  {
132  }
133 
135  {
136  return m_value;
137  }
138  constexpr const success_type& value() const& noexcept
139  {
140  return m_value;
141  }
143  {
144  return m_value;
145  }
146 
148  {
149  return m_error;
150  }
151  constexpr const error_type& error() const& noexcept
152  {
153  return m_error;
154  }
156  {
157  return m_error;
158  }
159 
160  constexpr explicit operator bool() const noexcept
161  {
162  return m_error.operator bool();
163  }
164  constexpr bool has_error() const noexcept
165  {
166  return !(operator bool());
167  }
168 
169  private:
170  success_type m_value;
171  Error m_error{Error::success_tag()};
172  };
173 
179  template <typename T, typename Error = ::scn::error, typename Enable = void>
180  class expected;
181 
188  template <typename T, typename Error>
189  class expected<T,
190  Error,
191  typename std::enable_if<
192  std::is_default_constructible<T>::value>::type> {
193  public:
194  using success_type = T;
195  using error_type = Error;
196 
197  constexpr expected(success_type s) : m_s(s) {}
198  constexpr expected(error_type e) : m_e(e) {}
199 
200  constexpr bool has_value() const noexcept
201  {
202  return m_e == error::good;
203  }
204  constexpr explicit operator bool() const noexcept
205  {
206  return has_value();
207  }
208  constexpr bool operator!() const noexcept
209  {
210  return !operator bool();
211  }
212 
214  {
215  return m_s;
216  }
217  constexpr success_type value() const& noexcept
218  {
219  return m_s;
220  }
222  {
223  return std::move(m_s);
224  }
225 
227  {
228  return m_e;
229  }
230  constexpr error_type error() const noexcept
231  {
232  return m_e;
233  }
234 
235  private:
236  success_type m_s{};
237  error_type m_e{error_type::success_tag()};
238  };
239 
245  template <typename T, typename Error>
246  class expected<T,
247  Error,
248  typename std::enable_if<
249  !std::is_default_constructible<T>::value>::type> {
250  public:
251  using success_type = T;
253  using error_type = Error;
254 
255  expected(success_type s) : m_s(std::move(s)) {}
256  constexpr expected(error_type e) : m_e(e) {}
257 
258  constexpr bool has_value() const noexcept
259  {
260  return m_e == error::good;
261  }
262  constexpr explicit operator bool() const noexcept
263  {
264  return has_value();
265  }
266  constexpr bool operator!() const noexcept
267  {
268  return !operator bool();
269  }
270 
272  {
273  return *m_s;
274  }
275  constexpr const success_type& value() const noexcept
276  {
277  return *m_s;
278  }
279 
281  {
282  return m_e;
283  }
284  constexpr error_type error() const noexcept
285  {
286  return m_e;
287  }
288 
289  private:
290  success_storage m_s{};
291  error_type m_e{error_type::success_tag()};
292  };
293 
294  // -Wpadded
296 
297  template <typename T,
298  typename U = typename std::remove_cv<
301  {
302  return expected<U>(std::forward<T>(val));
303  }
304 
305  namespace detail {
306  struct error_handler {
307  constexpr error_handler() = default;
308 
309  void on_error(error e);
310  void on_error(const char* msg);
311  };
312  } // namespace detail
313 
315 } // namespace scn
316 
317 #endif // SCN_DETAIL_RESULT_H
T success_type
Definition: result.h:125
constexpr bool is_recoverable() const noexcept
Can the stream be used again.
Definition: result.h:102
constexpr const char * msg() const noexcept
Definition: result.h:96
Scanned value was invalid for given type.
Definition: result.h:44
#define SCN_END_NAMESPACE
Definition: config.h:401
static constexpr success_tag_t success_tag()
Definition: result.h:67
This operation is only possible with exceptions enabled.
Definition: result.h:53
No error.
Definition: result.h:37
Scanned value was out of range for the desired type.
Definition: result.h:49
constexpr bool operator!=(error a, error b) noexcept
Definition: result.h:117
constexpr const error_type & error() const &noexcept
Definition: result.h:151
constexpr const success_type & value() const &noexcept
Definition: result.h:138
#define SCN_CLANG_IGNORE(x)
Definition: config.h:144
constexpr bool operator==(error a, error b) noexcept
Definition: result.h:113
Format string was invalid.
Definition: result.h:41
constexpr result(success_type val)
Definition: result.h:128
expected-like type.
Definition: result.h:180
#define SCN_CLANG_POP
Definition: config.h:143
SCN_CLANG_POP expected< U > make_expected(T &&val)
Definition: result.h:300
constexpr enum code code() const noexcept
Get error code.
Definition: result.h:92
#define SCN_TRIVIAL_ABI
Definition: config.h:266
SCN_CONSTEXPR14 error_type & error()&noexcept
Definition: result.h:147
Error error_type
Definition: result.h:126
Stream does not support the performed operation.
Definition: result.h:46
SCN_CONSTEXPR14 success_type & value()&noexcept
Definition: result.h:134
Error class.
Definition: result.h:32
#define SCN_BEGIN_NAMESPACE
Definition: config.h:400
Invalid argument given to operation.
Definition: result.h:51
The source range emitted an error that cannot be recovered from.
Definition: result.h:58
SCN_CONSTEXPR14 error_type error()&&noexcept
Definition: result.h:155
SCN_CONSTEXPR14 success_type value()&&noexcept
Definition: result.h:142
constexpr error_handler()=default
The source range emitted an error.
Definition: result.h:55
code
Error code.
Definition: result.h:35
constexpr bool operator!() const noexcept
Definition: result.h:84
constexpr bool has_error() const noexcept
Definition: result.h:164
constexpr error(enum code c, const char *m) noexcept
Definition: result.h:74
constexpr result(success_type val, error_type err)
Definition: result.h:129
#define SCN_CLANG_PUSH
Definition: config.h:142
#define SCN_CONSTEXPR14
Definition: config.h:240