blob: 8526f375c0133bf86fe0e601853894c9cf730455 [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
David Chisnall81e68582010-08-11 16:52:41 +0000240// Some error codes are not present on all platforms, so we provide equivalents
241// for them:
242
243
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000244//enum class errc
245struct errc
246{
247enum _ {
248 address_family_not_supported = EAFNOSUPPORT,
249 address_in_use = EADDRINUSE,
250 address_not_available = EADDRNOTAVAIL,
251 already_connected = EISCONN,
252 argument_list_too_long = E2BIG,
253 argument_out_of_domain = EDOM,
254 bad_address = EFAULT,
255 bad_file_descriptor = EBADF,
256 bad_message = EBADMSG,
257 broken_pipe = EPIPE,
258 connection_aborted = ECONNABORTED,
259 connection_already_in_progress = EALREADY,
260 connection_refused = ECONNREFUSED,
261 connection_reset = ECONNRESET,
262 cross_device_link = EXDEV,
263 destination_address_required = EDESTADDRREQ,
264 device_or_resource_busy = EBUSY,
265 directory_not_empty = ENOTEMPTY,
266 executable_format_error = ENOEXEC,
267 file_exists = EEXIST,
268 file_too_large = EFBIG,
269 filename_too_long = ENAMETOOLONG,
270 function_not_supported = ENOSYS,
271 host_unreachable = EHOSTUNREACH,
272 identifier_removed = EIDRM,
273 illegal_byte_sequence = EILSEQ,
274 inappropriate_io_control_operation = ENOTTY,
275 interrupted = EINTR,
276 invalid_argument = EINVAL,
277 invalid_seek = ESPIPE,
278 io_error = EIO,
279 is_a_directory = EISDIR,
280 message_size = EMSGSIZE,
281 network_down = ENETDOWN,
282 network_reset = ENETRESET,
283 network_unreachable = ENETUNREACH,
284 no_buffer_space = ENOBUFS,
285 no_child_process = ECHILD,
286 no_link = ENOLINK,
287 no_lock_available = ENOLCK,
David Chisnall81e68582010-08-11 16:52:41 +0000288#ifdef ENODATA
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000289 no_message_available = ENODATA,
David Chisnall81e68582010-08-11 16:52:41 +0000290#else
291 no_message_available = ENOMSG,
292#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000293 no_message = ENOMSG,
294 no_protocol_option = ENOPROTOOPT,
295 no_space_on_device = ENOSPC,
David Chisnall81e68582010-08-11 16:52:41 +0000296#ifdef ENOSR
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000297 no_stream_resources = ENOSR,
David Chisnall81e68582010-08-11 16:52:41 +0000298#else
299 no_stream_resources = ENOMEM,
300#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000301 no_such_device_or_address = ENXIO,
302 no_such_device = ENODEV,
303 no_such_file_or_directory = ENOENT,
304 no_such_process = ESRCH,
305 not_a_directory = ENOTDIR,
306 not_a_socket = ENOTSOCK,
David Chisnall81e68582010-08-11 16:52:41 +0000307#ifdef ENOSTR
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000308 not_a_stream = ENOSTR,
David Chisnall81e68582010-08-11 16:52:41 +0000309#else
310 not_a_stream = EINVAL,
311#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000312 not_connected = ENOTCONN,
313 not_enough_memory = ENOMEM,
314 not_supported = ENOTSUP,
315 operation_canceled = ECANCELED,
316 operation_in_progress = EINPROGRESS,
317 operation_not_permitted = EPERM,
318 operation_not_supported = EOPNOTSUPP,
319 operation_would_block = EWOULDBLOCK,
320 owner_dead = EOWNERDEAD,
321 permission_denied = EACCES,
322 protocol_error = EPROTO,
323 protocol_not_supported = EPROTONOSUPPORT,
324 read_only_file_system = EROFS,
325 resource_deadlock_would_occur = EDEADLK,
326 resource_unavailable_try_again = EAGAIN,
327 result_out_of_range = ERANGE,
328 state_not_recoverable = ENOTRECOVERABLE,
David Chisnall81e68582010-08-11 16:52:41 +0000329#ifdef ETIME
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000330 stream_timeout = ETIME,
David Chisnall81e68582010-08-11 16:52:41 +0000331#else
332 stream_timeout = ETIMEDOUT,
333#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000334 text_file_busy = ETXTBSY,
335 timed_out = ETIMEDOUT,
336 too_many_files_open_in_system = ENFILE,
337 too_many_files_open = EMFILE,
338 too_many_links = EMLINK,
339 too_many_symbolic_link_levels = ELOOP,
340 value_too_large = EOVERFLOW,
341 wrong_protocol_type = EPROTOTYPE
342};
343
344 _ __v_;
345
346 errc(_ __v) : __v_(__v) {}
347 operator int() const {return __v_;}
348
349};
350
351template <> struct is_error_condition_enum<errc>
352 : true_type { };
353
354template <> struct is_error_condition_enum<errc::_>
355 : true_type { };
356
357class error_condition;
358class error_code;
359
360// class error_category
361
362class __do_message;
363
364class error_category
365{
366public:
367 virtual ~error_category();
368
369private:
370 error_category();
371 error_category(const error_category&);// = delete;
372 error_category& operator=(const error_category&);// = delete;
373
374public:
375 virtual const char* name() const = 0;
376 virtual error_condition default_error_condition(int __ev) const;
377 virtual bool equivalent(int __code, const error_condition& __condition) const;
378 virtual bool equivalent(const error_code& __code, int __condition) const;
379 virtual string message(int __ev) const = 0;
380
381 _LIBCPP_ALWAYS_INLINE
382 bool operator==(const error_category& __rhs) const {return this == &__rhs;}
383
384 _LIBCPP_ALWAYS_INLINE
385 bool operator!=(const error_category& __rhs) const {return !(*this == __rhs);}
386
387 _LIBCPP_ALWAYS_INLINE
388 bool operator< (const error_category& __rhs) const {return this < &__rhs;}
389
390 friend class __do_message;
391};
392
393class _LIBCPP_HIDDEN __do_message
394 : public error_category
395{
396public:
397 virtual string message(int ev) const;
398};
399
400const error_category& generic_category();
401const error_category& system_category();
402
403class error_condition
404{
405 int __val_;
406 const error_category* __cat_;
407public:
408 _LIBCPP_ALWAYS_INLINE
409 error_condition() : __val_(0), __cat_(&generic_category()) {}
410
411 _LIBCPP_ALWAYS_INLINE
412 error_condition(int __val, const error_category& __cat)
413 : __val_(__val), __cat_(&__cat) {}
414
415 template <class _E>
416 _LIBCPP_ALWAYS_INLINE
417 error_condition(_E __e, typename enable_if<is_error_condition_enum<_E>::value>::type* = 0)
418 {*this = make_error_condition(__e);}
419
420 _LIBCPP_ALWAYS_INLINE
421 void assign(int __val, const error_category& __cat)
422 {
423 __val_ = __val;
424 __cat_ = &__cat;
425 }
426
427 template <class _E>
428 _LIBCPP_ALWAYS_INLINE
429 typename enable_if
430 <
431 is_error_condition_enum<_E>::value,
432 error_condition&
433 >::type
434 operator=(_E __e)
435 {*this = make_error_condition(__e); return *this;}
436
437 _LIBCPP_ALWAYS_INLINE
438 void clear()
439 {
440 __val_ = 0;
441 __cat_ = &generic_category();
442 }
443
444 _LIBCPP_ALWAYS_INLINE
445 int value() const {return __val_;}
446
447 _LIBCPP_ALWAYS_INLINE
448 const error_category& category() const {return *__cat_;}
449 string message() const;
450
451 _LIBCPP_ALWAYS_INLINE
452 //explicit
453 operator bool() const {return __val_ != 0;}
454};
455
456inline _LIBCPP_INLINE_VISIBILITY
457error_condition
458make_error_condition(errc __e)
459{
460 return error_condition(static_cast<int>(__e), generic_category());
461}
462
463inline _LIBCPP_INLINE_VISIBILITY
464bool
465operator<(const error_condition& __x, const error_condition& __y)
466{
467 return __x.category() < __y.category()
468 || __x.category() == __y.category() && __x.value() < __y.value();
469}
470
471// error_code
472
473class error_code
474{
475 int __val_;
476 const error_category* __cat_;
477public:
478 _LIBCPP_ALWAYS_INLINE
479 error_code() : __val_(0), __cat_(&system_category()) {}
480
481 _LIBCPP_ALWAYS_INLINE
482 error_code(int __val, const error_category& __cat)
483 : __val_(__val), __cat_(&__cat) {}
484
485 template <class _E>
486 _LIBCPP_ALWAYS_INLINE
487 error_code(_E __e, typename enable_if<is_error_code_enum<_E>::value>::type* = 0)
488 {*this = make_error_code(__e);}
489
490 _LIBCPP_ALWAYS_INLINE
491 void assign(int __val, const error_category& __cat)
492 {
493 __val_ = __val;
494 __cat_ = &__cat;
495 }
496
497 template <class _E>
498 _LIBCPP_ALWAYS_INLINE
499 typename enable_if
500 <
501 is_error_code_enum<_E>::value,
502 error_code&
503 >::type
504 operator=(_E __e)
505 {*this = make_error_code(__e); return *this;}
506
507 _LIBCPP_ALWAYS_INLINE
508 void clear()
509 {
510 __val_ = 0;
511 __cat_ = &system_category();
512 }
513
514 _LIBCPP_ALWAYS_INLINE
515 int value() const {return __val_;}
516
517 _LIBCPP_ALWAYS_INLINE
518 const error_category& category() const {return *__cat_;}
519
520 _LIBCPP_ALWAYS_INLINE
521 error_condition default_error_condition() const
522 {return __cat_->default_error_condition(__val_);}
523
524 string message() const;
525
526 _LIBCPP_ALWAYS_INLINE
527 //explicit
528 operator bool() const {return __val_ != 0;}
529};
530
531inline _LIBCPP_INLINE_VISIBILITY
532error_code
533make_error_code(errc __e)
534{
535 return error_code(static_cast<int>(__e), generic_category());
536}
537
538inline _LIBCPP_INLINE_VISIBILITY
539bool
540operator<(const error_code& __x, const error_code& __y)
541{
542 return __x.category() < __y.category()
543 || __x.category() == __y.category() && __x.value() < __y.value();
544}
545
546inline _LIBCPP_INLINE_VISIBILITY
547bool
548operator==(const error_code& __x, const error_code& __y)
549{
550 return __x.category() == __y.category() && __x.value() == __y.value();
551}
552
553inline _LIBCPP_INLINE_VISIBILITY
554bool
555operator==(const error_code& __x, const error_condition& __y)
556{
557 return __x.category().equivalent(__x.value(), __y)
558 || __y.category().equivalent(__x, __y.value());
559}
560
561inline _LIBCPP_INLINE_VISIBILITY
562bool
563operator==(const error_condition& __x, const error_code& __y)
564{
565 return __y == __x;
566}
567
568inline _LIBCPP_INLINE_VISIBILITY
569bool
570operator==(const error_condition& __x, const error_condition& __y)
571{
572 return __x.category() == __y.category() && __x.value() == __y.value();
573}
574
575inline _LIBCPP_INLINE_VISIBILITY
576bool
577operator!=(const error_code& __x, const error_code& __y) {return !(__x == __y);}
578
579inline _LIBCPP_INLINE_VISIBILITY
580bool
581operator!=(const error_code& __x, const error_condition& __y) {return !(__x == __y);}
582
583inline _LIBCPP_INLINE_VISIBILITY
584bool
585operator!=(const error_condition& __x, const error_code& __y) {return !(__x == __y);}
586
587inline _LIBCPP_INLINE_VISIBILITY
588bool
589operator!=(const error_condition& __x, const error_condition& __y) {return !(__x == __y);}
590
591template <>
592struct hash<error_code>
593 : public unary_function<error_code, size_t>
594{
595 size_t operator()(const error_code& __ec) const
596 {
597 return static_cast<size_t>(__ec.value());
598 }
599};
600
601// system_error
602
603class system_error
604 : public runtime_error
605{
606 error_code __ec_;
607public:
608 system_error(error_code __ec, const string& __what_arg);
609 system_error(error_code __ec, const char* __what_arg);
610 system_error(error_code __ec);
611 system_error(int __ev, const error_category& __ecat, const string& __what_arg);
612 system_error(int __ev, const error_category& __ecat, const char* __what_arg);
613 system_error(int __ev, const error_category& __ecat);
614 ~system_error() throw();
615
616 _LIBCPP_ALWAYS_INLINE
617 const error_code& code() const throw() {return __ec_;}
618
619private:
620 static string __init(const error_code&, string);
621};
622
623void __throw_system_error(int ev, const char* what_arg);
624
625_LIBCPP_END_NAMESPACE_STD
626
627#endif // _LIBCPP_SYSTEM_ERROR