Skip to content

Commit

Permalink
A Result or Outcome with void value type and move-only non-value ty…
Browse files Browse the repository at this point in the history
…pe was only usable in

const use cases, due to the lack of provision of non-const member functions in relevant observers
injection layers for the `void` specialisation. The missing non-const member functions have now
been added. Fixes #291.
  • Loading branch information
ned14 committed Nov 17, 2023
1 parent 441e316 commit f7892ac
Show file tree
Hide file tree
Showing 11 changed files with 289 additions and 47 deletions.
1 change: 1 addition & 0 deletions cmake/tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ set(outcome_TESTS
"test/tests/issue0247.cpp"
"test/tests/issue0255.cpp"
"test/tests/issue0259.cpp"
"test/tests/issue0291.cpp"
"test/tests/noexcept-propagation.cpp"
"test/tests/propagate.cpp"
"test/tests/serialisation.cpp"
Expand Down
6 changes: 6 additions & 0 deletions doc/src/content/changelog/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ passed before this was noticed, but it is now fixed. It is believed that this ha
without affecting ABI stability, however mixing old Outcome and new Outcome in the same binary
without recompiling all the C++ coroutine code to use new Outcome will not fix the bug.

[#291](https://github.com/ned14/outcome/issues/291)
- A Result or Outcome with `void` value type and move-only non-value type was only usable in
const use cases, due to the lack of provision of non-const member functions in relevant observers
injection layers for the `void` specialisation. The missing non-const member functions have now
been added.

---
## v2.2.7 13th August 2023 (Boost 1.83) [[release]](https://github.com/ned14/outcome/releases/tag/v2.2.7)

Expand Down
16 changes: 12 additions & 4 deletions include/outcome/detail/basic_outcome_exception_observers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ namespace detail
using Base::Base;

constexpr inline exception_type &assume_exception() & noexcept;
constexpr inline const exception_type &assume_exception() const &noexcept;
constexpr inline const exception_type &assume_exception() const & noexcept;
constexpr inline exception_type &&assume_exception() && noexcept;
constexpr inline const exception_type &&assume_exception() const &&noexcept;
constexpr inline const exception_type &&assume_exception() const && noexcept;

constexpr inline exception_type &exception() &;
constexpr inline const exception_type &exception() const &;
Expand All @@ -53,8 +53,16 @@ namespace detail
{
public:
using Base::Base;
constexpr void assume_exception() const noexcept { NoValuePolicy::narrow_exception_check(this); }
constexpr void exception() const { NoValuePolicy::wide_exception_check(this); }

constexpr void assume_exception() & noexcept { NoValuePolicy::narrow_exception_check(*this); }
constexpr void assume_exception() const & noexcept { NoValuePolicy::narrow_exception_check(*this); }
constexpr void assume_exception() && noexcept { NoValuePolicy::narrow_exception_check(std::move(*this)); }
constexpr void assume_exception() const && noexcept { NoValuePolicy::narrow_exception_check(std::move(*this)); }

constexpr void exception() & { NoValuePolicy::wide_exception_check(*this); }
constexpr void exception() const & { NoValuePolicy::wide_exception_check(*this); }
constexpr void exception() && { NoValuePolicy::wide_exception_check(std::move(*this)); }
constexpr void exception() const && { NoValuePolicy::wide_exception_check(std::move(*this)); }
};

} // namespace detail
Expand Down
16 changes: 12 additions & 4 deletions include/outcome/detail/basic_result_error_observers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace detail
NoValuePolicy::narrow_error_check(static_cast<basic_result_error_observers &>(*this));
return this->_state._error;
}
constexpr const error_type &assume_error() const &noexcept
constexpr const error_type &assume_error() const & noexcept
{
NoValuePolicy::narrow_error_check(static_cast<const basic_result_error_observers &>(*this));
return this->_state._error;
Expand All @@ -52,7 +52,7 @@ namespace detail
NoValuePolicy::narrow_error_check(static_cast<basic_result_error_observers &&>(*this));
return static_cast<error_type &&>(this->_state._error);
}
constexpr const error_type &&assume_error() const &&noexcept
constexpr const error_type &&assume_error() const && noexcept
{
NoValuePolicy::narrow_error_check(static_cast<const basic_result_error_observers &&>(*this));
return static_cast<const error_type &&>(this->_state._error);
Expand Down Expand Up @@ -83,8 +83,16 @@ namespace detail
{
public:
using Base::Base;
constexpr void assume_error() const noexcept { NoValuePolicy::narrow_error_check(*this); }
constexpr void error() const { NoValuePolicy::wide_error_check(*this); }

constexpr void assume_error() & noexcept { NoValuePolicy::narrow_error_check(static_cast<basic_result_error_observers &>(*this)); }
constexpr void assume_error() const & noexcept { NoValuePolicy::narrow_error_check(static_cast<const basic_result_error_observers &>(*this)); }
constexpr void assume_error() && noexcept { NoValuePolicy::narrow_error_check(static_cast<basic_result_error_observers &&>(*this)); }
constexpr void assume_error() const && noexcept { NoValuePolicy::narrow_error_check(static_cast<const basic_result_error_observers &&>(*this)); }

constexpr void error() & { NoValuePolicy::wide_error_check(static_cast<basic_result_error_observers &>(*this)); }
constexpr void error() const & { NoValuePolicy::wide_error_check(static_cast<const basic_result_error_observers &>(*this)); }
constexpr void error() && { NoValuePolicy::wide_error_check(static_cast<basic_result_error_observers &&>(*this)); }
constexpr void error() const && { NoValuePolicy::wide_error_check(static_cast<const basic_result_error_observers &&>(*this)); }
};
} // namespace detail
OUTCOME_V2_NAMESPACE_END
Expand Down
15 changes: 11 additions & 4 deletions include/outcome/detail/basic_result_value_observers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace detail
NoValuePolicy::narrow_value_check(static_cast<basic_result_value_observers &>(*this));
return this->_state._value; // NOLINT
}
constexpr const value_type &assume_value() const &noexcept
constexpr const value_type &assume_value() const & noexcept
{
NoValuePolicy::narrow_value_check(static_cast<const basic_result_value_observers &>(*this));
return this->_state._value; // NOLINT
Expand All @@ -52,7 +52,7 @@ namespace detail
NoValuePolicy::narrow_value_check(static_cast<basic_result_value_observers &&>(*this));
return static_cast<value_type &&>(this->_state._value); // NOLINT
}
constexpr const value_type &&assume_value() const &&noexcept
constexpr const value_type &&assume_value() const && noexcept
{
NoValuePolicy::narrow_value_check(static_cast<const basic_result_value_observers &&>(*this));
return static_cast<const value_type &&>(this->_state._value); // NOLINT
Expand Down Expand Up @@ -84,8 +84,15 @@ namespace detail
public:
using Base::Base;

constexpr void assume_value() const noexcept { NoValuePolicy::narrow_value_check(*this); }
constexpr void value() const { NoValuePolicy::wide_value_check(*this); }
constexpr void assume_value() & noexcept { NoValuePolicy::narrow_value_check(static_cast<basic_result_value_observers &>(*this)); }
constexpr void assume_value() const & noexcept { NoValuePolicy::narrow_value_check(static_cast<const basic_result_value_observers &>(*this)); }
constexpr void assume_value() && noexcept { NoValuePolicy::narrow_value_check(static_cast<basic_result_value_observers &&>(*this)); }
constexpr void assume_value() const && noexcept { NoValuePolicy::narrow_value_check(static_cast<const basic_result_value_observers &&>(*this)); }

constexpr void value() & { NoValuePolicy::wide_value_check(static_cast<basic_result_value_observers &>(*this)); }
constexpr void value() const & { NoValuePolicy::wide_value_check(static_cast<const basic_result_value_observers &>(*this)); }
constexpr void value() && { NoValuePolicy::wide_value_check(static_cast<basic_result_value_observers &&>(*this)); }
constexpr void value() const && { NoValuePolicy::wide_value_check(static_cast<const basic_result_value_observers &&>(*this)); }
};
} // namespace detail

