From 60efdc541e703d86c67c60254780b6bbd46914fc Mon Sep 17 00:00:00 2001 From: Mungo Gill Date: Thu, 29 Jan 2026 14:33:24 +0000 Subject: [PATCH] Simplify io_result<> constructors to eliminate include-order dependency Replace three separate constructors with a single template constructor that accepts any type convertible to std::error_code. The old approach used #ifdef BOOST_SYSTEM_ERROR_CODE_HPP_INCLUDED to conditionally compile the boost::system::error_code constructor. This created a fragile include-order dependency: if io_result.hpp was included before boost/system/error_code.hpp, the direct constructor wasn't available, forcing MSVC to apply two implicit conversions which triggers warning C4927. The new single template constructor handles all cases uniformly by relying on std::error_code's existing constructors and conversion operators. This eliminates the C4927 warning and removes the need to carefully order includes in headers that use io_result with Boost error codes. --- include/boost/capy/io_result.hpp | 46 +++++++++++++------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/include/boost/capy/io_result.hpp b/include/boost/capy/io_result.hpp index 23e5a0e2..7be93ae8 100644 --- a/include/boost/capy/io_result.hpp +++ b/include/boost/capy/io_result.hpp @@ -61,40 +61,32 @@ struct [[nodiscard]] io_result<> /** Default constructor. */ io_result() = default; - /** Construct from an error code. + /** Construct from any type convertible to std::error_code. - Enables implicit conversion from error_code, allowing - `co_return ec;` in coroutines returning `task>`. - */ - io_result(std::error_code e) noexcept - : ec(e) - { - } + This constructor accepts `std::error_code`, `boost::system::error_code`, + error code enums (types for which `std::is_error_code_enum` is true), + and any other type with implicit conversion to `std::error_code`. + The provided value is used to initialize the @ref ec member. -#ifdef BOOST_SYSTEM_ERROR_CODE_HPP_INCLUDED - /** Construct from a Boost error code. + @tparam E The error code type. Must satisfy + `std::is_convertible::value`. - Enables implicit conversion from boost::system::error_code, - available only when boost/system/error_code.hpp is included - before this header. - */ - BOOST_CAPY_FORCEINLINE - io_result(boost::system::error_code e) noexcept // conditional; not a dependency - : ec(e) - { - } -#endif + @param e The error code value to store. Should represent a valid + error code that can be converted to `std::error_code`. - /** Construct from an error code enum. + @par Constraints + This constructor only participates in overload resolution when + `std::is_convertible::value` is `true`. - Enables implicit conversion from error_code enums like - `route::next`, allowing direct `co_return` of enum values. + @par Exception Safety + This constructor is `noexcept` and will not throw exceptions. */ template::value>::type> - io_result(E e) noexcept - : ec(make_error_code(e)) + typename std::enable_if< + std::is_convertible::value, int>::type = 0> + BOOST_CAPY_FORCEINLINE + io_result(E const& e) noexcept + : ec(e) { }