From fcd78565df9af5a327d26b150b06639cca9d768e Mon Sep 17 00:00:00 2001 From: Simon Brand Date: Mon, 5 Mar 2018 11:03:10 +0000 Subject: [PATCH] Rename map_impl --- tl/expected.hpp | 311 ++++++++++++++++++++++++++---------------------- 1 file changed, 167 insertions(+), 144 deletions(-) diff --git a/tl/expected.hpp b/tl/expected.hpp index 6c9da9f..a52f202 100644 --- a/tl/expected.hpp +++ b/tl/expected.hpp @@ -50,23 +50,26 @@ // GCC < 5 doesn't support some standard C++11 type traits /// \exclude -#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ +#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ std::has_trivial_copy_constructor /// \exclude -#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::has_trivial_copy_assign +#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ + std::has_trivial_copy_assign // This one will be different for GCC 5.7 if it's ever supported /// \exclude -#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible +#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ + std::is_trivially_destructible #else /// \exclude -#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ +#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ std::is_trivially_copy_constructible /// \exclude -#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ +#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ std::is_trivially_copy_assignable /// \exclude -#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible +#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ + std::is_trivially_destructible #endif #if __cplusplus > 201103L @@ -262,15 +265,16 @@ using expected_enable_from_other = detail::enable_if_t< !std::is_convertible &, T>::value && !std::is_convertible &&, T>::value>; - template - using is_void_or = conditional_t::value, std::true_type, U>; +template +using is_void_or = conditional_t::value, std::true_type, U>; - template - using is_copy_constructible_or_void = is_void_or>; - - template - using is_move_constructible_or_void = is_void_or>; +template +using is_copy_constructible_or_void = + is_void_or>; +template +using is_move_constructible_or_void = + is_void_or>; } // namespace detail @@ -374,7 +378,8 @@ template struct expected_storage_base { // T is trivial, E is not. template struct expected_storage_base { constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {} - TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t) : m_has_val(false) {} + TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t) + : m_has_val(false) {} template ::value> * = @@ -529,16 +534,15 @@ template struct expected_operations_base : expected_storage_base { using expected_storage_base::expected_storage_base; - template void construct(Args &&... args) noexcept { - new (std::addressof(this->m_val)) T(std::forward(args)...); - this->m_has_val = true; - } + template void construct(Args &&... args) noexcept { + new (std::addressof(this->m_val)) T(std::forward(args)...); + this->m_has_val = true; + } - template - void construct_with(Rhs && rhs) noexcept { - new (std::addressof(this->m_val)) T(std::forward(rhs).get()); - this->m_has_val = true; - } + template void construct_with(Rhs &&rhs) noexcept { + new (std::addressof(this->m_val)) T(std::forward(rhs).get()); + this->m_has_val = true; + } template void construct_error(Args &&... args) noexcept { new (std::addressof(this->m_unexpect)) @@ -678,18 +682,15 @@ struct expected_operations_base : expected_storage_base { // This base class provides some handy member functions which can be used in // further derived classes template -struct expected_operations_base : expected_storage_base { +struct expected_operations_base : expected_storage_base { using expected_storage_base::expected_storage_base; - template void construct() noexcept { - this->m_has_val = true; - } + template void construct() noexcept { this->m_has_val = true; } // This function doesn't use its argument, but needs it so that code in // levels above this can work independently of whether T is void - template - void construct_with(Rhs &&) noexcept { - this->m_has_val = true; + template void construct_with(Rhs &&) noexcept { + this->m_has_val = true; } template void construct_error(Args &&... args) noexcept { @@ -698,20 +699,18 @@ struct expected_operations_base : expected_storage_base { this->m_has_val = false; } - template - void assign(Rhs &&rhs) noexcept { + template void assign(Rhs &&rhs) noexcept { if (!this->m_has_val) { - if (rhs.m_has_val) { - geterr().~unexpected(); - construct(); - } - else { - geterr() = std::forward(rhs).geterr(); - } + if (rhs.m_has_val) { + geterr().~unexpected(); + construct(); + } else { + geterr() = std::forward(rhs).geterr(); + } } else { - if (!rhs.m_has_val) { - construct_error(std::forward(rhs).geterr()); - } + if (!rhs.m_has_val) { + construct_error(std::forward(rhs).geterr()); + } } } @@ -734,8 +733,8 @@ struct expected_operations_base : expected_storage_base { // This class manages conditionally having a trivial copy constructor // This specialization is for when T and E are trivially copy constructible template ::value && - TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value> + bool = is_void_or:: + value &&TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value> struct expected_copy_base : expected_operations_base { using expected_operations_base::expected_operations_base; }; @@ -767,7 +766,7 @@ struct expected_copy_base : expected_operations_base { // move constructible #ifndef TL_EXPECTED_GCC49 template >::value + bool = is_void_or>::value &&std::is_trivially_move_constructible::value> struct expected_move_base : expected_copy_base { using expected_copy_base::expected_copy_base; @@ -796,14 +795,14 @@ struct expected_move_base : expected_copy_base { }; // This class manages conditionally having a trivial copy assignment operator -template < - class T, class E, - bool = is_void_or>::value && - TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(E)::value && - TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value && TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(E)::value> +template >::value + &&TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(E)::value + &&TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value + &&TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(E)::value> struct expected_copy_assign_base : expected_move_base { using expected_move_base::expected_move_base; }; @@ -832,12 +831,12 @@ struct expected_copy_assign_base : expected_move_base { #ifndef TL_EXPECTED_GCC49 template , - std::is_trivially_move_constructible, - std::is_trivially_move_assignable>>::value - &&std::is_trivially_destructible::value - &&std::is_trivially_move_constructible::value - &&std::is_trivially_move_assignable::value> + is_void_or, + std::is_trivially_move_constructible, + std::is_trivially_move_assignable>>:: + value &&std::is_trivially_destructible::value + &&std::is_trivially_move_constructible::value + &&std::is_trivially_move_assignable::value> struct expected_move_assign_base : expected_copy_assign_base { using expected_copy_assign_base::expected_copy_assign_base; }; @@ -986,7 +985,8 @@ struct default_constructor_tag { // consturctor if T is not default constructible. // This specialization is for when T is default constructible template ::value || std::is_void::value> + bool Enable = + std::is_default_constructible::value || std::is_void::value> struct expected_default_ctor_base { constexpr expected_default_ctor_base() noexcept = default; constexpr expected_default_ctor_base( @@ -1058,12 +1058,18 @@ class expected : private detail::expected_move_assign_base, T *valptr() { return std::addressof(this->m_val); } unexpected *errptr() { return std::addressof(this->m_unexpect); } - template ::value>* = nullptr> - U &val() { return this->m_val; } + template ::value> * = nullptr> + U &val() { + return this->m_val; + } unexpected &err() { return this->m_unexpect; } - template ::value>* = nullptr> - const U &val() const { return this->m_val; } + template ::value> * = nullptr> + const U &val() const { + return this->m_val; + } const unexpected &err() const { return this->m_unexpect; } using impl_base = detail::expected_move_assign_base; @@ -1086,26 +1092,26 @@ public: /// is returned. /// \synopsis template \nconstexpr auto and_then(F &&f) &; template TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & { - return and_then_impl(*this, std::forward(f)); + return and_then_impl(*this, std::forward(f)); } /// \group and_then /// \synopsis template \nconstexpr auto and_then(F &&f) &&; template TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && { - return and_then_impl(std::move(*this), std::forward(f)); + return and_then_impl(std::move(*this), std::forward(f)); } /// \group and_then /// \synopsis template \nconstexpr auto and_then(F &&f) const &; template constexpr auto and_then(F &&f) const & { - return and_then_impl(*this, std::forward(f)); + return and_then_impl(*this, std::forward(f)); } #ifndef TL_EXPECTED_NO_CONSTRR /// \group and_then /// \synopsis template \nconstexpr auto and_then(F &&f) const &&; template constexpr auto and_then(F &&f) const && { - return and_then_impl(std::move(*this), std::forward(f)); + return and_then_impl(std::move(*this), std::forward(f)); } #endif @@ -1120,30 +1126,34 @@ public: /// is returned. /// \synopsis template \nconstexpr auto and_then(F &&f) &; template - TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & -> decltype(and_then_impl(*this, std::forward(f))) { - return and_then_impl(*this, std::forward(f)); + TL_EXPECTED_11_CONSTEXPR auto + and_then(F &&f) & -> decltype(and_then_impl(*this, std::forward(f))) { + return and_then_impl(*this, std::forward(f)); } /// \group and_then /// \synopsis template \nconstexpr auto and_then(F &&f) &&; template - TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && -> decltype(and_then_impl(std::move(*this), std::forward(f))) { - return and_then_impl(std::move(*this), std::forward(f)); + TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && -> decltype( + and_then_impl(std::move(*this), std::forward(f))) { + return and_then_impl(std::move(*this), std::forward(f)); } /// \group and_then /// \synopsis template \nconstexpr auto and_then(F &&f) const &; template - constexpr auto and_then(F &&f) const & -> decltype(and_then_impl(*this, std::forward(f))) { - return and_then_impl(*this, std::forward(f)); + constexpr auto and_then(F &&f) const & -> decltype( + and_then_impl(*this, std::forward(f))) { + return and_then_impl(*this, std::forward(f)); } #ifndef TL_EXPECTED_NO_CONSTRR /// \group and_then /// \synopsis template \nconstexpr auto and_then(F &&f) const &&; template - constexpr auto and_then(F &&f) const && -> decltype(and_then_impl(std::move(*this), std::forward(f))) { - return and_then_impl(std::move(*this), std::forward(f)); + constexpr auto and_then(F &&f) const && -> decltype( + and_then_impl(std::move(*this), std::forward(f))) { + return and_then_impl(std::move(*this), std::forward(f)); } #endif #endif @@ -1161,25 +1171,25 @@ public: /// \group map /// \synopsis template constexpr auto map(F &&f) &; template TL_EXPECTED_11_CONSTEXPR auto map(F &&f) & { - return map_impl(*this, std::forward(f)); + return expected_map_impl(*this, std::forward(f)); } /// \group map /// \synopsis template constexpr auto map(F &&f) &&; template TL_EXPECTED_11_CONSTEXPR auto map(F &&f) && { - return map_impl(std::move(*this), std::forward(f)); + return expected_map_impl(std::move(*this), std::forward(f)); } /// \group map /// \synopsis template constexpr auto map(F &&f) const &; template constexpr auto map(F &&f) const & { - return map_impl(*this, std::forward(f)); + return expected_map_impl(*this, std::forward(f)); } /// \group map /// \synopsis template constexpr auto map(F &&f) const &&; template constexpr auto map(F &&f) const && { - return map_impl(std::move(*this), std::forward(f)); + return expected_map_impl(std::move(*this), std::forward(f)); } #else /// \brief Carries out some operation on the stored object if there is one. @@ -1193,38 +1203,38 @@ public: /// \group map /// \synopsis template constexpr auto map(F &&f) &; template - TL_EXPECTED_11_CONSTEXPR decltype(map_impl(std::declval(), - std::declval())) + TL_EXPECTED_11_CONSTEXPR decltype( + expected_map_impl(std::declval(), std::declval())) map(F &&f) & { - return map_impl(*this, std::forward(f)); + return expected_map_impl(*this, std::forward(f)); } /// \group map /// \synopsis template constexpr auto map(F &&f) &&; template - TL_EXPECTED_11_CONSTEXPR decltype(map_impl(std::declval(), - std::declval())) + TL_EXPECTED_11_CONSTEXPR decltype( + expected_map_impl(std::declval(), std::declval())) map(F &&f) && { - return map_impl(std::move(*this), std::forward(f)); + return expected_map_impl(std::move(*this), std::forward(f)); } /// \group map /// \synopsis template constexpr auto map(F &&f) const &; template - constexpr decltype(map_impl(std::declval(), - std::declval())) + constexpr decltype(expected_map_impl(std::declval(), + std::declval())) map(F &&f) const & { - return map_impl(*this, std::forward(f)); + return expected_map_impl(*this, std::forward(f)); } #ifndef TL_EXPECTED_NO_CONSTRR /// \group map /// \synopsis template constexpr auto map(F &&f) const &&; template - constexpr decltype(map_impl(std::declval(), - std::declval())) + constexpr decltype(expected_map_impl(std::declval(), + std::declval())) map(F &&f) const && { - return map_impl(std::move(*this), std::forward(f)); + return expected_map_impl(std::move(*this), std::forward(f)); } #endif #endif @@ -1477,29 +1487,29 @@ public: class U = T, detail::enable_if_t::value> * = nullptr, detail::expected_enable_forward_value * = nullptr> - explicit TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) : expected(in_place, std::forward(v)) {} + explicit TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) + : expected(in_place, std::forward(v)) {} /// \exclude template < class U = T, detail::enable_if_t::value> * = nullptr, detail::expected_enable_forward_value * = nullptr> - TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) : expected(in_place, std::forward(v)) {} + TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) + : expected(in_place, std::forward(v)) {} template < - class U = T, - class G = T, + class U = T, class G = T, detail::enable_if_t::value> * = - nullptr, - detail::enable_if_t::value>* = nullptr, + nullptr, + detail::enable_if_t::value> * = nullptr, detail::enable_if_t< (!std::is_same, detail::decay_t>::value && !detail::conjunction, std::is_same>>::value && std::is_constructible::value && std::is_assignable::value && - std::is_nothrow_move_constructible::value)> * = nullptr - > + std::is_nothrow_move_constructible::value)> * = nullptr> expected &operator=(U &&v) { if (has_value()) { val() = std::forward(v); @@ -1514,19 +1524,17 @@ public: /// \exclude template < - class U = T, - class G = T, + class U = T, class G = T, detail::enable_if_t::value> * = - nullptr, - detail::enable_if_t::value>* = nullptr, + nullptr, + detail::enable_if_t::value> * = nullptr, detail::enable_if_t< (!std::is_same, detail::decay_t>::value && !detail::conjunction, std::is_same>>::value && std::is_constructible::value && std::is_assignable::value && - std::is_nothrow_move_constructible::value)> * = nullptr - > + std::is_nothrow_move_constructible::value)> * = nullptr> expected &operator=(U &&v) { if (has_value()) { val() = std::forward(v); @@ -1678,17 +1686,29 @@ public: /// \returns the stored value /// \requires a value is stored /// \group deref - template ::value>* = nullptr> - constexpr const U &operator*() const & { return val(); } + template ::value> * = nullptr> + constexpr const U &operator*() const & { + return val(); + } /// \group deref - template ::value>* = nullptr> - TL_EXPECTED_11_CONSTEXPR U &operator*() & { return val(); } + template ::value> * = nullptr> + TL_EXPECTED_11_CONSTEXPR U &operator*() & { + return val(); + } /// \group deref - template ::value>* = nullptr> - constexpr const U &&operator*() const && { return std::move(val()); } + template ::value> * = nullptr> + constexpr const U &&operator*() const && { + return std::move(val()); + } /// \group deref - template ::value>* = nullptr> - TL_EXPECTED_11_CONSTEXPR U &&operator*() && { return std::move(val()); } + template ::value> * = nullptr> + TL_EXPECTED_11_CONSTEXPR U &&operator*() && { + return std::move(val()); + } /// \returns whether or not the optional has a value /// \group has_value @@ -1700,28 +1720,32 @@ public: /// [bad_expected_access] /// /// \group value - template ::value>* = nullptr> + template ::value> * = nullptr> TL_EXPECTED_11_CONSTEXPR const U &value() const & { if (!has_value()) throw bad_expected_access(err().value()); return val(); } /// \group value - template ::value>* = nullptr> + template ::value> * = nullptr> TL_EXPECTED_11_CONSTEXPR U &value() & { if (!has_value()) throw bad_expected_access(err().value()); return val(); } /// \group value - template ::value>* = nullptr> + template ::value> * = nullptr> TL_EXPECTED_11_CONSTEXPR const U &&value() const && { if (!has_value()) throw bad_expected_access(err().value()); return std::move(val()); } /// \group value - template ::value>* = nullptr> + template ::value> * = nullptr> TL_EXPECTED_11_CONSTEXPR U &&value() && { if (!has_value()) throw bad_expected_access(err().value()); @@ -1766,50 +1790,48 @@ template using ret_t = expected>; template (), *std::declval())), - detail::enable_if_t>::value> * = nullptr> + detail::enable_if_t>::value> * = nullptr> constexpr auto and_then_impl(Exp &&exp, F &&f) { - static_assert(detail::is_expected::value, - "F must return an expected"); + static_assert(detail::is_expected::value, "F must return an expected"); - return exp.has_value() ? detail::invoke(std::forward(f), *std::forward(exp)) - : Ret(unexpect, exp.error()); + return exp.has_value() + ? detail::invoke(std::forward(f), *std::forward(exp)) + : Ret(unexpect, exp.error()); } template (), *std::declval())), - detail::enable_if_t>::value> * = nullptr> + detail::enable_if_t>::value> * = nullptr> constexpr auto and_then_impl(Exp &&exp, F &&f) { - static_assert(detail::is_expected::value, - "F must return an expected"); + static_assert(detail::is_expected::value, "F must return an expected"); - return exp.has_value() ? detail::invoke(std::forward(f)) - : Ret(unexpect, exp.error()); + return exp.has_value() ? detail::invoke(std::forward(f)) + : Ret(unexpect, exp.error()); } #else - templatestruct TC; +template struct TC; template (), *std::declval())), - detail::enable_if_t>::value> * = nullptr> - auto and_then_impl(Exp &&exp, F &&f) -> Ret { - static_assert(detail::is_expected::value, - "F must return an expected"); + detail::enable_if_t>::value> * = nullptr> +auto and_then_impl(Exp &&exp, F &&f) -> Ret { + static_assert(detail::is_expected::value, "F must return an expected"); - return exp.has_value() ? detail::invoke(std::forward(f), *std::forward(exp)) - : Ret(unexpect, exp.error()); + return exp.has_value() + ? detail::invoke(std::forward(f), *std::forward(exp)) + : Ret(unexpect, exp.error()); } template (), *std::declval())), - detail::enable_if_t>::value> * = nullptr> + detail::enable_if_t>::value> * = nullptr> constexpr auto and_then_impl(Exp &&exp, F &&f) -> Ret { - static_assert(detail::is_expected::value, - "F must return an expected"); + static_assert(detail::is_expected::value, "F must return an expected"); - return exp.has_value() ? detail::invoke(std::forward(f)) - : Ret(unexpect, exp.error()); + return exp.has_value() ? detail::invoke(std::forward(f)) + : Ret(unexpect, exp.error()); } #endif @@ -1818,7 +1840,7 @@ template (), *std::declval())), detail::enable_if_t::value> * = nullptr> -constexpr auto map_impl(Exp &&exp, F &&f) { +constexpr auto expected_map_impl(Exp &&exp, F &&f) { using result = ret_t>; return exp.has_value() ? result(detail::invoke(std::forward(f), *std::forward(exp))) @@ -1829,7 +1851,7 @@ template (), *std::declval())), detail::enable_if_t::value> * = nullptr> -auto map_impl(Exp &&exp, F &&f) { +auto expected_map_impl(Exp &&exp, F &&f) { using result = expected>; if (exp.has_value()) { detail::invoke(std::forward(f), *std::forward(exp)); @@ -1844,7 +1866,8 @@ template ())), detail::enable_if_t::value> * = nullptr> -constexpr auto map_impl(Exp &&exp, F &&f) -> ret_t> { +constexpr auto expected_map_impl(Exp &&exp, F &&f) + -> ret_t> { using result = ret_t>; return exp.has_value() ? result(detail::invoke(std::forward(f), @@ -1857,7 +1880,7 @@ template ())), detail::enable_if_t::value> * = nullptr> -auto map_impl(Exp &&exp, F &&f) -> expected> { +auto expected_map_impl(Exp &&exp, F &&f) -> expected> { if (exp.has_value()) { detail::invoke(std::forward(f), *std::forward(exp)); return {};