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