1 #ifndef SILICIUM_ERROR_OR_HPP
2 #define SILICIUM_ERROR_OR_HPP
5 #include <boost/system/system_error.hpp>
6 #include <boost/throw_exception.hpp>
7 #include <boost/functional/hash.hpp>
8 #include <boost/mpl/bool.hpp>
9 #include <system_error>
16 boost::throw_exception(boost::system::system_error(error));
22 boost::throw_exception(std::system_error(error));
28 template <
class To,
class From>
31 return std::forward<From>(from);
34 template <
class To,
class From>
37 return To(std::forward<From>(from));
40 template <
class ErrorCode>
43 typedef typename std::decay<decltype(std::declval<ErrorCode>().
category())>::
type type;
47 template <
class Value,
class Error = boost::system::error_code>
54 #if SILICIUM_COMPILER_HAS_CXX11_UNION
58 #if !SILICIUM_COMPILER_HAS_CXX11_UNION
59 new (value_ptr()) Value();
63 template <class ConvertibleToValue, class = typename std::enable_if<std::is_convertible<ConvertibleToValue, Value>::value,
void>::type>
64 error_or(ConvertibleToValue &&value) BOOST_NOEXCEPT
66 #if SILICIUM_COMPILER_HAS_CXX11_UNION
67 ,
value_(std::forward<ConvertibleToValue>(value))
70 #if !SILICIUM_COMPILER_HAS_CXX11_UNION
71 new (value_ptr()) Value(std::forward<ConvertibleToValue>(value));
77 #if SILICIUM_COMPILER_HAS_CXX11_UNION
81 #if !SILICIUM_COMPILER_HAS_CXX11_UNION
82 new (value_ptr()) Value(
std::move(value));
92 #if !SILICIUM_COMPILER_HAS_CXX11_UNION
93 new (value_ptr()) Value(value);
112 new (value_ptr()) Value(*other.value_ptr());
119 if (other.is_error())
125 new (value_ptr()) Value(
std::move(*other.value_ptr()));
134 if (other.is_error())
140 new (value_ptr()) Value(
std::move(*other.value_ptr()));
145 if (other.is_error())
147 value_ptr()->~Value();
153 *value_ptr() =
std::move(*other.value_ptr());
171 new (value_ptr()) Value(
std::move(other));
185 new (value_ptr()) Value(other);
189 *value_ptr() = other;
198 value_ptr()->~Value();
233 #if SILICIUM_COMPILER_HAS_RVALUE_THIS_QUALIFIER
241 Value
const &
get()
const
275 #if SILICIUM_COMPILER_HAS_RVALUE_THIS_QUALIFIER
287 template <
class ComparableToValue>
298 return get() == other.
get();
301 template <class ConvertibleToValue, class = typename std::enable_if<std::is_convertible<ConvertibleToValue, Value>::value,
void>::type>
302 bool equals(ConvertibleToValue
const &right)
const
308 return get() == detail::convert_if_necessary<Value>(right, std::is_same<
typename std::decay<Value>::type,
typename std::decay<ConvertibleToValue>::type>());
317 return error() == right;
327 #if SILICIUM_COMPILER_HAS_CXX11_UNION
337 #if SILICIUM_COMPILER_HAS_CXX11_UNION
340 return reinterpret_cast<Value *
>(
value_.data());
344 Value
const *value_ptr()
const
346 #if SILICIUM_COMPILER_HAS_CXX11_UNION
349 return reinterpret_cast<Value
const *
>(
value_.data());
363 template <
class Value,
class Error>
368 template <
class Value,
class Error,
class Anything>
371 return left.
equals(right);
374 template <class Anything, class Value, class Error, class = typename std::enable_if<!is_error_or<Anything>::value,
void>::type>
377 return right.
equals(left);
380 template <
class Anything,
class Value,
class Error>
383 return !(left == right);
386 template <
class Anything,
class Value,
class Error>
389 return !(left == right);
392 template <
class Value,
class Error>
397 if (right.is_error())
399 return left.
error() < right.error();
408 if (right.is_error())
414 return left.get() < right.get();
421 template <
class Value,
class Error>
426 return boost::hash<Error>()(value.
error());
430 return boost::hash<Value>()(value.
get());
434 template <
class Value,
class Error>
435 std::ostream &operator << (std::ostream &out, error_or<Value, Error>
const &value)
437 if (value.is_error())
439 return out << value.error();
441 return out << value.get();
447 typename std::remove_reference<T>::type &&
move_if(boost::mpl::true_, T &&ref)
459 template <class ErrorOr, class OnValue, class CleanErrorOr = typename std::decay<ErrorOr>::type,
class = typename
std::enable_if<is_error_or<CleanErrorOr>::value, void>::type>
460 auto
map(ErrorOr &&maybe, OnValue &&on_value)
461 ->
error_or<decltype(std::forward<OnValue>(on_value)(std::forward<ErrorOr>(maybe).get()))>
463 if (maybe.is_error())
465 return maybe.
error();
467 return std::forward<OnValue>(on_value)(
469 detail::move_if(boost::mpl::bool_<!boost::is_lvalue_reference<ErrorOr>::value>(),
471 std::forward<ErrorOr>(maybe).
get()
478 template <
class Value,
class Error>
487 template <
class Value,
class Error>
488 struct hash<
Si::error_or<Value, Error>>
std::remove_reference< T >::type && move(T &&ref)
Definition: move.hpp:10
error_or(error_or &&other) BOOST_NOEXCEPT
Definition: error_or.hpp:116
Value value_type
Definition: error_or.hpp:50
Value && move_value()
Definition: error_or.hpp:250
BOOST_STATIC_ASSERT(Si::is_handle< absolute_path >::value)
#define SILICIUM_COMPILER_HAS_RVALUE_THIS_QUALIFIER
Definition: config.hpp:69
auto map(ErrorOr &&maybe, OnValue &&on_value) -> error_or< decltype(std::forward< OnValue >(on_value)(std::forward< ErrorOr >(maybe).get()))>
Definition: error_or.hpp:460
SILICIUM_NORETURN void throw_error(error_code< UnderlyingErrorCode, UnderlyingCategory > error)
Definition: error_code.hpp:69
bool equals(ConvertibleToValue const &right) const
Definition: error_or.hpp:302
Definition: error_or.hpp:359
optional< Value > get_optional()
Definition: error_or.hpp:274
Definition: absolute_path.hpp:352
void throw_if_error() const
Definition: error_or.hpp:216
Definition: absolute_path.hpp:19
error_or(error_or const &other)
Definition: error_or.hpp:103
Error error() const BOOST_NOEXCEPT
Definition: error_or.hpp:207
Definition: optional.hpp:39
#define SILICIUM_COMPILER_HAS_CXX11_UNION
Definition: config.hpp:105
~error_or() BOOST_NOEXCEPT
Definition: error_or.hpp:194
Value const * get_ptr() const BOOST_NOEXCEPT
Definition: error_or.hpp:265
Definition: error_or.hpp:41
std::size_t hash_value(error_or< Value, Error > const &value)
Definition: error_or.hpp:422
std::remove_reference< T >::type && move_if(boost::mpl::true_, T &&ref)
Definition: error_or.hpp:447
SILICIUM_USE_RESULT bool operator==(absolute_path const &left, ComparableToPath const &right)
Definition: absolute_path.hpp:169
#define SILICIUM_UNREACHABLE()
Definition: config.hpp:44
From && convert_if_necessary(From &&from, std::true_type)
Definition: error_or.hpp:29
category_type const * category
Definition: error_or.hpp:332
bool equals(error_or< ComparableToValue, Error > const &other) const
Definition: error_or.hpp:288
error_or(ConvertibleToValue &&value) BOOST_NOEXCEPT
Definition: error_or.hpp:64
Value & get()
Definition: error_or.hpp:224
error_or(Error error) BOOST_NOEXCEPT
Definition: error_or.hpp:97
error_or(Value const &value)
Definition: error_or.hpp:86
error_or() BOOST_NOEXCEPT
Definition: error_or.hpp:52
std::array< char, sizeof(Value)> value_
Definition: error_or.hpp:330
error_or & operator=(error_or &&other) BOOST_NOEXCEPT
Definition: error_or.hpp:129
#define SILICIUM_NORETURN
Definition: config.hpp:63
Definition: error_or.hpp:48
SILICIUM_USE_RESULT std::size_t hash_value(absolute_path const &value)
Definition: absolute_path.hpp:220
SILICIUM_USE_RESULT bool operator!=(absolute_path const &left, ComparableToPath const &right)
Definition: absolute_path.hpp:201
error_or(Value &&value) BOOST_NOEXCEPT
Definition: error_or.hpp:75
bool equals(Error const &right) const
Definition: error_or.hpp:311
Value * get_ptr() BOOST_NOEXCEPT
Definition: error_or.hpp:256
std::size_t operator()(Si::error_or< Value, Error > const &value) const
Definition: error_or.hpp:490
bool is_error() const BOOST_NOEXCEPT
Definition: error_or.hpp:202
std::decay< decltype(std::declval< ErrorCode >).category())>::type type
Definition: error_or.hpp:43