diff --git a/include/boost/system/detail/error_condition.hpp b/include/boost/system/detail/error_condition.hpp index 6b38376..bbf6280 100644 --- a/include/boost/system/detail/error_condition.hpp +++ b/include/boost/system/detail/error_condition.hpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -27,6 +29,17 @@ namespace system // error_conditions are portable, error_codes are system or library specific +namespace detail +{ + +struct generic_value_tag +{ + int value; + BOOST_SYSTEM_CONSTEXPR explicit generic_value_tag( int v ): value( v ) {} +}; + +} // namespace detail + class error_condition { private: @@ -39,7 +52,7 @@ public: // constructors: BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_NOEXCEPT: - val_( 0 ), cat_( &generic_category() ) + val_( 0 ), cat_( 0 ) { } @@ -48,12 +61,25 @@ public: { } + BOOST_SYSTEM_CONSTEXPR explicit error_condition( boost::system::detail::generic_value_tag vt ) BOOST_NOEXCEPT: + val_( vt.value ), cat_( 0 ) + { + } + template BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e, - typename detail::enable_if::value>::type* = 0) BOOST_NOEXCEPT + typename detail::enable_if< + is_error_condition_enum::value && !boost::system::detail::is_same::value + >::type* = 0) BOOST_NOEXCEPT { *this = make_error_condition( e ); } + template BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e, + typename detail::enable_if::value>::type* = 0) BOOST_NOEXCEPT: + val_( e ), cat_( 0 ) + { + } + // modifiers: BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT @@ -66,14 +92,14 @@ public: BOOST_SYSTEM_CONSTEXPR typename detail::enable_if::value, error_condition>::type & operator=( ErrorConditionEnum val ) BOOST_NOEXCEPT { - *this = make_error_condition( val ); + *this = error_condition( val ); return *this; } BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT { val_ = 0; - cat_ = &generic_category(); + cat_ = 0; } // observers: @@ -85,29 +111,50 @@ public: BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT { - return *cat_; + return cat_? *cat_: generic_category(); } std::string message() const { - return cat_->message( value() ); + if( cat_ ) + { + return cat_->message( value() ); + } + else + { + return generic_category().message( value() ); + } } - BOOST_SYSTEM_DEPRECATED("this function is slated for removal") 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 cat_->message( value(), buffer, len ); + if( cat_ ) + { + return cat_->message( value(), buffer, len ); + } + else + { + return generic_category().message( value(), buffer, len ); + } } - BOOST_SYSTEM_DEPRECATED("this function is slated for removal") BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT { - return detail::failed_impl( val_, *cat_ ); + if( cat_ ) + { + return detail::failed_impl( val_, *cat_ ); + } + else + { + return val_ != 0; + } } #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error { - return val_ != 0; + return failed(); } #else @@ -117,12 +164,12 @@ public: BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error { - return val_ != 0? unspecified_bool_true: 0; + return failed()? unspecified_bool_true: 0; } BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error { - return val_ == 0; + return !failed(); } #endif @@ -133,12 +180,19 @@ public: BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT { - return lhs.val_ == rhs.val_ && *lhs.cat_ == *rhs.cat_; + return lhs.val_ == rhs.val_ && lhs.category() == rhs.category(); } BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT { - return *lhs.cat_ < *rhs.cat_ || ( *lhs.cat_ == *rhs.cat_ && lhs.val_ < rhs.val_ ); + error_category const& lcat = lhs.category(); + error_category const& rcat = rhs.category(); + return lcat < rcat || ( lcat == rcat && lhs.val_ < rhs.val_ ); + } + + BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT + { + return !( lhs == rhs ); } #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) @@ -151,11 +205,6 @@ public: #endif }; -BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT -{ - return !( lhs == rhs ); -} - } // namespace system } // namespace boost diff --git a/include/boost/system/detail/is_same.hpp b/include/boost/system/detail/is_same.hpp new file mode 100644 index 0000000..dc466f8 --- /dev/null +++ b/include/boost/system/detail/is_same.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_SYSTEM_DETAIL_IS_SAME_HPP_INCLUDED +#define BOOST_SYSTEM_DETAIL_IS_SAME_HPP_INCLUDED + +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0 +// http://www.boost.org/LICENSE_1_0.txt + +namespace boost +{ + +namespace system +{ + +namespace detail +{ + +template struct is_same +{ + enum _vt { value = 0 }; +}; + +template struct is_same +{ + enum _vt { value = 1 }; +}; + +} // namespace detail + +} // namespace system + +} // namespace boost + +#endif // #ifndef BOOST_SYSTEM_DETAIL_IS_SAME_HPP_INCLUDED