From 736d6181207b8d80287c3b558b0b9f74b93864ba Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 15 Sep 2018 20:05:10 +0300 Subject: [PATCH 01/23] Reformat error_code.hpp --- include/boost/system/error_code.hpp | 1031 ++++++++++++++------------- 1 file changed, 533 insertions(+), 498 deletions(-) diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index eb22f8e..2d71783 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -66,150 +66,160 @@ namespace boost { - namespace system - { - class error_code; // values defined by the operating system - class error_condition; // portable generic values defined below, but ultimately - // based on the POSIX standard +namespace system +{ - // "Concept" helpers -------------------------------------------------------------// +class error_code; // values defined by the operating system +class error_condition; // portable generic values defined below, but ultimately + // based on the POSIX standard - template< class T > - struct is_error_code_enum { static const bool value = false; }; +// "Concept" helpers -------------------------------------------------------------// - template< class T > - struct is_error_condition_enum { static const bool value = false; }; +template struct is_error_code_enum +{ + static const bool value = false; +}; - // generic error_conditions ------------------------------------------------------// +template struct is_error_condition_enum +{ + static const bool value = false; +}; - namespace errc - { - enum errc_t - { - success = 0, - address_family_not_supported = EAFNOSUPPORT, - address_in_use = EADDRINUSE, - address_not_available = EADDRNOTAVAIL, - already_connected = EISCONN, - argument_list_too_long = E2BIG, - argument_out_of_domain = EDOM, - bad_address = EFAULT, - bad_file_descriptor = EBADF, - bad_message = EBADMSG, - broken_pipe = EPIPE, - connection_aborted = ECONNABORTED, - connection_already_in_progress = EALREADY, - connection_refused = ECONNREFUSED, - connection_reset = ECONNRESET, - cross_device_link = EXDEV, - destination_address_required = EDESTADDRREQ, - device_or_resource_busy = EBUSY, - directory_not_empty = ENOTEMPTY, - executable_format_error = ENOEXEC, - file_exists = EEXIST, - file_too_large = EFBIG, - filename_too_long = ENAMETOOLONG, - function_not_supported = ENOSYS, - host_unreachable = EHOSTUNREACH, - identifier_removed = EIDRM, - illegal_byte_sequence = EILSEQ, - inappropriate_io_control_operation = ENOTTY, - interrupted = EINTR, - invalid_argument = EINVAL, - invalid_seek = ESPIPE, - io_error = EIO, - is_a_directory = EISDIR, - message_size = EMSGSIZE, - network_down = ENETDOWN, - network_reset = ENETRESET, - network_unreachable = ENETUNREACH, - no_buffer_space = ENOBUFS, - no_child_process = ECHILD, - no_link = ENOLINK, - no_lock_available = ENOLCK, - no_message_available = ENODATA, - no_message = ENOMSG, - no_protocol_option = ENOPROTOOPT, - no_space_on_device = ENOSPC, - no_stream_resources = ENOSR, - no_such_device_or_address = ENXIO, - no_such_device = ENODEV, - no_such_file_or_directory = ENOENT, - no_such_process = ESRCH, - not_a_directory = ENOTDIR, - not_a_socket = ENOTSOCK, - not_a_stream = ENOSTR, - not_connected = ENOTCONN, - not_enough_memory = ENOMEM, - not_supported = ENOTSUP, - operation_canceled = ECANCELED, - operation_in_progress = EINPROGRESS, - operation_not_permitted = EPERM, - operation_not_supported = EOPNOTSUPP, - operation_would_block = EWOULDBLOCK, - owner_dead = EOWNERDEAD, - permission_denied = EACCES, - protocol_error = EPROTO, - protocol_not_supported = EPROTONOSUPPORT, - read_only_file_system = EROFS, - resource_deadlock_would_occur = EDEADLK, - resource_unavailable_try_again = EAGAIN, - result_out_of_range = ERANGE, - state_not_recoverable = ENOTRECOVERABLE, - stream_timeout = ETIME, - text_file_busy = ETXTBSY, - timed_out = ETIMEDOUT, - too_many_files_open_in_system = ENFILE, - too_many_files_open = EMFILE, - too_many_links = EMLINK, - too_many_symbolic_link_levels = ELOOP, - value_too_large = EOVERFLOW, - wrong_protocol_type = EPROTOTYPE - }; +// generic error_conditions ------------------------------------------------------// - } // namespace errc +namespace errc +{ -# ifdef BOOST_SYSTEM_ENABLE_DEPRECATED - namespace posix = errc; - namespace posix_error = errc; -# endif +enum errc_t +{ + success = 0, + address_family_not_supported = EAFNOSUPPORT, + address_in_use = EADDRINUSE, + address_not_available = EADDRNOTAVAIL, + already_connected = EISCONN, + argument_list_too_long = E2BIG, + argument_out_of_domain = EDOM, + bad_address = EFAULT, + bad_file_descriptor = EBADF, + bad_message = EBADMSG, + broken_pipe = EPIPE, + connection_aborted = ECONNABORTED, + connection_already_in_progress = EALREADY, + connection_refused = ECONNREFUSED, + connection_reset = ECONNRESET, + cross_device_link = EXDEV, + destination_address_required = EDESTADDRREQ, + device_or_resource_busy = EBUSY, + directory_not_empty = ENOTEMPTY, + executable_format_error = ENOEXEC, + file_exists = EEXIST, + file_too_large = EFBIG, + filename_too_long = ENAMETOOLONG, + function_not_supported = ENOSYS, + host_unreachable = EHOSTUNREACH, + identifier_removed = EIDRM, + illegal_byte_sequence = EILSEQ, + inappropriate_io_control_operation = ENOTTY, + interrupted = EINTR, + invalid_argument = EINVAL, + invalid_seek = ESPIPE, + io_error = EIO, + is_a_directory = EISDIR, + message_size = EMSGSIZE, + network_down = ENETDOWN, + network_reset = ENETRESET, + network_unreachable = ENETUNREACH, + no_buffer_space = ENOBUFS, + no_child_process = ECHILD, + no_link = ENOLINK, + no_lock_available = ENOLCK, + no_message_available = ENODATA, + no_message = ENOMSG, + no_protocol_option = ENOPROTOOPT, + no_space_on_device = ENOSPC, + no_stream_resources = ENOSR, + no_such_device_or_address = ENXIO, + no_such_device = ENODEV, + no_such_file_or_directory = ENOENT, + no_such_process = ESRCH, + not_a_directory = ENOTDIR, + not_a_socket = ENOTSOCK, + not_a_stream = ENOSTR, + not_connected = ENOTCONN, + not_enough_memory = ENOMEM, + not_supported = ENOTSUP, + operation_canceled = ECANCELED, + operation_in_progress = EINPROGRESS, + operation_not_permitted = EPERM, + operation_not_supported = EOPNOTSUPP, + operation_would_block = EWOULDBLOCK, + owner_dead = EOWNERDEAD, + permission_denied = EACCES, + protocol_error = EPROTO, + protocol_not_supported = EPROTONOSUPPORT, + read_only_file_system = EROFS, + resource_deadlock_would_occur = EDEADLK, + resource_unavailable_try_again = EAGAIN, + result_out_of_range = ERANGE, + state_not_recoverable = ENOTRECOVERABLE, + stream_timeout = ETIME, + text_file_busy = ETXTBSY, + timed_out = ETIMEDOUT, + too_many_files_open_in_system = ENFILE, + too_many_files_open = EMFILE, + too_many_links = EMLINK, + too_many_symbolic_link_levels = ELOOP, + value_too_large = EOVERFLOW, + wrong_protocol_type = EPROTOTYPE +}; - template<> struct is_error_condition_enum - { static const bool value = true; }; +} // namespace errc + +#ifdef BOOST_SYSTEM_ENABLE_DEPRECATED + +namespace posix = errc; +namespace posix_error = errc; + +#endif + +template<> struct is_error_condition_enum +{ + static const bool value = true; +}; - // --------------------------------------------------------------------------------// +// --------------------------------------------------------------------------------// - // Operating system specific interfaces ------------------------------------------// +// Operating system specific interfaces ------------------------------------------// - // The interface is divided into general and system-specific portions to - // meet these requirements: - // - // * Code calling an operating system API can create an error_code with - // a single category (system_category), even for POSIX-like operating - // systems that return some POSIX errno values and some native errno - // values. This code should not have to pay the cost of distinguishing - // between categories, since it is not yet known if that is needed. - // - // * Users wishing to write system-specific code should be given enums for - // at least the common error cases. - // - // * System specific code should fail at compile time if moved to another - // operating system. +// The interface is divided into general and system-specific portions to +// meet these requirements: +// +// * Code calling an operating system API can create an error_code with +// a single category (system_category), even for POSIX-like operating +// systems that return some POSIX errno values and some native errno +// values. This code should not have to pay the cost of distinguishing +// between categories, since it is not yet known if that is needed. +// +// * Users wishing to write system-specific code should be given enums for +// at least the common error cases. +// +// * System specific code should fail at compile time if moved to another +// operating system. - // The system specific portions of the interface are located in headers - // with names reflecting the operating system. For example, - // - // - // - // - // - // These headers are effectively empty for compiles on operating systems - // where they are not applicable. +// The system specific portions of the interface are located in headers +// with names reflecting the operating system. For example, +// +// +// +// +// +// These headers are effectively empty for compiles on operating systems +// where they are not applicable. - // --------------------------------------------------------------------------------// +// --------------------------------------------------------------------------------// #ifdef BOOST_MSVC #pragma warning(push) @@ -217,21 +227,21 @@ namespace boost #pragma warning(disable: 4355) #endif - // class error_category ------------------------------------------------// +// class error_category ------------------------------------------------// - class error_category : public noncopyable - { +class error_category: public noncopyable +{ #ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR - private: +private: - class std_category: public std::error_category - { - private: + class std_category: public std::error_category + { + private: boost::system::error_category const * pc_; - public: + public: BOOST_SYSTEM_CONSTEXPR explicit std_category( boost::system::error_category const * pc ): pc_( pc ) { @@ -239,50 +249,46 @@ namespace boost virtual const char * name() const BOOST_NOEXCEPT { - return pc_->name(); + return pc_->name(); } virtual std::string message( int ev ) const { - return pc_->message( ev ); + 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; - }; + virtual std::error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT; - std_category std_cat_; + 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; + }; - public: + std_category std_cat_; - BOOST_SYSTEM_CONSTEXPR error_category() BOOST_SYSTEM_NOEXCEPT: std_cat_( this ) {} +public: - operator std::error_category const & () const BOOST_SYSTEM_NOEXCEPT - { + 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 +// to maintain ABI compatibility between 03 and 11, +// define a class with the same layout +private: + + class std_category + { private: - class std_category - { - private: - boost::system::error_category const * pc_; - public: + public: BOOST_SYSTEM_CONSTEXPR explicit std_category( boost::system::error_category const * pc ): pc_( pc ) { @@ -292,7 +298,7 @@ namespace boost virtual const char * name() const BOOST_NOEXCEPT { - return pc_->name(); + return pc_->name(); } // we can't define message, because (1) it returns an std::string, @@ -304,47 +310,51 @@ namespace boost // 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: - - BOOST_SYSTEM_CONSTEXPR error_category() BOOST_SYSTEM_NOEXCEPT: std_cat_( this ) {} + std_category std_cat_; #endif - public: - virtual ~error_category(){} +public: - 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 bool equivalent( int code, - const error_condition & condition ) const - BOOST_SYSTEM_NOEXCEPT; - inline virtual bool equivalent( const error_code & code, - int condition ) const BOOST_SYSTEM_NOEXCEPT; - }; + BOOST_SYSTEM_CONSTEXPR error_category() BOOST_SYSTEM_NOEXCEPT: std_cat_( this ) + { + } - BOOST_SYSTEM_CONSTEXPR inline bool operator==( const error_category & lhs, - const error_category & rhs ) BOOST_SYSTEM_NOEXCEPT - { return &lhs == &rhs; } + virtual ~error_category() + { + } - BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_category & lhs, - const error_category & rhs ) BOOST_SYSTEM_NOEXCEPT - { return &lhs != &rhs; } + virtual const char * name() const BOOST_SYSTEM_NOEXCEPT = 0; - inline bool operator<( const error_category & lhs, - const error_category & rhs ) BOOST_SYSTEM_NOEXCEPT - { return std::less()( &lhs, &rhs ); } + virtual std::string message( int ev ) const = 0; + + 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; + inline virtual bool equivalent( const error_code & code, int condition ) const BOOST_SYSTEM_NOEXCEPT; +}; + +BOOST_SYSTEM_CONSTEXPR inline bool operator==( const error_category & lhs, const error_category & rhs ) BOOST_SYSTEM_NOEXCEPT +{ + return &lhs == &rhs; +} + +BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_category & lhs, const error_category & rhs ) BOOST_SYSTEM_NOEXCEPT +{ + return &lhs != &rhs; +} + +inline bool operator<( const error_category & lhs, const error_category & rhs ) BOOST_SYSTEM_NOEXCEPT +{ + return std::less()( &lhs, &rhs ); +} #ifdef BOOST_MSVC #pragma warning(pop) #endif - // predefined error categories ---------------------------------------------------// +// predefined error categories ---------------------------------------------------// namespace detail { @@ -499,445 +509,470 @@ inline const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT #endif - // deprecated synonyms ------------------------------------------------------------// +// 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(); + +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 +// error_conditions are portable, error_codes are system or library specific - class error_condition +class error_condition +{ +public: + + // constructors: + + BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_SYSTEM_NOEXCEPT: m_val( 0 ), m_cat( &generic_category() ) { - public: + } - // constructors: - BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_SYSTEM_NOEXCEPT : m_val(0), m_cat(&generic_category()) {} - BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT - : m_val(val), m_cat(&cat) {} + BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT: m_val( val ), m_cat( &cat ) + { + } - template - error_condition(ErrorConditionEnum e, - typename boost::enable_if_::value>::type* - = 0) BOOST_SYSTEM_NOEXCEPT - { - *this = make_error_condition(e); - } + template error_condition( ErrorConditionEnum e, + typename boost::enable_if_::value>::type* = 0) BOOST_SYSTEM_NOEXCEPT + { + *this = make_error_condition( e ); + } - // modifiers: + // modifiers: - BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT - { + BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT + { m_val = val; m_cat = &cat; - } + } - template - typename boost::enable_if_::value, - error_condition>::type & - operator=( ErrorConditionEnum val ) BOOST_SYSTEM_NOEXCEPT - { - *this = make_error_condition(val); + template + typename boost::enable_if_::value, error_condition>::type & + operator=( ErrorConditionEnum val ) BOOST_SYSTEM_NOEXCEPT + { + *this = make_error_condition( val ); return *this; - } + } - BOOST_SYSTEM_CONSTEXPR void clear() BOOST_SYSTEM_NOEXCEPT - { + BOOST_SYSTEM_CONSTEXPR void clear() BOOST_SYSTEM_NOEXCEPT + { m_val = 0; m_cat = &generic_category(); - } + } - // observers: - BOOST_SYSTEM_CONSTEXPR int value() const BOOST_SYSTEM_NOEXCEPT { return m_val; } - BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_SYSTEM_NOEXCEPT { return *m_cat; } - std::string message() const { return m_cat->message(value()); } + // observers: + + BOOST_SYSTEM_CONSTEXPR int value() const BOOST_SYSTEM_NOEXCEPT + { + return m_val; + } + + BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_SYSTEM_NOEXCEPT + { + return *m_cat; + } + + std::string message() const + { + return m_cat->message( value() ); + } #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) - BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_SYSTEM_NOEXCEPT // true if error - { + BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_SYSTEM_NOEXCEPT // true if error + { return m_val != 0; - } + } #else - typedef void (*unspecified_bool_type)(); - static void unspecified_bool_true() {} + typedef void (*unspecified_bool_type)(); + static void unspecified_bool_true() {} - BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_SYSTEM_NOEXCEPT // true if error - { + BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_SYSTEM_NOEXCEPT // true if error + { return m_val == 0 ? 0 : unspecified_bool_true; - } + } - BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_SYSTEM_NOEXCEPT // true if no error - { + BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_SYSTEM_NOEXCEPT // true if no error + { return m_val == 0; - } + } #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_SYSTEM_NOEXCEPT - { - return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val; - } + // relationals: + // the more symmetrical non-member syntax allows enum + // conversions work for both rhs and lhs. - inline friend bool operator<( const error_condition & lhs, - const error_condition & rhs ) BOOST_SYSTEM_NOEXCEPT - // the more symmetrical non-member syntax allows enum - // conversions work for both rhs and lhs. - { - return lhs.m_cat < rhs.m_cat - || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val); - } + BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) BOOST_SYSTEM_NOEXCEPT + { + return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val; + } + + inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) BOOST_SYSTEM_NOEXCEPT + { + return lhs.m_cat < rhs.m_cat || ( 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 - { + operator std::error_condition () const BOOST_SYSTEM_NOEXCEPT + { return std::error_condition( value(), category() ); - } + } #endif - private: - int m_val; - const error_category * m_cat; +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 - // polymorphic behavior based on the error category. This is achieved by - // abstract base class error_category supplying the polymorphic behavior, - // and error_code containing a pointer to an object of a type derived - // from error_category. - 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 +// polymorphic behavior based on the error category. This is achieved by +// abstract base class error_category supplying the polymorphic behavior, +// and error_code containing a pointer to an object of a type derived +// from error_category. + +class error_code +{ +public: + + // constructors: + + BOOST_SYSTEM_CONSTEXPR error_code() BOOST_SYSTEM_NOEXCEPT: m_val( 0 ), m_cat( &system_category() ) { - public: + } - // constructors: - BOOST_SYSTEM_CONSTEXPR error_code() BOOST_SYSTEM_NOEXCEPT : m_val(0), m_cat(&system_category()) {} - BOOST_SYSTEM_CONSTEXPR error_code( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT - : m_val(val), m_cat(&cat) {} + BOOST_SYSTEM_CONSTEXPR error_code( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT: m_val( val ), m_cat( &cat ) + { + } - template - error_code(ErrorCodeEnum e, - typename boost::enable_if_::value>::type* = 0) - BOOST_SYSTEM_NOEXCEPT - { - *this = make_error_code(e); - } + template error_code( ErrorCodeEnum e, + typename boost::enable_if_::value>::type* = 0 ) BOOST_SYSTEM_NOEXCEPT + { + *this = make_error_code( e ); + } - // modifiers: - BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT - { + // modifiers: + + BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT + { m_val = val; m_cat = &cat; - } + } - template + template typename boost::enable_if_::value, error_code>::type & - operator=( ErrorCodeEnum val ) BOOST_SYSTEM_NOEXCEPT - { - *this = make_error_code(val); + operator=( ErrorCodeEnum val ) BOOST_SYSTEM_NOEXCEPT + { + *this = make_error_code( val ); return *this; - } + } - BOOST_SYSTEM_CONSTEXPR void clear() BOOST_SYSTEM_NOEXCEPT - { + BOOST_SYSTEM_CONSTEXPR void clear() BOOST_SYSTEM_NOEXCEPT + { m_val = 0; m_cat = &system_category(); - } + } - // observers: - BOOST_SYSTEM_CONSTEXPR int value() const BOOST_SYSTEM_NOEXCEPT { return m_val; } - BOOST_SYSTEM_CONSTEXPR 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()); } - std::string message() const { return m_cat->message(value()); } + // observers: + + BOOST_SYSTEM_CONSTEXPR int value() const BOOST_SYSTEM_NOEXCEPT + { + return m_val; + } + + BOOST_SYSTEM_CONSTEXPR 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()); + } + + std::string message() const + { + return m_cat->message( value() ); + } #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) - BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_SYSTEM_NOEXCEPT // true if error - { + BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_SYSTEM_NOEXCEPT // true if error + { return m_val != 0; - } + } #else - typedef void (*unspecified_bool_type)(); - static void unspecified_bool_true() {} + typedef void (*unspecified_bool_type)(); + static void unspecified_bool_true() {} - BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_SYSTEM_NOEXCEPT // true if error - { + BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_SYSTEM_NOEXCEPT // true if error + { return m_val == 0 ? 0 : unspecified_bool_true; - } + } - BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_SYSTEM_NOEXCEPT // true if no error - { + BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_SYSTEM_NOEXCEPT // true if no error + { return m_val == 0; - } + } #endif - // relationals: - BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_code & lhs, - const error_code & rhs ) BOOST_SYSTEM_NOEXCEPT - // the more symmetrical non-member syntax allows enum - // conversions work for both rhs and lhs. - { + // 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_code & lhs, const error_code & rhs ) BOOST_SYSTEM_NOEXCEPT + { return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val; - } + } - inline friend bool operator<( const error_code & lhs, - const error_code & rhs ) BOOST_SYSTEM_NOEXCEPT - // the more symmetrical non-member syntax allows enum - // conversions work for both rhs and lhs. - { - return lhs.m_cat < rhs.m_cat - || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val); - } + inline friend bool operator<( const error_code & lhs, const error_code & rhs ) BOOST_SYSTEM_NOEXCEPT + { + return lhs.m_cat < rhs.m_cat || ( 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 - { + operator std::error_code () const BOOST_SYSTEM_NOEXCEPT + { return std::error_code( value(), category() ); - } + } #endif - private: - int m_val; - const error_category * m_cat; +private: - }; + int m_val; + const error_category * m_cat; +}; - // predefined error_code object used as "throw on error" tag -# ifdef BOOST_SYSTEM_ENABLE_DEPRECATED - BOOST_SYSTEM_DECL extern error_code throws; -# endif +// predefined error_code object used as "throw on error" tag - // Moving from a "throws" object to a "throws" function without breaking - // existing code is a bit of a problem. The workaround is to place the - // "throws" function in namespace boost rather than namespace boost::system. +#ifdef BOOST_SYSTEM_ENABLE_DEPRECATED - } // namespace system +BOOST_SYSTEM_DECL extern error_code throws; + +#endif + +// Moving from a "throws" object to a "throws" function without breaking +// existing code is a bit of a problem. The workaround is to place the +// "throws" function in namespace boost rather than namespace boost::system. + +} // namespace system - namespace detail - { - // Misuse of the error_code object is turned into a noisy failure by - // poisoning the reference. This particular implementation doesn't - // produce warnings or errors from popular compilers, is very efficient - // (as determined by inspecting generated code), and does not suffer - // from order of initialization problems. In practice, it also seems - // cause user function error handling implementation errors to be detected - // very early in the development cycle. - inline system::error_code* throws() - { - // See github.com/boostorg/system/pull/12 by visigoth for why the return - // is poisoned with nonzero rather than (0). A test, test_throws_usage(), - // has been added to error_code_test.cpp, and as visigoth mentioned it - // fails on clang for release builds with a return of 0 but works fine - // with (1). - // Since the undefined behavior sanitizer (-fsanitize=undefined) does not - // allow a reference to be formed to the unaligned address of (1), we use - // (8) instead. - return reinterpret_cast(8); - } - } +namespace detail +{ - inline system::error_code& throws() - { return *detail::throws(); } +// Misuse of the error_code object is turned into a noisy failure by +// poisoning the reference. This particular implementation doesn't +// produce warnings or errors from popular compilers, is very efficient +// (as determined by inspecting generated code), and does not suffer +// from order of initialization problems. In practice, it also seems +// cause user function error handling implementation errors to be detected +// very early in the development cycle. - namespace system - { - // non-member functions ------------------------------------------------// +inline system::error_code* throws() +{ + // See github.com/boostorg/system/pull/12 by visigoth for why the return + // is poisoned with nonzero rather than (0). A test, test_throws_usage(), + // has been added to error_code_test.cpp, and as visigoth mentioned it + // fails on clang for release builds with a return of 0 but works fine + // with (1). + // Since the undefined behavior sanitizer (-fsanitize=undefined) does not + // allow a reference to be formed to the unaligned address of (1), we use + // (8) instead. - BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_code & lhs, - const error_code & rhs ) BOOST_SYSTEM_NOEXCEPT - { - return !(lhs == rhs); - } + return reinterpret_cast(8); +} - BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_condition & lhs, - const error_condition & rhs ) BOOST_SYSTEM_NOEXCEPT - { - return !(lhs == rhs); - } +} // namespace detail - inline bool operator==( const error_code & code, - const error_condition & condition ) BOOST_SYSTEM_NOEXCEPT - { - return code.category().equivalent( code.value(), condition ) - || condition.category().equivalent( code, condition.value() ); - } +inline system::error_code& throws() +{ + return *detail::throws(); +} - inline bool operator!=( const error_code & lhs, - const error_condition & rhs ) BOOST_SYSTEM_NOEXCEPT - { - return !(lhs == rhs); - } +namespace system +{ - inline bool operator==( const error_condition & condition, - const error_code & code ) BOOST_SYSTEM_NOEXCEPT - { - return condition.category().equivalent( code, condition.value() ) - || code.category().equivalent( code.value(), condition ); - } +// non-member functions ------------------------------------------------// - inline bool operator!=( const error_condition & lhs, - const error_code & rhs ) BOOST_SYSTEM_NOEXCEPT - { - return !(lhs == rhs); - } +BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_code & lhs, const error_code & rhs ) BOOST_SYSTEM_NOEXCEPT +{ + return !( lhs == rhs ); +} - // TODO: both of these may move elsewhere, but the LWG hasn't spoken yet. +BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_condition & lhs, const error_condition & rhs ) BOOST_SYSTEM_NOEXCEPT +{ + return !( lhs == rhs ); +} - template +inline bool operator==( const error_code & code, const error_condition & condition ) BOOST_SYSTEM_NOEXCEPT +{ + return code.category().equivalent( code.value(), condition ) || condition.category().equivalent( code, condition.value() ); +} + +inline bool operator!=( const error_code & lhs, const error_condition & rhs ) BOOST_SYSTEM_NOEXCEPT +{ + return !( lhs == rhs ); +} + +inline bool operator==( const error_condition & condition, const error_code & code ) BOOST_SYSTEM_NOEXCEPT +{ + return condition.category().equivalent( code, condition.value() ) || code.category().equivalent( code.value(), condition ); +} + +inline bool operator!=( const error_condition & lhs, const error_code & rhs ) BOOST_SYSTEM_NOEXCEPT +{ + return !( lhs == rhs ); +} + +template inline std::basic_ostream& - operator<< (std::basic_ostream& os, error_code ec) - { - os << ec.category().name() << ':' << ec.value(); - return os; - } + operator<< (std::basic_ostream& os, error_code ec) +{ + os << ec.category().name() << ':' << ec.value(); + return os; +} - inline std::size_t hash_value( const error_code & ec ) - { - return static_cast(ec.value()) - + reinterpret_cast(&ec.category()); - } +inline std::size_t hash_value( const error_code & ec ) +{ + return static_cast( ec.value() ) + reinterpret_cast( &ec.category() ); +} - // make_* functions for errc::errc_t ---------------------------------------------// +// make_* functions for errc::errc_t ---------------------------------------------// - namespace errc - { - // explicit conversion: - inline error_code make_error_code( errc_t e ) BOOST_SYSTEM_NOEXCEPT - { return error_code( e, generic_category() ); } +namespace errc +{ - // implicit conversion: - inline error_condition make_error_condition( errc_t e ) BOOST_SYSTEM_NOEXCEPT - { return error_condition( e, generic_category() ); } - } +// explicit conversion: +inline error_code make_error_code( errc_t e ) BOOST_SYSTEM_NOEXCEPT +{ + return error_code( e, generic_category() ); +} - // error_category default implementation -----------------------------------------// +// implicit conversion: +inline error_condition make_error_condition( errc_t e ) BOOST_SYSTEM_NOEXCEPT +{ + return error_condition( e, generic_category() ); +} - error_condition error_category::default_error_condition( int ev ) const - BOOST_SYSTEM_NOEXCEPT - { - return error_condition( ev, *this ); - } +} // namespace errc - bool error_category::equivalent( int code, - const error_condition & condition ) const BOOST_SYSTEM_NOEXCEPT - { - return default_error_condition( code ) == condition; - } +// error_category default implementation -----------------------------------------// - bool error_category::equivalent( const error_code & code, - int condition ) const BOOST_SYSTEM_NOEXCEPT - { - return *this == code.category() && code.value() == condition; - } +error_condition error_category::default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT +{ + return error_condition( ev, *this ); +} + +bool error_category::equivalent( int code, const error_condition & condition ) const BOOST_SYSTEM_NOEXCEPT +{ + return default_error_condition( code ) == condition; +} + +bool error_category::equivalent( const error_code & code, int condition ) const BOOST_SYSTEM_NOEXCEPT +{ + 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 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 +inline bool error_category::std_category::equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT +{ + if( condition.category() == *this ) { - 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() ); - + } + 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() ) ) - { + + 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 +#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 ) { - 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() ); - + } + 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; - } } +#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 - } // namespace system + else if( *pc_ == boost::system::generic_category() ) + { + return std::generic_category().equivalent( code, condition ); + } + else + { + return false; + } +} + +#endif // #ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR + +} // namespace system + } // namespace boost #include // pops abi_prefix.hpp pragmas -# ifdef BOOST_ERROR_CODE_HEADER_ONLY -# include -# endif +#ifdef BOOST_ERROR_CODE_HEADER_ONLY +# include +#endif #endif // BOOST_SYSTEM_ERROR_CODE_HPP From 053972643d6842f79661a42f3ee6038e24b353a2 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 15 Sep 2018 20:06:14 +0300 Subject: [PATCH 02/23] Replace BOOST_SYSTEM_NOEXCEPT with BOOST_NOEXCEPT --- include/boost/system/error_code.hpp | 132 ++++++++++++++-------------- 1 file changed, 64 insertions(+), 68 deletions(-) diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index 2d71783..2926b9a 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -34,10 +34,6 @@ #include // must be the last #include -#ifndef BOOST_SYSTEM_NOEXCEPT -#define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT -#endif - #if !defined(BOOST_NO_CXX14_CONSTEXPR) # define BOOST_SYSTEM_HAS_CONSTEXPR #endif @@ -267,7 +263,7 @@ private: public: - operator std::error_category const & () const BOOST_SYSTEM_NOEXCEPT + operator std::error_category const & () const BOOST_NOEXCEPT { // do not map generic to std::generic on purpose; occasionally, // there are two std::generic categories in a program, which leads @@ -318,7 +314,7 @@ private: public: - BOOST_SYSTEM_CONSTEXPR error_category() BOOST_SYSTEM_NOEXCEPT: std_cat_( this ) + BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: std_cat_( this ) { } @@ -326,26 +322,26 @@ public: { } - virtual const char * name() const BOOST_SYSTEM_NOEXCEPT = 0; + virtual const char * name() const BOOST_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 bool equivalent( int code, const error_condition & condition ) const BOOST_SYSTEM_NOEXCEPT; - inline virtual bool equivalent( const error_code & code, int condition ) const BOOST_SYSTEM_NOEXCEPT; + inline virtual error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT; + inline virtual bool equivalent( int code, const error_condition & condition ) const BOOST_NOEXCEPT; + inline virtual bool equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT; }; -BOOST_SYSTEM_CONSTEXPR inline bool operator==( const error_category & lhs, const error_category & rhs ) BOOST_SYSTEM_NOEXCEPT +BOOST_SYSTEM_CONSTEXPR inline bool operator==( const error_category & lhs, const error_category & rhs ) BOOST_NOEXCEPT { return &lhs == &rhs; } -BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_category & lhs, const error_category & rhs ) BOOST_SYSTEM_NOEXCEPT +BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_category & lhs, const error_category & rhs ) BOOST_NOEXCEPT { return &lhs != &rhs; } -inline bool operator<( const error_category & lhs, const error_category & rhs ) BOOST_SYSTEM_NOEXCEPT +inline bool operator<( const error_category & lhs, const error_category & rhs ) BOOST_NOEXCEPT { return std::less()( &lhs, &rhs ); } @@ -371,11 +367,11 @@ public: // clang++ 3.8 and below: initialization of const object // requires a user-provided default constructor - BOOST_SYSTEM_CONSTEXPR generic_error_category() BOOST_SYSTEM_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR generic_error_category() BOOST_NOEXCEPT { } - const char * name() const BOOST_SYSTEM_NOEXCEPT + const char * name() const BOOST_NOEXCEPT { return "generic"; } @@ -387,17 +383,17 @@ class system_error_category: public error_category { public: - BOOST_SYSTEM_CONSTEXPR system_error_category() BOOST_SYSTEM_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR system_error_category() BOOST_NOEXCEPT { } - const char * name() const BOOST_SYSTEM_NOEXCEPT + const char * name() const BOOST_NOEXCEPT { return "system"; } BOOST_SYSTEM_DECL_ std::string message( int ev ) const; - BOOST_SYSTEM_DECL_ error_condition default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT; + BOOST_SYSTEM_DECL_ error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT; }; #undef BOOST_SYSTEM_DECL_ @@ -431,25 +427,25 @@ template BOOST_SYSTEM_REQUIRE_CONST_INIT generic_error_category cat_hol } // namespace detail -constexpr const error_category & system_category() BOOST_SYSTEM_NOEXCEPT +constexpr const error_category & system_category() BOOST_NOEXCEPT { return detail::cat_holder::system_category_instance; } -constexpr const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT +constexpr const error_category & generic_category() BOOST_NOEXCEPT { return detail::cat_holder::generic_category_instance; } # else -inline const error_category & system_category() BOOST_SYSTEM_NOEXCEPT +inline const error_category & system_category() BOOST_NOEXCEPT { static const detail::system_error_category system_category_instance; return system_category_instance; } -inline const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT +inline const error_category & generic_category() BOOST_NOEXCEPT { static const detail::generic_error_category generic_category_instance; return generic_category_instance; @@ -477,12 +473,12 @@ extern generic_error_category generic_category_instance; } // namespace detail -constexpr const error_category & system_category() BOOST_SYSTEM_NOEXCEPT +constexpr const error_category & system_category() BOOST_NOEXCEPT { return detail::system_category_instance; } -constexpr const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT +constexpr const error_category & generic_category() BOOST_NOEXCEPT { return detail::generic_category_instance; } @@ -492,17 +488,17 @@ constexpr const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT namespace detail { -BOOST_SYSTEM_DECL const error_category & system_category_ncx() BOOST_SYSTEM_NOEXCEPT; -BOOST_SYSTEM_DECL const error_category & generic_category_ncx() BOOST_SYSTEM_NOEXCEPT; +BOOST_SYSTEM_DECL const error_category & system_category_ncx() BOOST_NOEXCEPT; +BOOST_SYSTEM_DECL const error_category & generic_category_ncx() BOOST_NOEXCEPT; } // namespace detail -inline const error_category & system_category() BOOST_SYSTEM_NOEXCEPT +inline const error_category & system_category() BOOST_NOEXCEPT { return detail::system_category_ncx(); } -inline const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT +inline const error_category & generic_category() BOOST_NOEXCEPT { return detail::generic_category_ncx(); } @@ -532,23 +528,23 @@ public: // constructors: - BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_SYSTEM_NOEXCEPT: m_val( 0 ), m_cat( &generic_category() ) + BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_NOEXCEPT: m_val( 0 ), m_cat( &generic_category() ) { } - BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT: m_val( val ), m_cat( &cat ) + BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) BOOST_NOEXCEPT: m_val( val ), m_cat( &cat ) { } template error_condition( ErrorConditionEnum e, - typename boost::enable_if_::value>::type* = 0) BOOST_SYSTEM_NOEXCEPT + typename boost::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_SYSTEM_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT { m_val = val; m_cat = &cat; @@ -556,13 +552,13 @@ public: template typename boost::enable_if_::value, error_condition>::type & - operator=( ErrorConditionEnum val ) BOOST_SYSTEM_NOEXCEPT + operator=( ErrorConditionEnum val ) BOOST_NOEXCEPT { *this = make_error_condition( val ); return *this; } - BOOST_SYSTEM_CONSTEXPR void clear() BOOST_SYSTEM_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT { m_val = 0; m_cat = &generic_category(); @@ -570,12 +566,12 @@ public: // observers: - BOOST_SYSTEM_CONSTEXPR int value() const BOOST_SYSTEM_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT { return m_val; } - BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_SYSTEM_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT { return *m_cat; } @@ -587,7 +583,7 @@ public: #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) - BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_SYSTEM_NOEXCEPT // true if error + BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error { return m_val != 0; } @@ -597,12 +593,12 @@ public: typedef void (*unspecified_bool_type)(); static void unspecified_bool_true() {} - BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_SYSTEM_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; } - BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_SYSTEM_NOEXCEPT // true if no error + BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error { return m_val == 0; } @@ -613,19 +609,19 @@ public: // 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_SYSTEM_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_val == rhs.m_val; } - inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) BOOST_SYSTEM_NOEXCEPT + 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 ); } #ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR - operator std::error_condition () const BOOST_SYSTEM_NOEXCEPT + operator std::error_condition () const BOOST_NOEXCEPT { return std::error_condition( value(), category() ); } @@ -653,23 +649,23 @@ public: // constructors: - BOOST_SYSTEM_CONSTEXPR error_code() BOOST_SYSTEM_NOEXCEPT: m_val( 0 ), m_cat( &system_category() ) + BOOST_SYSTEM_CONSTEXPR error_code() BOOST_NOEXCEPT: m_val( 0 ), m_cat( &system_category() ) { } - BOOST_SYSTEM_CONSTEXPR error_code( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT: m_val( val ), m_cat( &cat ) + BOOST_SYSTEM_CONSTEXPR error_code( int val, const error_category & cat ) BOOST_NOEXCEPT: m_val( val ), m_cat( &cat ) { } template error_code( ErrorCodeEnum e, - typename boost::enable_if_::value>::type* = 0 ) BOOST_SYSTEM_NOEXCEPT + typename boost::enable_if_::value>::type* = 0 ) BOOST_NOEXCEPT { *this = make_error_code( e ); } // modifiers: - BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_SYSTEM_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_NOEXCEPT { m_val = val; m_cat = &cat; @@ -677,13 +673,13 @@ public: template typename boost::enable_if_::value, error_code>::type & - operator=( ErrorCodeEnum val ) BOOST_SYSTEM_NOEXCEPT + operator=( ErrorCodeEnum val ) BOOST_NOEXCEPT { *this = make_error_code( val ); return *this; } - BOOST_SYSTEM_CONSTEXPR void clear() BOOST_SYSTEM_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT { m_val = 0; m_cat = &system_category(); @@ -691,17 +687,17 @@ public: // observers: - BOOST_SYSTEM_CONSTEXPR int value() const BOOST_SYSTEM_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT { return m_val; } - BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_SYSTEM_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_NOEXCEPT { return *m_cat; } - error_condition default_error_condition() const BOOST_SYSTEM_NOEXCEPT + error_condition default_error_condition() const BOOST_NOEXCEPT { return m_cat->default_error_condition(value()); } @@ -713,7 +709,7 @@ public: #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) - BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_SYSTEM_NOEXCEPT // true if error + BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT // true if error { return m_val != 0; } @@ -723,12 +719,12 @@ public: typedef void (*unspecified_bool_type)(); static void unspecified_bool_true() {} - BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_SYSTEM_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; } - BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_SYSTEM_NOEXCEPT // true if no error + BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error { return m_val == 0; } @@ -740,19 +736,19 @@ public: // the more symmetrical non-member syntax allows enum // conversions work for both rhs and lhs. - BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_code & lhs, const error_code & rhs ) BOOST_SYSTEM_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_val == rhs.m_val; } - inline friend bool operator<( const error_code & lhs, const error_code & rhs ) BOOST_SYSTEM_NOEXCEPT + 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 ); } #ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR - operator std::error_code () const BOOST_SYSTEM_NOEXCEPT + operator std::error_code () const BOOST_NOEXCEPT { return std::error_code( value(), category() ); } @@ -816,32 +812,32 @@ namespace system // non-member functions ------------------------------------------------// -BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_code & lhs, const error_code & rhs ) BOOST_SYSTEM_NOEXCEPT +BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_code & lhs, const error_code & rhs ) BOOST_NOEXCEPT { return !( lhs == rhs ); } -BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_condition & lhs, const error_condition & rhs ) BOOST_SYSTEM_NOEXCEPT +BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT { return !( lhs == rhs ); } -inline bool operator==( const error_code & code, const error_condition & condition ) BOOST_SYSTEM_NOEXCEPT +inline bool operator==( const error_code & code, const error_condition & condition ) BOOST_NOEXCEPT { return code.category().equivalent( code.value(), condition ) || condition.category().equivalent( code, condition.value() ); } -inline bool operator!=( const error_code & lhs, const error_condition & rhs ) BOOST_SYSTEM_NOEXCEPT +inline bool operator!=( const error_code & lhs, const error_condition & rhs ) BOOST_NOEXCEPT { return !( lhs == rhs ); } -inline bool operator==( const error_condition & condition, const error_code & code ) BOOST_SYSTEM_NOEXCEPT +inline bool operator==( const error_condition & condition, const error_code & code ) BOOST_NOEXCEPT { return condition.category().equivalent( code, condition.value() ) || code.category().equivalent( code.value(), condition ); } -inline bool operator!=( const error_condition & lhs, const error_code & rhs ) BOOST_SYSTEM_NOEXCEPT +inline bool operator!=( const error_condition & lhs, const error_code & rhs ) BOOST_NOEXCEPT { return !( lhs == rhs ); } @@ -865,13 +861,13 @@ namespace errc { // explicit conversion: -inline error_code make_error_code( errc_t e ) BOOST_SYSTEM_NOEXCEPT +inline error_code make_error_code( errc_t e ) BOOST_NOEXCEPT { return error_code( e, generic_category() ); } // implicit conversion: -inline error_condition make_error_condition( errc_t e ) BOOST_SYSTEM_NOEXCEPT +inline error_condition make_error_condition( errc_t e ) BOOST_NOEXCEPT { return error_condition( e, generic_category() ); } @@ -880,17 +876,17 @@ inline error_condition make_error_condition( errc_t e ) BOOST_SYSTEM_NOEXCEPT // 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_NOEXCEPT { return error_condition( ev, *this ); } -bool error_category::equivalent( int code, const error_condition & condition ) const BOOST_SYSTEM_NOEXCEPT +bool error_category::equivalent( int code, const error_condition & condition ) const BOOST_NOEXCEPT { return default_error_condition( code ) == condition; } -bool error_category::equivalent( const error_code & code, int condition ) const BOOST_SYSTEM_NOEXCEPT +bool error_category::equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT { return *this == code.category() && code.value() == condition; } From 2fa0a00583a3a791092568d2ade793314181926e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 03:04:19 +0300 Subject: [PATCH 03/23] Make Boost.System header-only --- include/boost/system/api_config.hpp | 50 +- include/boost/system/config.hpp | 68 +- include/boost/system/detail/config.hpp | 74 +++ .../system/detail/std_interoperability.hpp | 131 ++++ .../system/detail/system_category_win32.hpp | 204 ++++++ include/boost/system/error_code.hpp | 592 ++++++------------ src/error_code.cpp | 29 +- test/dynamic_link_test.cpp | 4 +- test/error_code_test.cpp | 12 +- test/std_interop_test.cpp | 7 +- test/std_mismatch_test.cpp | 7 +- test/throw_test.cpp | 1 + 12 files changed, 680 insertions(+), 499 deletions(-) create mode 100644 include/boost/system/detail/config.hpp create mode 100644 include/boost/system/detail/std_interoperability.hpp create mode 100644 include/boost/system/detail/system_category_win32.hpp diff --git a/include/boost/system/api_config.hpp b/include/boost/system/api_config.hpp index 28b8bec..adbe355 100644 --- a/include/boost/system/api_config.hpp +++ b/include/boost/system/api_config.hpp @@ -1,42 +1,24 @@ -// boost/system/api_config.hpp -------------------------------------------------------// +#ifndef BOOST_SYSTEM_API_CONFIG_HPP_INCLUDED +#define BOOST_SYSTEM_API_CONFIG_HPP_INCLUDED -// Copyright Beman Dawes 2003, 2006, 2010 - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// See http://www.boost.org/libs/system for documentation. - -//--------------------------------------------------------------------------------------// - -// Boost.System calls operating system API functions to implement system error category -// functions. Usually there is no question as to which API is to be used. +// Copyright Beman Dawes 2003, 2006, 2010 +// Copyright 2018 Peter Dimov // -// In the case of MinGW or Cygwin/MinGW, however, both POSIX and Windows API's are -// available. Chaos ensues if other code thinks one is in use when Boost.System was -// actually built with the other. This header centralizes the API choice and prevents -// user definition of API macros, thus elminating the possibility of mismatches and the -// need to test configurations with little or no practical value. +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt // +// See http://www.boost.org/libs/system for documentation. -//--------------------------------------------------------------------------------------// +// This header is no longer used by Boost.System. +// Its use is discouraged and it will be deprecated. -#ifndef BOOST_SYSTEM_API_CONFIG_HPP -#define BOOST_SYSTEM_API_CONFIG_HPP +// Definition of BOOST_*_API retained for compatibility. -# if defined(BOOST_POSIX_API) || defined(BOOST_WINDOWS_API) -# error user defined BOOST_POSIX_API or BOOST_WINDOWS_API not supported -# endif - -// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use -// Cygwin/MinGW does not predefine _WIN32. -// Standalone MinGW and all other known Windows compilers do predefine _WIN32 -// Compilers that predefine _WIN32 or __MINGW32__ do so for Windows 64-bit builds too. - -# if defined(_WIN32) || defined(__CYGWIN__) // Windows default, including MinGW and Cygwin -# define BOOST_WINDOWS_API +#if defined(_WIN32) || defined(__CYGWIN__) +// Windows default, including MinGW and Cygwin +# define BOOST_WINDOWS_API # else -# define BOOST_POSIX_API -# endif +# define BOOST_POSIX_API +#endif -#endif // BOOST_SYSTEM_API_CONFIG_HPP +#endif // BOOST_SYSTEM_API_CONFIG_HPP_INCLUDED diff --git a/include/boost/system/config.hpp b/include/boost/system/config.hpp index 14faa63..4c45ae6 100644 --- a/include/boost/system/config.hpp +++ b/include/boost/system/config.hpp @@ -1,40 +1,23 @@ -// boost/system/config.hpp -----------------------------------------------------------// +#ifndef BOOST_SYSTEM_CONFIG_HPP_INCLUDED +#define BOOST_SYSTEM_CONFIG_HPP_INCLUDED -// Copyright Beman Dawes 2003, 2006 +// Copyright Beman Dawes 2003, 2006 +// Copyright 2018 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) +// +// See http://www.boost.org/libs/system for documentation. -// 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 http://www.boost.org/libs/system for documentation. - -#ifndef BOOST_SYSTEM_CONFIG_HPP -#define BOOST_SYSTEM_CONFIG_HPP +// This header is no longer used by Boost.System. +// Its use is discouraged and it will be deprecated. #include -#include -#include // for BOOST_POSIX_API or BOOST_WINDOWS_API -// This header implements separate compilation features as described in -// http://www.boost.org/more/separate_compilation.html +// Included for compatibility. Not used. +#include -// normalize macros ------------------------------------------------------------------// - -#if !defined(BOOST_SYSTEM_DYN_LINK) && !defined(BOOST_SYSTEM_STATIC_LINK) \ - && !defined(BOOST_ALL_DYN_LINK) && !defined(BOOST_ALL_STATIC_LINK) -# define BOOST_SYSTEM_STATIC_LINK -#endif - -#if defined(BOOST_ALL_DYN_LINK) && !defined(BOOST_SYSTEM_DYN_LINK) -# define BOOST_SYSTEM_DYN_LINK -#elif defined(BOOST_ALL_STATIC_LINK) && !defined(BOOST_SYSTEM_STATIC_LINK) -# define BOOST_SYSTEM_STATIC_LINK -#endif - -#if defined(BOOST_SYSTEM_DYN_LINK) && defined(BOOST_SYSTEM_STATIC_LINK) -# error Must not define both BOOST_SYSTEM_DYN_LINK and BOOST_SYSTEM_STATIC_LINK -#endif - -// enable dynamic or static linking as requested --------------------------------------// +// Definition of BOOST_SYSTEM_DECL retained for compatibility. #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK) # if defined(BOOST_SYSTEM_SOURCE) @@ -46,25 +29,4 @@ # define BOOST_SYSTEM_DECL #endif -// enable automatic library variant selection ----------------------------------------// - -#if !defined(BOOST_SYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SYSTEM_NO_LIB) -// -// Set the name of our library, this will get undef'ed by auto_link.hpp -// once it's done with it: -// -#define BOOST_LIB_NAME boost_system -// -// If we're importing code from a dll, then tell auto_link.hpp about it: -// -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK) -# define BOOST_DYN_LINK -#endif -// -// And include the header that does the work: -// -#include -#endif // auto-linking disabled - -#endif // BOOST_SYSTEM_CONFIG_HPP - +#endif // BOOST_SYSTEM_CONFIG_HPP_INCLUDED diff --git a/include/boost/system/detail/config.hpp b/include/boost/system/detail/config.hpp new file mode 100644 index 0000000..e0b193f --- /dev/null +++ b/include/boost/system/detail/config.hpp @@ -0,0 +1,74 @@ +#ifndef BOOST_SYSTEM_DETAIL_CONFIG_HPP_INCLUDED +#define BOOST_SYSTEM_DETAIL_CONFIG_HPP_INCLUDED + +// Copyright 2018 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) +// +// See http://www.boost.org/libs/system for documentation. + +#include + +// BOOST_SYSTEM_HAS_SYSTEM_ERROR + +#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) +# define BOOST_SYSTEM_HAS_SYSTEM_ERROR +#endif + +#if defined(BOOST_MSVC) && BOOST_MSVC < 1700 +// msvc-10.0 has no two-argument map::emplace +# undef BOOST_SYSTEM_HAS_SYSTEM_ERROR +#endif + +// BOOST_SYSTEM_NOEXCEPT +// Retained for backward compatibility only + +#define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT + +// BOOST_SYSTEM_HAS_CONSTEXPR + +#if !defined(BOOST_NO_CXX14_CONSTEXPR) +# define BOOST_SYSTEM_HAS_CONSTEXPR +#endif + +#if defined(__GNUC__) && (__GNUC__ == 7 && __GNUC_MINOR__ < 4) && __cplusplus >= 201700L +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83835 +# undef BOOST_SYSTEM_HAS_CONSTEXPR +#endif + +#if defined(__clang__) && defined(_MSC_VER) && defined(_CPPLIB_VER) +// Clang on Windows with MSVC headers, the constructor of std::error_category +// is not constexpr at least up to VS2017 15.7.x (_MSVC_STL_UPDATE 201803) +# undef BOOST_SYSTEM_HAS_CONSTEXPR +#endif + +#if defined(__clang__) && defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 40900 +// The constructor of std::error_category is not constexpr in libstdc++ 4.8 +# undef BOOST_SYSTEM_HAS_CONSTEXPR +#endif + +#if defined(BOOST_SYSTEM_HAS_CONSTEXPR) +# define BOOST_SYSTEM_CONSTEXPR constexpr +#else +# define BOOST_SYSTEM_CONSTEXPR +#endif + +// BOOST_SYSTEM_REQUIRE_CONST_INIT + +#define BOOST_SYSTEM_REQUIRE_CONST_INIT + +#if defined(__has_cpp_attribute) +#if __has_cpp_attribute(clang::require_constant_initialization) +# undef BOOST_SYSTEM_REQUIRE_CONST_INIT +# define BOOST_SYSTEM_REQUIRE_CONST_INIT [[clang::require_constant_initialization]] +#endif +#endif + +// BOOST_SYSTEM_WIN32 + +#if defined( _WIN32 ) || defined( __CYGWIN__ ) +# define BOOST_SYSTEM_WIN32 +#endif + +#endif // BOOST_SYSTEM_DETAIL_CONFIG_HPP_INCLUDED diff --git a/include/boost/system/detail/std_interoperability.hpp b/include/boost/system/detail/std_interoperability.hpp new file mode 100644 index 0000000..2db8f62 --- /dev/null +++ b/include/boost/system/detail/std_interoperability.hpp @@ -0,0 +1,131 @@ +// Support for interoperability between Boost.System and +// +// Copyright 2018 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) +// +// See library home page at http://www.boost.org/libs/system + +#include +#include + +// + +namespace boost +{ + +namespace system +{ + +namespace detail +{ + +class std_category: public std::error_category +{ +private: + + boost::system::error_category const * pc_; + +public: + + 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 + { + return pc_->default_error_condition( ev ); + } + + 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; +}; + +inline std::error_category const & to_std_category( boost::system::error_category const & cat ) +{ + typedef std::map map_type; + + static map_type map_; + + std::pair p = map_.emplace( &cat, &cat ); + + return p.first->second; +} + +inline bool 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 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; + } +} + +} // namespace detail + +} // namespace system + +} // namespace boost diff --git a/include/boost/system/detail/system_category_win32.hpp b/include/boost/system/detail/system_category_win32.hpp new file mode 100644 index 0000000..075a1ce --- /dev/null +++ b/include/boost/system/detail/system_category_win32.hpp @@ -0,0 +1,204 @@ +// Windows implementation of system_error_category + +// Copyright Beman Dawes 2002, 2006 +// Copyright (c) Microsoft Corporation 2014 +// Copyright 2018 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) + +// See library home page at http://www.boost.org/libs/system + +#include +#include +#include +#include + +// + +namespace boost +{ + +namespace system +{ + +namespace detail +{ + +inline std::string system_category_message_win32( int ev ) +{ + using namespace boost::winapi; + + std::wstring buf( 128, wchar_t() ); + + for( ;; ) + { + DWORD_ retval = boost::winapi::FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_, + NULL, + ev, + MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language + &buf[0], + static_cast( buf.size() ), + NULL + ); + + if( retval > 0 ) + { + buf.resize(retval); + break; + } + else if( boost::winapi::GetLastError() != ERROR_INSUFFICIENT_BUFFER_ ) + { + return "Unknown error"; + } + else + { + buf.resize( buf.size() + buf.size() / 2 ); + } + } + + int num_chars = static_cast( buf.size() + 1 ) * 2; + + boost::winapi::LPSTR_ narrow_buffer = +#if defined(__GNUC__) + (boost::winapi::LPSTR_)__builtin_alloca( num_chars ); +#else + (boost::winapi::LPSTR_)_alloca( num_chars ); +#endif + + if( boost::winapi::WideCharToMultiByte( CP_ACP_, 0, buf.c_str(), -1, narrow_buffer, num_chars, NULL, NULL ) == 0 ) + { + return "Unknown error"; + } + + std::string str( narrow_buffer ); + + while( !str.empty() && ( str[ str.size() - 1 ] == '\n' || str[ str.size() - 1 ] == '\r' ) ) + { + str.erase( str.size() - 1 ); + } + + if( str.size() && str[ str.size() - 1 ] == '.' ) + { + str.erase( str.size() - 1 ); + } + + return str; +} + +inline error_condition system_category_default_error_condition_win32( int ev ) BOOST_NOEXCEPT +{ + // When using the Windows Runtime, most system errors are reported as HRESULTs. + // We want to map the common Win32 errors to their equivalent error condition, + // whether or not they are reported via an HRESULT. + +#define BOOST_SYSTEM_FAILED(hr) ((hr) < 0) +#define BOOST_SYSTEM_HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff) +#define BOOST_SYSTEM_HRESULT_CODE(hr) ((hr) & 0xFFFF) +#define BOOST_SYSTEM_FACILITY_WIN32 7 + + if( BOOST_SYSTEM_FAILED( ev ) && BOOST_SYSTEM_HRESULT_FACILITY( ev ) == BOOST_SYSTEM_FACILITY_WIN32 ) + { + ev = BOOST_SYSTEM_HRESULT_CODE( ev ); + } + +#undef BOOST_SYSTEM_FAILED +#undef BOOST_SYSTEM_HRESULT_FACILITY +#undef BOOST_SYSTEM_HRESULT_CODE +#undef BOOST_SYSTEM_FACILITY_WIN32 + + using namespace boost::winapi; + using namespace errc; + + // Windows system -> posix_errno decode table + // see WinError.h comments for descriptions of errors + + switch ( ev ) + { + case 0: return make_error_condition( success ); + + case ERROR_ACCESS_DENIED_: return make_error_condition( permission_denied ); + case ERROR_ALREADY_EXISTS_: return make_error_condition( file_exists ); + case ERROR_BAD_UNIT_: return make_error_condition( no_such_device ); + case ERROR_BUFFER_OVERFLOW_: return make_error_condition( filename_too_long ); + case ERROR_BUSY_: return make_error_condition( device_or_resource_busy ); + case ERROR_BUSY_DRIVE_: return make_error_condition( device_or_resource_busy ); + case ERROR_CANNOT_MAKE_: return make_error_condition( permission_denied ); + case ERROR_CANTOPEN_: return make_error_condition( io_error ); + case ERROR_CANTREAD_: return make_error_condition( io_error ); + case ERROR_CANTWRITE_: return make_error_condition( io_error ); + case ERROR_CURRENT_DIRECTORY_: return make_error_condition( permission_denied ); + case ERROR_DEV_NOT_EXIST_: return make_error_condition( no_such_device ); + case ERROR_DEVICE_IN_USE_: return make_error_condition( device_or_resource_busy ); + case ERROR_DIR_NOT_EMPTY_: return make_error_condition( directory_not_empty ); + case ERROR_DIRECTORY_: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid" + case ERROR_DISK_FULL_: return make_error_condition( no_space_on_device ); + case ERROR_FILE_EXISTS_: return make_error_condition( file_exists ); + case ERROR_FILE_NOT_FOUND_: return make_error_condition( no_such_file_or_directory ); + case ERROR_HANDLE_DISK_FULL_: return make_error_condition( no_space_on_device ); + case ERROR_INVALID_ACCESS_: return make_error_condition( permission_denied ); + case ERROR_INVALID_DRIVE_: return make_error_condition( no_such_device ); + case ERROR_INVALID_FUNCTION_: return make_error_condition( function_not_supported ); + case ERROR_INVALID_HANDLE_: return make_error_condition( invalid_argument ); + case ERROR_INVALID_NAME_: return make_error_condition( invalid_argument ); + case ERROR_LOCK_VIOLATION_: return make_error_condition( no_lock_available ); + case ERROR_LOCKED_: return make_error_condition( no_lock_available ); + case ERROR_NEGATIVE_SEEK_: return make_error_condition( invalid_argument ); + case ERROR_NOACCESS_: return make_error_condition( permission_denied ); + case ERROR_NOT_ENOUGH_MEMORY_: return make_error_condition( not_enough_memory ); + case ERROR_NOT_READY_: return make_error_condition( resource_unavailable_try_again ); + case ERROR_NOT_SAME_DEVICE_: return make_error_condition( cross_device_link ); + case ERROR_OPEN_FAILED_: return make_error_condition( io_error ); + case ERROR_OPEN_FILES_: return make_error_condition( device_or_resource_busy ); + case ERROR_OPERATION_ABORTED_: return make_error_condition( operation_canceled ); + case ERROR_OUTOFMEMORY_: return make_error_condition( not_enough_memory ); + case ERROR_PATH_NOT_FOUND_: return make_error_condition( no_such_file_or_directory ); + case ERROR_READ_FAULT_: return make_error_condition( io_error ); + case ERROR_RETRY_: return make_error_condition( resource_unavailable_try_again ); + case ERROR_SEEK_: return make_error_condition( io_error ); + case ERROR_SHARING_VIOLATION_: return make_error_condition( permission_denied ); + case ERROR_TOO_MANY_OPEN_FILES_: return make_error_condition( too_many_files_open ); + case ERROR_WRITE_FAULT_: return make_error_condition( io_error ); + case ERROR_WRITE_PROTECT_: return make_error_condition( permission_denied ); + case WSAEACCES_: return make_error_condition( permission_denied ); + case WSAEADDRINUSE_: return make_error_condition( address_in_use ); + case WSAEADDRNOTAVAIL_: return make_error_condition( address_not_available ); + case WSAEAFNOSUPPORT_: return make_error_condition( address_family_not_supported ); + case WSAEALREADY_: return make_error_condition( connection_already_in_progress ); + case WSAEBADF_: return make_error_condition( bad_file_descriptor ); + case WSAECONNABORTED_: return make_error_condition( connection_aborted ); + case WSAECONNREFUSED_: return make_error_condition( connection_refused ); + case WSAECONNRESET_: return make_error_condition( connection_reset ); + case WSAEDESTADDRREQ_: return make_error_condition( destination_address_required ); + case WSAEFAULT_: return make_error_condition( bad_address ); + case WSAEHOSTUNREACH_: return make_error_condition( host_unreachable ); + case WSAEINPROGRESS_: return make_error_condition( operation_in_progress ); + case WSAEINTR_: return make_error_condition( interrupted ); + case WSAEINVAL_: return make_error_condition( invalid_argument ); + case WSAEISCONN_: return make_error_condition( already_connected ); + case WSAEMFILE_: return make_error_condition( too_many_files_open ); + case WSAEMSGSIZE_: return make_error_condition( message_size ); + case WSAENAMETOOLONG_: return make_error_condition( filename_too_long ); + case WSAENETDOWN_: return make_error_condition( network_down ); + case WSAENETRESET_: return make_error_condition( network_reset ); + case WSAENETUNREACH_: return make_error_condition( network_unreachable ); + case WSAENOBUFS_: return make_error_condition( no_buffer_space ); + case WSAENOPROTOOPT_: return make_error_condition( no_protocol_option ); + case WSAENOTCONN_: return make_error_condition( not_connected ); + case WSAENOTSOCK_: return make_error_condition( not_a_socket ); + case WSAEOPNOTSUPP_: return make_error_condition( operation_not_supported ); + case WSAEPROTONOSUPPORT_: return make_error_condition( protocol_not_supported ); + case WSAEPROTOTYPE_: return make_error_condition( wrong_protocol_type ); + case WSAETIMEDOUT_: return make_error_condition( timed_out ); + case WSAEWOULDBLOCK_: return make_error_condition( operation_would_block ); + + default: return error_condition( ev, system_category() ); + } +} + +} // namespace detail + +} // namespace system + +} // namespace boost diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index 2926b9a..6cb09d6 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -1,63 +1,29 @@ -// boost/system/error_code.hpp -------------------------------------------------------// +#ifndef BOOST_SYSTEM_ERROR_CODE_HPP_INCLUDED +#define BOOST_SYSTEM_ERROR_CODE_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 -#ifndef BOOST_SYSTEM_ERROR_CODE_HPP -#define BOOST_SYSTEM_ERROR_CODE_HPP - -#include -#include -#include +#include #include +#include +#include #include #include -#include #include +#include // TODO: undef these macros if not already defined #include -#if !defined(BOOST_POSIX_API) && !defined(BOOST_WINDOWS_API) -# error BOOST_POSIX_API or BOOST_WINDOWS_API must be defined -#endif - -#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR -#include -#endif - -#include // must be the last #include - -#if !defined(BOOST_NO_CXX14_CONSTEXPR) -# define BOOST_SYSTEM_HAS_CONSTEXPR -#endif - -#if defined(__GNUC__) && (__GNUC__ == 7 && __GNUC_MINOR__ < 4) && __cplusplus >= 201700L -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83835 -# undef BOOST_SYSTEM_HAS_CONSTEXPR -#endif - -#if defined(__clang__) && defined(_MSC_VER) && defined(_CPPLIB_VER) -// Clang on Windows with MSVC headers, the constructor of std::error_category -// is not constexpr at least up to VS2017 15.7.x (_MSVC_STL_UPDATE 201803) -# undef BOOST_SYSTEM_HAS_CONSTEXPR -#endif - -#if defined(__clang__) && defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 40900 -// The constructor of std::error_category is not constexpr in libstdc++ 4.8 -# undef BOOST_SYSTEM_HAS_CONSTEXPR -#endif - -#if defined(BOOST_SYSTEM_HAS_CONSTEXPR) -# define BOOST_SYSTEM_CONSTEXPR constexpr -#else -# define BOOST_SYSTEM_CONSTEXPR +#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) +# include #endif namespace boost @@ -70,7 +36,7 @@ class error_code; // values defined by the operating system class error_condition; // portable generic values defined below, but ultimately // based on the POSIX standard -// "Concept" helpers -------------------------------------------------------------// +// "Concept" helpers template struct is_error_code_enum { @@ -82,7 +48,7 @@ template struct is_error_condition_enum static const bool value = false; }; -// generic error_conditions ------------------------------------------------------// +// Generic error_conditions namespace errc { @@ -184,141 +150,55 @@ template<> struct is_error_condition_enum static const bool value = true; }; - -// --------------------------------------------------------------------------------// - -// Operating system specific interfaces ------------------------------------------// - - -// The interface is divided into general and system-specific portions to -// meet these requirements: -// -// * Code calling an operating system API can create an error_code with -// a single category (system_category), even for POSIX-like operating -// systems that return some POSIX errno values and some native errno -// values. This code should not have to pay the cost of distinguishing -// between categories, since it is not yet known if that is needed. -// -// * Users wishing to write system-specific code should be given enums for -// at least the common error cases. -// -// * System specific code should fail at compile time if moved to another -// operating system. - -// The system specific portions of the interface are located in headers -// with names reflecting the operating system. For example, -// -// -// -// -// -// These headers are effectively empty for compiles on operating systems -// where they are not applicable. - -// --------------------------------------------------------------------------------// +// class error_category #ifdef BOOST_MSVC -#pragma warning(push) +#pragma warning( push ) // 'this' : used in base member initializer list -#pragma warning(disable: 4355) +#pragma warning( disable: 4355 ) #endif -// class error_category ------------------------------------------------// - -class error_category: public noncopyable +class error_category { -#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +public: + + error_category( error_category const & ) = delete; + error_category& operator=( error_category const & ) = delete; + +#else +private: + + error_category( error_category const & ); + error_category& operator=( error_category const & ); + +#endif private: - class std_category: public std::error_category - { - private: + boost::ulong_long_type id_; - boost::system::error_category const * pc_; +protected: - public: +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS) - BOOST_SYSTEM_CONSTEXPR 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: - - operator std::error_category const & () const BOOST_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_; - } + ~error_category() = default; #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: - - BOOST_SYSTEM_CONSTEXPR 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_; - -#endif - -public: - - BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: std_cat_( this ) + ~error_category() { } - virtual ~error_category() +#endif + + explicit BOOST_SYSTEM_CONSTEXPR error_category( boost::ulong_long_type id ) BOOST_NOEXCEPT: id_( id ) + { + } + +public: + + BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: id_( 0 ) { } @@ -326,48 +206,63 @@ public: virtual std::string message( int ev ) const = 0; - inline virtual error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT; - inline virtual bool equivalent( int code, const error_condition & condition ) const BOOST_NOEXCEPT; - inline virtual bool equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT; + virtual error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT; + virtual bool equivalent( int code, const error_condition & condition ) const BOOST_NOEXCEPT; + virtual bool equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT; + + BOOST_SYSTEM_CONSTEXPR bool operator==( const error_category & rhs ) const BOOST_NOEXCEPT + { + return rhs.id_ == 0? this == &rhs: id_ == rhs.id_; + } + + BOOST_SYSTEM_CONSTEXPR bool operator!=( const error_category & rhs ) const BOOST_NOEXCEPT + { + return !( *this == rhs ); + } + + BOOST_SYSTEM_CONSTEXPR bool operator<( const error_category & rhs ) const BOOST_NOEXCEPT + { + if( id_ < rhs.id_ ) + { + return true; + } + + if( id_ > rhs.id_ ) + { + return false; + } + + if( rhs.id_ != 0 ) + { + return false; // equal + } + + return std::less()( this, &rhs ); + } + +#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) + + operator std::error_category const & () const BOOST_NOEXCEPT; + +#endif }; -BOOST_SYSTEM_CONSTEXPR inline bool operator==( const error_category & lhs, const error_category & rhs ) BOOST_NOEXCEPT -{ - return &lhs == &rhs; -} - -BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_category & lhs, const error_category & rhs ) BOOST_NOEXCEPT -{ - return &lhs != &rhs; -} - -inline bool operator<( const error_category & lhs, const error_category & rhs ) BOOST_NOEXCEPT -{ - return std::less()( &lhs, &rhs ); -} - #ifdef BOOST_MSVC -#pragma warning(pop) +#pragma warning( pop ) #endif -// predefined error categories ---------------------------------------------------// +// predefined error categories namespace detail { -#ifdef BOOST_ERROR_CODE_HEADER_ONLY -# define BOOST_SYSTEM_DECL_ -#else -# define BOOST_SYSTEM_DECL_ BOOST_SYSTEM_DECL -#endif - class generic_error_category: public error_category { public: // clang++ 3.8 and below: initialization of const object // requires a user-provided default constructor - BOOST_SYSTEM_CONSTEXPR generic_error_category() BOOST_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR generic_error_category() BOOST_NOEXCEPT: error_category( 0xB2AB117A257EDF0Dull ) { } @@ -376,14 +271,14 @@ public: return "generic"; } - BOOST_SYSTEM_DECL_ std::string message( int ev ) const; + std::string message( int ev ) const; }; class system_error_category: public error_category { public: - BOOST_SYSTEM_CONSTEXPR system_error_category() BOOST_NOEXCEPT + BOOST_SYSTEM_CONSTEXPR system_error_category() BOOST_NOEXCEPT: error_category( 0x8FAFD21E25C5E09Bull ) { } @@ -392,120 +287,57 @@ public: return "system"; } - BOOST_SYSTEM_DECL_ std::string message( int ev ) const; - BOOST_SYSTEM_DECL_ error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT; + std::string message( int ev ) const; + error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT; }; -#undef BOOST_SYSTEM_DECL_ - } // namespace detail -#define BOOST_SYSTEM_REQUIRE_CONST_INIT +// generic_category(), system_category() -#if defined(__has_cpp_attribute) -#if __has_cpp_attribute(clang::require_constant_initialization) -# undef BOOST_SYSTEM_REQUIRE_CONST_INIT -# define BOOST_SYSTEM_REQUIRE_CONST_INIT [[clang::require_constant_initialization]] -#endif -#endif - -#if defined(BOOST_ERROR_CODE_HEADER_ONLY) - -# if defined(BOOST_SYSTEM_HAS_CONSTEXPR) +#if defined(BOOST_SYSTEM_HAS_CONSTEXPR) namespace detail { template struct cat_holder { - static system_error_category system_category_instance; - static generic_error_category generic_category_instance; + BOOST_SYSTEM_REQUIRE_CONST_INIT static constexpr system_error_category system_category_instance{}; + BOOST_SYSTEM_REQUIRE_CONST_INIT static constexpr generic_error_category generic_category_instance{}; }; -template BOOST_SYSTEM_REQUIRE_CONST_INIT system_error_category cat_holder::system_category_instance; -template BOOST_SYSTEM_REQUIRE_CONST_INIT generic_error_category cat_holder::generic_category_instance; +template BOOST_SYSTEM_REQUIRE_CONST_INIT constexpr system_error_category cat_holder::system_category_instance; +template BOOST_SYSTEM_REQUIRE_CONST_INIT constexpr generic_error_category cat_holder::generic_category_instance; } // namespace detail -constexpr const error_category & system_category() BOOST_NOEXCEPT +constexpr error_category const & system_category() BOOST_NOEXCEPT { return detail::cat_holder::system_category_instance; } -constexpr const error_category & generic_category() BOOST_NOEXCEPT +constexpr error_category const & generic_category() BOOST_NOEXCEPT { return detail::cat_holder::generic_category_instance; } -# else +#else // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR) -inline const error_category & system_category() BOOST_NOEXCEPT +inline error_category const & system_category() BOOST_NOEXCEPT { static const detail::system_error_category system_category_instance; return system_category_instance; } -inline const error_category & generic_category() BOOST_NOEXCEPT +inline error_category const & generic_category() BOOST_NOEXCEPT { static const detail::generic_error_category generic_category_instance; return generic_category_instance; } -# endif +#endif // #if defined(BOOST_SYSTEM_HAS_CONSTEXPR) -#elif defined(BOOST_SYSTEM_HAS_CONSTEXPR) - -namespace detail -{ - -#if defined(BOOST_SYSTEM_SOURCE) - -// clang++ requires a strictly matching declaration -BOOST_SYSTEM_DECL extern system_error_category system_category_instance; -BOOST_SYSTEM_DECL extern generic_error_category generic_category_instance; - -#else - -extern system_error_category system_category_instance; -extern generic_error_category generic_category_instance; - -#endif - -} // namespace detail - -constexpr const error_category & system_category() BOOST_NOEXCEPT -{ - return detail::system_category_instance; -} - -constexpr const error_category & generic_category() BOOST_NOEXCEPT -{ - return detail::generic_category_instance; -} - -#else - -namespace detail -{ - -BOOST_SYSTEM_DECL const error_category & system_category_ncx() BOOST_NOEXCEPT; -BOOST_SYSTEM_DECL const error_category & generic_category_ncx() BOOST_NOEXCEPT; - -} // namespace detail - -inline const error_category & system_category() BOOST_NOEXCEPT -{ - return detail::system_category_ncx(); -} - -inline const error_category & generic_category() BOOST_NOEXCEPT -{ - return detail::generic_category_ncx(); -} - -#endif - -// deprecated synonyms ------------------------------------------------------------// +// deprecated synonyms #ifdef BOOST_SYSTEM_ENABLE_DEPRECATED @@ -518,12 +350,17 @@ static const error_category & native_ecat BOOST_ATTRIBUTE_UNUSED = system_catego #endif -// class error_condition ---------------------------------------------------------// +// class error_condition -// error_conditions are portable, error_codes are system or library specific +// error_conditions are portable, error_codes are system or library specific class error_condition { +private: + + int m_val; + error_category const * m_cat; + public: // constructors: @@ -536,8 +373,8 @@ public: { } - template error_condition( ErrorConditionEnum e, - typename boost::enable_if_::value>::type* = 0) BOOST_NOEXCEPT + template BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e, + typename boost::enable_if_::value>::type* = 0) BOOST_NOEXCEPT { *this = make_error_condition( e ); } @@ -551,7 +388,7 @@ public: } template - typename boost::enable_if_::value, error_condition>::type & + BOOST_SYSTEM_CONSTEXPR typename boost::enable_if_::value, error_condition>::type & operator=( ErrorConditionEnum val ) BOOST_NOEXCEPT { *this = make_error_condition( val ); @@ -595,7 +432,7 @@ public: BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error { - return m_val == 0 ? 0 : unspecified_bool_true; + return m_val == 0? 0 : unspecified_bool_true; } BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error @@ -611,15 +448,15 @@ public: 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_val == rhs.m_val; + return lhs.m_val == rhs.m_val && *lhs.m_cat == *rhs.m_cat; } - 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.m_cat < *rhs.m_cat || ( *lhs.m_cat == *rhs.m_cat && lhs.m_val < rhs.m_val ); } -#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR +#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) operator std::error_condition () const BOOST_NOEXCEPT { @@ -627,14 +464,9 @@ public: } #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 @@ -645,6 +477,11 @@ private: class error_code { +private: + + int m_val; + const error_category * m_cat; + public: // constructors: @@ -657,7 +494,7 @@ public: { } - template error_code( ErrorCodeEnum e, + template BOOST_SYSTEM_CONSTEXPR error_code( ErrorCodeEnum e, typename boost::enable_if_::value>::type* = 0 ) BOOST_NOEXCEPT { *this = make_error_code( e ); @@ -672,7 +509,7 @@ public: } template - typename boost::enable_if_::value, error_code>::type & + BOOST_SYSTEM_CONSTEXPR typename boost::enable_if_::value, error_code>::type & operator=( ErrorCodeEnum val ) BOOST_NOEXCEPT { *this = make_error_code( val ); @@ -699,7 +536,7 @@ public: error_condition default_error_condition() const BOOST_NOEXCEPT { - return m_cat->default_error_condition(value()); + return m_cat->default_error_condition( value() ); } std::string message() const @@ -721,7 +558,7 @@ public: BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT // true if error { - return m_val == 0 ? 0 : unspecified_bool_true; + return m_val == 0? 0 : unspecified_bool_true; } BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT // true if no error @@ -735,18 +572,18 @@ public: // the more symmetrical non-member syntax allows enum // conversions work for both rhs and lhs. - + 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_val == rhs.m_val; + return lhs.m_val == rhs.m_val && *lhs.m_cat == *rhs.m_cat; } - 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.m_cat < *rhs.m_cat || ( *lhs.m_cat == *rhs.m_cat && lhs.m_val < rhs.m_val ); } -#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR +#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) operator std::error_code () const BOOST_NOEXCEPT { @@ -754,27 +591,12 @@ public: } #endif - -private: - - int m_val; - const error_category * m_cat; }; -// predefined error_code object used as "throw on error" tag - -#ifdef BOOST_SYSTEM_ENABLE_DEPRECATED - -BOOST_SYSTEM_DECL extern error_code throws; - -#endif - -// Moving from a "throws" object to a "throws" function without breaking -// existing code is a bit of a problem. The workaround is to place the -// "throws" function in namespace boost rather than namespace boost::system. - } // namespace system - + +// boost::throws() + namespace detail { @@ -807,11 +629,11 @@ inline system::error_code& throws() return *detail::throws(); } +// non-member functions of error_code and error_condition + namespace system { -// non-member functions ------------------------------------------------// - BOOST_SYSTEM_CONSTEXPR inline bool operator!=( const error_code & lhs, const error_code & rhs ) BOOST_NOEXCEPT { return !( lhs == rhs ); @@ -852,123 +674,119 @@ template inline std::size_t hash_value( const error_code & ec ) { + // TODO use category id_, FNV combiner return static_cast( ec.value() ) + reinterpret_cast( &ec.category() ); } -// make_* functions for errc::errc_t ---------------------------------------------// +// make_* functions for errc::errc_t namespace errc { -// explicit conversion: -inline error_code make_error_code( errc_t e ) BOOST_NOEXCEPT +// explicit conversion: +BOOST_SYSTEM_CONSTEXPR inline error_code make_error_code( errc_t e ) BOOST_NOEXCEPT { return error_code( e, generic_category() ); } -// implicit conversion: -inline error_condition make_error_condition( errc_t e ) BOOST_NOEXCEPT +// implicit conversion: +BOOST_SYSTEM_CONSTEXPR inline error_condition make_error_condition( errc_t e ) BOOST_NOEXCEPT { return error_condition( e, generic_category() ); } } // namespace errc -// error_category default implementation -----------------------------------------// +// error_category default implementation -error_condition error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT +inline error_condition error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT { return error_condition( ev, *this ); } -bool error_category::equivalent( int code, const error_condition & condition ) const BOOST_NOEXCEPT +inline bool error_category::equivalent( int code, const error_condition & condition ) const BOOST_NOEXCEPT { return default_error_condition( code ) == condition; } -bool error_category::equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT +inline bool error_category::equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT { return *this == code.category() && code.value() == condition; } -#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR +// generic_error_category implementation -inline std::error_condition error_category::std_category::default_error_condition( int ev ) const BOOST_NOEXCEPT +namespace detail { - return pc_->default_error_condition( ev ); -} -inline bool error_category::std_category::equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT +inline char const * generic_error_category_message( int ev ) { - 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 ); - } - +#ifdef BOOST_MSVC +#pragma warning( push ) +#pragma warning( disable: 4996 ) #endif - else - { - return default_error_condition( code ) == condition; - } -} + char const * m = std::strerror( ev ); -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 ); - } +#ifdef BOOST_MSVC +#pragma warning( pop ) #endif - else if( *pc_ == boost::system::generic_category() ) - { - return std::generic_category().equivalent( code, condition ); - } - else - { - return false; - } + return m? m: "Unknown error"; } -#endif // #ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR +inline std::string generic_error_category::message( int ev ) const +{ + return generic_error_category_message( ev ); +} + +} // namespace detail } // namespace system } // namespace boost -#include // pops abi_prefix.hpp pragmas +// system_error_category implementation -#ifdef BOOST_ERROR_CODE_HEADER_ONLY -# include -#endif +#if defined(BOOST_SYSTEM_WIN32) -#endif // BOOST_SYSTEM_ERROR_CODE_HPP +#include + +inline std::string boost::system::detail::system_error_category::message( int ev ) const +{ + return system_category_message_win32( ev ); +} + +inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT +{ + return system_category_default_error_condition_win32( ev ); +} + +#else // #if defined(BOOST_SYSTEM_WIN32) + +inline std::string boost::system::detail::system_error_category::message( int ev ) const +{ + return generic_error_category_message( ev ); +} + +inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT +{ + return boost::system::error_condition( ev, generic_category() ); +} + +#endif // #if defined(BOOST_SYSTEM_WIN32) + +// interoperability with std::error_code, std::error_condition + +#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) + +#include + +inline boost::system::error_category::operator std::error_category const & () const BOOST_NOEXCEPT +{ + return boost::system::detail::to_std_category( *this ); +} + +#endif // #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) + +#endif // BOOST_SYSTEM_ERROR_CODE_HPP_INCLUDED diff --git a/src/error_code.cpp b/src/error_code.cpp index aa628ab..d451940 100644 --- a/src/error_code.cpp +++ b/src/error_code.cpp @@ -1,6 +1,7 @@ -// error_code support implementation file ----------------------------------// +// error_code stub implementation, for compatibility only // Copyright Beman Dawes 2002, 2006 +// Copyright Peter Dimov 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) @@ -9,12 +10,24 @@ //----------------------------------------------------------------------------// -// define BOOST_SYSTEM_SOURCE so that knows -// the library is being built (possibly exporting rather than importing code) -#define BOOST_SYSTEM_SOURCE +#include -#include - -#ifndef BOOST_ERROR_CODE_HEADER_ONLY -#include +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK) +# define BOOST_SYSTEM_DECL BOOST_SYMBOL_EXPORT +#else +# define BOOST_SYSTEM_DECL #endif + +namespace boost +{ + +namespace system +{ + +BOOST_SYSTEM_DECL void dummy_exported_function() +{ +} + +} // namespace system + +} // namespace boost diff --git a/test/dynamic_link_test.cpp b/test/dynamic_link_test.cpp index 87f37c2..e49dea7 100644 --- a/test/dynamic_link_test.cpp +++ b/test/dynamic_link_test.cpp @@ -19,7 +19,7 @@ //--------------------------------------------------------------------------------------// #include - +#include #include namespace boost @@ -52,4 +52,4 @@ int main() std::cout << " error: failed to catch boost::system::system_error\n"; return 1; -} \ No newline at end of file +} diff --git a/test/error_code_test.cpp b/test/error_code_test.cpp index 7965541..82f0fb1 100644 --- a/test/error_code_test.cpp +++ b/test/error_code_test.cpp @@ -123,17 +123,7 @@ int main( int, char ** ) BOOST_TEST( generic_category() != system_category() ); BOOST_TEST( system_category() != generic_category() ); - if ( std::less()( &generic_category(), &system_category() ) ) - { - BOOST_TEST( generic_category() < system_category() ); - BOOST_TEST( !(system_category() < generic_category()) ); - } - else - { - BOOST_TEST( system_category() < generic_category() ); - BOOST_TEST( !(generic_category() < system_category()) ); - } - + BOOST_TEST_NE( generic_category() < system_category(), system_category() < generic_category() ); error_code ec; error_condition econd; diff --git a/test/std_interop_test.cpp b/test/std_interop_test.cpp index 5e52c50..94845d1 100644 --- a/test/std_interop_test.cpp +++ b/test/std_interop_test.cpp @@ -11,10 +11,14 @@ // Avoid spurious VC++ warnings # define _CRT_SECURE_NO_WARNINGS +#include #include +#include #include -#if defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) +#if !defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) + +BOOST_PRAGMA_MESSAGE( "BOOST_SYSTEM_HAS_SYSTEM_ERROR not defined, test will be skipped" ) int main() { @@ -25,7 +29,6 @@ int main() #else -#include #include #include #include diff --git a/test/std_mismatch_test.cpp b/test/std_mismatch_test.cpp index 9c97cdd..3a34bb2 100644 --- a/test/std_mismatch_test.cpp +++ b/test/std_mismatch_test.cpp @@ -11,10 +11,14 @@ // Avoid spurious VC++ warnings # define _CRT_SECURE_NO_WARNINGS +#include #include +#include #include -#if defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) +#if !defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) + +BOOST_PRAGMA_MESSAGE( "BOOST_SYSTEM_HAS_SYSTEM_ERROR not defined, test will be skipped" ) int main() { @@ -25,7 +29,6 @@ int main() #else -#include #include #include #include diff --git a/test/throw_test.cpp b/test/throw_test.cpp index c42f422..b04d3bf 100644 --- a/test/throw_test.cpp +++ b/test/throw_test.cpp @@ -18,6 +18,7 @@ #define BOOST_SYSTEM_SOURCE #include +#include namespace boost { From 038786179a3a092e3ac5cdc49594ea075053c5da Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 03:05:17 +0300 Subject: [PATCH 04/23] Remove unnecessary files --- include/boost/system/detail/error_code.ipp | 496 ------------------ .../detail/local_free_on_destruction.hpp | 42 -- 2 files changed, 538 deletions(-) delete mode 100644 include/boost/system/detail/error_code.ipp delete mode 100644 include/boost/system/detail/local_free_on_destruction.hpp diff --git a/include/boost/system/detail/error_code.ipp b/include/boost/system/detail/error_code.ipp deleted file mode 100644 index f9516e0..0000000 --- a/include/boost/system/detail/error_code.ipp +++ /dev/null @@ -1,496 +0,0 @@ -// error_code support implementation file --------------------------------------------// - -// Copyright Beman Dawes 2002, 2006 -// Copyright (c) Microsoft Corporation 2014 -// 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 -#include -#include -#include - -#include // for strerror/strerror_r - -# if defined( BOOST_WINDOWS_API ) -# include -# include -# include -# if !BOOST_PLAT_WINDOWS_RUNTIME -# include -# endif -# ifndef ERROR_INCORRECT_SIZE -# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS -# endif -# endif - -//--------------------------------------------------------------------------------------// -namespace boost -{ - -namespace system -{ - -namespace detail -{ - -#ifdef BOOST_ERROR_CODE_HEADER_ONLY -# define BOOST_SYSTEM_DECL_ inline -#else -# define BOOST_SYSTEM_DECL_ BOOST_SYSTEM_DECL -#endif - - // generic_error_category implementation ---------------------------------// - - BOOST_SYSTEM_DECL_ std::string generic_error_category::message( int ev ) const - { - using namespace boost::system::errc; -#if defined(__PGI) - using boost::system::errc::invalid_argument; -#endif - - static std::string unknown_err( "Unknown error" ); - // strerror_r is preferred because it is always thread safe, - // however, we fallback to strerror in certain cases because: - // -- Windows doesn't provide strerror_r. - // -- HP and Sun do provide strerror_r on newer systems, but there is - // no way to tell if is available at runtime and in any case their - // versions of strerror are thread safe anyhow. - // -- Linux only sometimes provides strerror_r. - // -- Tru64 provides strerror_r only when compiled -pthread. - // -- VMS doesn't provide strerror_r, but on this platform, strerror is - // thread safe. - # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\ - || (defined(__linux) && (!defined(__USE_XOPEN2K)\ - || defined(BOOST_SYSTEM_USE_STRERROR)))\ - || (defined(__osf__) && !defined(_REENTRANT))\ - || (defined(__INTEGRITY))\ - || (defined(__vms))\ - || (defined(__QNXNTO__)) - const char * c_str = std::strerror( ev ); - return c_str - ? std::string( c_str ) - : unknown_err; - # else // use strerror_r - char buf[64]; - char * bp = buf; - std::size_t sz = sizeof(buf); - # if defined(__CYGWIN__) || defined(__USE_GNU) - // Oddball version of strerror_r - const char * c_str = strerror_r( ev, bp, sz ); - return c_str - ? std::string( c_str ) - : unknown_err; - # else - // POSIX version of strerror_r - int result; - for (;;) - { - // strerror_r returns 0 on success, otherwise ERANGE if buffer too small, - // invalid_argument if ev not a valid error number - # if defined (__sgi) - const char * c_str = strerror( ev ); - result = 0; - return c_str - ? std::string( c_str ) - : unknown_err; - # else - result = strerror_r( ev, bp, sz ); - # endif - if (result == 0 ) - break; - else - { - # if defined(__linux) - // Linux strerror_r returns -1 on error, with error number in errno - result = errno; - # endif - if ( result != ERANGE ) break; - if ( sz > sizeof(buf) ) std::free( bp ); - sz *= 2; - if ( (bp = static_cast(std::malloc( sz ))) == 0 ) - return std::string( "ENOMEM" ); - } - } - std::string msg; -# ifndef BOOST_NO_EXCEPTIONS - try -# endif - { - msg = ( ( result == invalid_argument ) ? "Unknown error" : bp ); - } - -# ifndef BOOST_NO_EXCEPTIONS - // See ticket #2098 - catch(...) - { - // just eat the exception - } -# endif - - if ( sz > sizeof(buf) ) std::free( bp ); - return msg; - # endif // else POSIX version of strerror_r - # endif // else use strerror_r - } - // system_error_category implementation --------------------------------------------// - - BOOST_SYSTEM_DECL_ error_condition system_error_category::default_error_condition( int ev ) const - BOOST_SYSTEM_NOEXCEPT - { - using namespace boost::system::errc; -#if defined(__PGI) - using boost::system::errc::invalid_argument; -#endif - -# if defined(BOOST_WINDOWS_API) -# if defined(WINAPI_FAMILY) && ((WINAPI_FAMILY & WINAPI_PARTITION_APP) != 0) - // When using the Windows Runtime, most system errors are reported as HRESULTs. - // We want to map the common Win32 errors to their equivalent error condition, - // whether or not they are reported via an HRESULT. - if ( ev < 0 ) // Check for failed HRESULTs only. - if ( HRESULT_FACILITY( ev ) == FACILITY_WIN32 ) - ev = HRESULT_CODE( ev ); -# endif -# endif - -# if defined(BOOST_WINDOWS_API) - - using namespace boost::winapi; // for error codes - -# endif - - switch ( ev ) - { - case 0: return make_error_condition( success ); -# if defined(BOOST_POSIX_API) - // POSIX-like O/S -> posix_errno decode table -------------------------------------// - case E2BIG: return make_error_condition( argument_list_too_long ); - case EACCES: return make_error_condition( permission_denied ); - case EADDRINUSE: return make_error_condition( address_in_use ); - case EADDRNOTAVAIL: return make_error_condition( address_not_available ); - case EAFNOSUPPORT: return make_error_condition( address_family_not_supported ); - case EAGAIN: return make_error_condition( resource_unavailable_try_again ); -# if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino - case EALREADY: return make_error_condition( connection_already_in_progress ); -# endif - case EBADF: return make_error_condition( bad_file_descriptor ); - case EBADMSG: return make_error_condition( bad_message ); - case EBUSY: return make_error_condition( device_or_resource_busy ); - case ECANCELED: return make_error_condition( operation_canceled ); - case ECHILD: return make_error_condition( no_child_process ); - case ECONNABORTED: return make_error_condition( connection_aborted ); - case ECONNREFUSED: return make_error_condition( connection_refused ); - case ECONNRESET: return make_error_condition( connection_reset ); - case EDEADLK: return make_error_condition( resource_deadlock_would_occur ); - case EDESTADDRREQ: return make_error_condition( destination_address_required ); - case EDOM: return make_error_condition( argument_out_of_domain ); - case EEXIST: return make_error_condition( file_exists ); - case EFAULT: return make_error_condition( bad_address ); - case EFBIG: return make_error_condition( file_too_large ); - case EHOSTUNREACH: return make_error_condition( host_unreachable ); - case EIDRM: return make_error_condition( identifier_removed ); - case EILSEQ: return make_error_condition( illegal_byte_sequence ); - case EINPROGRESS: return make_error_condition( operation_in_progress ); - case EINTR: return make_error_condition( interrupted ); - case EINVAL: return make_error_condition( invalid_argument ); - case EIO: return make_error_condition( io_error ); - case EISCONN: return make_error_condition( already_connected ); - case EISDIR: return make_error_condition( is_a_directory ); - case ELOOP: return make_error_condition( too_many_symbolic_link_levels ); - case EMFILE: return make_error_condition( too_many_files_open ); - case EMLINK: return make_error_condition( too_many_links ); - case EMSGSIZE: return make_error_condition( message_size ); - case ENAMETOOLONG: return make_error_condition( filename_too_long ); - case ENETDOWN: return make_error_condition( network_down ); - case ENETRESET: return make_error_condition( network_reset ); - case ENETUNREACH: return make_error_condition( network_unreachable ); - case ENFILE: return make_error_condition( too_many_files_open_in_system ); - case ENOBUFS: return make_error_condition( no_buffer_space ); - case ENODATA: return make_error_condition( no_message_available ); - case ENODEV: return make_error_condition( no_such_device ); - case ENOENT: return make_error_condition( no_such_file_or_directory ); - case ENOEXEC: return make_error_condition( executable_format_error ); - case ENOLCK: return make_error_condition( no_lock_available ); - case ENOLINK: return make_error_condition( no_link ); - case ENOMEM: return make_error_condition( not_enough_memory ); - case ENOMSG: return make_error_condition( no_message ); - case ENOPROTOOPT: return make_error_condition( no_protocol_option ); - case ENOSPC: return make_error_condition( no_space_on_device ); - case ENOSR: return make_error_condition( no_stream_resources ); - case ENOSTR: return make_error_condition( not_a_stream ); - case ENOSYS: return make_error_condition( function_not_supported ); - case ENOTCONN: return make_error_condition( not_connected ); - case ENOTDIR: return make_error_condition( not_a_directory ); - # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value - case ENOTEMPTY: return make_error_condition( directory_not_empty ); - # endif // ENOTEMPTY != EEXIST - # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips - case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable ); - # endif // ENOTRECOVERABLE != ECONNRESET - case ENOTSOCK: return make_error_condition( not_a_socket ); - case ENOTSUP: return make_error_condition( not_supported ); - case ENOTTY: return make_error_condition( inappropriate_io_control_operation ); - case ENXIO: return make_error_condition( no_such_device_or_address ); - # if EOPNOTSUPP != ENOTSUP - case EOPNOTSUPP: return make_error_condition( operation_not_supported ); - # endif // EOPNOTSUPP != ENOTSUP - case EOVERFLOW: return make_error_condition( value_too_large ); - # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips - case EOWNERDEAD: return make_error_condition( owner_dead ); - # endif // EOWNERDEAD != ECONNABORTED - case EPERM: return make_error_condition( operation_not_permitted ); - case EPIPE: return make_error_condition( broken_pipe ); - case EPROTO: return make_error_condition( protocol_error ); - case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); - case EPROTOTYPE: return make_error_condition( wrong_protocol_type ); - case ERANGE: return make_error_condition( result_out_of_range ); - case EROFS: return make_error_condition( read_only_file_system ); - case ESPIPE: return make_error_condition( invalid_seek ); - case ESRCH: return make_error_condition( no_such_process ); - case ETIME: return make_error_condition( stream_timeout ); - case ETIMEDOUT: return make_error_condition( timed_out ); - case ETXTBSY: return make_error_condition( text_file_busy ); - # if EAGAIN != EWOULDBLOCK - case EWOULDBLOCK: return make_error_condition( operation_would_block ); - # endif // EAGAIN != EWOULDBLOCK - case EXDEV: return make_error_condition( cross_device_link ); - #else - // Windows system -> posix_errno decode table ---------------------------// - // see WinError.h comments for descriptions of errors - case ERROR_ACCESS_DENIED_: return make_error_condition( permission_denied ); - case ERROR_ALREADY_EXISTS_: return make_error_condition( file_exists ); - case ERROR_BAD_UNIT_: return make_error_condition( no_such_device ); - case ERROR_BUFFER_OVERFLOW_: return make_error_condition( filename_too_long ); - case ERROR_BUSY_: return make_error_condition( device_or_resource_busy ); - case ERROR_BUSY_DRIVE_: return make_error_condition( device_or_resource_busy ); - case ERROR_CANNOT_MAKE_: return make_error_condition( permission_denied ); - case ERROR_CANTOPEN_: return make_error_condition( io_error ); - case ERROR_CANTREAD_: return make_error_condition( io_error ); - case ERROR_CANTWRITE_: return make_error_condition( io_error ); - case ERROR_CURRENT_DIRECTORY_: return make_error_condition( permission_denied ); - case ERROR_DEV_NOT_EXIST_: return make_error_condition( no_such_device ); - case ERROR_DEVICE_IN_USE_: return make_error_condition( device_or_resource_busy ); - case ERROR_DIR_NOT_EMPTY_: return make_error_condition( directory_not_empty ); - case ERROR_DIRECTORY_: return make_error_condition( invalid_argument );\ - // WinError.h: "The directory name is invalid" - case ERROR_DISK_FULL_: return make_error_condition( no_space_on_device ); - case ERROR_FILE_EXISTS_: return make_error_condition( file_exists ); - case ERROR_FILE_NOT_FOUND_: return make_error_condition( no_such_file_or_directory ); - case ERROR_HANDLE_DISK_FULL_: return make_error_condition( no_space_on_device ); - case ERROR_INVALID_ACCESS_: return make_error_condition( permission_denied ); - case ERROR_INVALID_DRIVE_: return make_error_condition( no_such_device ); - case ERROR_INVALID_FUNCTION_: return make_error_condition( function_not_supported ); - case ERROR_INVALID_HANDLE_: return make_error_condition( invalid_argument ); - case ERROR_INVALID_NAME_: return make_error_condition( invalid_argument ); - case ERROR_LOCK_VIOLATION_: return make_error_condition( no_lock_available ); - case ERROR_LOCKED_: return make_error_condition( no_lock_available ); - case ERROR_NEGATIVE_SEEK_: return make_error_condition( invalid_argument ); - case ERROR_NOACCESS_: return make_error_condition( permission_denied ); - case ERROR_NOT_ENOUGH_MEMORY_: return make_error_condition( not_enough_memory ); - case ERROR_NOT_READY_: return make_error_condition( resource_unavailable_try_again ); - case ERROR_NOT_SAME_DEVICE_: return make_error_condition( cross_device_link ); - case ERROR_OPEN_FAILED_: return make_error_condition( io_error ); - case ERROR_OPEN_FILES_: return make_error_condition( device_or_resource_busy ); - case ERROR_OPERATION_ABORTED_: return make_error_condition( operation_canceled ); - case ERROR_OUTOFMEMORY_: return make_error_condition( not_enough_memory ); - case ERROR_PATH_NOT_FOUND_: return make_error_condition( no_such_file_or_directory ); - case ERROR_READ_FAULT_: return make_error_condition( io_error ); - case ERROR_RETRY_: return make_error_condition( resource_unavailable_try_again ); - case ERROR_SEEK_: return make_error_condition( io_error ); - case ERROR_SHARING_VIOLATION_: return make_error_condition( permission_denied ); - case ERROR_TOO_MANY_OPEN_FILES_: return make_error_condition( too_many_files_open ); - case ERROR_WRITE_FAULT_: return make_error_condition( io_error ); - case ERROR_WRITE_PROTECT_: return make_error_condition( permission_denied ); - case WSAEACCES_: return make_error_condition( permission_denied ); - case WSAEADDRINUSE_: return make_error_condition( address_in_use ); - case WSAEADDRNOTAVAIL_: return make_error_condition( address_not_available ); - case WSAEAFNOSUPPORT_: return make_error_condition( address_family_not_supported ); - case WSAEALREADY_: return make_error_condition( connection_already_in_progress ); - case WSAEBADF_: return make_error_condition( bad_file_descriptor ); - case WSAECONNABORTED_: return make_error_condition( connection_aborted ); - case WSAECONNREFUSED_: return make_error_condition( connection_refused ); - case WSAECONNRESET_: return make_error_condition( connection_reset ); - case WSAEDESTADDRREQ_: return make_error_condition( destination_address_required ); - case WSAEFAULT_: return make_error_condition( bad_address ); - case WSAEHOSTUNREACH_: return make_error_condition( host_unreachable ); - case WSAEINPROGRESS_: return make_error_condition( operation_in_progress ); - case WSAEINTR_: return make_error_condition( interrupted ); - case WSAEINVAL_: return make_error_condition( invalid_argument ); - case WSAEISCONN_: return make_error_condition( already_connected ); - case WSAEMFILE_: return make_error_condition( too_many_files_open ); - case WSAEMSGSIZE_: return make_error_condition( message_size ); - case WSAENAMETOOLONG_: return make_error_condition( filename_too_long ); - case WSAENETDOWN_: return make_error_condition( network_down ); - case WSAENETRESET_: return make_error_condition( network_reset ); - case WSAENETUNREACH_: return make_error_condition( network_unreachable ); - case WSAENOBUFS_: return make_error_condition( no_buffer_space ); - case WSAENOPROTOOPT_: return make_error_condition( no_protocol_option ); - case WSAENOTCONN_: return make_error_condition( not_connected ); - case WSAENOTSOCK_: return make_error_condition( not_a_socket ); - case WSAEOPNOTSUPP_: return make_error_condition( operation_not_supported ); - case WSAEPROTONOSUPPORT_: return make_error_condition( protocol_not_supported ); - case WSAEPROTOTYPE_: return make_error_condition( wrong_protocol_type ); - case WSAETIMEDOUT_: return make_error_condition( timed_out ); - case WSAEWOULDBLOCK_: return make_error_condition( operation_would_block ); - #endif - default: return error_condition( ev, system_category() ); - } - } - -# if !defined( BOOST_WINDOWS_API ) - - BOOST_SYSTEM_DECL_ std::string system_error_category::message( int ev ) const - { - return generic_category().message( ev ); - } -# else - - BOOST_SYSTEM_DECL_ std::string system_error_category::message( int ev ) const - { -#if defined(UNDER_CE) || BOOST_PLAT_WINDOWS_RUNTIME || defined(BOOST_NO_ANSI_APIS) - std::wstring buf(128, wchar_t()); - for (;;) - { - boost::winapi::DWORD_ retval = boost::winapi::FormatMessageW( - boost::winapi::FORMAT_MESSAGE_FROM_SYSTEM_ | - boost::winapi::FORMAT_MESSAGE_IGNORE_INSERTS_, - NULL, - ev, - boost::winapi::MAKELANGID_(boost::winapi::LANG_NEUTRAL_, - boost::winapi::SUBLANG_DEFAULT_), // Default language - &buf[0], - static_cast(buf.size()), - NULL - ); - - if (retval > 0) - { - buf.resize(retval); - break; - } - else if (boost::winapi::GetLastError() != - boost::winapi::ERROR_INSUFFICIENT_BUFFER_) - { - return std::string("Unknown error"); - } - else - { - buf.resize(buf.size() + buf.size() / 2); - } - } - - int num_chars = static_cast(buf.size() + 1) * 2; - - boost::winapi::LPSTR_ narrow_buffer = -#if defined(__GNUC__) - (boost::winapi::LPSTR_)__builtin_alloca(num_chars); -#else - (boost::winapi::LPSTR_)_alloca(num_chars); -#endif - - if (boost::winapi::WideCharToMultiByte(boost::winapi::CP_ACP_, 0, - buf.c_str(), -1, narrow_buffer, num_chars, NULL, NULL) == 0) - { - return std::string("Unknown error"); - } - - std::string str( narrow_buffer ); -#else - boost::winapi::LPVOID_ lpMsgBuf = 0; - boost::winapi::DWORD_ retval = boost::winapi::FormatMessageA( - boost::winapi::FORMAT_MESSAGE_ALLOCATE_BUFFER_ | - boost::winapi::FORMAT_MESSAGE_FROM_SYSTEM_ | - boost::winapi::FORMAT_MESSAGE_IGNORE_INSERTS_, - NULL, - ev, - boost::winapi::MAKELANGID_(boost::winapi::LANG_NEUTRAL_, - boost::winapi::SUBLANG_DEFAULT_), // Default language - (boost::winapi::LPSTR_) &lpMsgBuf, - 0, - NULL - ); - detail::local_free_on_destruction lfod(lpMsgBuf); - if (retval == 0) - return std::string("Unknown error"); - - std::string str(static_cast(lpMsgBuf)); -# endif - while ( str.size() - && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) - str.erase( str.size()-1 ); - if ( str.size() && str[str.size()-1] == '.' ) - { str.erase( str.size()-1 ); } - return str; - } -# endif - -#undef BOOST_SYSTEM_DECL_ - -} // namespace detail - - -# ifdef BOOST_SYSTEM_ENABLE_DEPRECATED - BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code; - // note that it doesn't matter if this - // isn't initialized before use since - // the only use is to take its - // address for comparison purposes -# endif - -#if defined(BOOST_ERROR_CODE_HEADER_ONLY) - -// defined in error_code.hpp - -#elif defined(BOOST_SYSTEM_HAS_CONSTEXPR) - -namespace detail -{ - -BOOST_SYSTEM_REQUIRE_CONST_INIT BOOST_SYSTEM_DECL system_error_category system_category_instance; -BOOST_SYSTEM_REQUIRE_CONST_INIT BOOST_SYSTEM_DECL generic_error_category generic_category_instance; - -BOOST_SYSTEM_DECL const error_category & system_category_ncx() BOOST_SYSTEM_NOEXCEPT -{ - return system_category_instance; -} - -BOOST_SYSTEM_DECL const error_category & generic_category_ncx() BOOST_SYSTEM_NOEXCEPT -{ - return generic_category_instance; -} - -} // namespace detail - -#else - -namespace detail -{ - -BOOST_SYSTEM_DECL const error_category & system_category_ncx() BOOST_SYSTEM_NOEXCEPT -{ - static const detail::system_error_category system_category_instance; - return system_category_instance; -} - -BOOST_SYSTEM_DECL const error_category & generic_category_ncx() BOOST_SYSTEM_NOEXCEPT -{ - static const detail::generic_error_category generic_category_instance; - return generic_category_instance; -} - -} // namespace detail - -#endif - -} // namespace system - -} // namespace boost diff --git a/include/boost/system/detail/local_free_on_destruction.hpp b/include/boost/system/detail/local_free_on_destruction.hpp deleted file mode 100644 index 9016e74..0000000 --- a/include/boost/system/detail/local_free_on_destruction.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// local_free_on_exit.hpp ------------------------------------------------------------// - -// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2010 Beman Dawes - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// This is derived from boost/asio/detail/local_free_on_block_exit.hpp to avoid -// a dependency on asio. Thanks to Chris Kohlhoff for pointing it out. - -#ifndef BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP -#define BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP - -#include - -namespace boost { -namespace system { -namespace detail { - -class local_free_on_destruction -{ -public: - explicit local_free_on_destruction(void* p) - : p_(p) {} - - ~local_free_on_destruction() - { - boost::winapi::LocalFree(p_); - } - -private: - void* p_; - local_free_on_destruction(const local_free_on_destruction&); // = deleted - local_free_on_destruction& operator=(const local_free_on_destruction&); // = deleted -}; - -} // namespace detail -} // namespace system -} // namespace boost - -#endif // BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP From f14e9e7d5c513416f6ed13b530c227ae3261e05d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 05:23:35 +0300 Subject: [PATCH 05/23] Revert changes to api_config.hpp --- include/boost/system/api_config.hpp | 50 ++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/include/boost/system/api_config.hpp b/include/boost/system/api_config.hpp index adbe355..28b8bec 100644 --- a/include/boost/system/api_config.hpp +++ b/include/boost/system/api_config.hpp @@ -1,24 +1,42 @@ -#ifndef BOOST_SYSTEM_API_CONFIG_HPP_INCLUDED -#define BOOST_SYSTEM_API_CONFIG_HPP_INCLUDED +// boost/system/api_config.hpp -------------------------------------------------------// -// Copyright Beman Dawes 2003, 2006, 2010 -// Copyright 2018 Peter Dimov +// Copyright Beman Dawes 2003, 2006, 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/system for documentation. + +//--------------------------------------------------------------------------------------// + +// Boost.System calls operating system API functions to implement system error category +// functions. Usually there is no question as to which API is to be used. // -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt +// In the case of MinGW or Cygwin/MinGW, however, both POSIX and Windows API's are +// available. Chaos ensues if other code thinks one is in use when Boost.System was +// actually built with the other. This header centralizes the API choice and prevents +// user definition of API macros, thus elminating the possibility of mismatches and the +// need to test configurations with little or no practical value. // -// See http://www.boost.org/libs/system for documentation. -// This header is no longer used by Boost.System. -// Its use is discouraged and it will be deprecated. +//--------------------------------------------------------------------------------------// -// Definition of BOOST_*_API retained for compatibility. +#ifndef BOOST_SYSTEM_API_CONFIG_HPP +#define BOOST_SYSTEM_API_CONFIG_HPP -#if defined(_WIN32) || defined(__CYGWIN__) -// Windows default, including MinGW and Cygwin -# define BOOST_WINDOWS_API +# if defined(BOOST_POSIX_API) || defined(BOOST_WINDOWS_API) +# error user defined BOOST_POSIX_API or BOOST_WINDOWS_API not supported +# endif + +// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use +// Cygwin/MinGW does not predefine _WIN32. +// Standalone MinGW and all other known Windows compilers do predefine _WIN32 +// Compilers that predefine _WIN32 or __MINGW32__ do so for Windows 64-bit builds too. + +# if defined(_WIN32) || defined(__CYGWIN__) // Windows default, including MinGW and Cygwin +# define BOOST_WINDOWS_API # else -# define BOOST_POSIX_API -#endif +# define BOOST_POSIX_API +# endif -#endif // BOOST_SYSTEM_API_CONFIG_HPP_INCLUDED +#endif // BOOST_SYSTEM_API_CONFIG_HPP From 731df11ffdbb35348ff17c49044b1cbb962c4651 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 05:44:58 +0300 Subject: [PATCH 06/23] Add system_category_posix.hpp; remove BOOST_SYSTEM_WIN32 --- include/boost/system/detail/config.hpp | 6 - .../system/detail/system_category_posix.hpp | 132 ++++++++++++++++++ .../system/detail/system_category_win32.hpp | 13 +- include/boost/system/error_code.hpp | 11 +- 4 files changed, 145 insertions(+), 17 deletions(-) create mode 100644 include/boost/system/detail/system_category_posix.hpp diff --git a/include/boost/system/detail/config.hpp b/include/boost/system/detail/config.hpp index e0b193f..1ff28f4 100644 --- a/include/boost/system/detail/config.hpp +++ b/include/boost/system/detail/config.hpp @@ -65,10 +65,4 @@ #endif #endif -// BOOST_SYSTEM_WIN32 - -#if defined( _WIN32 ) || defined( __CYGWIN__ ) -# define BOOST_SYSTEM_WIN32 -#endif - #endif // BOOST_SYSTEM_DETAIL_CONFIG_HPP_INCLUDED diff --git a/include/boost/system/detail/system_category_posix.hpp b/include/boost/system/detail/system_category_posix.hpp new file mode 100644 index 0000000..9a40623 --- /dev/null +++ b/include/boost/system/detail/system_category_posix.hpp @@ -0,0 +1,132 @@ +// POSIX-specific implementation details of system_error_category +// +// Copyright 2018 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) +// +// See library home page at http://www.boost.org/libs/system + +namespace boost +{ + +namespace system +{ + +namespace detail +{ + +inline bool is_generic_value( int ev ) BOOST_NOEXCEPT +{ + using namespace errc; + + static int const gen[] = + { + success, + address_family_not_supported, + address_in_use, + address_not_available, + already_connected, + argument_list_too_long, + argument_out_of_domain, + bad_address, + bad_file_descriptor, + bad_message, + broken_pipe, + connection_aborted, + connection_already_in_progress, + connection_refused, + connection_reset, + cross_device_link, + destination_address_required, + device_or_resource_busy, + directory_not_empty, + executable_format_error, + file_exists, + file_too_large, + filename_too_long, + function_not_supported, + host_unreachable, + identifier_removed, + illegal_byte_sequence, + inappropriate_io_control_operation, + interrupted, + invalid_argument, + invalid_seek, + io_error, + is_a_directory, + message_size, + network_down, + network_reset, + network_unreachable, + no_buffer_space, + no_child_process, + no_link, + no_lock_available, + no_message_available, + no_message, + no_protocol_option, + no_space_on_device, + no_stream_resources, + no_such_device_or_address, + no_such_device, + no_such_file_or_directory, + no_such_process, + not_a_directory, + not_a_socket, + not_a_stream, + not_connected, + not_enough_memory, + not_supported, + operation_canceled, + operation_in_progress, + operation_not_permitted, + operation_not_supported, + operation_would_block, + owner_dead, + permission_denied, + protocol_error, + protocol_not_supported, + read_only_file_system, + resource_deadlock_would_occur, + resource_unavailable_try_again, + result_out_of_range, + state_not_recoverable, + stream_timeout, + text_file_busy, + timed_out, + too_many_files_open_in_system, + too_many_files_open, + too_many_links, + too_many_symbolic_link_levels, + value_too_large, + wrong_protocol_type + }; + + int const n = sizeof( gen ) / sizeof( gen[0] ); + + for( int i = 0; i < n; ++i ) + { + if( ev == gen[ i ] ) return true; + } + + return false; +} + +inline error_condition system_category_default_error_condition_posix( int ev ) BOOST_NOEXCEPT +{ + if( is_generic_value( ev ) ) + { + return error_condition( ev, generic_category() ); + } + else + { + return error_condition( ev, system_category() ); + } +} + +} // namespace detail + +} // namespace system + +} // namespace boost diff --git a/include/boost/system/detail/system_category_win32.hpp b/include/boost/system/detail/system_category_win32.hpp index 075a1ce..66b8e1e 100644 --- a/include/boost/system/detail/system_category_win32.hpp +++ b/include/boost/system/detail/system_category_win32.hpp @@ -1,18 +1,17 @@ // Windows implementation of system_error_category - +// // Copyright Beman Dawes 2002, 2006 // Copyright (c) Microsoft Corporation 2014 // Copyright 2018 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) - -// See library home page at http://www.boost.org/libs/system +// +// 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 // diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index 6cb09d6..8b21f88 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -10,6 +10,7 @@ // // See library home page at http://www.boost.org/libs/system +#include #include #include #include @@ -748,7 +749,7 @@ inline std::string generic_error_category::message( int ev ) const // system_error_category implementation -#if defined(BOOST_SYSTEM_WIN32) +#if defined(BOOST_WINDOWS_API) #include @@ -762,7 +763,9 @@ inline boost::system::error_condition boost::system::detail::system_error_catego return system_category_default_error_condition_win32( ev ); } -#else // #if defined(BOOST_SYSTEM_WIN32) +#else // #if defined(BOOST_WINDOWS_API) + +#include inline std::string boost::system::detail::system_error_category::message( int ev ) const { @@ -771,10 +774,10 @@ inline std::string boost::system::detail::system_error_category::message( int ev inline boost::system::error_condition boost::system::detail::system_error_category::default_error_condition( int ev ) const BOOST_NOEXCEPT { - return boost::system::error_condition( ev, generic_category() ); + return system_category_default_error_condition_posix( ev ); } -#endif // #if defined(BOOST_SYSTEM_WIN32) +#endif // #if defined(BOOST_WINDOWS_API) // interoperability with std::error_code, std::error_condition From 57ecfeb2c26331c4616f8a47228b30adc39dc8cb Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 05:58:29 +0300 Subject: [PATCH 07/23] Use map::insert instead of map::emplace, which doesn't work on g++ pre-6 (and msvc-10.0) --- include/boost/system/detail/config.hpp | 5 ----- .../system/detail/std_interoperability.hpp | 18 ++++++++++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/include/boost/system/detail/config.hpp b/include/boost/system/detail/config.hpp index 1ff28f4..a9e6c72 100644 --- a/include/boost/system/detail/config.hpp +++ b/include/boost/system/detail/config.hpp @@ -16,11 +16,6 @@ # define BOOST_SYSTEM_HAS_SYSTEM_ERROR #endif -#if defined(BOOST_MSVC) && BOOST_MSVC < 1700 -// msvc-10.0 has no two-argument map::emplace -# undef BOOST_SYSTEM_HAS_SYSTEM_ERROR -#endif - // BOOST_SYSTEM_NOEXCEPT // Retained for backward compatibility only diff --git a/include/boost/system/detail/std_interoperability.hpp b/include/boost/system/detail/std_interoperability.hpp index 2db8f62..f38c98e 100644 --- a/include/boost/system/detail/std_interoperability.hpp +++ b/include/boost/system/detail/std_interoperability.hpp @@ -9,6 +9,7 @@ #include #include +#include // @@ -29,7 +30,7 @@ private: public: - std_category( boost::system::error_category const * pc ): pc_( pc ) + explicit std_category( boost::system::error_category const * pc ): pc_( pc ) { } @@ -54,13 +55,22 @@ public: inline std::error_category const & to_std_category( boost::system::error_category const & cat ) { - typedef std::map map_type; + typedef std::map< boost::system::error_category const *, std::unique_ptr > map_type; static map_type map_; - std::pair p = map_.emplace( &cat, &cat ); + map_type::iterator i = map_.find( &cat ); - return p.first->second; + if( i == map_.end() ) + { + std::unique_ptr p( new std_category( &cat ) ); + + std::pair 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 From 34600a62dfe60995e8407e8c3e427fca28f215c3 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 06:15:22 +0300 Subject: [PATCH 08/23] The constexpr workarounds are no longer needed --- include/boost/system/detail/config.hpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/include/boost/system/detail/config.hpp b/include/boost/system/detail/config.hpp index a9e6c72..2a94f39 100644 --- a/include/boost/system/detail/config.hpp +++ b/include/boost/system/detail/config.hpp @@ -17,7 +17,7 @@ #endif // BOOST_SYSTEM_NOEXCEPT -// Retained for backward compatibility only +// Retained for backward compatibility #define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT @@ -27,22 +27,6 @@ # define BOOST_SYSTEM_HAS_CONSTEXPR #endif -#if defined(__GNUC__) && (__GNUC__ == 7 && __GNUC_MINOR__ < 4) && __cplusplus >= 201700L -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83835 -# undef BOOST_SYSTEM_HAS_CONSTEXPR -#endif - -#if defined(__clang__) && defined(_MSC_VER) && defined(_CPPLIB_VER) -// Clang on Windows with MSVC headers, the constructor of std::error_category -// is not constexpr at least up to VS2017 15.7.x (_MSVC_STL_UPDATE 201803) -# undef BOOST_SYSTEM_HAS_CONSTEXPR -#endif - -#if defined(__clang__) && defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 40900 -// The constructor of std::error_category is not constexpr in libstdc++ 4.8 -# undef BOOST_SYSTEM_HAS_CONSTEXPR -#endif - #if defined(BOOST_SYSTEM_HAS_CONSTEXPR) # define BOOST_SYSTEM_CONSTEXPR constexpr #else From 7a06df877d3861e5a352897b560fad4d7cc7cd3f Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 06:27:30 +0300 Subject: [PATCH 09/23] Revert changes to throw_test.cpp and dynamic_link_test.cpp --- test/dynamic_link_test.cpp | 1 - test/throw_test.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/test/dynamic_link_test.cpp b/test/dynamic_link_test.cpp index e49dea7..b4c4615 100644 --- a/test/dynamic_link_test.cpp +++ b/test/dynamic_link_test.cpp @@ -19,7 +19,6 @@ //--------------------------------------------------------------------------------------// #include -#include #include namespace boost diff --git a/test/throw_test.cpp b/test/throw_test.cpp index b04d3bf..c42f422 100644 --- a/test/throw_test.cpp +++ b/test/throw_test.cpp @@ -18,7 +18,6 @@ #define BOOST_SYSTEM_SOURCE #include -#include namespace boost { From 41de9d916a67fc3e9f4f78b3102ceb19adf0ffd0 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 04:32:33 +0300 Subject: [PATCH 10/23] Fix throw_test.cpp to not meddle with BOOST_SYSTEM_SOURCE as it needs to import from Boost.System while exporting throw_test() --- test/Jamfile.v2 | 8 ++------ test/dynamic_link_test.cpp | 11 ++--------- test/throw_test.cpp | 21 +++++++++------------ 3 files changed, 13 insertions(+), 27 deletions(-) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 784fd8e..037b004 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -15,12 +15,8 @@ project /boost/system//boost_system msvc:on ; - - lib throw_test - : throw_test.cpp - : shared:BOOST_SYSTEM_DYN_LINK=1 - static:BOOST_SYSTEM_STATIC_LINK=1 - ; + + lib throw_test : throw_test.cpp : shared:THROW_DYN_LINK=1 ; lib single_instance_lib1 : single_instance_1.cpp : shared:SINGLE_INSTANCE_DYN_LINK ; lib single_instance_lib2 : single_instance_2.cpp : shared:SINGLE_INSTANCE_DYN_LINK ; diff --git a/test/dynamic_link_test.cpp b/test/dynamic_link_test.cpp index b4c4615..8826f83 100644 --- a/test/dynamic_link_test.cpp +++ b/test/dynamic_link_test.cpp @@ -21,19 +21,13 @@ #include #include -namespace boost -{ - namespace system - { - BOOST_SYSTEM_DECL void throw_test(); - } -} +void throw_test(); int main() { try { - boost::system::throw_test(); + throw_test(); } catch (const boost::system::system_error& ex) { @@ -41,7 +35,6 @@ int main() std::cout << " what() reports " << ex.what() << '\n'; return 0; } - catch (const std::runtime_error& ex) { std::cout << " error: caught std::runtime_error instead of boost::system::system_error\n"; diff --git a/test/throw_test.cpp b/test/throw_test.cpp index c42f422..c7ae517 100644 --- a/test/throw_test.cpp +++ b/test/throw_test.cpp @@ -13,19 +13,16 @@ //--------------------------------------------------------------------------------------// -// define BOOST_SYSTEM_SOURCE so that knows -// the library is being built (possibly exporting rather than importing code) -#define BOOST_SYSTEM_SOURCE - #include +#include -namespace boost +#if defined(THROW_DYN_LINK) +# define EXPORT BOOST_SYMBOL_EXPORT +#else +# define EXPORT +#endif + +EXPORT void throw_test() { - namespace system - { - BOOST_SYSTEM_DECL void throw_test() - { - throw system_error(9999, system_category(), "boo boo"); - } - } + throw boost::system::system_error( 9999, boost::system::system_category(), "boo boo" ); } From 9d86d0296ef1ebddd93b09ddb046bf9481195f2b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 07:04:27 +0300 Subject: [PATCH 11/23] Revert boost/system/config.hpp --- include/boost/system/config.hpp | 68 +++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/include/boost/system/config.hpp b/include/boost/system/config.hpp index 4c45ae6..14faa63 100644 --- a/include/boost/system/config.hpp +++ b/include/boost/system/config.hpp @@ -1,23 +1,40 @@ -#ifndef BOOST_SYSTEM_CONFIG_HPP_INCLUDED -#define BOOST_SYSTEM_CONFIG_HPP_INCLUDED +// boost/system/config.hpp -----------------------------------------------------------// -// Copyright Beman Dawes 2003, 2006 -// Copyright 2018 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) -// -// See http://www.boost.org/libs/system for documentation. +// Copyright Beman Dawes 2003, 2006 -// This header is no longer used by Boost.System. -// Its use is discouraged and it will be deprecated. +// 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 http://www.boost.org/libs/system for documentation. + +#ifndef BOOST_SYSTEM_CONFIG_HPP +#define BOOST_SYSTEM_CONFIG_HPP #include +#include +#include // for BOOST_POSIX_API or BOOST_WINDOWS_API -// Included for compatibility. Not used. -#include +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html -// Definition of BOOST_SYSTEM_DECL retained for compatibility. +// normalize macros ------------------------------------------------------------------// + +#if !defined(BOOST_SYSTEM_DYN_LINK) && !defined(BOOST_SYSTEM_STATIC_LINK) \ + && !defined(BOOST_ALL_DYN_LINK) && !defined(BOOST_ALL_STATIC_LINK) +# define BOOST_SYSTEM_STATIC_LINK +#endif + +#if defined(BOOST_ALL_DYN_LINK) && !defined(BOOST_SYSTEM_DYN_LINK) +# define BOOST_SYSTEM_DYN_LINK +#elif defined(BOOST_ALL_STATIC_LINK) && !defined(BOOST_SYSTEM_STATIC_LINK) +# define BOOST_SYSTEM_STATIC_LINK +#endif + +#if defined(BOOST_SYSTEM_DYN_LINK) && defined(BOOST_SYSTEM_STATIC_LINK) +# error Must not define both BOOST_SYSTEM_DYN_LINK and BOOST_SYSTEM_STATIC_LINK +#endif + +// enable dynamic or static linking as requested --------------------------------------// #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK) # if defined(BOOST_SYSTEM_SOURCE) @@ -29,4 +46,25 @@ # define BOOST_SYSTEM_DECL #endif -#endif // BOOST_SYSTEM_CONFIG_HPP_INCLUDED +// enable automatic library variant selection ----------------------------------------// + +#if !defined(BOOST_SYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SYSTEM_NO_LIB) +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_system +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include +#endif // auto-linking disabled + +#endif // BOOST_SYSTEM_CONFIG_HPP + From 81c34ab7a4f33a7ee66c802b57a763e81117889e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 07:06:04 +0300 Subject: [PATCH 12/23] Remove autolink --- include/boost/system/config.hpp | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/include/boost/system/config.hpp b/include/boost/system/config.hpp index 14faa63..1e5f686 100644 --- a/include/boost/system/config.hpp +++ b/include/boost/system/config.hpp @@ -7,15 +7,16 @@ // See http://www.boost.org/libs/system for documentation. -#ifndef BOOST_SYSTEM_CONFIG_HPP +#ifndef BOOST_SYSTEM_CONFIG_HPP #define BOOST_SYSTEM_CONFIG_HPP #include -#include #include // for BOOST_POSIX_API or BOOST_WINDOWS_API -// This header implements separate compilation features as described in +// This header implemented separate compilation features as described in // http://www.boost.org/more/separate_compilation.html +// +// It's only retained for compatibility now that the library is header-only. // normalize macros ------------------------------------------------------------------// @@ -46,25 +47,4 @@ # define BOOST_SYSTEM_DECL #endif -// enable automatic library variant selection ----------------------------------------// - -#if !defined(BOOST_SYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SYSTEM_NO_LIB) -// -// Set the name of our library, this will get undef'ed by auto_link.hpp -// once it's done with it: -// -#define BOOST_LIB_NAME boost_system -// -// If we're importing code from a dll, then tell auto_link.hpp about it: -// -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK) -# define BOOST_DYN_LINK -#endif -// -// And include the header that does the work: -// -#include -#endif // auto-linking disabled - #endif // BOOST_SYSTEM_CONFIG_HPP - From 6bd05dc92d71d6da99de3a62be549b8f6f5637dc Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 19:32:38 +0300 Subject: [PATCH 13/23] Add BOOST_SYMBOL_VISIBLE to category classes to placate UBSan --- include/boost/system/detail/std_interoperability.hpp | 2 +- include/boost/system/error_code.hpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/system/detail/std_interoperability.hpp b/include/boost/system/detail/std_interoperability.hpp index f38c98e..b1b41d3 100644 --- a/include/boost/system/detail/std_interoperability.hpp +++ b/include/boost/system/detail/std_interoperability.hpp @@ -22,7 +22,7 @@ namespace system namespace detail { -class std_category: public std::error_category +class BOOST_SYMBOL_VISIBLE std_category: public std::error_category { private: diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index 8b21f88..a859deb 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -159,7 +159,7 @@ template<> struct is_error_condition_enum #pragma warning( disable: 4355 ) #endif -class error_category +class BOOST_SYMBOL_VISIBLE error_category { #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) public: @@ -257,7 +257,7 @@ public: namespace detail { -class generic_error_category: public error_category +class BOOST_SYMBOL_VISIBLE generic_error_category: public error_category { public: @@ -275,7 +275,7 @@ public: std::string message( int ev ) const; }; -class system_error_category: public error_category +class BOOST_SYMBOL_VISIBLE system_error_category: public error_category { public: From fe1dbd9df969c047113f53676cf890fd94d53d38 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 20:36:02 +0300 Subject: [PATCH 14/23] Use g++-8, clang-6 with libstdc++-5 for UBSan (libstdc++-4.9's map triggers errors in end()) --- .travis.yml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5c65a91..0ecc47e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -108,18 +108,18 @@ matrix: - ubuntu-toolchain-r-test - os: linux - compiler: g++-7 - env: UBSAN=1 TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold + compiler: g++-8 + env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17 addons: apt: packages: - - g++-7 + - g++-8 sources: - ubuntu-toolchain-r-test - os: linux compiler: g++-8 - env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17 + env: UBSAN=1 TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold addons: apt: packages: @@ -297,18 +297,6 @@ matrix: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-5.0 - - os: linux - compiler: clang++-5.0 - env: UBSAN=1 TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1 - addons: - apt: - packages: - - clang-5.0 - - libstdc++-4.9-dev - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-5.0 - - os: linux compiler: clang++-6.0 env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17 @@ -332,6 +320,18 @@ matrix: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-6.0 + - os: linux + compiler: clang++-6.0 + env: UBSAN=1 TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1 + addons: + apt: + packages: + - clang-6.0 + - libstdc++-5-dev + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-6.0 + - os: linux compiler: clang++-libc++ env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z From 56651f6633c39f79d504750bdcfcbb06724a71a4 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 16 Sep 2018 20:49:33 +0300 Subject: [PATCH 15/23] Disable interoperation on g++ 4.4/4.5 --- include/boost/system/detail/config.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/boost/system/detail/config.hpp b/include/boost/system/detail/config.hpp index 2a94f39..fde93cb 100644 --- a/include/boost/system/detail/config.hpp +++ b/include/boost/system/detail/config.hpp @@ -9,6 +9,7 @@ // See http://www.boost.org/libs/system for documentation. #include +#include // BOOST_SYSTEM_HAS_SYSTEM_ERROR @@ -16,6 +17,11 @@ # define BOOST_SYSTEM_HAS_SYSTEM_ERROR #endif +#if BOOST_WORKAROUND(BOOST_GCC, < 40600) +// g++ 4.4's is not good enough +# undef BOOST_SYSTEM_HAS_SYSTEM_ERROR +#endif + // BOOST_SYSTEM_NOEXCEPT // Retained for backward compatibility From 041678752bf455d7b2e19d75a667280972ad8057 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 17 Sep 2018 02:55:40 +0300 Subject: [PATCH 16/23] Revert deletion of BOOST_*_API check --- include/boost/system/error_code.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index a859deb..7729049 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -27,6 +27,10 @@ # include #endif +#if !defined(BOOST_POSIX_API) && !defined(BOOST_WINDOWS_API) +# error BOOST_POSIX_API or BOOST_WINDOWS_API must be defined +#endif + namespace boost { From a9e56e1a6ab72c2d0cad09c8c0df31f7a1dd1395 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 17 Sep 2018 03:21:42 +0300 Subject: [PATCH 17/23] Remove dependency on type_traits --- include/boost/system/error_code.hpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index 7729049..3bce6ef 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -355,6 +354,22 @@ static const error_category & native_ecat BOOST_ATTRIBUTE_UNUSED = system_catego #endif +// enable_if + +namespace detail +{ + +template struct enable_if +{ + typedef T type; +}; + +template struct enable_if +{ +}; + +} // namespace detail + // class error_condition // error_conditions are portable, error_codes are system or library specific @@ -379,7 +394,7 @@ public: } template BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e, - typename boost::enable_if_::value>::type* = 0) BOOST_NOEXCEPT + typename detail::enable_if::value>::type* = 0) BOOST_NOEXCEPT { *this = make_error_condition( e ); } @@ -393,7 +408,7 @@ public: } template - BOOST_SYSTEM_CONSTEXPR typename boost::enable_if_::value, error_condition>::type & + BOOST_SYSTEM_CONSTEXPR typename detail::enable_if::value, error_condition>::type & operator=( ErrorConditionEnum val ) BOOST_NOEXCEPT { *this = make_error_condition( val ); @@ -499,8 +514,8 @@ public: { } - template BOOST_SYSTEM_CONSTEXPR error_code( ErrorCodeEnum e, - typename boost::enable_if_::value>::type* = 0 ) BOOST_NOEXCEPT + template BOOST_SYSTEM_CONSTEXPR error_code( ErrorCodeEnum e, + typename detail::enable_if::value>::type* = 0 ) BOOST_NOEXCEPT { *this = make_error_code( e ); } @@ -514,7 +529,7 @@ public: } template - BOOST_SYSTEM_CONSTEXPR typename boost::enable_if_::value, error_code>::type & + BOOST_SYSTEM_CONSTEXPR typename detail::enable_if::value, error_code>::type & operator=( ErrorCodeEnum val ) BOOST_NOEXCEPT { *this = make_error_code( val ); From 96320384ccd4c16afddb92e9ff075a1cc26c18ff Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 17 Sep 2018 17:08:25 +0300 Subject: [PATCH 18/23] Revert unnecessary changes to error_code.cpp --- src/error_code.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/error_code.cpp b/src/error_code.cpp index d451940..b86a38c 100644 --- a/src/error_code.cpp +++ b/src/error_code.cpp @@ -10,13 +10,11 @@ //----------------------------------------------------------------------------// -#include +// define BOOST_SYSTEM_SOURCE so that knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_SYSTEM_SOURCE -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK) -# define BOOST_SYSTEM_DECL BOOST_SYMBOL_EXPORT -#else -# define BOOST_SYSTEM_DECL -#endif +#include namespace boost { From 11b07164c1e25d02bebbd998764a94890d9d2fc7 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 17 Sep 2018 17:29:50 +0300 Subject: [PATCH 19/23] Add win32_hresult_test --- test/Jamfile.v2 | 1 + test/win32_hresult_test.cpp | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 test/win32_hresult_test.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 037b004..9e5beb7 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -123,6 +123,7 @@ else [ system-run before_main_test.cpp ] [ run-fail throws_assign_fail.cpp ] [ system-run- constexpr_test.cpp ] + [ system-run win32_hresult_test.cpp ] ; # Quick (CI) test diff --git a/test/win32_hresult_test.cpp b/test/win32_hresult_test.cpp new file mode 100644 index 0000000..1b7d7da --- /dev/null +++ b/test/win32_hresult_test.cpp @@ -0,0 +1,40 @@ + +// Copyright 2018 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 + +// See library home page at http://www.boost.org/libs/system + +#include +#include +#include + +#if !defined(BOOST_WINDOWS_API) + +BOOST_PRAGMA_MESSAGE( "Skipping test, BOOST_WINDOWS_API is not defined" ) + +#else + +#include + +int main() +{ + namespace sys = boost::system; + + HRESULT r = HRESULT_FROM_WIN32( ERROR_ACCESS_DENIED ); + + sys::error_code ec( r, sys::system_category() ); + sys::error_condition en = make_error_condition( sys::errc::permission_denied ); + + BOOST_TEST( ec == en ); + BOOST_TEST( ec.default_error_condition() == en ); + + BOOST_TEST_EQ( ec.default_error_condition().value(), en.value() ); + + return boost::report_errors(); +} + +#endif From 11a908a3fea0363641ea6256d1c7add6a2643225 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 17 Sep 2018 18:18:37 +0300 Subject: [PATCH 20/23] Fix hash_value --- include/boost/system/error_code.hpp | 33 ++++++++++++++++++++++++++--- test/single_instance_test.cpp | 19 +++++++++++++++-- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index 3bce6ef..c92a18e 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -162,8 +162,14 @@ template<> struct is_error_condition_enum #pragma warning( disable: 4355 ) #endif +std::size_t hash_value( error_code const & ec ); + class BOOST_SYMBOL_VISIBLE error_category { +private: + + friend std::size_t hash_value( error_code const & ec ); + #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) public: @@ -692,10 +698,31 @@ template return os; } -inline std::size_t hash_value( const error_code & ec ) +inline std::size_t hash_value( error_code const & ec ) { - // TODO use category id_, FNV combiner - return static_cast( ec.value() ) + reinterpret_cast( &ec.category() ); + error_category const & cat = ec.category(); + + boost::ulong_long_type id = cat.id_; + + if( id == 0 ) + { + id = reinterpret_cast( &cat ); + } + + boost::ulong_long_type hv = 0xCBF29CE484222325ull; + boost::ulong_long_type const prime = 0x00000100000001B3ull; + + // id + + hv ^= id; + hv *= prime; + + // value + + hv ^= static_cast( ec.value() ); + hv *= prime; + + return static_cast( hv ); } // make_* functions for errc::errc_t diff --git a/test/single_instance_test.cpp b/test/single_instance_test.cpp index d5b67cf..65de5a9 100644 --- a/test/single_instance_test.cpp +++ b/test/single_instance_test.cpp @@ -25,8 +25,23 @@ error_code get_generic_code(); int main() { - BOOST_TEST_EQ( lib1::get_system_code(), lib2::get_system_code() ); - BOOST_TEST_EQ( lib1::get_generic_code(), lib2::get_generic_code() ); + { + error_code e1 = lib1::get_system_code(); + error_code e2 = lib2::get_system_code(); + + BOOST_TEST_EQ( e1, e2 ); + + BOOST_TEST_EQ( hash_value( e1 ), hash_value( e2 ) ); + } + + { + error_code e1 = lib1::get_generic_code(); + error_code e2 = lib2::get_generic_code(); + + BOOST_TEST_EQ( e1, e2 ); + + BOOST_TEST_EQ( hash_value( e1 ), hash_value( e2 ) ); + } return boost::report_errors(); } From 465e9e019e5e2107e6e48c67d58be1e4662491ba Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 17 Sep 2018 20:12:10 +0300 Subject: [PATCH 21/23] Remove noexcept from operator std::error_category const& (allocates and can throw) --- include/boost/system/error_code.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index c92a18e..c3b51f1 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -252,7 +252,7 @@ public: #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) - operator std::error_category const & () const BOOST_NOEXCEPT; + operator std::error_category const & () const; #endif }; @@ -831,7 +831,7 @@ inline boost::system::error_condition boost::system::detail::system_error_catego #include -inline boost::system::error_category::operator std::error_category const & () const BOOST_NOEXCEPT +inline boost::system::error_category::operator std::error_category const & () const { return boost::system::detail::to_std_category( *this ); } From 7d38263d711d5ddfbae441b1c606b660f700a051 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 17 Sep 2018 20:25:13 +0300 Subject: [PATCH 22/23] Add an empty main() in win32_hresult_test when not on Windows --- test/win32_hresult_test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/win32_hresult_test.cpp b/test/win32_hresult_test.cpp index 1b7d7da..b79c51d 100644 --- a/test/win32_hresult_test.cpp +++ b/test/win32_hresult_test.cpp @@ -10,14 +10,15 @@ #include #include -#include #if !defined(BOOST_WINDOWS_API) BOOST_PRAGMA_MESSAGE( "Skipping test, BOOST_WINDOWS_API is not defined" ) +int main() {} #else +#include #include int main() From 515fbb21b4fef21348964a2d306f9f38a9c22923 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 18 Sep 2018 22:21:13 +0300 Subject: [PATCH 23/23] Use strerror_r on glibc --- .../boost/system/detail/generic_category.hpp | 69 +++++++++++++++++++ include/boost/system/error_code.hpp | 38 +++------- 2 files changed, 78 insertions(+), 29 deletions(-) create mode 100644 include/boost/system/detail/generic_category.hpp diff --git a/include/boost/system/detail/generic_category.hpp b/include/boost/system/detail/generic_category.hpp new file mode 100644 index 0000000..cba4a2e --- /dev/null +++ b/include/boost/system/detail/generic_category.hpp @@ -0,0 +1,69 @@ +// Implementation details of generic_error_category +// +// Copyright 2018 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) +// +// See library home page at http://www.boost.org/libs/system + +#include + +namespace boost +{ + +namespace system +{ + +namespace detail +{ + +#if defined(__GLIBC__) + +// std::strerror is not thread-safe on glibc (for no reason) +// glibc also has two incompatible strerror_r definitions (for no reason) + +inline char const * strerror_r_helper( char const * r, char const * ) +{ + return r; +} + +inline char const * strerror_r_helper( int r, char const * buffer ) +{ + return r == 0? buffer: "Unknown error"; +} + +inline std::string generic_error_category_message( int ev ) +{ + char buffer[ 128 ]; + return strerror_r_helper( strerror_r( ev, buffer, sizeof( buffer ) ), buffer ); +} + +#else + +// std::strerror is thread-safe on everything else, incl. Windows + +inline std::string generic_error_category_message( int ev ) +{ + +# if defined( BOOST_MSVC ) +# pragma warning( push ) +# pragma warning( disable: 4996 ) +# endif + + char const * m = std::strerror( ev ); + +# if defined( BOOST_MSVC ) +# pragma warning( pop ) +# endif + + return m? m: "Unknown error"; + +#endif +} + +} // namespace detail + +} // namespace system + +} // namespace boost diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index c3b51f1..684cd47 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -17,7 +17,6 @@ #include #include #include -#include // TODO: undef these macros if not already defined #include @@ -761,38 +760,19 @@ inline bool error_category::equivalent( const error_code & code, int condition ) return *this == code.category() && code.value() == condition; } -// generic_error_category implementation - -namespace detail -{ - -inline char const * generic_error_category_message( int ev ) -{ -#ifdef BOOST_MSVC -#pragma warning( push ) -#pragma warning( disable: 4996 ) -#endif - - char const * m = std::strerror( ev ); - -#ifdef BOOST_MSVC -#pragma warning( pop ) -#endif - - return m? m: "Unknown error"; -} - -inline std::string generic_error_category::message( int ev ) const -{ - return generic_error_category_message( ev ); -} - -} // namespace detail - } // namespace system } // namespace boost +// generic_error_category implementation + +#include + +inline std::string boost::system::detail::generic_error_category::message( int ev ) const +{ + return generic_error_category_message( ev ); +} + // system_error_category implementation #if defined(BOOST_WINDOWS_API)