source: mainline/uspace/lib/cpp/include/impl/system_error.hpp@ 68cfab1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 68cfab1 was 68cfab1, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added system_error

  • Property mode set to 100644
File size: 10.5 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_SYSTEM_ERROR
30#define LIBCPP_SYSTEM_ERROR
31
32#include <internal/aux.hpp>
33#include <stdexcept>
34
35namespace std
36{
37 class error_condition;
38 class error_code;
39
40 enum class errc
41 { // TODO: add matching values
42 address_family_not_supported,
43 address_in_use,
44 address_not_available,
45 already_connected,
46 argument_list_too_long,
47 argument_out_of_domain,
48 bad_address,
49 bad_file_descriptor,
50 bad_message,
51 broken_pipe,
52 connection_aborted,
53 connection_already_in_progress,
54 connection_refused,
55 connection_reset,
56 cross_device_link,
57 destination_address_required,
58 device_or_resource_busy,
59 directory_not_empty,
60 executable_format_error,
61 file_exists,
62 file_too_large,
63 filename_too_long,
64 function_not_supported,
65 host_unreachable,
66 identifier_removed,
67 illegal_byte_sequence,
68 inappropriate_io_control_operation,
69 interrupted,
70 invalid_argument,
71 invalid_seek,
72 io_error,
73 is_a_directory,
74 message_size,
75 network_down,
76 network_reset,
77 network_unreachable,
78 no_buffer_space,
79 no_child_process,
80 no_link,
81 no_lock_available,
82 no_message_available,
83 no_message,
84 no_protocol_option,
85 no_space_on_device,
86 no_stream_resources,
87 no_such_device_or_address,
88 no_such_device,
89 no_such_file_or_directory,
90 no_such_process,
91 not_a_directory,
92 not_a_socket,
93 not_a_stream,
94 not_connected,
95 not_enough_memory,
96 not_supported,
97 operation_canceled,
98 operation_in_progress,
99 operation_not_permitted,
100 operation_not_supported,
101 operation_would_block,
102 owner_dead,
103 permission_denied,
104 protocol_error,
105 protocol_not_supported,
106 read_only_file_system,
107 resource_deadlock_would_occur,
108 resource_unavailable_try_again,
109 result_out_of_range,
110 state_not_recoverable,
111 stream_timeout,
112 text_file_busy,
113 timed_out,
114 too_many_files_open_in_system,
115 too_many_files_open,
116 too_many_links,
117 too_many_symbolic_link_levels,
118 value_too_large,
119 wrong_protocol_type
120 };
121
122 template<class>
123 struct is_error_code_enum: false_type
124 { /* DUMMY BODY */ };
125
126 template<>
127 struct is_error_code_enum<errc>: true_type
128 { /* DUMMY BODY */ };
129
130 template<class T>
131 inline constexpr bool is_error_code_enum_v = is_error_code_enum<T>::value;
132
133 template<class>
134 struct is_error_condition_enum: false_type
135 { /* DUMMY BODY */ };
136
137 template<>
138 struct is_error_condition_enum<errc>: true_type
139 { /* DUMMY BODY */ };
140
141 template<class T>
142 inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<T>::value;
143
144 /**
145 * 19.5.1, class error_category:
146 */
147
148 class error_category
149 {
150 public:
151 constexpr error_category() noexcept = default;
152 virtual ~error_category();
153
154 error_category(const error_category&) = delete;
155 error_category& operator=(const error_category&) = delete;
156
157 virtual const char* name() const noexcept = 0;
158 virtual error_condition default_error_condition(int) const noexcept;
159 virtual bool equivalent(int, const error_condition&) const noexcept;
160 virtual bool equivalent(const error_code&, int) const noexcept;
161 virtual string message(int) const = 0;
162
163 bool operator==(const error_category&) const noexcept;
164 bool operator!=(const error_category&) const noexcept;
165 bool operator<(const error_category&) const noexcept;
166 };
167
168 const error_category& generic_category() noexcept;
169 const error_category& system_category() noexcept;
170
171 /**
172 * 19.5.2, class error_code:
173 */
174
175 class error_code
176 {
177 public:
178 /**
179 * 19.5.2.2, constructors:
180 */
181
182 error_code() noexcept;
183 error_code(int, const error_category&) noexcept;
184
185 template<class ErrorCodeEnum>
186 error_code(
187 enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
188 ) noexcept
189 {
190 val_ = static_cast<int>(e);
191 cat_ = &generic_category();
192 }
193
194 /**
195 * 19.5.2.3, modifiers:
196 */
197
198 void assign(int, const error_category&) noexcept;
199
200 template<class ErrorCodeEnum>
201 error_code& operator=(
202 enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
203 ) noexcept
204 {
205 val_ = static_cast<int>(e);
206 cat_ = &generic_category();
207
208 return *this;
209 }
210
211 void clear() noexcept;
212
213 /**
214 * 19.5.2.4, observers:
215 */
216
217 int value() const noexcept;
218 const error_category& category() const noexcept;
219 error_condition default_error_condition() const noexcept;
220 string message() const;
221
222 explicit operator bool() const noexcept
223 {
224 return val_ != 0;
225 }
226
227 private:
228 int val_;
229 const error_category* cat_;
230 };
231
232 /**
233 * 19.5.2.5, non-member functions:
234 */
235
236 error_code make_error_code(errc e) noexcept;
237 bool operator<(const error_code&, const error_code&) noexcept;
238
239 template<class Char, class Traits>
240 basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
241 const error_code& ec)
242 {
243 return os << ec.category().name() << ": " << ec.value();
244 }
245
246 /**
247 * 19.5.3, class error_condition:
248 */
249
250 class error_condition
251 {
252 public:
253 /**
254 * 19.5.3.2, constructors:
255 */
256
257 error_condition() noexcept;
258 error_condition(int, const error_category&) noexcept;
259
260 template<class ErrorCodeEnum>
261 error_condition(
262 enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
263 ) noexcept
264 {
265 val_ = static_cast<int>(e);
266 cat_ = &generic_category();
267 }
268
269 /**
270 * 19.5.3.3, modifiers:
271 */
272
273 void assign(int, const error_category&) noexcept;
274
275 template<class ErrorCodeEnum>
276 error_condition& operator=(
277 enable_if_t<is_error_code_enum_v<ErrorCodeEnum>, ErrorCodeEnum> e
278 ) noexcept
279 {
280 val_ = static_cast<int>(e);
281 cat_ = &generic_category();
282
283 return *this;
284 }
285
286 void clear() noexcept;
287
288 /**
289 * 19.5.3.4, observers:
290 */
291
292 int value() const noexcept;
293 const error_category& category() const noexcept;
294 string message() const;
295
296 explicit operator bool() const noexcept
297 {
298 return val_ != 0;
299 }
300
301 private:
302 int val_;
303 const error_category* cat_;
304 };
305
306 /**
307 * 19.5.3.4, non-member functions:
308 */
309
310 error_condition make_error_condition(errc e) noexcept;
311 bool operator<(const error_condition&, const error_condition&) noexcept;
312
313 /**
314 * 19.5.4, comparison operators:
315 */
316
317 bool operator==(const error_code&, const error_code&) noexcept;
318 bool operator==(const error_code&, const error_condition&) noexcept;
319 bool operator==(const error_condition&, const error_code&) noexcept;
320 bool operator==(const error_condition&, const error_condition&) noexcept;
321 bool operator!=(const error_code&, const error_code&) noexcept;
322 bool operator!=(const error_code&, const error_condition&) noexcept;
323 bool operator!=(const error_condition&, const error_code&) noexcept;
324 bool operator!=(const error_condition&, const error_condition&) noexcept;
325
326 /**
327 * 19.5.6, class system_error:
328 */
329
330 class system_error: public runtime_error
331 {
332 public:
333 system_error(error_code, const string&);
334 system_error(error_code, const char*);
335 system_error(error_code);
336 system_error(int, const error_category&, const string&);
337 system_error(int, const error_category&, const char*);
338 system_error(int, const error_category&);
339
340 const error_code& code() const noexcept;
341
342 const char* what() const noexcept override;
343
344 private:
345 error_code code_;
346 string what_;
347 };
348
349 /**
350 * 19.5.5, hash support:
351 */
352
353 template<class>
354 struct hash;
355
356 template<>
357 struct hash<error_code>
358 {
359 size_t operator()(const error_code& ec) const noexcept
360 {
361 return static_cast<size_t>(ec.value());
362 }
363
364 using result_type = size_t;
365 using argument_type = error_code;
366 };
367}
368
369#endif
Note: See TracBrowser for help on using the repository browser.