blob: f0897f6890c60e24dbe28d4c3c27b99a5151b353 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===---------------------------- system_error ----------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_SYSTEM_ERROR
12#define _LIBCPP_SYSTEM_ERROR
13
14/*
15 system_error synopsis
16
17namespace std
18{
19
20class error_category
21{
22public:
23 virtual ~error_category();
24
25 error_category(const error_category&) = delete;
26 error_category& operator=(const error_category&) = delete;
27
28 virtual const char* name() const = 0;
29 virtual error_condition default_error_condition(int ev) const;
30 virtual bool equivalent(int code, const error_condition& condition) const;
31 virtual bool equivalent(const error_code& code, int condition) const;
32 virtual string message(int ev) const = 0;
33
34 bool operator==(const error_category& rhs) const;
35 bool operator!=(const error_category& rhs) const;
36 bool operator<(const error_category& rhs) const;
37};
38
39const error_category& generic_category();
40const error_category& system_category();
41
42template <class T> struct is_error_code_enum
43 : public false_type {};
44
45template <class T> struct is_error_condition_enum
46 : public false_type {};
47
48class error_code
49{
50public:
51 // constructors:
52 error_code();
53 error_code(int val, const error_category& cat);
54 template <class ErrorCodeEnum>
55 error_code(ErrorCodeEnum e);
56
57 // modifiers:
58 void assign(int val, const error_category& cat);
59 template <class ErrorCodeEnum>
60 error_code& operator=(ErrorCodeEnum e);
61 void clear();
62
63 // observers:
64 int value() const;
65 const error_category& category() const;
66 error_condition default_error_condition() const;
67 string message() const;
68 explicit operator bool() const;
69};
70
71// non-member functions:
72bool operator<(const error_code& lhs, const error_code& rhs);
73template <class charT, class traits>
74 basic_ostream<charT,traits>&
75 operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
76
77class error_condition
78{
79public:
80 // constructors:
81 error_condition();
82 error_condition(int val, const error_category& cat);
83 template <class ErrorConditionEnum>
84 error_condition(ErrorConditionEnum e);
85
86 // modifiers:
87 void assign(int val, const error_category& cat);
88 template <class ErrorConditionEnum>
89 error_condition& operator=(ErrorConditionEnum e);
90 void clear();
91
92 // observers:
93 int value() const;
94 const error_category& category() const;
95 string message() const;
96 explicit operator bool() const;
97};
98
99bool operator<(const error_condition& lhs, const error_condition& rhs);
100
101class system_error
102 : public runtime_error
103{
104public:
105 system_error(error_code ec, const string& what_arg);
106 system_error(error_code ec, const char* what_arg);
107 system_error(error_code ec);
108 system_error(int ev, const error_category& ecat, const string& what_arg);
109 system_error(int ev, const error_category& ecat, const char* what_arg);
110 system_error(int ev, const error_category& ecat);
111
112 const error_code& code() const throw();
113 const char* what() const throw();
114};
115
116enum class errc
117{
118 address_family_not_supported, // EAFNOSUPPORT
119 address_in_use, // EADDRINUSE
120 address_not_available, // EADDRNOTAVAIL
121 already_connected, // EISCONN
122 argument_list_too_long, // E2BIG
123 argument_out_of_domain, // EDOM
124 bad_address, // EFAULT
125 bad_file_descriptor, // EBADF
126 bad_message, // EBADMSG
127 broken_pipe, // EPIPE
128 connection_aborted, // ECONNABORTED
129 connection_already_in_progress, // EALREADY
130 connection_refused, // ECONNREFUSED
131 connection_reset, // ECONNRESET
132 cross_device_link, // EXDEV
133 destination_address_required, // EDESTADDRREQ
134 device_or_resource_busy, // EBUSY
135 directory_not_empty, // ENOTEMPTY
136 executable_format_error, // ENOEXEC
137 file_exists, // EEXIST
138 file_too_large, // EFBIG
139 filename_too_long, // ENAMETOOLONG
140 function_not_supported, // ENOSYS
141 host_unreachable, // EHOSTUNREACH
142 identifier_removed, // EIDRM
143 illegal_byte_sequence, // EILSEQ
144 inappropriate_io_control_operation, // ENOTTY
145 interrupted, // EINTR
146 invalid_argument, // EINVAL
147 invalid_seek, // ESPIPE
148 io_error, // EIO
149 is_a_directory, // EISDIR
150 message_size, // EMSGSIZE
151 network_down, // ENETDOWN
152 network_reset, // ENETRESET
153 network_unreachable, // ENETUNREACH
154 no_buffer_space, // ENOBUFS
155 no_child_process, // ECHILD
156 no_link, // ENOLINK
157 no_lock_available, // ENOLCK
158 no_message_available, // ENODATA
159 no_message, // ENOMSG
160 no_protocol_option, // ENOPROTOOPT
161 no_space_on_device, // ENOSPC
162 no_stream_resources, // ENOSR
163 no_such_device_or_address, // ENXIO
164 no_such_device, // ENODEV
165 no_such_file_or_directory, // ENOENT
166 no_such_process, // ESRCH
167 not_a_directory, // ENOTDIR
168 not_a_socket, // ENOTSOCK
169 not_a_stream, // ENOSTR
170 not_connected, // ENOTCONN
171 not_enough_memory, // ENOMEM
172 not_supported, // ENOTSUP
173 operation_canceled, // ECANCELED
174 operation_in_progress, // EINPROGRESS
175 operation_not_permitted, // EPERM
176 operation_not_supported, // EOPNOTSUPP
177 operation_would_block, // EWOULDBLOCK
178 owner_dead, // EOWNERDEAD
179 permission_denied, // EACCES
180 protocol_error, // EPROTO
181 protocol_not_supported, // EPROTONOSUPPORT
182 read_only_file_system, // EROFS
183 resource_deadlock_would_occur, // EDEADLK
184 resource_unavailable_try_again, // EAGAIN
185 result_out_of_range, // ERANGE
186 state_not_recoverable, // ENOTRECOVERABLE
187 stream_timeout, // ETIME
188 text_file_busy, // ETXTBSY
189 timed_out, // ETIMEDOUT
190 too_many_files_open_in_system, // ENFILE
191 too_many_files_open, // EMFILE
192 too_many_links, // EMLINK
193 too_many_symbolic_link_levels, // ELOOP
194 value_too_large, // EOVERFLOW
195 wrong_protocol_type // EPROTOTYPE
196};
197
198template <> struct is_error_condition_enum<errc>
199 : true_type { }
200
201error_code make_error_code(errc e);
202error_condition make_error_condition(errc e);
203
204// Comparison operators:
205bool operator==(const error_code& lhs, const error_code& rhs);
206bool operator==(const error_code& lhs, const error_condition& rhs);
207bool operator==(const error_condition& lhs, const error_code& rhs);
208bool operator==(const error_condition& lhs, const error_condition& rhs);
209bool operator!=(const error_code& lhs, const error_code& rhs);
210bool operator!=(const error_code& lhs, const error_condition& rhs);
211bool operator!=(const error_condition& lhs, const error_code& rhs);
212bool operator!=(const error_condition& lhs, const error_condition& rhs);
213
214template <> struct hash<std::error_code>;
215
216} // std
217
218*/
219
220#include <__config>
221#include <cerrno>
222#include <type_traits>
223#include <stdexcept>
224#include <__functional_base>
225
226#pragma GCC system_header
227
228_LIBCPP_BEGIN_NAMESPACE_STD
229
230// is_error_code_enum
231
232template <class _Tp> struct is_error_code_enum
233 : public false_type {};
234
235// is_error_condition_enum
236
237template <class _Tp> struct is_error_condition_enum
238 : public false_type {};
239
240//enum class errc
241struct errc
242{
243enum _ {
244 address_family_not_supported = EAFNOSUPPORT,
245 address_in_use = EADDRINUSE,
246 address_not_available = EADDRNOTAVAIL,
247 already_connected = EISCONN,
248 argument_list_too_long = E2BIG,
249 argument_out_of_domain = EDOM,
250 bad_address = EFAULT,
251 bad_file_descriptor = EBADF,
252 bad_message = EBADMSG,
253 broken_pipe = EPIPE,
254 connection_aborted = ECONNABORTED,
255 connection_already_in_progress = EALREADY,
256 connection_refused = ECONNREFUSED,
257 connection_reset = ECONNRESET,
258 cross_device_link = EXDEV,
259 destination_address_required = EDESTADDRREQ,
260 device_or_resource_busy = EBUSY,
261 directory_not_empty = ENOTEMPTY,
262 executable_format_error = ENOEXEC,
263 file_exists = EEXIST,
264 file_too_large = EFBIG,
265 filename_too_long = ENAMETOOLONG,
266 function_not_supported = ENOSYS,
267 host_unreachable = EHOSTUNREACH,
268 identifier_removed = EIDRM,
269 illegal_byte_sequence = EILSEQ,
270 inappropriate_io_control_operation = ENOTTY,
271 interrupted = EINTR,
272 invalid_argument = EINVAL,
273 invalid_seek = ESPIPE,
274 io_error = EIO,
275 is_a_directory = EISDIR,
276 message_size = EMSGSIZE,
277 network_down = ENETDOWN,
278 network_reset = ENETRESET,
279 network_unreachable = ENETUNREACH,
280 no_buffer_space = ENOBUFS,
281 no_child_process = ECHILD,
282 no_link = ENOLINK,
283 no_lock_available = ENOLCK,
284 no_message_available = ENODATA,
285 no_message = ENOMSG,
286 no_protocol_option = ENOPROTOOPT,
287 no_space_on_device = ENOSPC,
288 no_stream_resources = ENOSR,
289 no_such_device_or_address = ENXIO,
290 no_such_device = ENODEV,
291 no_such_file_or_directory = ENOENT,
292 no_such_process = ESRCH,
293 not_a_directory = ENOTDIR,
294 not_a_socket = ENOTSOCK,
295 not_a_stream = ENOSTR,
296 not_connected = ENOTCONN,
297 not_enough_memory = ENOMEM,
298 not_supported = ENOTSUP,
299 operation_canceled = ECANCELED,
300 operation_in_progress = EINPROGRESS,
301 operation_not_permitted = EPERM,
302 operation_not_supported = EOPNOTSUPP,
303 operation_would_block = EWOULDBLOCK,
304 owner_dead = EOWNERDEAD,
305 permission_denied = EACCES,
306 protocol_error = EPROTO,
307 protocol_not_supported = EPROTONOSUPPORT,
308 read_only_file_system = EROFS,
309 resource_deadlock_would_occur = EDEADLK,
310 resource_unavailable_try_again = EAGAIN,
311 result_out_of_range = ERANGE,
312 state_not_recoverable = ENOTRECOVERABLE,
313 stream_timeout = ETIME,
314 text_file_busy = ETXTBSY,
315 timed_out = ETIMEDOUT,
316 too_many_files_open_in_system = ENFILE,
317 too_many_files_open = EMFILE,
318 too_many_links = EMLINK,
319 too_many_symbolic_link_levels = ELOOP,
320 value_too_large = EOVERFLOW,
321 wrong_protocol_type = EPROTOTYPE
322};
323
324 _ __v_;
325
326 errc(_ __v) : __v_(__v) {}
327 operator int() const {return __v_;}
328
329};
330
331template <> struct is_error_condition_enum<errc>
332 : true_type { };
333
334template <> struct is_error_condition_enum<errc::_>
335 : true_type { };
336
337class error_condition;
338class error_code;
339
340// class error_category
341
342class __do_message;
343
344class error_category
345{
346public:
347 virtual ~error_category();
348
349private:
350 error_category();
351 error_category(const error_category&);// = delete;
352 error_category& operator=(const error_category&);// = delete;
353
354public:
355 virtual const char* name() const = 0;
356 virtual error_condition default_error_condition(int __ev) const;
357 virtual bool equivalent(int __code, const error_condition& __condition) const;
358 virtual bool equivalent(const error_code& __code, int __condition) const;
359 virtual string message(int __ev) const = 0;
360
361 _LIBCPP_ALWAYS_INLINE
362 bool operator==(const error_category& __rhs) const {return this == &__rhs;}
363
364 _LIBCPP_ALWAYS_INLINE
365 bool operator!=(const error_category& __rhs) const {return !(*this == __rhs);}
366
367 _LIBCPP_ALWAYS_INLINE
368 bool operator< (const error_category& __rhs) const {return this < &__rhs;}
369
370 friend class __do_message;
371};
372
373class _LIBCPP_HIDDEN __do_message
374 : public error_category
375{
376public:
377 virtual string message(int ev) const;
378};
379
380const error_category& generic_category();
381const error_category& system_category();
382
383class error_condition
384{
385 int __val_;
386 const error_category* __cat_;
387public:
388 _LIBCPP_ALWAYS_INLINE
389 error_condition() : __val_(0), __cat_(&generic_category()) {}
390
391 _LIBCPP_ALWAYS_INLINE
392 error_condition(int __val, const error_category& __cat)
393 : __val_(__val), __cat_(&__cat) {}
394
395 template <class _E>
396 _LIBCPP_ALWAYS_INLINE
397 error_condition(_E __e, typename enable_if<is_error_condition_enum<_E>::value>::type* = 0)
398 {*this = make_error_condition(__e);}
399
400 _LIBCPP_ALWAYS_INLINE
401 void assign(int __val, const error_category& __cat)
402 {
403 __val_ = __val;
404 __cat_ = &__cat;
405 }
406
407 template <class _E>
408 _LIBCPP_ALWAYS_INLINE
409 typename enable_if
410 <
411 is_error_condition_enum<_E>::value,
412 error_condition&
413 >::type
414 operator=(_E __e)
415 {*this = make_error_condition(__e); return *this;}
416
417 _LIBCPP_ALWAYS_INLINE
418 void clear()
419 {
420 __val_ = 0;
421 __cat_ = &generic_category();
422 }
423
424 _LIBCPP_ALWAYS_INLINE
425 int value() const {return __val_;}
426
427 _LIBCPP_ALWAYS_INLINE
428 const error_category& category() const {return *__cat_;}
429 string message() const;
430
431 _LIBCPP_ALWAYS_INLINE
432 //explicit
433 operator bool() const {return __val_ != 0;}
434};
435
436inline _LIBCPP_INLINE_VISIBILITY
437error_condition
438make_error_condition(errc __e)
439{
440 return error_condition(static_cast<int>(__e), generic_category());
441}
442
443inline _LIBCPP_INLINE_VISIBILITY
444bool
445operator<(const error_condition& __x, const error_condition& __y)
446{
447 return __x.category() < __y.category()
448 || __x.category() == __y.category() && __x.value() < __y.value();
449}
450
451// error_code
452
453class error_code
454{
455 int __val_;
456 const error_category* __cat_;
457public:
458 _LIBCPP_ALWAYS_INLINE
459 error_code() : __val_(0), __cat_(&system_category()) {}
460
461 _LIBCPP_ALWAYS_INLINE
462 error_code(int __val, const error_category& __cat)
463 : __val_(__val), __cat_(&__cat) {}
464
465 template <class _E>
466 _LIBCPP_ALWAYS_INLINE
467 error_code(_E __e, typename enable_if<is_error_code_enum<_E>::value>::type* = 0)
468 {*this = make_error_code(__e);}
469
470 _LIBCPP_ALWAYS_INLINE
471 void assign(int __val, const error_category& __cat)
472 {
473 __val_ = __val;
474 __cat_ = &__cat;
475 }
476
477 template <class _E>
478 _LIBCPP_ALWAYS_INLINE
479 typename enable_if
480 <
481 is_error_code_enum<_E>::value,
482 error_code&
483 >::type
484 operator=(_E __e)
485 {*this = make_error_code(__e); return *this;}
486
487 _LIBCPP_ALWAYS_INLINE
488 void clear()
489 {
490 __val_ = 0;
491 __cat_ = &system_category();
492 }
493
494 _LIBCPP_ALWAYS_INLINE
495 int value() const {return __val_;}
496
497 _LIBCPP_ALWAYS_INLINE
498 const error_category& category() const {return *__cat_;}
499
500 _LIBCPP_ALWAYS_INLINE
501 error_condition default_error_condition() const
502 {return __cat_->default_error_condition(__val_);}
503
504 string message() const;
505
506 _LIBCPP_ALWAYS_INLINE
507 //explicit
508 operator bool() const {return __val_ != 0;}
509};
510
511inline _LIBCPP_INLINE_VISIBILITY
512error_code
513make_error_code(errc __e)
514{
515 return error_code(static_cast<int>(__e), generic_category());
516}
517
518inline _LIBCPP_INLINE_VISIBILITY
519bool
520operator<(const error_code& __x, const error_code& __y)
521{
522 return __x.category() < __y.category()
523 || __x.category() == __y.category() && __x.value() < __y.value();
524}
525
526inline _LIBCPP_INLINE_VISIBILITY
527bool
528operator==(const error_code& __x, const error_code& __y)
529{
530 return __x.category() == __y.category() && __x.value() == __y.value();
531}
532
533inline _LIBCPP_INLINE_VISIBILITY
534bool
535operator==(const error_code& __x, const error_condition& __y)
536{
537 return __x.category().equivalent(__x.value(), __y)
538 || __y.category().equivalent(__x, __y.value());
539}
540
541inline _LIBCPP_INLINE_VISIBILITY
542bool
543operator==(const error_condition& __x, const error_code& __y)
544{
545 return __y == __x;
546}
547
548inline _LIBCPP_INLINE_VISIBILITY
549bool
550operator==(const error_condition& __x, const error_condition& __y)
551{
552 return __x.category() == __y.category() && __x.value() == __y.value();
553}
554
555inline _LIBCPP_INLINE_VISIBILITY
556bool
557operator!=(const error_code& __x, const error_code& __y) {return !(__x == __y);}
558
559inline _LIBCPP_INLINE_VISIBILITY
560bool
561operator!=(const error_code& __x, const error_condition& __y) {return !(__x == __y);}
562
563inline _LIBCPP_INLINE_VISIBILITY
564bool
565operator!=(const error_condition& __x, const error_code& __y) {return !(__x == __y);}
566
567inline _LIBCPP_INLINE_VISIBILITY
568bool
569operator!=(const error_condition& __x, const error_condition& __y) {return !(__x == __y);}
570
571template <>
572struct hash<error_code>
573 : public unary_function<error_code, size_t>
574{
575 size_t operator()(const error_code& __ec) const
576 {
577 return static_cast<size_t>(__ec.value());
578 }
579};
580
581// system_error
582
583class system_error
584 : public runtime_error
585{
586 error_code __ec_;
587public:
588 system_error(error_code __ec, const string& __what_arg);
589 system_error(error_code __ec, const char* __what_arg);
590 system_error(error_code __ec);
591 system_error(int __ev, const error_category& __ecat, const string& __what_arg);
592 system_error(int __ev, const error_category& __ecat, const char* __what_arg);
593 system_error(int __ev, const error_category& __ecat);
594 ~system_error() throw();
595
596 _LIBCPP_ALWAYS_INLINE
597 const error_code& code() const throw() {return __ec_;}
598
599private:
600 static string __init(const error_code&, string);
601};
602
603void __throw_system_error(int ev, const char* what_arg);
604
605_LIBCPP_END_NAMESPACE_STD
606
607#endif // _LIBCPP_SYSTEM_ERROR