From ffdf175981477518d2dbd0cfa1888adb8a1c6672 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Sat, 29 Dec 2018 23:58:52 +0100 Subject: [PATCH] - Add noexcept specifiers - Add rvalue overloads for left_opt and right_opt --- src/cpp-utils/either.h | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/cpp-utils/either.h b/src/cpp-utils/either.h index e718a63b..3eb5a612 100644 --- a/src/cpp-utils/either.h +++ b/src/cpp-utils/either.h @@ -12,13 +12,13 @@ namespace cpputils { class either final { public: template::value && !std::is_constructible::value>* = nullptr> - either(Head&& construct_left_head_arg, Tail&&... construct_left_tail_args) /* TODO noexcept(noexcept(std::declval>()._construct_left(std::forward(construct_left_head_arg), std::forward(construct_left_tail_args)...))) */ + either(Head&& construct_left_head_arg, Tail&&... construct_left_tail_args) noexcept(noexcept(std::declval>()._construct_left(std::forward(construct_left_head_arg), std::forward(construct_left_tail_args)...))) : _side(Side::left) { _construct_left(std::forward(construct_left_head_arg), std::forward(construct_left_tail_args)...); } template::value && std::is_constructible::value>* = nullptr> - either(Head&& construct_right_head_arg, Tail&&... construct_right_tail_args) /* TODO noexcept(noexcept(std::declval>()._construct_right(std::forward(construct_right_head_arg), std::forward(construct_right_tail_args)...))) */ + either(Head&& construct_right_head_arg, Tail&&... construct_right_tail_args) noexcept(noexcept(std::declval>()._construct_right(std::forward(construct_right_head_arg), std::forward(construct_right_tail_args)...))) : _side(Side::right) { _construct_right(std::forward(construct_right_head_arg), std::forward(construct_right_tail_args)...); } @@ -33,7 +33,7 @@ namespace cpputils { } } - either(either &&rhs) /* TODO noexcept(noexcept(_construct_left(std::move(rhs._left))) && noexcept(_construct_right(std::move(rhs._right)))) */ + either(either &&rhs) noexcept(noexcept(std::declval>()._construct_left(std::move(rhs._left))) && noexcept(std::declval>()._construct_right(std::move(rhs._right)))) : _side(rhs._side) { if(_side == Side::left) { _construct_left(std::move(rhs._left)); // NOLINT(cppcoreguidelines-pro-type-union-access) @@ -47,7 +47,7 @@ namespace cpputils { } //TODO Try allowing copy-assignment when Left/Right types are std::is_convertible - either &operator=(const either &rhs) /* TODO noexcept(noexcept(_construct_left(rhs._left)) && noexcept(_construct_right(rhs._right))) */ { + either &operator=(const either &rhs) noexcept(noexcept(std::declval>()._construct_left(rhs._left)) && noexcept(std::declval>()._construct_right(rhs._right))) { _destruct(); _side = rhs._side; if (_side == Side::left) { @@ -58,7 +58,7 @@ namespace cpputils { return *this; } - either &operator=(either &&rhs) /* TODO noexcept(noexcept(_construct_left(std::move(rhs._left))) && noexcept(_construct_right(std::move(rhs._right)))) */ { + either &operator=(either &&rhs) noexcept(noexcept(std::declval>()._construct_left(std::move(rhs._left))) && noexcept(std::declval>()._construct_right(std::move(rhs._right)))) { _destruct(); _side = rhs._side; if (_side == Side::left) { @@ -119,7 +119,15 @@ namespace cpputils { return boost::none; } } - // left_opt()&& not offered because optional doesn't work + // warning: opposed to the other left_opt variants, this one already moves the content and returns by value. + boost::optional left_opt() && noexcept(noexcept(boost::optional(std::move(std::declval>()._left)))) { + if (_side == Side::left) { + return std::move(_left); // NOLINT(cppcoreguidelines-pro-type-union-access) + } else { + return boost::none; + } + } + boost::optional right_opt() const& noexcept { if (_side == Side::right) { @@ -135,7 +143,16 @@ namespace cpputils { return boost::none; } } - // right_opt()&& not offered because optional doesn't work + // warning: opposed to the other left_opt variants, this one already moves the content and returns by value. + boost::optional right_opt() && noexcept(noexcept(boost::optional(std::move(std::declval>()._right)))) { + if (_side == Side::right) { + return std::move(_right); // NOLINT(cppcoreguidelines-pro-type-union-access) + } else { + return boost::none; + } + } + + private: union { @@ -163,10 +180,10 @@ namespace cpputils { } template - friend either make_left(Args&&... args) /* TODO noexcept(noexcept(std::declval>()._construct_left(std::forward(args)...)))*/; + friend either make_left(Args&&... args) /* TODO noexcept(noexcept(std::declval>()._construct_left(std::forward(args)...))) */; template - friend either make_right(Args&&... args) /* TODO noexcept(noexcept(std::declval>()._construct_right(std::forward(args)...)))*/; + friend either make_right(Args&&... args) /* TODO noexcept(noexcept(std::declval>()._construct_right(std::forward(args)...))) */; }; template