Add failed()

This commit is contained in:
Peter Dimov
2018-09-22 17:34:40 +03:00
parent 349fb30e8e
commit f48cc5aec6
3 changed files with 267 additions and 35 deletions

View File

@@ -224,6 +224,8 @@ public:
virtual std::string message( int ev ) const = 0; virtual std::string message( int ev ) const = 0;
virtual char const * message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT; virtual char const * message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT;
virtual bool failed( int ev ) const BOOST_NOEXCEPT;
BOOST_SYSTEM_CONSTEXPR bool operator==( const error_category & rhs ) const BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR bool operator==( const error_category & rhs ) const BOOST_NOEXCEPT
{ {
return rhs.id_ == 0? this == &rhs: id_ == rhs.id_; return rhs.id_ == 0? this == &rhs: id_ == rhs.id_;
@@ -381,6 +383,31 @@ template<class T> struct enable_if<false, T>
{ {
}; };
// failed_impl
#if defined(BOOST_SYSTEM_HAS_CONSTEXPR)
BOOST_SYSTEM_CONSTEXPR inline bool failed_impl( int ev, error_category const & cat )
{
if( cat == system_category() || cat == generic_category() )
{
return ev != 0;
}
else
{
return cat.failed( ev );
}
}
#else
inline bool failed_impl( int ev, error_category const & cat )
{
return cat.failed( ev );
}
#endif
} // namespace detail } // namespace detail
// class error_condition // class error_condition
@@ -391,18 +418,21 @@ class error_condition
{ {
private: private:
int m_val; int val_;
error_category const * m_cat; bool failed_;
error_category const * cat_;
public: public:
// constructors: // constructors:
BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_NOEXCEPT: m_val( 0 ), m_cat( &generic_category() ) BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_NOEXCEPT:
val_( 0 ), failed_( false ), cat_( &generic_category() )
{ {
} }
BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) BOOST_NOEXCEPT: m_val( val ), m_cat( &cat ) BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) BOOST_NOEXCEPT:
val_( val ), failed_( detail::failed_impl( val, cat ) ), cat_( &cat )
{ {
} }
@@ -416,8 +446,9 @@ public:
BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT
{ {
m_val = val; val_ = val;
m_cat = &cat; failed_ = detail::failed_impl( val, cat );
cat_ = &cat;
} }
template<typename ErrorConditionEnum> template<typename ErrorConditionEnum>
@@ -430,37 +461,43 @@ public:
BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT
{ {
m_val = 0; val_ = 0;
m_cat = &generic_category(); failed_ = false;
cat_ = &generic_category();
} }
// observers: // observers:
BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT
{ {
return m_val; return val_;
} }
BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT
{ {
return *m_cat; return *cat_;
} }
std::string message() const std::string message() const
{ {
return m_cat->message( value() ); return cat_->message( value() );
} }
char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT
{ {
return m_cat->message( value(), buffer, len ); return cat_->message( value(), buffer, len );
}
BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT
{
return failed_;
} }
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error
{ {
return m_val != 0; return failed_;
} }
#else #else
@@ -470,12 +507,12 @@ public:
BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error
{ {
return m_val == 0? 0 : unspecified_bool_true; return failed_? unspecified_bool_true: 0;
} }
BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error
{ {
return m_val == 0; return !failed_;
} }
#endif #endif
@@ -486,12 +523,12 @@ public:
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
{ {
return lhs.m_val == rhs.m_val && *lhs.m_cat == *rhs.m_cat; return lhs.val_ == rhs.val_ && *lhs.cat_ == *rhs.cat_;
} }
BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
{ {
return *lhs.m_cat < *rhs.m_cat || ( *lhs.m_cat == *rhs.m_cat && lhs.m_val < rhs.m_val ); return *lhs.cat_ < *rhs.cat_ || ( *lhs.cat_ == *rhs.cat_ && lhs.val_ < rhs.val_ );
} }
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
@@ -517,18 +554,21 @@ class error_code
{ {
private: private:
int m_val; int val_;
const error_category * m_cat; bool failed_;
const error_category * cat_;
public: public:
// constructors: // constructors:
BOOST_SYSTEM_CONSTEXPR error_code() BOOST_NOEXCEPT: m_val( 0 ), m_cat( &system_category() ) BOOST_SYSTEM_CONSTEXPR error_code() BOOST_NOEXCEPT:
val_( 0 ), failed_( false ), cat_( &system_category() )
{ {
} }
BOOST_SYSTEM_CONSTEXPR error_code( int val, const error_category & cat ) BOOST_NOEXCEPT: m_val( val ), m_cat( &cat ) BOOST_SYSTEM_CONSTEXPR error_code( int val, const error_category & cat ) BOOST_NOEXCEPT:
val_( val ), failed_( detail::failed_impl( val, cat ) ), cat_( &cat )
{ {
} }
@@ -542,8 +582,9 @@ public:
BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT
{ {
m_val = val; val_ = val;
m_cat = &cat; failed_ = detail::failed_impl( val, cat );
cat_ = &cat;
} }
template<typename ErrorCodeEnum> template<typename ErrorCodeEnum>
@@ -556,42 +597,48 @@ public:
BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT
{ {
m_val = 0; val_ = 0;
m_cat = &system_category(); failed_ = false;
cat_ = &system_category();
} }
// observers: // observers:
BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT
{ {
return m_val; return val_;
} }
BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT
{ {
return *m_cat; return *cat_;
} }
error_condition default_error_condition() const BOOST_NOEXCEPT error_condition default_error_condition() const BOOST_NOEXCEPT
{ {
return m_cat->default_error_condition( value() ); return cat_->default_error_condition( value() );
} }
std::string message() const std::string message() const
{ {
return m_cat->message( value() ); return cat_->message( value() );
} }
char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT
{ {
return m_cat->message( value(), buffer, len ); return cat_->message( value(), buffer, len );
}
BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT
{
return failed_;
} }
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error
{ {
return m_val != 0; return failed_;
} }
#else #else
@@ -601,12 +648,12 @@ public:
BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error
{ {
return m_val == 0? 0 : unspecified_bool_true; return failed_? unspecified_bool_true: 0;
} }
BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error
{ {
return m_val == 0; return !failed_;
} }
#endif #endif
@@ -618,12 +665,12 @@ public:
BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_code & lhs, const error_code & rhs ) BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_code & lhs, const error_code & rhs ) BOOST_NOEXCEPT
{ {
return lhs.m_val == rhs.m_val && *lhs.m_cat == *rhs.m_cat; return lhs.val_ == rhs.val_ && *lhs.cat_ == *rhs.cat_;
} }
BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_code & lhs, const error_code & rhs ) BOOST_NOEXCEPT BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_code & lhs, const error_code & rhs ) BOOST_NOEXCEPT
{ {
return *lhs.m_cat < *rhs.m_cat || ( *lhs.m_cat == *rhs.m_cat && lhs.m_val < rhs.m_val ); return *lhs.cat_ < *rhs.cat_ || ( *lhs.cat_ == *rhs.cat_ && lhs.val_ < rhs.val_ );
} }
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
@@ -819,6 +866,11 @@ inline char const * error_category::message( int ev, char * buffer, std::size_t
#endif #endif
} }
inline bool error_category::failed( int ev ) const BOOST_NOEXCEPT
{
return ev != 0;
}
} // namespace system } // namespace system
} // namespace boost } // namespace boost

