summaryrefslogtreecommitdiff
path: root/boost/system/error_code.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/system/error_code.hpp')
-rw-r--r--boost/system/error_code.hpp293
1 files changed, 247 insertions, 46 deletions
diff --git a/boost/system/error_code.hpp b/boost/system/error_code.hpp
index b6ff6e4bad..0d64b2b72e 100644
--- a/boost/system/error_code.hpp
+++ b/boost/system/error_code.hpp
@@ -1,4 +1,4 @@
-// boost/system/error_code.hpp ---------------------------------------------//
+// boost/system/error_code.hpp -------------------------------------------------------//
// Copyright Beman Dawes 2006, 2007
// Copyright Christoper Kohlhoff 2007
@@ -28,6 +28,10 @@
# error BOOST_POSIX_API or BOOST_WINDOWS_API must be defined
#endif
+#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR
+#include <system_error>
+#endif
+
#include <boost/config/abi_prefix.hpp> // must be the last #include
#ifndef BOOST_SYSTEM_NOEXCEPT
@@ -43,7 +47,7 @@ namespace boost
class error_condition; // portable generic values defined below, but ultimately
// based on the POSIX standard
- // "Concept" helpers ---------------------------------------------------//
+ // "Concept" helpers -------------------------------------------------------------//
template< class T >
struct is_error_code_enum { static const bool value = false; };
@@ -51,7 +55,7 @@ namespace boost
template< class T >
struct is_error_condition_enum { static const bool value = false; };
- // generic error_conditions --------------------------------------------//
+ // generic error_conditions ------------------------------------------------------//
namespace errc
{
@@ -149,9 +153,9 @@ namespace boost
{ static const bool value = true; };
- // ----------------------------------------------------------------------//
+ // --------------------------------------------------------------------------------//
- // Operating system specific interfaces --------------------------------//
+ // Operating system specific interfaces ------------------------------------------//
// The interface is divided into general and system-specific portions to
@@ -179,52 +183,152 @@ namespace boost
// These headers are effectively empty for compiles on operating systems
// where they are not applicable.
- // ----------------------------------------------------------------------//
+ // --------------------------------------------------------------------------------//
+
+ class error_category;
+
+ // predefined error categories ---------------------------------------------------//
+
+#ifdef BOOST_ERROR_CODE_HEADER_ONLY
+ inline const error_category & system_category() BOOST_SYSTEM_NOEXCEPT;
+ inline const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT;
+#else
+ BOOST_SYSTEM_DECL const error_category & system_category() BOOST_SYSTEM_NOEXCEPT;
+ BOOST_SYSTEM_DECL const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT;
+#endif
+ // deprecated synonyms ------------------------------------------------------------//
+
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+ inline const error_category & get_system_category() { return system_category(); }
+ inline const error_category & get_generic_category() { return generic_category(); }
+ inline const error_category & get_posix_category() { return generic_category(); }
+ static const error_category & posix_category BOOST_ATTRIBUTE_UNUSED
+ = generic_category();
+ static const error_category & errno_ecat BOOST_ATTRIBUTE_UNUSED
+ = generic_category();
+ static const error_category & native_ecat BOOST_ATTRIBUTE_UNUSED
+ = system_category();
+#endif
// class error_category ------------------------------------------------//
class error_category : public noncopyable
{
+#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR
+
+ private:
+
+ class std_category: public std::error_category
+ {
+ private:
+
+ boost::system::error_category const * pc_;
+
+ public:
+
+ explicit std_category( boost::system::error_category const * pc ): pc_( pc )
+ {
+ }
+
+ virtual const char * name() const BOOST_NOEXCEPT
+ {
+ return pc_->name();
+ }
+
+ virtual std::string message( int ev ) const
+ {
+ return pc_->message( ev );
+ }
+
+ virtual std::error_condition default_error_condition( int ev ) const
+ BOOST_NOEXCEPT;
+ virtual bool equivalent( int code, const std::error_condition & condition ) const
+ BOOST_NOEXCEPT;
+ virtual bool equivalent( const std::error_code & code, int condition ) const
+ BOOST_NOEXCEPT;
+ };
+
+ std_category std_cat_;
+
+ public:
+
+ error_category() BOOST_SYSTEM_NOEXCEPT: std_cat_( this ) {}
+
+ operator std::error_category const & () const BOOST_SYSTEM_NOEXCEPT
+ {
+ // do not map generic to std::generic on purpose; occasionally,
+ // there are two std::generic categories in a program, which leads
+ // to error codes/conditions mysteriously not being equal to themselves
+ return std_cat_;
+ }
+
+#else
+
+ // to maintain ABI compatibility between 03 and 11,
+ // define a class with the same layout
+
+ private:
+
+ class std_category
+ {
+ private:
+
+ boost::system::error_category const * pc_;
+
+ public:
+
+ explicit std_category( boost::system::error_category const * pc ): pc_( pc )
+ {
+ }
+
+ virtual ~std_category() {}
+
+ virtual const char * name() const BOOST_NOEXCEPT
+ {
+ return pc_->name();
+ }
+
+ // we can't define message, because (1) it returns an std::string,
+ // which can be different between 03 and 11, and (2) on mingw, there
+ // are actually two `message` functions, not one, so it doesn't work
+ // even if we do
+
+ // neither can we define default_error_condition or equivalent
+
+ // if these functions are called, it will crash, but that's still
+ // better than the alternative of having the class layout change
+ };
+
+ std_category std_cat_;
+
+ public:
+
+ error_category() BOOST_SYSTEM_NOEXCEPT: std_cat_( this ) {}
+
+#endif
+
public:
virtual ~error_category(){}
virtual const char * name() const BOOST_SYSTEM_NOEXCEPT = 0;
virtual std::string message( int ev ) const = 0;
- inline virtual error_condition default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT;
+ inline virtual error_condition default_error_condition( int ev ) const
+ BOOST_SYSTEM_NOEXCEPT;
inline virtual bool equivalent( int code,
- const error_condition & condition ) const BOOST_SYSTEM_NOEXCEPT;
+ const error_condition & condition ) const
+ BOOST_SYSTEM_NOEXCEPT;
inline virtual bool equivalent( const error_code & code,
int condition ) const BOOST_SYSTEM_NOEXCEPT;
- bool operator==(const error_category & rhs) const BOOST_SYSTEM_NOEXCEPT { return this == &rhs; }
- bool operator!=(const error_category & rhs) const BOOST_SYSTEM_NOEXCEPT { return this != &rhs; }
+ bool operator==(const error_category & rhs) const BOOST_SYSTEM_NOEXCEPT
+ { return this == &rhs; }
+ bool operator!=(const error_category & rhs) const BOOST_SYSTEM_NOEXCEPT
+ { return this != &rhs; }
bool operator<( const error_category & rhs ) const BOOST_SYSTEM_NOEXCEPT
- {
- return std::less<const error_category*>()( this, &rhs );
- }
+ { return std::less<const error_category*>()( this, &rhs ); }
};
- // predefined error categories -----------------------------------------//
-
-# ifdef BOOST_ERROR_CODE_HEADER_ONLY
- inline const error_category & system_category() BOOST_SYSTEM_NOEXCEPT;
- inline const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT;
-#else
- BOOST_SYSTEM_DECL const error_category & system_category() BOOST_SYSTEM_NOEXCEPT;
- BOOST_SYSTEM_DECL const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT;
-#endif
- // deprecated synonyms --------------------------------------------------//
-
-# ifndef BOOST_SYSTEM_NO_DEPRECATED
- inline const error_category & get_system_category() { return system_category(); }
- inline const error_category & get_generic_category() { return generic_category(); }
- inline const error_category & get_posix_category() { return generic_category(); }
- static const error_category & posix_category BOOST_ATTRIBUTE_UNUSED = generic_category();
- static const error_category & errno_ecat BOOST_ATTRIBUTE_UNUSED = generic_category();
- static const error_category & native_ecat BOOST_ATTRIBUTE_UNUSED = system_category();
-# endif
-
- // class error_condition -----------------------------------------------//
+ // class error_condition ---------------------------------------------------------//
// error_conditions are portable, error_codes are system or library specific
@@ -234,11 +338,13 @@ namespace boost
// constructors:
error_condition() BOOST_SYSTEM_NOEXCEPT : m_val(0), m_cat(&generic_category()) {}
- error_condition( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT : m_val(val), m_cat(&cat) {}
+ error_condition( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT
+ : m_val(val), m_cat(&cat) {}
template <class ErrorConditionEnum>
error_condition(ErrorConditionEnum e,
- typename boost::enable_if<is_error_condition_enum<ErrorConditionEnum> >::type* = 0) BOOST_SYSTEM_NOEXCEPT
+ typename boost::enable_if<is_error_condition_enum<ErrorConditionEnum> >::type*
+ = 0) BOOST_SYSTEM_NOEXCEPT
{
*this = make_error_condition(e);
}
@@ -252,7 +358,8 @@ namespace boost
}
template<typename ErrorConditionEnum>
- typename boost::enable_if<is_error_condition_enum<ErrorConditionEnum>, error_condition>::type &
+ typename boost::enable_if<is_error_condition_enum<ErrorConditionEnum>,
+ error_condition>::type &
operator=( ErrorConditionEnum val ) BOOST_SYSTEM_NOEXCEPT
{
*this = make_error_condition(val);
@@ -301,13 +408,22 @@ namespace boost
|| (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);
}
+#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR
+
+ operator std::error_condition () const BOOST_SYSTEM_NOEXCEPT
+ {
+ return std::error_condition( value(), category() );
+ }
+
+#endif
+
private:
int m_val;
const error_category * m_cat;
};
- // class error_code ----------------------------------------------------//
+ // class error_code --------------------------------------------------------------//
// We want error_code to be a value type that can be copied without slicing
// and without requiring heap allocation, but we also want it to have
@@ -321,11 +437,13 @@ namespace boost
// constructors:
error_code() BOOST_SYSTEM_NOEXCEPT : m_val(0), m_cat(&system_category()) {}
- error_code( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT : m_val(val), m_cat(&cat) {}
+ error_code( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT
+ : m_val(val), m_cat(&cat) {}
template <class ErrorCodeEnum>
error_code(ErrorCodeEnum e,
- typename boost::enable_if<is_error_code_enum<ErrorCodeEnum> >::type* = 0) BOOST_SYSTEM_NOEXCEPT
+ typename boost::enable_if<is_error_code_enum<ErrorCodeEnum> >::type* = 0)
+ BOOST_SYSTEM_NOEXCEPT
{
*this = make_error_code(e);
}
@@ -354,7 +472,8 @@ namespace boost
// observers:
int value() const BOOST_SYSTEM_NOEXCEPT { return m_val; }
const error_category & category() const BOOST_SYSTEM_NOEXCEPT { return *m_cat; }
- error_condition default_error_condition() const BOOST_SYSTEM_NOEXCEPT { return m_cat->default_error_condition(value()); }
+ error_condition default_error_condition() const BOOST_SYSTEM_NOEXCEPT
+ { return m_cat->default_error_condition(value()); }
std::string message() const { return m_cat->message(value()); }
typedef void (*unspecified_bool_type)();
@@ -388,6 +507,15 @@ namespace boost
|| (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);
}
+#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR
+
+ operator std::error_code () const BOOST_SYSTEM_NOEXCEPT
+ {
+ return std::error_code( value(), category() );
+ }
+
+#endif
+
private:
int m_val;
const error_category * m_cat;
@@ -475,7 +603,7 @@ namespace boost
+ reinterpret_cast<std::size_t>(&ec.category());
}
- // make_* functions for errc::errc_t -----------------------------//
+ // make_* functions for errc::errc_t ---------------------------------------------//
namespace errc
{
@@ -488,9 +616,10 @@ namespace boost
{ return error_condition( e, generic_category() ); }
}
- // error_category default implementation -------------------------------//
+ // error_category default implementation -----------------------------------------//
- error_condition error_category::default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT
+ error_condition error_category::default_error_condition( int ev ) const
+ BOOST_SYSTEM_NOEXCEPT
{
return error_condition( ev, *this );
}
@@ -507,6 +636,80 @@ namespace boost
return *this == code.category() && code.value() == condition;
}
+#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR
+
+ inline std::error_condition error_category::std_category::default_error_condition(
+ int ev ) const BOOST_NOEXCEPT
+ {
+ return pc_->default_error_condition( ev );
+ }
+
+ inline bool error_category::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 error_category::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;
+ }
+ }
+
+#endif
+
} // namespace system
} // namespace boost
@@ -517,5 +720,3 @@ namespace boost
# endif
#endif // BOOST_SYSTEM_ERROR_CODE_HPP
-
-