mirror of
https://github.com/boostorg/system.git
synced 2025-12-25 08:18:05 +01:00
Compare commits
7 Commits
feature/wa
...
feature/is
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32bf67f748 | ||
|
|
5d15aa1267 | ||
|
|
36e1236a0f | ||
|
|
2c20b6e7e5 | ||
|
|
103f3b4f00 | ||
|
|
14f779e234 | ||
|
|
bfccd4b4d9 |
@@ -143,7 +143,7 @@ inline void error_category::init_stdcat() const
|
||||
|
||||
if( sc_init_.load( std::memory_order_acquire ) == 0 )
|
||||
{
|
||||
::new( static_cast<void*>( stdcat_ ) ) boost::system::detail::std_category( this, 0 );
|
||||
::new( static_cast<void*>( stdcat_ ) ) boost::system::detail::std_category( this, system::detail::id_wrapper<0>() );
|
||||
sc_init_.store( 1, std::memory_order_release );
|
||||
}
|
||||
}
|
||||
@@ -160,7 +160,7 @@ inline BOOST_NOINLINE error_category::operator std::error_category const & () co
|
||||
// This condition must be the same as the one in error_condition.hpp
|
||||
#if defined(BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY)
|
||||
|
||||
static const boost::system::detail::std_category generic_instance( this, 0x1F4D3 );
|
||||
static const boost::system::detail::std_category generic_instance( this, system::detail::id_wrapper<0x1F4D3>() );
|
||||
return generic_instance;
|
||||
|
||||
#else
|
||||
@@ -175,7 +175,7 @@ inline BOOST_NOINLINE error_category::operator std::error_category const & () co
|
||||
// This condition must be the same as the one in error_code.hpp
|
||||
#if defined(BOOST_SYSTEM_AVOID_STD_SYSTEM_CATEGORY)
|
||||
|
||||
static const boost::system::detail::std_category system_instance( this, 0x1F4D7 );
|
||||
static const boost::system::detail::std_category system_instance( this, system::detail::id_wrapper<0x1F4D7>() );
|
||||
return system_instance;
|
||||
|
||||
#else
|
||||
|
||||
@@ -403,7 +403,12 @@ public:
|
||||
{
|
||||
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
|
||||
if( lhs.lc_flags_ == 1 && rhs.lc_flags_ == 1 )
|
||||
bool s1 = lhs.lc_flags_ == 1;
|
||||
bool s2 = rhs.lc_flags_ == 1;
|
||||
|
||||
if( s1 != s2 ) return false;
|
||||
|
||||
if( s1 && s2 )
|
||||
{
|
||||
std::error_code const& e1 = *reinterpret_cast<std::error_code const*>( lhs.d2_ );
|
||||
std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( rhs.d2_ );
|
||||
@@ -421,7 +426,13 @@ public:
|
||||
{
|
||||
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
|
||||
if( lhs.lc_flags_ == 1 && rhs.lc_flags_ == 1 )
|
||||
bool s1 = lhs.lc_flags_ == 1;
|
||||
bool s2 = rhs.lc_flags_ == 1;
|
||||
|
||||
if( s1 < s2 ) return true;
|
||||
if( s2 < s1 ) return false;
|
||||
|
||||
if( s1 && s2 )
|
||||
{
|
||||
std::error_code const& e1 = *reinterpret_cast<std::error_code const*>( lhs.d2_ );
|
||||
std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( rhs.d2_ );
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
// See library home page at http://www.boost.org/libs/system
|
||||
|
||||
#include <boost/system/detail/error_category.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <system_error>
|
||||
|
||||
//
|
||||
@@ -24,6 +25,8 @@ namespace system
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<unsigned Id> struct id_wrapper {};
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE std_category: public std::error_category
|
||||
{
|
||||
private:
|
||||
@@ -39,20 +42,22 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
explicit std_category( boost::system::error_category const * pc, unsigned id ): pc_( pc )
|
||||
template<unsigned Id>
|
||||
explicit std_category( boost::system::error_category const * pc, id_wrapper<Id> ): pc_( pc )
|
||||
{
|
||||
if( id != 0 )
|
||||
{
|
||||
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
|
||||
|
||||
// Poking into the protected _Addr member of std::error_category
|
||||
// is not a particularly good programming practice, but what can
|
||||
// you do
|
||||
// We used to assign to the protected _Addr member of std::error_category
|
||||
// here when Id != 0, but this should never happen now because this code
|
||||
// path is no longer used
|
||||
|
||||
_Addr = id;
|
||||
#if !defined(BOOST_NO_CXX11_STATIC_ASSERT)
|
||||
|
||||
static_assert( Id == 0, "This constructor should only be called with Id == 0 under MS STL 14.0+" );
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
const char * name() const BOOST_NOEXCEPT BOOST_OVERRIDE
|
||||
|
||||
@@ -59,6 +59,7 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
|
||||
case ERROR_ACCESS_DENIED_: return permission_denied;
|
||||
case ERROR_ALREADY_EXISTS_: return file_exists;
|
||||
case ERROR_BAD_NETPATH_: return no_such_file_or_directory;
|
||||
case ERROR_BAD_NET_NAME_: return no_such_file_or_directory;
|
||||
case ERROR_BAD_UNIT_: return no_such_device;
|
||||
case ERROR_BROKEN_PIPE_: return broken_pipe;
|
||||
case ERROR_BUFFER_OVERFLOW_: return filename_too_long;
|
||||
@@ -75,6 +76,7 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
|
||||
case ERROR_DIR_NOT_EMPTY_: return directory_not_empty;
|
||||
case ERROR_DIRECTORY_: return invalid_argument; // WinError.h: "The directory name is invalid"
|
||||
case ERROR_DISK_FULL_: return no_space_on_device;
|
||||
case ERROR_FILENAME_EXCED_RANGE_: return filename_too_long;
|
||||
case ERROR_FILE_EXISTS_: return file_exists;
|
||||
case ERROR_FILE_NOT_FOUND_: return no_such_file_or_directory;
|
||||
case ERROR_HANDLE_DISK_FULL_: return no_space_on_device;
|
||||
@@ -100,12 +102,16 @@ inline int system_category_condition_win32( int ev ) BOOST_NOEXCEPT
|
||||
case ERROR_REPARSE_TAG_INVALID_: return invalid_argument;
|
||||
case ERROR_RETRY_: return resource_unavailable_try_again;
|
||||
case ERROR_SEEK_: return io_error;
|
||||
case ERROR_SEM_TIMEOUT_: return timed_out;
|
||||
case ERROR_SHARING_VIOLATION_: return permission_denied;
|
||||
case ERROR_NOT_SUPPORTED_: return not_supported; // WinError.h: "The request is not supported."
|
||||
case ERROR_TIMEOUT_: return timed_out;
|
||||
case ERROR_TOO_MANY_OPEN_FILES_: return too_many_files_open;
|
||||
case ERROR_WRITE_FAULT_: return io_error;
|
||||
case ERROR_WRITE_PROTECT_: return permission_denied;
|
||||
|
||||
case 258: return timed_out; // WAIT_TIMEOUT
|
||||
|
||||
case WSAEACCES_: return permission_denied;
|
||||
case WSAEADDRINUSE_: return address_in_use;
|
||||
case WSAEADDRNOTAVAIL_: return address_not_available;
|
||||
|
||||
@@ -130,6 +130,10 @@ boost_test(TYPE compile SOURCES constexpr_test2.cpp)
|
||||
boost_test(TYPE run SOURCES error_code_test3.cpp)
|
||||
boost_test(TYPE run SOURCES std_interop_test15.cpp)
|
||||
|
||||
boost_test(TYPE run SOURCES win32_generic_test.cpp)
|
||||
|
||||
boost_test(TYPE run SOURCES ec_hash_value_test.cpp)
|
||||
|
||||
# result
|
||||
|
||||
set(BOOST_TEST_COMPILE_FEATURES cxx_std_11)
|
||||
|
||||
@@ -158,6 +158,10 @@ compile constexpr_test2.cpp ;
|
||||
run error_code_test3.cpp ;
|
||||
run std_interop_test15.cpp ;
|
||||
|
||||
run win32_generic_test.cpp ;
|
||||
|
||||
run ec_hash_value_test.cpp ;
|
||||
|
||||
# result
|
||||
|
||||
import ../../config/checks/config : requires ;
|
||||
|
||||
132
test/ec_hash_value_test.cpp
Normal file
132
test/ec_hash_value_test.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
// Copyright 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/system/generic_category.hpp>
|
||||
#include <boost/system/system_category.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <cerrno>
|
||||
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
#include <system_error>
|
||||
#endif
|
||||
|
||||
namespace sys = boost::system;
|
||||
|
||||
int main()
|
||||
{
|
||||
// normal against normal (equal, system)
|
||||
{
|
||||
sys::error_code e2( 0, sys::system_category() );
|
||||
sys::error_code e3( e2.value(), e2.category() );
|
||||
|
||||
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
|
||||
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
|
||||
}
|
||||
|
||||
// normal against normal (equal, generic)
|
||||
{
|
||||
sys::error_code e2( EINVAL, sys::generic_category() );
|
||||
sys::error_code e3( e2.value(), e2.category() );
|
||||
|
||||
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
|
||||
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
|
||||
}
|
||||
|
||||
// normal against normal (inequal, value, generic)
|
||||
{
|
||||
sys::error_code e2( 0, sys::generic_category() );
|
||||
sys::error_code e3( EINVAL, sys::generic_category() );
|
||||
|
||||
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
|
||||
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
|
||||
}
|
||||
|
||||
// normal against normal (inequal, value, system)
|
||||
{
|
||||
sys::error_code e2( 1, sys::system_category() );
|
||||
sys::error_code e3( 2, sys::system_category() );
|
||||
|
||||
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
|
||||
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
|
||||
}
|
||||
|
||||
// normal against normal (inequal, category)
|
||||
{
|
||||
sys::error_code e2( 0, sys::system_category() );
|
||||
sys::error_code e3( 0, sys::generic_category() );
|
||||
|
||||
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
|
||||
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
|
||||
}
|
||||
|
||||
// empty against normal
|
||||
{
|
||||
sys::error_code e2;
|
||||
sys::error_code e3( e2.value(), e2.category() );
|
||||
|
||||
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
|
||||
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
|
||||
}
|
||||
|
||||
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
|
||||
// std:: wrapping against normal
|
||||
{
|
||||
std::error_code e1( EINVAL, std::generic_category() );
|
||||
|
||||
sys::error_code e2( e1 );
|
||||
sys::error_code e3( e2.value(), e2.category() );
|
||||
|
||||
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
|
||||
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
|
||||
}
|
||||
|
||||
// empty against wrapping std:: empty
|
||||
{
|
||||
std::error_code e1;
|
||||
|
||||
sys::error_code e2( e1 );
|
||||
sys::error_code e3;
|
||||
|
||||
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
|
||||
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
|
||||
}
|
||||
|
||||
// empty against roundtrip via std
|
||||
{
|
||||
sys::error_code e2;
|
||||
|
||||
std::error_code e1( e2 );
|
||||
sys::error_code e3( e1 );
|
||||
|
||||
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
|
||||
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
|
||||
}
|
||||
|
||||
// normal/generic against roundtrip via std
|
||||
{
|
||||
sys::error_code e2( EINVAL, boost::system::generic_category() );
|
||||
|
||||
std::error_code e1( e2 );
|
||||
sys::error_code e3( e1 );
|
||||
|
||||
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
|
||||
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
|
||||
}
|
||||
|
||||
// normal/system against roundtrip via std
|
||||
{
|
||||
sys::error_code e2( 0, boost::system::system_category() );
|
||||
|
||||
std::error_code e1( e2 );
|
||||
sys::error_code e3( e1 );
|
||||
|
||||
BOOST_TEST( e2 != e3 || hash_value( e2 ) == hash_value( e3 ) );
|
||||
BOOST_TEST( e2 == e3 || hash_value( e2 ) != hash_value( e3 ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
52
test/win32_generic_test.cpp
Normal file
52
test/win32_generic_test.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if !defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Skipping test, BOOST_SYSTEM_HAS_SYSTEM_ERROR is not defined" )
|
||||
int main() {}
|
||||
|
||||
#elif !defined(BOOST_MSSTL_VERSION) || BOOST_MSSTL_VERSION < 140
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Skipping test, BOOST_MSSTL_VERSION is not defined or is less than 140" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <system_error>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
namespace sys = boost::system;
|
||||
|
||||
int n = 0;
|
||||
|
||||
for( int i = 0; i < 65000; ++i )
|
||||
{
|
||||
sys::error_code ec1( i, sys::system_category() );
|
||||
sys::error_condition en1 = ec1.default_error_condition();
|
||||
|
||||
std::error_code ec2( i, std::system_category() );
|
||||
std::error_condition en2 = ec2.default_error_condition();
|
||||
|
||||
if( en1 != en2 )
|
||||
{
|
||||
std::cout << i << ": " << en1 << " (" << en1.message() << ") != cond:" << en2.category().name() << ":" << en2.value() << " (" << en2.message() << ")\n";
|
||||
|
||||
if( en2.category() == std::generic_category() && i != 123 ) // msvc-14.0, msvc-14.1 disagree with us on ERROR_INVALID_NAME
|
||||
{
|
||||
++n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n < 256 ? n: 255;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user