1 //
2 // error_code.hpp
3 // ~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef ASIO_ERROR_CODE_HPP
12 #define ASIO_ERROR_CODE_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include "asio/detail/config.hpp"
19
20 #if defined(ASIO_HAS_STD_SYSTEM_ERROR)
21 # include <system_error>
22 #else // defined(ASIO_HAS_STD_SYSTEM_ERROR)
23 # include <string>
24 # include "asio/detail/noncopyable.hpp"
25 # if !defined(ASIO_NO_IOSTREAM)
26 # include <iosfwd>
27 # endif // !defined(ASIO_NO_IOSTREAM)
28 #endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)
29
30 #include "asio/detail/push_options.hpp"
31
32 namespace asio {
33
34 #if defined(ASIO_HAS_STD_SYSTEM_ERROR)
35
36 typedef std::error_category error_category;
37
38 #else // defined(ASIO_HAS_STD_SYSTEM_ERROR)
39
40 /// Base class for all error categories.
41 class error_category : private noncopyable
42 {
43 public:
44 /// Destructor.
45 virtual ~error_category()
46 {
47 }
48
49 /// Returns a string naming the error gategory.
50 virtual const char* name() const = 0;
51
52 /// Returns a string describing the error denoted by @c value.
53 virtual std::string message(int value) const = 0;
54
55 /// Equality operator to compare two error categories.
56 bool operator==(const error_category& rhs) const
57 {
58 return this == &rhs;
59 }
60
61 /// Inequality operator to compare two error categories.
62 bool operator!=(const error_category& rhs) const
63 {
64 return !(*this == rhs);
65 }
66 };
67
68 #endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)
69
70 /// Returns the error category used for the system errors produced by asio.
71 extern ASIO_DECL const error_category& system_category();
72
73 #if defined(ASIO_HAS_STD_SYSTEM_ERROR)
74
75 typedef std::error_code error_code;
76
77 #else // defined(ASIO_HAS_STD_SYSTEM_ERROR)
78
79 /// Class to represent an error code value.
80 class error_code
81 {
82 public:
83 /// Default constructor.
error_code()84 error_code()
85 : value_(0),
86 category_(&system_category())
87 {
88 }
89
90 /// Construct with specific error code and category.
error_code(int v,const error_category & c)91 error_code(int v, const error_category& c)
92 : value_(v),
93 category_(&c)
94 {
95 }
96
97 /// Construct from an error code enum.
98 template <typename ErrorEnum>
error_code(ErrorEnum e)99 error_code(ErrorEnum e)
100 {
101 *this = make_error_code(e);
102 }
103
104 /// Clear the error value to the default.
clear()105 void clear()
106 {
107 value_ = 0;
108 category_ = &system_category();
109 }
110
111 /// Assign a new error value.
assign(int v,const error_category & c)112 void assign(int v, const error_category& c)
113 {
114 value_ = v;
115 category_ = &c;
116 }
117
118 /// Get the error value.
value() const119 int value() const
120 {
121 return value_;
122 }
123
124 /// Get the error category.
category() const125 const error_category& category() const
126 {
127 return *category_;
128 }
129
130 /// Get the message associated with the error.
message() const131 std::string message() const
132 {
133 return category_->message(value_);
134 }
135
136 struct unspecified_bool_type_t
137 {
138 };
139
140 typedef void (*unspecified_bool_type)(unspecified_bool_type_t);
141
unspecified_bool_true(unspecified_bool_type_t)142 static void unspecified_bool_true(unspecified_bool_type_t) {}
143
144 /// Operator returns non-null if there is a non-success error code.
operator unspecified_bool_type() const145 operator unspecified_bool_type() const
146 {
147 if (value_ == 0)
148 return 0;
149 else
150 return &error_code::unspecified_bool_true;
151 }
152
153 /// Operator to test if the error represents success.
operator !() const154 bool operator!() const
155 {
156 return value_ == 0;
157 }
158
159 /// Equality operator to compare two error objects.
operator ==(const error_code & e1,const error_code & e2)160 friend bool operator==(const error_code& e1, const error_code& e2)
161 {
162 return e1.value_ == e2.value_ && e1.category_ == e2.category_;
163 }
164
165 /// Inequality operator to compare two error objects.
operator !=(const error_code & e1,const error_code & e2)166 friend bool operator!=(const error_code& e1, const error_code& e2)
167 {
168 return e1.value_ != e2.value_ || e1.category_ != e2.category_;
169 }
170
171 private:
172 // The value associated with the error code.
173 int value_;
174
175 // The category associated with the error code.
176 const error_category* category_;
177 };
178
179 # if !defined(ASIO_NO_IOSTREAM)
180
181 /// Output an error code.
182 template <typename Elem, typename Traits>
operator <<(std::basic_ostream<Elem,Traits> & os,const error_code & ec)183 std::basic_ostream<Elem, Traits>& operator<<(
184 std::basic_ostream<Elem, Traits>& os, const error_code& ec)
185 {
186 os << ec.category().name() << ':' << ec.value();
187 return os;
188 }
189
190 # endif // !defined(ASIO_NO_IOSTREAM)
191
192 #endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)
193
194 } // namespace asio
195
196 #include "asio/detail/pop_options.hpp"
197
198 #if defined(ASIO_HEADER_ONLY)
199 # include "asio/impl/error_code.ipp"
200 #endif // defined(ASIO_HEADER_ONLY)
201
202 #endif // ASIO_ERROR_CODE_HPP
203