View File

@@ -127,6 +127,7 @@ system-run error_category_test.cpp ;
system-run generic_category_test.cpp ; system-run generic_category_test.cpp ;
system-run system_category_test.cpp ; system-run system_category_test.cpp ;
system-run after_main_test.cpp ; system-run after_main_test.cpp ;
system-run failed_test.cpp ;
# Quick (CI) test # Quick (CI) test
run quick.cpp ; run quick.cpp ;

179
test/failed_test.cpp Normal file
View File

@@ -0,0 +1,179 @@
// Copyright 2018 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// Avoid spurious VC++ warnings
#define _CRT_SECURE_NO_WARNINGS
#include <boost/system/error_code.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cstdio>
using namespace boost::system;
struct http_category_impl: public error_category
{
char const * name() const BOOST_NOEXCEPT
{
return "http";
}
std::string message( int ev ) const
{
char buffer[ 32 ];
std::sprintf( buffer, "HTTP/1.0 %d", ev );
return buffer;
}
bool failed( int ev ) const BOOST_NOEXCEPT
{
return !( ev >= 200 && ev < 300 );
}
};
error_category const & http_category()
{
static const http_category_impl instance;
return instance;
}
#define TEST_NOT_FAILED(ec) BOOST_TEST( !ec.failed() ); BOOST_TEST( ec? false: true ); BOOST_TEST( !ec );
#define TEST_FAILED(ec) BOOST_TEST( ec.failed() ); BOOST_TEST( ec ); BOOST_TEST( !!ec );
template<class Ec> void test()
{
{
Ec ec;
TEST_NOT_FAILED( ec );
ec.assign( 1, generic_category() );
TEST_FAILED( ec );
ec.clear();
TEST_NOT_FAILED( ec );
ec = Ec( 1, generic_category() );
TEST_FAILED( ec );
ec = Ec();
TEST_NOT_FAILED( ec );
}
{
Ec ec;
TEST_NOT_FAILED( ec );
ec.assign( 1, system_category() );
TEST_FAILED( ec );
ec.clear();
TEST_NOT_FAILED( ec );
ec = Ec( 1, system_category() );
TEST_FAILED( ec );
ec = Ec();
TEST_NOT_FAILED( ec );
}
{
Ec ec( 0, generic_category() );
TEST_NOT_FAILED( ec );
ec.assign( 1, system_category() );
TEST_FAILED( ec );
ec = Ec( 0, system_category() );
TEST_NOT_FAILED( ec );
}
{
Ec ec( 1, generic_category() );
TEST_FAILED( ec );
ec.assign( 0, system_category() );
TEST_NOT_FAILED( ec );
}
{
Ec ec( 0, system_category() );
TEST_NOT_FAILED( ec );
ec.assign( 1, generic_category() );
TEST_FAILED( ec );
ec = Ec( 0, generic_category() );
TEST_NOT_FAILED( ec );
}
{
Ec ec( 1, system_category() );
TEST_FAILED( ec );
ec.assign( 0, generic_category() );
TEST_NOT_FAILED( ec );
}
{
Ec ec( 0, http_category() );
TEST_FAILED( ec );
ec.assign( 200, http_category() );
TEST_NOT_FAILED( ec );
ec = Ec( 404, http_category() );
TEST_FAILED( ec );
}
}
int main()
{
BOOST_TEST( !generic_category().failed( 0 ) );
BOOST_TEST( generic_category().failed( 7 ) );
BOOST_TEST( !system_category().failed( 0 ) );
BOOST_TEST( system_category().failed( 7 ) );
BOOST_TEST( http_category().failed( 0 ) );
BOOST_TEST( !http_category().failed( 200 ) );
BOOST_TEST( http_category().failed( 404 ) );
test<error_code>();
test<error_condition>();
{
error_condition ec( errc::success );
TEST_NOT_FAILED( ec );
ec = errc::address_family_not_supported;
TEST_FAILED( ec );
}
{
error_condition ec( errc::address_family_not_supported );
TEST_FAILED( ec );
ec = errc::success;
TEST_NOT_FAILED( ec );
}
{
error_code ec( make_error_code( errc::success ) );
TEST_NOT_FAILED( ec );
ec = make_error_code( errc::address_family_not_supported );
TEST_FAILED( ec );
}
{
error_code ec( make_error_code( errc::address_family_not_supported ) );
TEST_FAILED( ec );
ec = make_error_code( errc::success );
TEST_NOT_FAILED( ec );
}
return boost::report_errors();
}