diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index 81c979b..70a41cd 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -607,8 +607,20 @@ namespace boost } else if( condition.category() == std::generic_category() || condition.category() == boost::system::generic_category() ) { - return pc_->equivalent( code, boost::system::error_condition( condition.value(), boost::system::generic_category() ) ); + boost::system::error_code bc( code, *pc_ ); + boost::system::error_condition bn( condition.value(), boost::system::generic_category() ); + + return bc == bn; } +#ifndef BOOST_NO_RTTI + else if( std_category const* pc2 = dynamic_cast< std_category const* >( &condition.category() ) ) + { + boost::system::error_code bc( code, *pc_ ); + boost::system::error_condition bn( condition.value(), *pc2->pc_ ); + + return bc == bn; + } +#endif else { return false; @@ -623,8 +635,7 @@ namespace boost } else if( *pc_ == boost::system::generic_category() ) { - std::error_category const & st = std::generic_category(); - return st.equivalent( code, condition ); + return code == std::error_condition( condition, std::generic_category() ); } else { @@ -644,5 +655,3 @@ namespace boost # endif #endif // BOOST_SYSTEM_ERROR_CODE_HPP - - diff --git a/test/std_interop_test.cpp b/test/std_interop_test.cpp index 5ee69a8..6b9c77d 100644 --- a/test/std_interop_test.cpp +++ b/test/std_interop_test.cpp @@ -120,6 +120,8 @@ static void test_system_category() } } +// test_user_category + class user_category_impl: public boost::system::error_category { public: @@ -251,11 +253,103 @@ static void test_user_category() } } +// test_user2_category + +enum user2_errc +{ + my_enoent = 1, + my_einval, + my_other +}; + +class user2_category_impl: public boost::system::error_category +{ +public: + + virtual const char * name() const BOOST_NOEXCEPT + { + return "user2"; + } + + virtual std::string message( int ev ) const + { + char buffer[ 256 ]; + sprintf( buffer, "user2 message %d", ev ); + + return buffer; + } + + virtual boost::system::error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT + { + return boost::system::error_condition( ev, *this ); + } + + virtual bool equivalent( int code, const boost::system::error_condition & condition ) const BOOST_NOEXCEPT + { + return default_error_condition( code ) == condition; + } + + virtual bool equivalent( const boost::system::error_code & code, int condition ) const BOOST_NOEXCEPT + { + if( code.category() == *this ) + { + return condition == code.value(); + } + else if( condition == my_enoent ) + { + return code == boost::system::errc::no_such_file_or_directory; + } + else if( condition == my_einval ) + { + return code == boost::system::errc::invalid_argument; + } + else + { + return false; + } + } +}; + +boost::system::error_category const & user2_category() +{ + static user2_category_impl cat_; + return cat_; +} + +static void test_user2_category() +{ + boost::system::error_category const & bt = user2_category(); + std::error_category const & st = bt; + + int ev = my_enoent; + + boost::system::error_condition bn( ev, bt ); + + BOOST_TEST_EQ( bn.value(), ev ); + BOOST_TEST_EQ( &bn.category(), &bt ); + + boost::system::error_code bc = make_error_code( boost::system::errc::no_such_file_or_directory ); + + BOOST_TEST( bc == bn ); + + std::error_condition sn( bn ); + + BOOST_TEST_EQ( sn.value(), ev ); + BOOST_TEST_EQ( &sn.category(), &st ); + + std::error_code sc( bc ); + + BOOST_TEST( sc == sn ); +} + +// + int main() { test_generic_category(); test_system_category(); test_user_category(); + test_user2_category(); return boost::report_errors(); }