Re-enable left_opt() and right_opt() for rvalue references
This commit is contained in:
parent
2878313993
commit
4de6f1d8d9
@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
namespace cpputils {
|
namespace cpputils {
|
||||||
|
|
||||||
template<class Left, class Right>
|
template<class Left, class Right>
|
||||||
class either final {
|
class either final {
|
||||||
public:
|
public:
|
||||||
template<class Head, class... Tail, std::enable_if_t<std::is_constructible<Left, Head, Tail...>::value && !std::is_constructible<Right, Head, Tail...>::value>* = nullptr>
|
template<class Head, class... Tail, std::enable_if_t<std::is_constructible<Left, Head, Tail...>::value && !std::is_constructible<Right, Head, Tail...>::value>* = nullptr>
|
||||||
either(Head&& construct_left_head_arg, Tail&&... construct_left_tail_args) noexcept(noexcept(std::declval<either<Left, Right>>()._construct_left(std::forward<Head>(construct_left_head_arg), std::forward<Tail>(construct_left_tail_args)...)))
|
either(Head&& construct_left_head_arg, Tail&&... construct_left_tail_args) noexcept(noexcept(std::declval<either<Left, Right>>()._construct_left(std::forward<Head>(construct_left_head_arg), std::forward<Tail>(construct_left_tail_args)...)))
|
||||||
: _side(Side::left) {
|
: _side(Side::left) {
|
||||||
@ -115,7 +115,14 @@ namespace cpputils {
|
|||||||
return boost::none;
|
return boost::none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// left_opt()&& not offered because optional<Left&&> doesn't work
|
// warning: opposed to the other left_opt variants, this one already moves the content and returns by value.
|
||||||
|
boost::optional<Left> left_opt() && noexcept(noexcept(boost::optional<Left>(std::move(_left)))) {
|
||||||
|
if (_side == Side::left) {
|
||||||
|
return std::move(_left);
|
||||||
|
} else {
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boost::optional<const Right&> right_opt() const& noexcept {
|
boost::optional<const Right&> right_opt() const& noexcept {
|
||||||
if (_side == Side::right) {
|
if (_side == Side::right) {
|
||||||
@ -131,9 +138,16 @@ namespace cpputils {
|
|||||||
return boost::none;
|
return boost::none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// right_opt()&& not offered because optional<Right&&> doesn't work
|
// warning: opposed to the other left_opt variants, this one already moves the content and returns by value.
|
||||||
|
boost::optional<Right> right_opt() && noexcept(noexcept(boost::optional<Right>(std::move(_right)))) {
|
||||||
|
if (_side == Side::right) {
|
||||||
|
return std::move(_right);
|
||||||
|
} else {
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
Left _left;
|
Left _left;
|
||||||
Right _right;
|
Right _right;
|
||||||
@ -163,10 +177,10 @@ namespace cpputils {
|
|||||||
|
|
||||||
template<typename Left_, typename Right_, typename... Args>
|
template<typename Left_, typename Right_, typename... Args>
|
||||||
friend either<Left_, Right_> make_right(Args&&... args) /* TODO noexcept(noexcept(std::declval<either<Left, Right>>()._construct_right(std::forward<Args>(args)...))) */;
|
friend either<Left_, Right_> make_right(Args&&... args) /* TODO noexcept(noexcept(std::declval<either<Left, Right>>()._construct_right(std::forward<Args>(args)...))) */;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Left, class Right>
|
template<class Left, class Right>
|
||||||
inline bool operator==(const either<Left, Right> &lhs, const either<Left, Right> &rhs) noexcept(noexcept(std::declval<Left>() == std::declval<Left>()) && noexcept(std::declval<Right>() == std::declval<Right>())) {
|
inline bool operator==(const either<Left, Right> &lhs, const either<Left, Right> &rhs) noexcept(noexcept(std::declval<Left>() == std::declval<Left>()) && noexcept(std::declval<Right>() == std::declval<Right>())) {
|
||||||
if (lhs.is_left() != rhs.is_left()) {
|
if (lhs.is_left() != rhs.is_left()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -175,36 +189,36 @@ namespace cpputils {
|
|||||||
} else {
|
} else {
|
||||||
return lhs.right() == rhs.right();
|
return lhs.right() == rhs.right();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Left, class Right>
|
template<class Left, class Right>
|
||||||
inline bool operator!=(const either<Left, Right> &lhs, const either<Left, Right> &rhs) noexcept(noexcept(operator==(lhs, rhs))) {
|
inline bool operator!=(const either<Left, Right> &lhs, const either<Left, Right> &rhs) noexcept(noexcept(operator==(lhs, rhs))) {
|
||||||
return !operator==(lhs, rhs);
|
return !operator==(lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Left, class Right>
|
template<class Left, class Right>
|
||||||
inline std::ostream &operator<<(std::ostream &stream, const either<Left, Right> &value) {
|
inline std::ostream &operator<<(std::ostream &stream, const either<Left, Right> &value) {
|
||||||
if (value.is_left()) {
|
if (value.is_left()) {
|
||||||
stream << "Left(" << value.left() << ")";
|
stream << "Left(" << value.left() << ")";
|
||||||
} else {
|
} else {
|
||||||
stream << "Right(" << value.right() << ")";
|
stream << "Right(" << value.right() << ")";
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Left, typename Right, typename... Args>
|
template<typename Left, typename Right, typename... Args>
|
||||||
inline either<Left, Right> make_left(Args&&... args) /* TODO noexcept(noexcept(std::declval<either<Left, Right>>()._construct_left(std::forward<Args>(args)...))) */ {
|
inline either<Left, Right> make_left(Args&&... args) /* TODO noexcept(noexcept(std::declval<either<Left, Right>>()._construct_left(std::forward<Args>(args)...))) */ {
|
||||||
either<Left, Right> result(either<Left, Right>::Side::left);
|
either<Left, Right> result(either<Left, Right>::Side::left);
|
||||||
result._construct_left(std::forward<Args>(args)...);
|
result._construct_left(std::forward<Args>(args)...);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Left, typename Right, typename... Args>
|
template<typename Left, typename Right, typename... Args>
|
||||||
inline either<Left, Right> make_right(Args&&... args) /* TODO noexcept(noexcept(std::declval<either<Left, Right>>()._construct_right(std::forward<Args>(args)...))) */ {
|
inline either<Left, Right> make_right(Args&&... args) /* TODO noexcept(noexcept(std::declval<either<Left, Right>>()._construct_right(std::forward<Args>(args)...))) */ {
|
||||||
either<Left, Right> result(either<Left, Right>::Side::right);
|
either<Left, Right> result(either<Left, Right>::Side::right);
|
||||||
result._construct_right(std::forward<Args>(args)...);
|
result._construct_right(std::forward<Args>(args)...);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user