From 28a13571b9042efeefc555aecda0a4d7ea8793d6 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 17 Mar 2022 21:59:01 +0200 Subject: [PATCH] Restore the original system::error_code from std::error_code (refs #79) --- .../system/detail/error_category_impl.hpp | 2 +- include/boost/system/detail/error_code.hpp | 21 +++- include/boost/system/detail/std_category.hpp | 76 ++------------- .../boost/system/detail/std_category_impl.hpp | 97 +++++++++++++++++++ 4 files changed, 126 insertions(+), 70 deletions(-) create mode 100644 include/boost/system/detail/std_category_impl.hpp diff --git a/include/boost/system/detail/error_category_impl.hpp b/include/boost/system/detail/error_category_impl.hpp index 11f64a0..3512ddc 100644 --- a/include/boost/system/detail/error_category_impl.hpp +++ b/include/boost/system/detail/error_category_impl.hpp @@ -97,7 +97,7 @@ inline char const * error_category::message( int ev, char * buffer, std::size_t #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) -#include +#include namespace boost { diff --git a/include/boost/system/detail/error_code.hpp b/include/boost/system/detail/error_code.hpp index 587b3ab..1a643fc 100644 --- a/include/boost/system/detail/error_code.hpp +++ b/include/boost/system/detail/error_code.hpp @@ -21,6 +21,11 @@ #include #include #include + +#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) +# include +#endif + #include #include #include @@ -158,9 +163,21 @@ public: #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) error_code( std::error_code const& ec ) BOOST_NOEXCEPT: - lc_flags_( 1 ) + d1_(), lc_flags_( 0 ) { - ::new( d2_ ) std::error_code( ec ); +#ifndef BOOST_NO_RTTI + + if( detail::std_category const* pc2 = dynamic_cast< detail::std_category const* >( &ec.category() ) ) + { + *this = boost::system::error_code( ec.value(), pc2->original_category() ); + } + else + +#endif + { + ::new( d2_ ) std::error_code( ec ); + lc_flags_ = 1; + } } #endif diff --git a/include/boost/system/detail/std_category.hpp b/include/boost/system/detail/std_category.hpp index e8f70e1..2b98aa7 100644 --- a/include/boost/system/detail/std_category.hpp +++ b/include/boost/system/detail/std_category.hpp @@ -11,9 +11,6 @@ // See library home page at http://www.boost.org/libs/system #include -#include -#include -#include #include // @@ -33,6 +30,13 @@ private: boost::system::error_category const * pc_; +public: + + boost::system::error_category const & original_category() const BOOST_NOEXCEPT + { + return *pc_; + } + public: explicit std_category( boost::system::error_category const * pc, unsigned id ): pc_( pc ) @@ -66,72 +70,10 @@ public: return pc_->default_error_condition( ev ); } - bool equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT BOOST_OVERRIDE; - bool equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT BOOST_OVERRIDE; + inline bool equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT BOOST_OVERRIDE; + inline bool equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT BOOST_OVERRIDE; }; -inline bool std_category::equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT -{ - if( condition.category() == *this ) - { - boost::system::error_condition bn( condition.value(), *pc_ ); - return pc_->equivalent( code, bn ); - } - else if( condition.category() == std::generic_category() || condition.category() == boost::system::generic_category() ) - { - boost::system::error_condition bn( condition.value(), boost::system::generic_category() ); - return pc_->equivalent( code, bn ); - } - -#ifndef BOOST_NO_RTTI - - else if( std_category const* pc2 = dynamic_cast< std_category const* >( &condition.category() ) ) - { - boost::system::error_condition bn( condition.value(), *pc2->pc_ ); - return pc_->equivalent( code, bn ); - } - -#endif - - else - { - return default_error_condition( code ) == condition; - } -} - -inline bool std_category::equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT -{ - if( code.category() == *this ) - { - boost::system::error_code bc( code.value(), *pc_ ); - return pc_->equivalent( bc, condition ); - } - else if( code.category() == std::generic_category() || code.category() == boost::system::generic_category() ) - { - boost::system::error_code bc( code.value(), boost::system::generic_category() ); - return pc_->equivalent( bc, condition ); - } - -#ifndef BOOST_NO_RTTI - - else if( std_category const* pc2 = dynamic_cast< std_category const* >( &code.category() ) ) - { - boost::system::error_code bc( code.value(), *pc2->pc_ ); - return pc_->equivalent( bc, condition ); - } - -#endif - - else if( *pc_ == boost::system::generic_category() ) - { - return std::generic_category().equivalent( code, condition ); - } - else - { - return false; - } -} - } // namespace detail } // namespace system diff --git a/include/boost/system/detail/std_category_impl.hpp b/include/boost/system/detail/std_category_impl.hpp new file mode 100644 index 0000000..9dee5e7 --- /dev/null +++ b/include/boost/system/detail/std_category_impl.hpp @@ -0,0 +1,97 @@ +#ifndef BOOST_SYSTEM_DETAIL_STD_CATEGORY_IMPL_HPP_INCLUDED +#define BOOST_SYSTEM_DETAIL_STD_CATEGORY_IMPL_HPP_INCLUDED + +// Support for interoperability between Boost.System and +// +// Copyright 2018, 2021 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See library home page at http://www.boost.org/libs/system + +#include +#include +#include +#include + +// + +namespace boost +{ + +namespace system +{ + +namespace detail +{ + +inline bool std_category::equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT +{ + if( condition.category() == *this ) + { + boost::system::error_condition bn( condition.value(), *pc_ ); + return pc_->equivalent( code, bn ); + } + else if( condition.category() == std::generic_category() || condition.category() == boost::system::generic_category() ) + { + boost::system::error_condition bn( condition.value(), boost::system::generic_category() ); + return pc_->equivalent( code, bn ); + } + +#ifndef BOOST_NO_RTTI + + else if( std_category const* pc2 = dynamic_cast< std_category const* >( &condition.category() ) ) + { + boost::system::error_condition bn( condition.value(), *pc2->pc_ ); + return pc_->equivalent( code, bn ); + } + +#endif + + else + { + return default_error_condition( code ) == condition; + } +} + +inline bool std_category::equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT +{ + if( code.category() == *this ) + { + boost::system::error_code bc( code.value(), *pc_ ); + return pc_->equivalent( bc, condition ); + } + else if( code.category() == std::generic_category() || code.category() == boost::system::generic_category() ) + { + boost::system::error_code bc( code.value(), boost::system::generic_category() ); + return pc_->equivalent( bc, condition ); + } + +#ifndef BOOST_NO_RTTI + + else if( std_category const* pc2 = dynamic_cast< std_category const* >( &code.category() ) ) + { + boost::system::error_code bc( code.value(), *pc2->pc_ ); + return pc_->equivalent( bc, condition ); + } + +#endif + + else if( *pc_ == boost::system::generic_category() ) + { + return std::generic_category().equivalent( code, condition ); + } + else + { + return false; + } +} + +} // namespace detail + +} // namespace system + +} // namespace boost + +#endif // #ifndef BOOST_SYSTEM_DETAIL_STD_CATEGORY_IMPL_HPP_INCLUDED