forked from boostorg/system
Improve the implementation of the std::category conversion
This commit is contained in:
@ -13,20 +13,10 @@
|
||||
|
||||
// BOOST_SYSTEM_HAS_SYSTEM_ERROR
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
|
||||
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) && !defined(BOOST_NO_CXX11_HDR_ATOMIC)
|
||||
# define BOOST_SYSTEM_HAS_SYSTEM_ERROR
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_GCC, < 40600)
|
||||
// g++ 4.4's <map> is not good enough
|
||||
# undef BOOST_SYSTEM_HAS_SYSTEM_ERROR
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_CXX11_HDR_MUTEX)
|
||||
// Required for thread-safe map manipulation
|
||||
# undef BOOST_SYSTEM_HAS_SYSTEM_ERROR
|
||||
#endif
|
||||
|
||||
// BOOST_SYSTEM_NOEXCEPT
|
||||
// Retained for backward compatibility
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
# include <system_error>
|
||||
# include <atomic>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
@ -38,11 +39,7 @@ namespace detail
|
||||
|
||||
BOOST_SYSTEM_CONSTEXPR bool failed_impl( int ev, error_category const & cat );
|
||||
|
||||
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
|
||||
std::error_category const & to_std_category( error_category const & cat );
|
||||
|
||||
#endif
|
||||
class std_category;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@ -58,10 +55,6 @@ private:
|
||||
friend std::size_t hash_value( error_code const & ec );
|
||||
friend BOOST_SYSTEM_CONSTEXPR bool detail::failed_impl( int ev, error_category const & cat );
|
||||
|
||||
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
friend std::error_category const & detail::to_std_category( error_category const & cat );
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
|
||||
public:
|
||||
|
||||
@ -80,6 +73,16 @@ private:
|
||||
|
||||
boost::ulong_long_type id_;
|
||||
|
||||
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
|
||||
mutable std::atomic< boost::system::detail::std_category* > ps_;
|
||||
|
||||
#else
|
||||
|
||||
boost::system::detail::std_category* ps_;
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
|
||||
@ -97,11 +100,11 @@ protected:
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: id_( 0 )
|
||||
BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: id_( 0 ), ps_()
|
||||
{
|
||||
}
|
||||
|
||||
explicit BOOST_SYSTEM_CONSTEXPR error_category( boost::ulong_long_type id ) BOOST_NOEXCEPT: id_( id )
|
||||
explicit BOOST_SYSTEM_CONSTEXPR error_category( boost::ulong_long_type id ) BOOST_NOEXCEPT: id_( id ), ps_()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -96,11 +96,40 @@ inline char const * error_category::message( int ev, char * buffer, std::size_t
|
||||
|
||||
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
|
||||
#include <boost/system/detail/to_std_category.hpp>
|
||||
#include <boost/system/detail/std_category.hpp>
|
||||
|
||||
inline boost::system::error_category::operator std::error_category const & () const
|
||||
{
|
||||
return boost::system::detail::to_std_category( *this );
|
||||
if( id_ == boost::system::detail::system_category_id )
|
||||
{
|
||||
static const boost::system::detail::std_category system_instance( this, 0x1F4D7 );
|
||||
return system_instance;
|
||||
}
|
||||
|
||||
if( id_ == boost::system::detail::generic_category_id )
|
||||
{
|
||||
static const boost::system::detail::std_category generic_instance( this, 0x1F4D3 );
|
||||
return generic_instance;
|
||||
}
|
||||
|
||||
boost::system::detail::std_category* p = ps_.load( std::memory_order_acquire );
|
||||
|
||||
if( p != 0 )
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
|
||||
boost::system::detail::std_category* q = new detail::std_category( this, 0 );
|
||||
|
||||
if( ps_.compare_exchange_strong( p, q, std::memory_order_release, std::memory_order_acquire ) )
|
||||
{
|
||||
return *q;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete q;
|
||||
return *p;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef BOOST_SYSTEM_DETAIL_TO_STD_CATEGORY_HPP_INCLUDED
|
||||
#define BOOST_SYSTEM_DETAIL_TO_STD_CATEGORY_HPP_INCLUDED
|
||||
#ifndef BOOST_SYSTEM_DETAIL_STD_CATEGORY_HPP_INCLUDED
|
||||
#define BOOST_SYSTEM_DETAIL_STD_CATEGORY_HPP_INCLUDED
|
||||
|
||||
// Support for interoperability between Boost.System and <system_error>
|
||||
//
|
||||
// Copyright 2018 Peter Dimov
|
||||
// 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)
|
||||
@ -15,9 +15,6 @@
|
||||
#include <boost/system/detail/error_code.hpp>
|
||||
#include <boost/system/detail/generic_category.hpp>
|
||||
#include <system_error>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
//
|
||||
|
||||
@ -73,54 +70,6 @@ public:
|
||||
bool equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT BOOST_OVERRIDE;
|
||||
};
|
||||
|
||||
#if !defined(__SUNPRO_CC) // trailing __global is not supported
|
||||
inline std::error_category const & to_std_category( boost::system::error_category const & cat ) BOOST_SYMBOL_VISIBLE;
|
||||
#endif
|
||||
|
||||
struct cat_ptr_less
|
||||
{
|
||||
bool operator()( boost::system::error_category const * p1, boost::system::error_category const * p2 ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return *p1 < *p2;
|
||||
}
|
||||
};
|
||||
|
||||
inline std::error_category const & to_std_category( boost::system::error_category const & cat )
|
||||
{
|
||||
if( cat.id_ == boost::system::detail::system_category_id )
|
||||
{
|
||||
static const std_category system_instance( &cat, 0x1F4D7 );
|
||||
return system_instance;
|
||||
}
|
||||
else if( cat.id_ == boost::system::detail::generic_category_id )
|
||||
{
|
||||
static const std_category generic_instance( &cat, 0x1F4D3 );
|
||||
return generic_instance;
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef std::map< boost::system::error_category const *, std::unique_ptr<std_category>, cat_ptr_less > map_type;
|
||||
|
||||
static map_type map_;
|
||||
static std::mutex map_mx_;
|
||||
|
||||
std::lock_guard<std::mutex> guard( map_mx_ );
|
||||
|
||||
map_type::iterator i = map_.find( &cat );
|
||||
|
||||
if( i == map_.end() )
|
||||
{
|
||||
std::unique_ptr<std_category> p( new std_category( &cat, 0 ) );
|
||||
|
||||
std::pair<map_type::iterator, bool> r = map_.insert( map_type::value_type( &cat, std::move( p ) ) );
|
||||
|
||||
i = r.first;
|
||||
}
|
||||
|
||||
return *i->second;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool std_category::equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT
|
||||
{
|
||||
if( condition.category() == *this )
|
||||
@ -170,6 +119,7 @@ inline bool std_category::equivalent( const std::error_code & code, int conditio
|
||||
boost::system::error_code bc( code.value(), *pc2->pc_ );
|
||||
return pc_->equivalent( bc, condition );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
else if( *pc_ == boost::system::generic_category() )
|
||||
@ -188,4 +138,4 @@ inline bool std_category::equivalent( const std::error_code & code, int conditio
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SYSTEM_DETAIL_TO_STD_CATEGORY_HPP_INCLUDED
|
||||
#endif // #ifndef BOOST_SYSTEM_DETAIL_STD_CATEGORY_HPP_INCLUDED
|
Reference in New Issue
Block a user