1 #ifndef BOOST_SYSTEM_DETAIL_ERROR_CATEGORY_HPP_INCLUDED
2 #define BOOST_SYSTEM_DETAIL_ERROR_CATEGORY_HPP_INCLUDED
3
4 // Copyright Beman Dawes 2006, 2007
5 // Copyright Christoper Kohlhoff 2007
6 // Copyright Peter Dimov 2017, 2018
7 //
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // See library home page at http://www.boost.org/libs/system
12
13 #include <boost/system/detail/config.hpp>
14 #include <boost/cstdint.hpp>
15 #include <boost/config.hpp>
16 #include <string>
17 #include <functional>
18 #include <cstddef>
19
20 #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
21 # include <system_error>
22 #endif
23
24 namespace boost
25 {
26
27 namespace system
28 {
29
30 class error_category;
31 class error_code;
32 class error_condition;
33
34 std::size_t hash_value( error_code const & ec );
35
36 namespace detail
37 {
38
39 BOOST_SYSTEM_CONSTEXPR bool failed_impl( int ev, error_category const & cat );
40
41 #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
42
43 std::error_category const & to_std_category( error_category const & cat );
44
45 #endif
46
47 } // namespace detail
48
49 #if ( defined( BOOST_GCC ) && BOOST_GCC >= 40600 ) || defined( BOOST_CLANG )
50 #pragma GCC diagnostic push
51 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
52 #endif
53
54 class BOOST_SYMBOL_VISIBLE error_category
55 {
56 private:
57
58 friend std::size_t hash_value( error_code const & ec );
59 friend BOOST_SYSTEM_CONSTEXPR bool detail::failed_impl( int ev, error_category const & cat );
60
61 #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
62 friend std::error_category const & detail::to_std_category( error_category const & cat );
63 #endif
64
65 #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
66 public:
67
68 error_category( error_category const & ) = delete;
69 error_category& operator=( error_category const & ) = delete;
70
71 #else
72 private:
73
74 error_category( error_category const & );
75 error_category& operator=( error_category const & );
76
77 #endif
78
79 private:
80
81 boost::ulong_long_type id_;
82
83 protected:
84
85 #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
86
87 ~error_category() = default;
88
89 #else
90
91 // We'd like to make the destructor protected, to make code that deletes
92 // an error_category* not compile; unfortunately, doing the below makes
93 // the destructor user-provided and hence breaks use after main, as the
94 // categories may get destroyed before code that uses them
95
96 // ~error_category() {}
97
98 #endif
99
error_category()100 BOOST_SYSTEM_CONSTEXPR error_category() BOOST_NOEXCEPT: id_( 0 )
101 {
102 }
103
error_category(boost::ulong_long_type id)104 explicit BOOST_SYSTEM_CONSTEXPR error_category( boost::ulong_long_type id ) BOOST_NOEXCEPT: id_( id )
105 {
106 }
107
108 public:
109
110 virtual const char * name() const BOOST_NOEXCEPT = 0;
111
112 virtual error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT;
113 virtual bool equivalent( int code, const error_condition & condition ) const BOOST_NOEXCEPT;
114 virtual bool equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT;
115
116 virtual std::string message( int ev ) const = 0;
117 virtual char const * message( int ev, char * buffer, std::size_t len ) const BOOST_NOEXCEPT;
118
failed(int ev) const119 virtual bool failed( int ev ) const BOOST_NOEXCEPT
120 {
121 return ev != 0;
122 }
123
operator ==(const error_category & rhs) const124 BOOST_SYSTEM_CONSTEXPR bool operator==( const error_category & rhs ) const BOOST_NOEXCEPT
125 {
126 return rhs.id_ == 0? this == &rhs: id_ == rhs.id_;
127 }
128
operator !=(const error_category & rhs) const129 BOOST_SYSTEM_CONSTEXPR bool operator!=( const error_category & rhs ) const BOOST_NOEXCEPT
130 {
131 return !( *this == rhs );
132 }
133
operator <(const error_category & rhs) const134 BOOST_SYSTEM_CONSTEXPR bool operator<( const error_category & rhs ) const BOOST_NOEXCEPT
135 {
136 if( id_ < rhs.id_ )
137 {
138 return true;
139 }
140
141 if( id_ > rhs.id_ )
142 {
143 return false;
144 }
145
146 if( rhs.id_ != 0 )
147 {
148 return false; // equal
149 }
150
151 return std::less<error_category const *>()( this, &rhs );
152 }
153
154 #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
155
156 operator std::error_category const & () const;
157
158 #endif
159 };
160
161 #if ( defined( BOOST_GCC ) && BOOST_GCC >= 40600 ) || defined( BOOST_CLANG )
162 #pragma GCC diagnostic pop
163 #endif
164
165 namespace detail
166 {
167
168 static const boost::ulong_long_type generic_category_id = ( boost::ulong_long_type( 0xB2AB117A ) << 32 ) + 0x257EDF0D;
169 static const boost::ulong_long_type system_category_id = ( boost::ulong_long_type( 0x8FAFD21E ) << 32 ) + 0x25C5E09B;
170
failed_impl(int ev,error_category const & cat)171 BOOST_SYSTEM_CONSTEXPR inline bool failed_impl( int ev, error_category const & cat )
172 {
173 if( cat.id_ == system_category_id || cat.id_ == generic_category_id )
174 {
175 return ev != 0;
176 }
177 else
178 {
179 return cat.failed( ev );
180 }
181 }
182
183 } // namespace detail
184
185 } // namespace system
186
187 } // namespace boost
188
189 #endif // #ifndef BOOST_SYSTEM_DETAIL_ERROR_CATEGORY_HPP_INCLUDED
190