Expand Down
6 changes: 3 additions & 3 deletions include/outcome/detail/revision.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ Distributed under the Boost Software License, Version 1.0.
*/

// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
#define OUTCOME_PREVIOUS_COMMIT_REF 1407d02d60c604e642ae202dbbd721e8c9851fbb
#define OUTCOME_PREVIOUS_COMMIT_DATE "2023-08-15 19:19:42 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 1407d02d
#define OUTCOME_PREVIOUS_COMMIT_REF 441e3164801151ae7671ea331a04b4a712f505e9
#define OUTCOME_PREVIOUS_COMMIT_DATE "2023-10-31 21:54:05 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 441e3164
24 changes: 21 additions & 3 deletions single-header/outcome-basic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,11 @@ Distributed under the Boost Software License, Version 1.0.
#endif // __GXX_EXPERIMENTAL_CXX0X__
#endif // clang
#endif
/*
This is a dummy header file which is a placeholder for the real config.hpp which
gets generated by the build system. This file is here to allow the library to be
used without the build system.
*/
#define QUICKCPPLIB_VERSION_GLUE2(a, b) a##b
#define QUICKCPPLIB_VERSION_GLUE(a, b) QUICKCPPLIB_VERSION_GLUE2(a, b)
// clang-format off
Expand Down Expand Up @@ -656,6 +661,19 @@ extern "C" void _mm_pause();
#define QUICKCPPLIB_NOINLINE
#endif
#endif
#if defined(QUICKCPPLIB_REQUIRE_CXX_STANDARD)
#define QUICKCPPLIB_REQUIRE_CXX17 (QUICKCPPLIB_REQUIRE_CXX_STANDARD >= 201703L)
#define QUICKCPPLIB_REQUIRE_CXX20 (QUICKCPPLIB_REQUIRE_CXX_STANDARD >= 202002L)
#define QUICKCPPLIB_USE_STD_BYTE QUICKCPPLIB_REQUIRE_CXX17
#define QUICKCPPLIB_USE_STD_OPTIONAL QUICKCPPLIB_REQUIRE_CXX17
#define QUICKCPPLIB_USE_STD_SPAN QUICKCPPLIB_REQUIRE_CXX20
#endif // ^^^ defined QUICKCPPLIB_REQUIRE_CXX_STANDARD ^^^
#if !defined(QUICKCPPLIB_USE_SYSTEM_BYTE_LITE)
#define QUICKCPPLIB_USE_SYSTEM_BYTE_LITE 0
#endif
#if !defined(QUICKCPPLIB_USE_SYSTEM_SPAN_LITE)
#define QUICKCPPLIB_USE_SYSTEM_SPAN_LITE 0
#endif
#ifdef __has_cpp_attribute
#define QUICKCPPLIB_HAS_CPP_ATTRIBUTE(attr, edition) (__has_cpp_attribute(attr) >= (edition) && __cplusplus >= (edition))
#else
Expand Down Expand Up @@ -996,9 +1014,9 @@ Distributed under the Boost Software License, Version 1.0.
http://www.boost.org/LICENSE_1_0.txt)
*/
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
#define OUTCOME_PREVIOUS_COMMIT_REF 1407d02d60c604e642ae202dbbd721e8c9851fbb
#define OUTCOME_PREVIOUS_COMMIT_DATE "2023-08-15 19:19:42 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 1407d02d
#define OUTCOME_PREVIOUS_COMMIT_REF 441e3164801151ae7671ea331a04b4a712f505e9
#define OUTCOME_PREVIOUS_COMMIT_DATE "2023-10-31 21:54:05 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 441e3164
#define OUTCOME_V2 (QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2))
#ifdef _DEBUG
#define OUTCOME_V2_CXX_MODULE_NAME QUICKCPPLIB_BIND_NAMESPACE((QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2d)))
Expand Down
26 changes: 22 additions & 4 deletions single-header/outcome-experimental.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,11 @@ Distributed under the Boost Software License, Version 1.0.
#endif // __GXX_EXPERIMENTAL_CXX0X__
#endif // clang
#endif
/*
This is a dummy header file which is a placeholder for the real config.hpp which
gets generated by the build system. This file is here to allow the library to be
used without the build system.
*/
#define QUICKCPPLIB_VERSION_GLUE2(a, b) a##b
#define QUICKCPPLIB_VERSION_GLUE(a, b) QUICKCPPLIB_VERSION_GLUE2(a, b)
// clang-format off
Expand Down Expand Up @@ -681,6 +686,19 @@ extern "C" void _mm_pause();
#define QUICKCPPLIB_NOINLINE
#endif
#endif
#if defined(QUICKCPPLIB_REQUIRE_CXX_STANDARD)
#define QUICKCPPLIB_REQUIRE_CXX17 (QUICKCPPLIB_REQUIRE_CXX_STANDARD >= 201703L)
#define QUICKCPPLIB_REQUIRE_CXX20 (QUICKCPPLIB_REQUIRE_CXX_STANDARD >= 202002L)
#define QUICKCPPLIB_USE_STD_BYTE QUICKCPPLIB_REQUIRE_CXX17
#define QUICKCPPLIB_USE_STD_OPTIONAL QUICKCPPLIB_REQUIRE_CXX17
#define QUICKCPPLIB_USE_STD_SPAN QUICKCPPLIB_REQUIRE_CXX20
#endif // ^^^ defined QUICKCPPLIB_REQUIRE_CXX_STANDARD ^^^
#if !defined(QUICKCPPLIB_USE_SYSTEM_BYTE_LITE)
#define QUICKCPPLIB_USE_SYSTEM_BYTE_LITE 0
#endif
#if !defined(QUICKCPPLIB_USE_SYSTEM_SPAN_LITE)
#define QUICKCPPLIB_USE_SYSTEM_SPAN_LITE 0
#endif
#ifdef __has_cpp_attribute
#define QUICKCPPLIB_HAS_CPP_ATTRIBUTE(attr, edition) (__has_cpp_attribute(attr) >= (edition) && __cplusplus >= (edition))
#else
Expand Down Expand Up @@ -1021,9 +1039,9 @@ Distributed under the Boost Software License, Version 1.0.
http://www.boost.org/LICENSE_1_0.txt)
*/
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
#define OUTCOME_PREVIOUS_COMMIT_REF 1407d02d60c604e642ae202dbbd721e8c9851fbb
#define OUTCOME_PREVIOUS_COMMIT_DATE "2023-08-15 19:19:42 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 1407d02d
#define OUTCOME_PREVIOUS_COMMIT_REF 441e3164801151ae7671ea331a04b4a712f505e9
#define OUTCOME_PREVIOUS_COMMIT_DATE "2023-10-31 21:54:05 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 441e3164
#define OUTCOME_V2 (QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2))
#ifdef _DEBUG
#define OUTCOME_V2_CXX_MODULE_NAME QUICKCPPLIB_BIND_NAMESPACE((QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2d)))
Expand Down Expand Up @@ -7865,7 +7883,7 @@ class SYSTEM_ERROR2_TRIVIAL_ABI status_code<detail::erased<ErasedType>>
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
//! Explicit copy construction from an unknown status code. Note that this will throw an exception if its value type is not trivially copyable or would not
//! fit into our storage or the source domain's `_do_erased_copy()` refused the copy.
explicit SYSTEM_ERROR2_CONSTEXPR14 status_code(const status_code<void> &v) // NOLINT
explicit SYSTEM_ERROR2_CONSTEXPR14 status_code(in_place_t, const status_code<void> &v) // NOLINT
: _base(typename _base::_value_type_constructor{}, v._domain_ptr(), value_type{})
{
status_code_domain::payload_info_t info{sizeof(value_type), sizeof(status_code), alignof(status_code)};
Expand Down
Loading

0 comments on commit f7892ac

Please sign in to comment.