diff --git a/include/boost/system/detail/error_condition.hpp b/include/boost/system/detail/error_condition.hpp new file mode 100644 index 0000000..5d6840f --- /dev/null +++ b/include/boost/system/detail/error_condition.hpp @@ -0,0 +1,159 @@ +#ifndef BOOST_SYSTEM_DETAIL_ERROR_CONDITION_HPP_INCLUDED +#define BOOST_SYSTEM_DETAIL_ERROR_CONDITION_HPP_INCLUDED + +// Copyright Beman Dawes 2006, 2007 +// Copyright Christoper Kohlhoff 2007 +// Copyright Peter Dimov 2017, 2018 +// +// 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) +// +// See library home page at http://www.boost.org/libs/system + +#include +#include +#include +#include + +namespace boost +{ + +namespace system +{ + +// class error_condition + +// error_conditions are portable, error_codes are system or library specific + +class error_condition +{ +private: + + int val_; + bool failed_; + error_category const * cat_; + +public: + + // constructors: + + 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: + val_( val ), failed_( detail::failed_impl( val, cat ) ), cat_( &cat ) + { + } + + template BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e, + typename detail::enable_if::value>::type* = 0) BOOST_NOEXCEPT + { + *this = make_error_condition( e ); + } + + // modifiers: + + BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT + { + val_ = val; + failed_ = detail::failed_impl( val, cat ); + cat_ = &cat; + } + + template + BOOST_SYSTEM_CONSTEXPR typename detail::enable_if::value, error_condition>::type & + operator=( ErrorConditionEnum val ) BOOST_NOEXCEPT + { + *this = make_error_condition( val ); + return *this; + } + + BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT + { + val_ = 0; + failed_ = false; + cat_ = &generic_category(); + } + + // observers: + + BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT + { + return val_; + } + + BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT + { + return *cat_; + } + + std::string message() const + { + return cat_->message( value() ); + } + + char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT + { + return cat_->message( value(), buffer, len ); + } + + BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT + { + return failed_; + } + +#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) + + BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error + { + return failed_; + } + +#else + + typedef void (*unspecified_bool_type)(); + static void unspecified_bool_true() {} + + BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error + { + return failed_? unspecified_bool_true: 0; + } + + BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error + { + return !failed_; + } + +#endif + + // relationals: + // the more symmetrical non-member syntax allows enum + // conversions work for both rhs and lhs. + + 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_; + } + + 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_ ); + } + +#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) + + operator std::error_condition () const + { + return std::error_condition( value(), category() ); + } + +#endif +}; + +} // namespace system + +} // namespace boost + +#endif // #ifndef BOOST_SYSTEM_DETAIL_ERROR_CONDITION_HPP_INCLUDED diff --git a/include/boost/system/detail/generic_category.hpp b/include/boost/system/detail/generic_category.hpp index 01f5687..bad6085 100644 --- a/include/boost/system/detail/generic_category.hpp +++ b/include/boost/system/detail/generic_category.hpp @@ -134,6 +134,55 @@ inline char const * generic_error_category::message( int ev, char * buffer, std: } // namespace detail +// generic_category() + +#if defined(BOOST_SYSTEM_HAS_CONSTEXPR) + +namespace detail +{ + +template struct BOOST_SYMBOL_VISIBLE generic_cat_holder +{ + static constexpr generic_error_category instance{}; +}; + +// Before C++17 it was mandatory to redeclare all static constexpr +#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) +template constexpr generic_error_category generic_cat_holder::instance; +#endif + +} // namespace detail + +constexpr error_category const & generic_category() BOOST_NOEXCEPT +{ + return detail::generic_cat_holder::instance; +} + +#else // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR) + +#if !defined(__SUNPRO_CC) // trailing __global is not supported +inline error_category const & generic_category() BOOST_NOEXCEPT BOOST_SYMBOL_VISIBLE; +#endif + +inline error_category const & generic_category() BOOST_NOEXCEPT +{ + static const detail::generic_error_category instance; + return instance; +} + +#endif // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR) + +// deprecated synonyms + +#ifdef BOOST_SYSTEM_ENABLE_DEPRECATED + +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(); + +#endif + } // namespace system } // namespace boost diff --git a/include/boost/system/detail/system_category.hpp b/include/boost/system/detail/system_category.hpp index 8e9d69b..633989b 100644 --- a/include/boost/system/detail/system_category.hpp +++ b/include/boost/system/detail/system_category.hpp @@ -58,6 +58,53 @@ public: } // namespace detail +// system_category() + +#if defined(BOOST_SYSTEM_HAS_CONSTEXPR) + +namespace detail +{ + +template struct BOOST_SYMBOL_VISIBLE system_cat_holder +{ + static constexpr system_error_category instance{}; +}; + +// Before C++17 it was mandatory to redeclare all static constexpr +#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) +template constexpr system_error_category system_cat_holder::instance; +#endif + +} // namespace detail + +constexpr error_category const & system_category() BOOST_NOEXCEPT +{ + return detail::system_cat_holder::instance; +} + +#else // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR) + +#if !defined(__SUNPRO_CC) // trailing __global is not supported +inline error_category const & system_category() BOOST_NOEXCEPT BOOST_SYMBOL_VISIBLE; +#endif + +inline error_category const & system_category() BOOST_NOEXCEPT +{ + static const detail::system_error_category instance; + return instance; +} + +#endif // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR) + +// deprecated synonyms + +#ifdef BOOST_SYSTEM_ENABLE_DEPRECATED + +inline const error_category & get_system_category() { return system_category(); } +static const error_category & native_ecat BOOST_ATTRIBUTE_UNUSED = system_category(); + +#endif + } // namespace system } // namespace boost diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index 7e92edc..ad4b3cd 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -44,202 +45,6 @@ class error_code; // values defined by the operating system class error_condition; // portable generic values defined below, but ultimately // based on the POSIX standard -// generic_category(), system_category() - -#if defined(BOOST_SYSTEM_HAS_CONSTEXPR) - -namespace detail -{ - -template struct BOOST_SYMBOL_VISIBLE cat_holder -{ - static constexpr system_error_category system_category_instance{}; - static constexpr generic_error_category generic_category_instance{}; -}; - -// Before C++17 it was mandatory to redeclare all static constexpr -#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) -template constexpr system_error_category cat_holder::system_category_instance; -template constexpr generic_error_category cat_holder::generic_category_instance; -#endif - -} // namespace detail - -constexpr error_category const & system_category() BOOST_NOEXCEPT -{ - return detail::cat_holder::system_category_instance; -} - -constexpr error_category const & generic_category() BOOST_NOEXCEPT -{ - return detail::cat_holder::generic_category_instance; -} - -#else // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR) - -#if !defined(__SUNPRO_CC) // trailing __global is not supported -inline error_category const & system_category() BOOST_NOEXCEPT BOOST_SYMBOL_VISIBLE; -inline error_category const & generic_category() BOOST_NOEXCEPT BOOST_SYMBOL_VISIBLE; -#endif - -inline error_category const & system_category() BOOST_NOEXCEPT -{ - static const detail::system_error_category system_category_instance; - return system_category_instance; -} - -inline error_category const & generic_category() BOOST_NOEXCEPT -{ - static const detail::generic_error_category generic_category_instance; - return generic_category_instance; -} - -#endif // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR) - -// deprecated synonyms - -#ifdef BOOST_SYSTEM_ENABLE_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 - -// error_conditions are portable, error_codes are system or library specific - -class error_condition -{ -private: - - int val_; - bool failed_; - error_category const * cat_; - -public: - - // constructors: - - 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: - val_( val ), failed_( detail::failed_impl( val, cat ) ), cat_( &cat ) - { - } - - template BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e, - typename detail::enable_if::value>::type* = 0) BOOST_NOEXCEPT - { - *this = make_error_condition( e ); - } - - // modifiers: - - BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT - { - val_ = val; - failed_ = detail::failed_impl( val, cat ); - cat_ = &cat; - } - - template - BOOST_SYSTEM_CONSTEXPR typename detail::enable_if::value, error_condition>::type & - operator=( ErrorConditionEnum val ) BOOST_NOEXCEPT - { - *this = make_error_condition( val ); - return *this; - } - - BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT - { - val_ = 0; - failed_ = false; - cat_ = &generic_category(); - } - - // observers: - - BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT - { - return val_; - } - - BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT - { - return *cat_; - } - - std::string message() const - { - return cat_->message( value() ); - } - - char const * message( char * buffer, std::size_t len ) const BOOST_NOEXCEPT - { - return cat_->message( value(), buffer, len ); - } - - BOOST_SYSTEM_CONSTEXPR bool failed() const BOOST_NOEXCEPT - { - return failed_; - } - -#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) - - BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error - { - return failed_; - } - -#else - - typedef void (*unspecified_bool_type)(); - static void unspecified_bool_true() {} - - BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error - { - return failed_? unspecified_bool_true: 0; - } - - BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error - { - return !failed_; - } - -#endif - - // relationals: - // the more symmetrical non-member syntax allows enum - // conversions work for both rhs and lhs. - - 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_; - } - - 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_ ); - } - -#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) - - operator std::error_condition () const - { - return std::error_condition( value(), category() ); - } - -#endif -}; - // class error_code // We want error_code to be a value type that can be copied without slicing