CppWAMP
C++11 client library for the WAMP protocol
erroror.hpp
Go to the documentation of this file.
1 /*------------------------------------------------------------------------------
2  Copyright Butterfly Energy Systems 2022.
3  Distributed under the Boost Software License, Version 1.0.
4  http://www.boost.org/LICENSE_1_0.txt
5 ------------------------------------------------------------------------------*/
6 
7 #ifndef CPPWAMP_ERROROR_HPP
8 #define CPPWAMP_ERROROR_HPP
9 
10 //------------------------------------------------------------------------------
13 //------------------------------------------------------------------------------
14 
15 #include <cassert>
16 #include <functional>
17 #include <system_error>
18 #include <utility>
19 #include "api.hpp"
20 #include "config.hpp"
21 #include "error.hpp"
22 #include "traits.hpp"
23 
24 namespace wamp
25 {
26 
27 //------------------------------------------------------------------------------
35 //------------------------------------------------------------------------------
36 template <typename E>
38 {
39 public:
40  using error_type = E;
41 
42  Unexpected() = delete;
43 
45  explicit Unexpected(error_type error) noexcept : error_(std::move(error)) {}
46 
48  error_type& value() & noexcept { return error_; }
49 
51  error_type&& value() && noexcept { return std::move(error_); }
52 
54  const error_type& value() const& noexcept { return error_; }
55 
57  const error_type&& value() const&& noexcept { return std::move(error_); }
58 
60  void swap(Unexpected& other) noexcept(std::is_nothrow_swappable<E>::value)
61  {
62  using std::swap;
63  swap(error_, other.error_);
64  }
65 
66 private:
67  error_type error_;
68 };
69 
72 template <typename E1, typename E2>
73 CPPWAMP_API bool operator==(const Unexpected<E1>& x, const Unexpected<E2>& y)
74 {
75  return x.value() == y.value();
76 }
77 
80 template <typename E1, typename E2>
81 CPPWAMP_API bool operator!=(const Unexpected<E1>& x, const Unexpected<E2>& y)
82 {
83  return x.value() != y.value();
84 }
85 
88 template <typename E>
89 CPPWAMP_API void swap(Unexpected<E>& x, Unexpected<E>& y)
90  noexcept(noexcept(x.swap(y)))
91 {
92  x.swap(y);
93 }
94 
97 template <typename E>
99 {
100  return Unexpected<ValueTypeOf<E>>{std::forward<E>(error)};
101 }
102 
103 
104 //------------------------------------------------------------------------------
107 
108 //------------------------------------------------------------------------------
111 //------------------------------------------------------------------------------
112 template <typename TErrorEnum>
113 CPPWAMP_API UnexpectedError makeUnexpectedError(TErrorEnum errc)
114 {
115  return UnexpectedError(make_error_code(errc));
116 }
117 
118 
119 //------------------------------------------------------------------------------
126 //------------------------------------------------------------------------------
127 template <typename T>
128 class CPPWAMP_API ErrorOr
129 {
130 public:
131  using value_type = T;
132  using error_type = std::error_code;
133 
135  ErrorOr() = default;
136 
138  ErrorOr(const ErrorOr&) = default;
139 
141  ErrorOr(ErrorOr&&) = default;
142 
145  : value_(std::move(value)),
146  hasError_(false)
147  {}
148 
150  template <typename G>
152  : error_(std::move(unex).value()),
153  hasError_(true)
154  {}
155 
158  template <typename... Args>
159  value_type& emplace(Args&&... args)
160  {
161  value_ = value_type(std::forward<Args>(args)...);
162  error_ = error_type();
163  hasError_ = false;
164  return value_;
165  }
166 
168  ErrorOr& operator=(const ErrorOr&) = default;
169 
171  ErrorOr& operator=(ErrorOr&&) = default;
172 
175  {
176  value_ = std::move(value);
177  error_ = error_type();
178  hasError_ = false;
179  return *this;
180  }
181 
183  template <typename G>
185  {
186  error_ = error_type(std::move(unex).value());
187  value_ = value_type();
188  hasError_ = true;
189  return *this;
190  }
191 
193  void swap(ErrorOr& rhs)
194  noexcept(std::is_nothrow_swappable<value_type>::value)
195  {
196  using std::swap;
197  swap(value_, rhs.value_);
198  swap(error_, rhs.error_);
199  swap(hasError_, rhs.hasError_);
200  }
201 
204  {
205  assert(has_value());
206  return std::addressof(value_);
207  }
208 
210  const value_type* operator->() const
211  {
212  assert(has_value());
213  return std::addressof(value_);
214  }
215 
219  {
220  assert(has_value());
221  return value_;
222  }
223 
227  {
228  assert(has_value());
229  return std::move(value_);
230  }
231 
234  const value_type& operator*() const&
235  {
236  assert(has_value());
237  return value_;
238  }
239 
242  const value_type&& operator*() const&&
243  {
244  assert(has_value());
245  return std::move(value_);
246  }
247 
249  explicit operator bool() const noexcept {return has_value();}
250 
252  bool has_value() const noexcept {return !hasError_;}
253 
258  {
259  checkError();
260  return value_;
261  }
262 
267  {
268  checkError();
269  return std::move(value_);
270  }
271 
275  const value_type& value() const&
276  {
277  checkError();
278  return value_;
279  }
280 
284  const value_type&& value() const&&
285  {
286  checkError();
287  return std::move(value_);
288  }
289 
293  {
294  assert(!has_value());
295  return error_;
296  }
297 
300  const error_type& error() const
301  {
302  assert(!has_value());
303  return error_;
304  }
305 
307  template <typename U>
308  value_type value_or(U&& v) const&
309  {
310  if (has_value())
311  return value_;
312  else
313  return std::forward<U>(v);
314  }
315 
318  template <typename U>
320  {
321  if (has_value())
322  return std::move(value_);
323  else
324  return std::forward<U>(v);
325  }
326 
329 
332 
334  CPPWAMP_DEPRECATED ErrorOr(std::error_code ec)
335  : ErrorOr(makeUnexpected(ec))
336  {}
337 
339  CPPWAMP_DEPRECATED ErrorOr(std::error_code ec, std::string)
340  : ErrorOr(makeUnexpected(ec))
341  {}
342 
344  CPPWAMP_DEPRECATED ValueType& get() {return value();}
345 
347  CPPWAMP_DEPRECATED const ValueType& get() const {return value();}
348 
350  CPPWAMP_DEPRECATED std::error_code errorCode() const
351  {
352  return hasError_ ? error() : error_type{};
353  }
354 
356  CPPWAMP_DEPRECATED const std::string& errorInfo() const
357  {
358  static const std::string empty;
359  return empty;
360  }
361 
363  CPPWAMP_DEPRECATED ErrorOr& setValue(T value)
364  {
365  value_ = std::move(value);
366  error_ = error_type();
367  hasError_ = false;
368  return *this;
369  }
370 
372  CPPWAMP_DEPRECATED ErrorOr& setError(std::error_code ec)
373  {
374  error_ = ec;
375  value_ = value_type();
376  hasError_ = true;
377  return *this;
378  }
379 
381  CPPWAMP_DEPRECATED ErrorOr& setError(std::error_code ec, std::string)
382  {
383  setError(ec);
384  }
386 
387 private:
388  CPPWAMP_HIDDEN void checkError() const
389  {
390  if (hasError_)
391  throw error::Failure(error_);
392  }
393 
394  value_type value_;
395  error_type error_;
396  bool hasError_ = false;
397 };
398 
401 template <typename T>
402 CPPWAMP_API void swap(ErrorOr<T>& x, ErrorOr<T>& y)
403  noexcept(noexcept(x.swap(y)))
404 {
405  x.swap(y);
406 }
407 
410 template <typename T1, typename T2>
411 CPPWAMP_API bool operator==(const ErrorOr<T1>& x, const ErrorOr<T2>& y)
412 {
413  return (x.has_value() == y.has_value())
414  ? (x.has_value() ? *x == *y : x.error() == y.error())
415  : false;
416 }
417 
420 template <typename T1, typename T2>
421 CPPWAMP_API bool operator!=(const ErrorOr<T1>& x, const ErrorOr<T2>& y)
422 {
423  return (x.has_value() == y.has_value())
424  ? (x.has_value() ? *x != *y : x.error() != y.error())
425  : true;
426 }
427 
430 template <typename T1, typename T2>
431 CPPWAMP_API bool operator==(const ErrorOr<T1>& x, const T2& v)
432 {
433  return x.has_value() ? *x == v : false;
434 }
435 
438 template <typename T1, typename T2>
439 CPPWAMP_API bool operator==(const T2& v, const ErrorOr<T1>& x)
440 {
441  return x.has_value() ? *x == v : false;
442 }
443 
446 template <typename T1, typename T2>
447 CPPWAMP_API bool operator!=(const ErrorOr<T1>& x, const T2& v)
448 {
449  return x.has_value() ? *x != v : true;
450 }
451 
454 template <typename T1, typename T2>
455 CPPWAMP_API bool operator!=(const T2& v, const ErrorOr<T1>& x)
456 {
457  return x.has_value() ? *x != v : true;
458 }
459 
462 template <typename T, typename E>
463 CPPWAMP_API bool operator==(const ErrorOr<T>& x, const Unexpected<E>& e)
464 {
465  return x.has_value() ? false : x.error() == e.value();
466 }
467 
470 template <typename T, typename E>
471 CPPWAMP_API bool operator==(const Unexpected<E>& e, const ErrorOr<T>& x)
472 {
473  return x.has_value() ? false : x.error() == e.value();
474 }
475 
478 template <typename T, typename E>
479 CPPWAMP_API bool operator!=(const ErrorOr<T>& x, const Unexpected<E>& e)
480 {
481  return x.has_value() ? true : x.error() != e.value();
482 }
483 
486 template <typename T, typename E>
487 CPPWAMP_API bool operator!=(const Unexpected<E>& e, const ErrorOr<T>& x)
488 {
489  return x.has_value() ? true : x.error() != e.value();
490 }
491 
492 //------------------------------------------------------------------------------
494 //------------------------------------------------------------------------------
495 template <typename T> using AsyncHandler = std::function<void (ErrorOr<T>)>;
496 
497 } // namespace wamp
498 
499 #endif // CPPWAMP_ERROROR_HPP
wamp::ErrorOr::get
ValueType & get()
Definition: erroror.hpp:344
wamp::Unexpected::Unexpected
Unexpected(error_type error) noexcept
Constructor taking an error value.
Definition: erroror.hpp:45
wamp::Unexpected::value
const error_type && value() const &&noexcept
Moves the error value.
Definition: erroror.hpp:57
wamp::ErrorOr::operator->
const value_type * operator->() const
Unchecked access of a member of the stored value.
Definition: erroror.hpp:210
wamp::ErrorOr::setError
ErrorOr & setError(std::error_code ec)
Definition: erroror.hpp:372
wamp::ErrorOr::value_or
value_type value_or(U &&v) const &
Returns the stored value if it exists, or the given fallback value.
Definition: erroror.hpp:308
wamp::ErrorOr::ValueType
value_type ValueType
Definition: erroror.hpp:328
api.hpp
Defines macros related to exporting/importing APIs.
wamp::ErrorOr::value
const value_type & value() const &
Checked access of the stored value.
Definition: erroror.hpp:275
wamp::ErrorOr::value
value_type && value() &&
Checked move of the stored value.
Definition: erroror.hpp:266
wamp::ErrorOr::setError
ErrorOr & setError(std::error_code ec, std::string)
Definition: erroror.hpp:381
wamp::ErrorOr::swap
void swap(ErrorOr &rhs) noexcept(std::is_nothrow_swappable< value_type >::value)
Swap contents with another instance.
Definition: erroror.hpp:193
wamp::Unexpected::swap
void swap(Unexpected &other) noexcept(std::is_nothrow_swappable< E >::value)
Swaps contents with another UnexpectedError.
Definition: erroror.hpp:60
wamp::ErrorOr::emplace
value_type & emplace(Args &&... args)
Initializes the value in-place using the given value constructor arguments.
Definition: erroror.hpp:159
wamp::error::Failure
General purpose runtime exception that wraps a std::error_code.
Definition: error.hpp:52
wamp::ErrorOr::error
error_type & error()
Unchecked access of the stored error.
Definition: erroror.hpp:292
wamp::ErrorOr::operator=
ErrorOr & operator=(Unexpected< G > unex)
Error assignment.
Definition: erroror.hpp:184
wamp::ErrorOr::operator*
const value_type & operator*() const &
Unchecked access of the stored value.
Definition: erroror.hpp:234
wamp::ErrorOr::value_or
value_type value_or(U &&v) &&
Returns the moved stored value if it exists, or the given fallback value.
Definition: erroror.hpp:319
wamp::ErrorOr::errorCode
std::error_code errorCode() const
Definition: erroror.hpp:350
wamp::UnexpectedError
Unexpected< std::error_code > UnexpectedError
Type alias for Unexpected<std::error_code>.
Definition: erroror.hpp:106
wamp::makeUnexpectedError
UnexpectedError makeUnexpectedError(TErrorEnum errc)
Convenience function that creates an UnexpectedError from an error code enum.
Definition: erroror.hpp:113
wamp::ErrorOr::operator->
value_type * operator->()
Unchecked access of a member of the stored value.
Definition: erroror.hpp:203
wamp::Unexpected::error_type
E error_type
Type representing errors.
Definition: erroror.hpp:40
wamp::ErrorOr::value
value_type & value() &
Checked access of the stored value.
Definition: erroror.hpp:257
wamp::ErrorOr::error
const error_type & error() const
Unchecked access of the stored error.
Definition: erroror.hpp:300
wamp
Definition: anyhandler.hpp:36
wamp::Unexpected::value
error_type & value() &noexcept
Accesses the error value.
Definition: erroror.hpp:48
wamp::ErrorOr::operator*
const value_type && operator*() const &&
Unchecked move of the stored value.
Definition: erroror.hpp:242
wamp::ErrorOr::setValue
ErrorOr & setValue(T value)
Definition: erroror.hpp:363
wamp::Unexpected::makeUnexpected
constexpr Unexpected< ValueTypeOf< E > > makeUnexpected(E &&error)
Non-standard factory function needed in C++11 due to lack of CTAD.
Definition: erroror.hpp:98
wamp::ErrorOr::ErrorOr
ErrorOr(std::error_code ec, std::string)
Definition: erroror.hpp:339
wamp::ErrorOr::has_value
bool has_value() const noexcept
Indicates if a value is being contained.
Definition: erroror.hpp:252
wamp::ErrorOr::ErrorOr
ErrorOr(std::error_code ec)
Definition: erroror.hpp:334
wamp::Unexpected
Minimalistic implementation of std::unexpected<std::error_code>.
Definition: erroror.hpp:37
wamp::Unexpected::value
error_type && value() &&noexcept
Moves the error value.
Definition: erroror.hpp:51
wamp::ErrorOr::errorInfo
const std::string & errorInfo() const
Definition: erroror.hpp:356
wamp::ErrorOr::operator=
ErrorOr & operator=(value_type value)
Value assignment.
Definition: erroror.hpp:174
wamp::AsyncHandler
std::function< void(ErrorOr< T >)> AsyncHandler
Type alias for a handler taking an ErrorOr<T> parameter.
Definition: erroror.hpp:495
wamp::ErrorOr::ErrorOr
ErrorOr(Unexpected< G > unex)
Converting constructor taking an Unexpected.
Definition: erroror.hpp:151
wamp::ErrorOr
Minimalistic implementation of std::expected<T, std::error_code>
Definition: erroror.hpp:128
wamp::ErrorOr::value
const value_type && value() const &&
Checked move of the stored value.
Definition: erroror.hpp:284
wamp::ErrorOr::error_type
std::error_code error_type
Type representing errors. *‍/.
Definition: erroror.hpp:132
wamp::ErrorOr::operator*
value_type & operator*() &
Unchecked access of the stored value.
Definition: erroror.hpp:218
wamp::ErrorOr::ErrorOr
ErrorOr(value_type value)
Converting constructor taking a value.
Definition: erroror.hpp:144
traits.hpp
Contains general-purpose type traits.
wamp::ErrorOr::operator*
value_type && operator*() &&
Unchecked move of the stored value.
Definition: erroror.hpp:226
wamp::ErrorOr::value_type
T value_type
Type representing result values.
Definition: erroror.hpp:131
wamp::ErrorOr::get
const ValueType & get() const
Definition: erroror.hpp:347
wamp::Unexpected::value
const error_type & value() const &noexcept
Accesses the error value.
Definition: erroror.hpp:54
error.hpp
Contains facilities for reporting and describing errors.