KillTheDoctor: Fix 2008 build. I'm actually surprised 2010 defines all of these,...
[oota-llvm.git] / utils / KillTheDoctor / system_error.h
1 //===---------------------------- system_error ----------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This was lifted from libc++ and modified for C++03.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_SYSTEM_SYSTEM_ERROR_H
15 #define LLVM_SYSTEM_SYSTEM_ERROR_H
16
17 /*
18     system_error synopsis
19
20 namespace std
21 {
22
23 class error_category
24 {
25 public:
26     virtual ~error_category();
27
28     error_category(const error_category&) = delete;
29     error_category& operator=(const error_category&) = delete;
30
31     virtual const char* name() const = 0;
32     virtual error_condition default_error_condition(int ev) const;
33     virtual bool equivalent(int code, const error_condition& condition) const;
34     virtual bool equivalent(const error_code& code, int condition) const;
35     virtual std::string message(int ev) const = 0;
36
37     bool operator==(const error_category& rhs) const;
38     bool operator!=(const error_category& rhs) const;
39     bool operator<(const error_category& rhs) const;
40 };
41
42 const error_category& generic_category();
43 const error_category& system_category();
44
45 template <class T> struct is_error_code_enum
46     : public false_type {};
47
48 template <class T> struct is_error_condition_enum
49     : public false_type {};
50
51 class error_code
52 {
53 public:
54     // constructors:
55     error_code();
56     error_code(int val, const error_category& cat);
57     template <class ErrorCodeEnum>
58         error_code(ErrorCodeEnum e);
59
60     // modifiers:
61     void assign(int val, const error_category& cat);
62     template <class ErrorCodeEnum>
63         error_code& operator=(ErrorCodeEnum e);
64     void clear();
65
66     // observers:
67     int value() const;
68     const error_category& category() const;
69     error_condition default_error_condition() const;
70     std::string message() const;
71     explicit operator bool() const;
72 };
73
74 // non-member functions:
75 bool operator<(const error_code& lhs, const error_code& rhs);
76 template <class charT, class traits>
77     basic_ostream<charT,traits>&
78     operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
79
80 class error_condition
81 {
82 public:
83     // constructors:
84     error_condition();
85     error_condition(int val, const error_category& cat);
86     template <class ErrorConditionEnum>
87         error_condition(ErrorConditionEnum e);
88
89     // modifiers:
90     void assign(int val, const error_category& cat);
91     template <class ErrorConditionEnum>
92         error_condition& operator=(ErrorConditionEnum e);
93     void clear();
94
95     // observers:
96     int value() const;
97     const error_category& category() const;
98     std::string message() const;
99     explicit operator bool() const;
100 };
101
102 bool operator<(const error_condition& lhs, const error_condition& rhs);
103
104 class system_error
105     : public runtime_error
106 {
107 public:
108     system_error(error_code ec, const std::string& what_arg);
109     system_error(error_code ec, const char* what_arg);
110     system_error(error_code ec);
111     system_error(int ev, const error_category& ecat, const std::string& what_arg);
112     system_error(int ev, const error_category& ecat, const char* what_arg);
113     system_error(int ev, const error_category& ecat);
114
115     const error_code& code() const throw();
116     const char* what() const throw();
117 };
118
119 enum class errc
120 {
121     address_family_not_supported,       // EAFNOSUPPORT
122     address_in_use,                     // EADDRINUSE
123     address_not_available,              // EADDRNOTAVAIL
124     already_connected,                  // EISCONN
125     argument_list_too_long,             // E2BIG
126     argument_out_of_domain,             // EDOM
127     bad_address,                        // EFAULT
128     bad_file_descriptor,                // EBADF
129     bad_message,                        // EBADMSG
130     broken_pipe,                        // EPIPE
131     connection_aborted,                 // ECONNABORTED
132     connection_already_in_progress,     // EALREADY
133     connection_refused,                 // ECONNREFUSED
134     connection_reset,                   // ECONNRESET
135     cross_device_link,                  // EXDEV
136     destination_address_required,       // EDESTADDRREQ
137     device_or_resource_busy,            // EBUSY
138     directory_not_empty,                // ENOTEMPTY
139     executable_format_error,            // ENOEXEC
140     file_exists,                        // EEXIST
141     file_too_large,                     // EFBIG
142     filename_too_long,                  // ENAMETOOLONG
143     function_not_supported,             // ENOSYS
144     host_unreachable,                   // EHOSTUNREACH
145     identifier_removed,                 // EIDRM
146     illegal_byte_sequence,              // EILSEQ
147     inappropriate_io_control_operation, // ENOTTY
148     interrupted,                        // EINTR
149     invalid_argument,                   // EINVAL
150     invalid_seek,                       // ESPIPE
151     io_error,                           // EIO
152     is_a_directory,                     // EISDIR
153     message_size,                       // EMSGSIZE
154     network_down,                       // ENETDOWN
155     network_reset,                      // ENETRESET
156     network_unreachable,                // ENETUNREACH
157     no_buffer_space,                    // ENOBUFS
158     no_child_process,                   // ECHILD
159     no_link,                            // ENOLINK
160     no_lock_available,                  // ENOLCK
161     no_message_available,               // ENODATA
162     no_message,                         // ENOMSG
163     no_protocol_option,                 // ENOPROTOOPT
164     no_space_on_device,                 // ENOSPC
165     no_stream_resources,                // ENOSR
166     no_such_device_or_address,          // ENXIO
167     no_such_device,                     // ENODEV
168     no_such_file_or_directory,          // ENOENT
169     no_such_process,                    // ESRCH
170     not_a_directory,                    // ENOTDIR
171     not_a_socket,                       // ENOTSOCK
172     not_a_stream,                       // ENOSTR
173     not_connected,                      // ENOTCONN
174     not_enough_memory,                  // ENOMEM
175     not_supported,                      // ENOTSUP
176     operation_canceled,                 // ECANCELED
177     operation_in_progress,              // EINPROGRESS
178     operation_not_permitted,            // EPERM
179     operation_not_supported,            // EOPNOTSUPP
180     operation_would_block,              // EWOULDBLOCK
181     owner_dead,                         // EOWNERDEAD
182     permission_denied,                  // EACCES
183     protocol_error,                     // EPROTO
184     protocol_not_supported,             // EPROTONOSUPPORT
185     read_only_file_system,              // EROFS
186     resource_deadlock_would_occur,      // EDEADLK
187     resource_unavailable_try_again,     // EAGAIN
188     result_out_of_range,                // ERANGE
189     state_not_recoverable,              // ENOTRECOVERABLE
190     stream_timeout,                     // ETIME
191     text_file_busy,                     // ETXTBSY
192     timed_out,                          // ETIMEDOUT
193     too_many_files_open_in_system,      // ENFILE
194     too_many_files_open,                // EMFILE
195     too_many_links,                     // EMLINK
196     too_many_symbolic_link_levels,      // ELOOP
197     value_too_large,                    // EOVERFLOW
198     wrong_protocol_type                 // EPROTOTYPE
199 };
200
201 template <> struct is_error_condition_enum<errc> : true_type { }
202
203 error_code make_error_code(errc e);
204 error_condition make_error_condition(errc e);
205
206 // Comparison operators:
207 bool operator==(const error_code& lhs, const error_code& rhs);
208 bool operator==(const error_code& lhs, const error_condition& rhs);
209 bool operator==(const error_condition& lhs, const error_code& rhs);
210 bool operator==(const error_condition& lhs, const error_condition& rhs);
211 bool operator!=(const error_code& lhs, const error_code& rhs);
212 bool operator!=(const error_code& lhs, const error_condition& rhs);
213 bool operator!=(const error_condition& lhs, const error_code& rhs);
214 bool operator!=(const error_condition& lhs, const error_condition& rhs);
215
216 template <> struct hash<std::error_code>;
217
218 }  // std
219
220 */
221
222 #include "llvm/Config/config.h"
223 #include "llvm/Support/type_traits.h"
224 #include <cerrno>
225 #include <string>
226
227 #ifdef LLVM_ON_WIN32
228   // VS 2008 needs this for some of the defines below.
229 # include <WinSock2.h>
230
231   // The following numbers were taken from VS2010.
232 # ifndef EAFNOSUPPORT
233 #   define EAFNOSUPPORT WSAEAFNOSUPPORT
234 # endif
235 # ifndef EADDRINUSE
236 #   define EADDRINUSE WSAEADDRINUSE
237 # endif
238 # ifndef EADDRNOTAVAIL
239 #   define EADDRNOTAVAIL WSAEADDRNOTAVAIL
240 # endif
241 # ifndef EISCONN
242 #   define EISCONN WSAEISCONN
243 # endif
244 # ifndef E2BIG
245 #   define E2BIG WSAE2BIG
246 # endif
247 # ifndef EDOM
248 #   define EDOM WSAEDOM
249 # endif
250 # ifndef EFAULT
251 #   define EFAULT WSAEFAULT
252 # endif
253 # ifndef EBADF
254 #   define EBADF WSAEBADF
255 # endif
256 # ifndef EBADMSG
257 #   define EBADMSG 104
258 # endif
259 # ifndef EPIPE
260 #   define EPIPE WSAEPIPE
261 # endif
262 # ifndef ECONNABORTED
263 #   define ECONNABORTED WSAECONNABORTED
264 # endif
265 # ifndef EALREADY
266 #   define EALREADY WSAEALREADY
267 # endif
268 # ifndef ECONNREFUSED
269 #   define ECONNREFUSED WSAECONNREFUSED
270 # endif
271 # ifndef ECONNRESET
272 #   define ECONNRESET WSAECONNRESET
273 # endif
274 # ifndef EXDEV
275 #   define EXDEV WSAEXDEV
276 # endif
277 # ifndef EDESTADDRREQ
278 #   define EDESTADDRREQ WSAEDESTADDRREQ
279 # endif
280 # ifndef EBUSY
281 #   define EBUSY WSAEBUSY
282 # endif
283 # ifndef ENOTEMPTY
284 #   define ENOTEMPTY WSAENOTEMPTY
285 # endif
286 # ifndef ENOEXEC
287 #   define ENOEXEC WSAENOEXEC
288 # endif
289 # ifndef EEXIST
290 #   define EEXIST WSAEEXIST
291 # endif
292 # ifndef EFBIG
293 #   define EFBIG WSAEFBIG
294 # endif
295 # ifndef ENAMETOOLONG
296 #   define ENAMETOOLONG WSAENAMETOOLONG
297 # endif
298 # ifndef ENOSYS
299 #   define ENOSYS WSAENOSYS
300 # endif
301 # ifndef EHOSTUNREACH
302 #   define EHOSTUNREACH WSAEHOSTUNREACH
303 # endif
304 # ifndef EIDRM
305 #   define EIDRM 111
306 # endif
307 # ifndef EILSEQ
308 #   define EILSEQ WSAEILSEQ
309 # endif
310 # ifndef ENOTTY
311 #   define ENOTTY WSAENOTTY
312 # endif
313 # ifndef EINTR
314 #   define EINTR WSAEINTR
315 # endif
316 # ifndef EINVAL
317 #   define EINVAL WSAEINVAL
318 # endif
319 # ifndef ESPIPE
320 #   define ESPIPE WSAESPIPE
321 # endif
322 # ifndef EIO
323 #   define EIO WSAEIO
324 # endif
325 # ifndef EISDIR
326 #   define EISDIR WSAEISDIR
327 # endif
328 # ifndef EMSGSIZE
329 #   define EMSGSIZE WSAEMSGSIZE
330 # endif
331 # ifndef ENETDOWN
332 #   define ENETDOWN WSAENETDOWN
333 # endif
334 # ifndef ENETRESET
335 #   define ENETRESET WSAENETRESET
336 # endif
337 # ifndef ENETUNREACH
338 #   define ENETUNREACH WSAENETUNREACH
339 # endif
340 # ifndef ENOBUFS
341 #   define ENOBUFS WSAENOBUFS
342 # endif
343 # ifndef ECHILD
344 #   define ECHILD WSAECHILD
345 # endif
346 # ifndef ENOLINK
347 #   define ENOLINK 121
348 # endif
349 # ifndef ENOLCK
350 #   define ENOLCK WSAENOLCK
351 # endif
352 # ifndef ENODATA
353 #   define ENODATA 120
354 # endif
355 # ifndef ENOMSG
356 #   define ENOMSG 122
357 # endif
358 # ifndef ENOPROTOOPT
359 #   define ENOPROTOOPT WSAENOPROTOOPT
360 # endif
361 # ifndef ENOSPC
362 #   define ENOSPC WSAENOSPC
363 # endif
364 # ifndef ENOSR
365 #   define ENOSR 124
366 # endif
367 # ifndef ENXIO
368 #   define ENXIO WSAENXIO
369 # endif
370 # ifndef ENODEV
371 #   define ENODEV WSAENODEV
372 # endif
373 # ifndef ENOENT
374 #   define ENOENT WSAENOENT
375 # endif
376 # ifndef ESRCH
377 #   define ESRCH WSAESRCH
378 # endif
379 # ifndef ENOTDIR
380 #   define ENOTDIR WSAENOTDIR
381 # endif
382 # ifndef ENOTSOCK
383 #   define ENOTSOCK WSAENOTSOCK
384 # endif
385 # ifndef ENOSTR
386 #   define ENOSTR 125
387 # endif
388 # ifndef ENOTCONN
389 #   define ENOTCONN WSAENOTCONN
390 # endif
391 # ifndef ENOMEM
392 #   define ENOMEM WSAENOMEM
393 # endif
394 # ifndef ENOTSUP
395 #   define ENOTSUP 129
396 # endif
397 # ifndef ECANCELED
398 #   define ECANCELED 105
399 # endif
400 # ifndef EINPROGRESS
401 #   define EINPROGRESS WSAEINPROGRESS
402 # endif
403 # ifndef EPERM
404 #   define EPERM WSAEPERM
405 # endif
406 # ifndef EOPNOTSUPP
407 #   define EOPNOTSUPP WSAEOPNOTSUPP
408 # endif
409 # ifndef EWOULDBLOCK
410 #   define EWOULDBLOCK WSAEWOULDBLOCK
411 # endif
412 # ifndef EOWNERDEAD
413 #   define EOWNERDEAD 133
414 # endif
415 # ifndef EACCES
416 #   define EACCES WSAEACCES
417 # endif
418 # ifndef EPROTO
419 #   define EPROTO 134
420 # endif
421 # ifndef EPROTONOSUPPORT
422 #   define EPROTONOSUPPORT WSAEPROTONOSUPPORT
423 # endif
424 # ifndef EROFS
425 #   define EROFS WSAEROFS
426 # endif
427 # ifndef EDEADLK
428 #   define EDEADLK WSAEDEADLK
429 # endif
430 # ifndef EAGAIN
431 #   define EAGAIN WSAEAGAIN
432 # endif
433 # ifndef ERANGE
434 #   define ERANGE WSAERANGE
435 # endif
436 # ifndef ENOTRECOVERABLE
437 #   define ENOTRECOVERABLE 127
438 # endif
439 # ifndef ETIME
440 #   define ETIME 137
441 # endif
442 # ifndef ETXTBSY
443 #   define ETXTBSY 139
444 # endif
445 # ifndef ETIMEDOUT
446 #   define ETIMEDOUT WSAETIMEDOUT
447 # endif
448 # ifndef ENFILE
449 #   define ENFILE WSAENFILE
450 # endif
451 # ifndef EMFILE
452 #   define EMFILE WSAEMFILE
453 # endif
454 # ifndef EMLINK
455 #   define EMLINK WSAEMLINK
456 # endif
457 # ifndef ELOOP
458 #   define ELOOP WSAELOOP
459 # endif
460 # ifndef EOVERFLOW
461 #   define EOVERFLOW 132
462 # endif
463 # ifndef EPROTOTYPE
464 #   define EPROTOTYPE WSAEPROTOTYPE
465 # endif
466 #endif
467
468 namespace llvm {
469
470 template <class T, T v>
471 struct integral_constant {
472   typedef T value_type;
473   static const value_type value = v;
474   typedef integral_constant<T,v> type;
475   operator value_type() { return value; }
476 };
477
478 typedef integral_constant<bool, true> true_type;
479 typedef integral_constant<bool, false> false_type;
480
481 // is_error_code_enum
482
483 template <class Tp> struct is_error_code_enum : public false_type {};
484
485 // is_error_condition_enum
486
487 template <class Tp> struct is_error_condition_enum : public false_type {};
488
489 // Some error codes are not present on all platforms, so we provide equivalents
490 // for them:
491
492 //enum class errc
493 struct errc {
494 enum _ {
495   success                             = 0,
496   address_family_not_supported        = EAFNOSUPPORT,
497   address_in_use                      = EADDRINUSE,
498   address_not_available               = EADDRNOTAVAIL,
499   already_connected                   = EISCONN,
500   argument_list_too_long              = E2BIG,
501   argument_out_of_domain              = EDOM,
502   bad_address                         = EFAULT,
503   bad_file_descriptor                 = EBADF,
504   bad_message                         = EBADMSG,
505   broken_pipe                         = EPIPE,
506   connection_aborted                  = ECONNABORTED,
507   connection_already_in_progress      = EALREADY,
508   connection_refused                  = ECONNREFUSED,
509   connection_reset                    = ECONNRESET,
510   cross_device_link                   = EXDEV,
511   destination_address_required        = EDESTADDRREQ,
512   device_or_resource_busy             = EBUSY,
513   directory_not_empty                 = ENOTEMPTY,
514   executable_format_error             = ENOEXEC,
515   file_exists                         = EEXIST,
516   file_too_large                      = EFBIG,
517   filename_too_long                   = ENAMETOOLONG,
518   function_not_supported              = ENOSYS,
519   host_unreachable                    = EHOSTUNREACH,
520   identifier_removed                  = EIDRM,
521   illegal_byte_sequence               = EILSEQ,
522   inappropriate_io_control_operation  = ENOTTY,
523   interrupted                         = EINTR,
524   invalid_argument                    = EINVAL,
525   invalid_seek                        = ESPIPE,
526   io_error                            = EIO,
527   is_a_directory                      = EISDIR,
528   message_size                        = EMSGSIZE,
529   network_down                        = ENETDOWN,
530   network_reset                       = ENETRESET,
531   network_unreachable                 = ENETUNREACH,
532   no_buffer_space                     = ENOBUFS,
533   no_child_process                    = ECHILD,
534   no_link                             = ENOLINK,
535   no_lock_available                   = ENOLCK,
536 #ifdef ENODATA
537   no_message_available                = ENODATA,
538 #else
539   no_message_available                = ENOMSG,
540 #endif
541   no_message                          = ENOMSG,
542   no_protocol_option                  = ENOPROTOOPT,
543   no_space_on_device                  = ENOSPC,
544 #ifdef ENOSR
545   no_stream_resources                 = ENOSR,
546 #else
547   no_stream_resources                 = ENOMEM,
548 #endif
549   no_such_device_or_address           = ENXIO,
550   no_such_device                      = ENODEV,
551   no_such_file_or_directory           = ENOENT,
552   no_such_process                     = ESRCH,
553   not_a_directory                     = ENOTDIR,
554   not_a_socket                        = ENOTSOCK,
555 #ifdef ENOSTR
556   not_a_stream                        = ENOSTR,
557 #else
558   not_a_stream                        = EINVAL,
559 #endif
560   not_connected                       = ENOTCONN,
561   not_enough_memory                   = ENOMEM,
562   not_supported                       = ENOTSUP,
563   operation_canceled                  = ECANCELED,
564   operation_in_progress               = EINPROGRESS,
565   operation_not_permitted             = EPERM,
566   operation_not_supported             = EOPNOTSUPP,
567   operation_would_block               = EWOULDBLOCK,
568   owner_dead                          = EOWNERDEAD,
569   permission_denied                   = EACCES,
570   protocol_error                      = EPROTO,
571   protocol_not_supported              = EPROTONOSUPPORT,
572   read_only_file_system               = EROFS,
573   resource_deadlock_would_occur       = EDEADLK,
574   resource_unavailable_try_again      = EAGAIN,
575   result_out_of_range                 = ERANGE,
576   state_not_recoverable               = ENOTRECOVERABLE,
577 #ifdef ETIME
578   stream_timeout                      = ETIME,
579 #else
580   stream_timeout                      = ETIMEDOUT,
581 #endif
582   text_file_busy                      = ETXTBSY,
583   timed_out                           = ETIMEDOUT,
584   too_many_files_open_in_system       = ENFILE,
585   too_many_files_open                 = EMFILE,
586   too_many_links                      = EMLINK,
587   too_many_symbolic_link_levels       = ELOOP,
588   value_too_large                     = EOVERFLOW,
589   wrong_protocol_type                 = EPROTOTYPE
590 };
591
592   _ v_;
593
594   errc(_ v) : v_(v) {}
595   operator int() const {return v_;}
596 };
597
598 template <> struct is_error_condition_enum<errc> : true_type { };
599
600 template <> struct is_error_condition_enum<errc::_> : true_type { };
601
602 class error_condition;
603 class error_code;
604
605 // class error_category
606
607 class _do_message;
608
609 class error_category
610 {
611 public:
612   virtual ~error_category();
613
614 private:
615   error_category();
616   error_category(const error_category&);// = delete;
617   error_category& operator=(const error_category&);// = delete;
618
619 public:
620   virtual const char* name() const = 0;
621   virtual error_condition default_error_condition(int _ev) const;
622   virtual bool equivalent(int _code, const error_condition& _condition) const;
623   virtual bool equivalent(const error_code& _code, int _condition) const;
624   virtual std::string message(int _ev) const = 0;
625
626   bool operator==(const error_category& _rhs) const {return this == &_rhs;}
627
628   bool operator!=(const error_category& _rhs) const {return !(*this == _rhs);}
629
630   bool operator< (const error_category& _rhs) const {return this < &_rhs;}
631
632   friend class _do_message;
633 };
634
635 class _do_message : public error_category
636 {
637 public:
638   virtual std::string message(int ev) const;
639 };
640
641 const error_category& generic_category();
642 const error_category& system_category();
643
644 class error_condition
645 {
646   int _val_;
647   const error_category* _cat_;
648 public:
649   error_condition() : _val_(0), _cat_(&generic_category()) {}
650
651   error_condition(int _val, const error_category& _cat)
652     : _val_(_val), _cat_(&_cat) {}
653
654   template <class E>
655   error_condition(E _e, typename enable_if_c<
656                           is_error_condition_enum<E>::value
657                         >::type* = 0)
658     {*this = make_error_condition(_e);}
659
660   void assign(int _val, const error_category& _cat) {
661     _val_ = _val;
662     _cat_ = &_cat;
663   }
664
665   template <class E>
666     typename enable_if_c
667     <
668       is_error_condition_enum<E>::value,
669       error_condition&
670     >::type
671     operator=(E _e)
672       {*this = make_error_condition(_e); return *this;}
673
674   void clear() {
675     _val_ = 0;
676     _cat_ = &generic_category();
677   }
678
679   int value() const {return _val_;}
680
681   const error_category& category() const {return *_cat_;}
682   std::string message() const;
683
684   // explicit
685   operator bool() const {return _val_ != 0;}
686 };
687
688 inline error_condition make_error_condition(errc _e) {
689   return error_condition(static_cast<int>(_e), generic_category());
690 }
691
692 inline bool operator<(const error_condition& _x, const error_condition& _y) {
693   return _x.category() < _y.category()
694       || _x.category() == _y.category() && _x.value() < _y.value();
695 }
696
697 // error_code
698
699 class error_code {
700   int _val_;
701   const error_category* _cat_;
702 public:
703   error_code() : _val_(0), _cat_(&system_category()) {}
704
705   error_code(int _val, const error_category& _cat)
706     : _val_(_val), _cat_(&_cat) {}
707
708   template <class E>
709   error_code(E _e, typename enable_if_c<
710                      is_error_code_enum<E>::value
711                    >::type* = 0) {
712     *this = make_error_code(_e);
713   }
714
715   void assign(int _val, const error_category& _cat) {
716       _val_ = _val;
717       _cat_ = &_cat;
718   }
719
720   template <class E>
721     typename enable_if_c
722     <
723       is_error_code_enum<E>::value,
724       error_code&
725     >::type
726     operator=(E _e)
727       {*this = make_error_code(_e); return *this;}
728
729   void clear() {
730     _val_ = 0;
731     _cat_ = &system_category();
732   }
733
734   int value() const {return _val_;}
735
736   const error_category& category() const {return *_cat_;}
737
738   error_condition default_error_condition() const
739     {return _cat_->default_error_condition(_val_);}
740
741   std::string message() const;
742
743   // explicit
744   operator bool() const {return _val_ != 0;}
745 };
746
747 inline error_code make_error_code(errc _e) {
748   return error_code(static_cast<int>(_e), generic_category());
749 }
750
751 inline bool operator<(const error_code& _x, const error_code& _y) {
752   return _x.category() < _y.category()
753       || _x.category() == _y.category() && _x.value() < _y.value();
754 }
755
756 inline bool operator==(const error_code& _x, const error_code& _y) {
757   return _x.category() == _y.category() && _x.value() == _y.value();
758 }
759
760 inline bool operator==(const error_code& _x, const error_condition& _y) {
761   return _x.category().equivalent(_x.value(), _y)
762       || _y.category().equivalent(_x, _y.value());
763 }
764
765 inline bool operator==(const error_condition& _x, const error_code& _y) {
766   return _y == _x;
767 }
768
769 inline bool operator==(const error_condition& _x, const error_condition& _y) {
770    return _x.category() == _y.category() && _x.value() == _y.value();
771 }
772
773 inline bool operator!=(const error_code& _x, const error_code& _y) {
774   return !(_x == _y);
775 }
776
777 inline bool operator!=(const error_code& _x, const error_condition& _y) {
778   return !(_x == _y);
779 }
780
781 inline bool operator!=(const error_condition& _x, const error_code& _y) {
782   return !(_x == _y);
783 }
784
785 inline bool operator!=(const error_condition& _x, const error_condition& _y) {
786   return !(_x == _y);
787 }
788
789 // system_error
790
791 class system_error : public std::runtime_error {
792   error_code _ec_;
793 public:
794   system_error(error_code _ec, const std::string& _what_arg);
795   system_error(error_code _ec, const char* _what_arg);
796   system_error(error_code _ec);
797   system_error(int _ev, const error_category& _ecat,
798                const std::string& _what_arg);
799   system_error(int _ev, const error_category& _ecat, const char* _what_arg);
800   system_error(int _ev, const error_category& _ecat);
801   ~system_error() throw();
802
803   const error_code& code() const throw() {return _ec_;}
804
805 private:
806   static std::string _init(const error_code&, std::string);
807 };
808
809 void _throw_system_error(int ev, const char* what_arg);
810
811 } // end namespace llvm
812
813 #ifdef LLVM_ON_WIN32
814 #include <Windows.h>
815 #include <WinError.h>
816
817 namespace llvm {
818
819 //  To construct an error_code after a API error:
820 //
821 //      error_code( ::GetLastError(), system_category() )
822 struct windows_error {
823 enum _ {
824   success = 0,
825   // These names and values are based on Windows winerror.h
826   invalid_function = ERROR_INVALID_FUNCTION,
827   file_not_found = ERROR_FILE_NOT_FOUND,
828   path_not_found = ERROR_PATH_NOT_FOUND,
829   too_many_open_files = ERROR_TOO_MANY_OPEN_FILES,
830   access_denied = ERROR_ACCESS_DENIED,
831   invalid_handle = ERROR_INVALID_HANDLE,
832   arena_trashed = ERROR_ARENA_TRASHED,
833   not_enough_memory = ERROR_NOT_ENOUGH_MEMORY,
834   invalid_block = ERROR_INVALID_BLOCK,
835   bad_environment = ERROR_BAD_ENVIRONMENT,
836   bad_format = ERROR_BAD_FORMAT,
837   invalid_access = ERROR_INVALID_ACCESS,
838   outofmemory = ERROR_OUTOFMEMORY,
839   invalid_drive = ERROR_INVALID_DRIVE,
840   current_directory = ERROR_CURRENT_DIRECTORY,
841   not_same_device = ERROR_NOT_SAME_DEVICE,
842   no_more_files = ERROR_NO_MORE_FILES,
843   write_protect = ERROR_WRITE_PROTECT,
844   bad_unit = ERROR_BAD_UNIT,
845   not_ready = ERROR_NOT_READY,
846   bad_command = ERROR_BAD_COMMAND,
847   crc = ERROR_CRC,
848   bad_length = ERROR_BAD_LENGTH,
849   seek = ERROR_SEEK,
850   not_dos_disk = ERROR_NOT_DOS_DISK,
851   sector_not_found = ERROR_SECTOR_NOT_FOUND,
852   out_of_paper = ERROR_OUT_OF_PAPER,
853   write_fault = ERROR_WRITE_FAULT,
854   read_fault = ERROR_READ_FAULT,
855   gen_failure = ERROR_GEN_FAILURE,
856   sharing_violation = ERROR_SHARING_VIOLATION,
857   lock_violation = ERROR_LOCK_VIOLATION,
858   wrong_disk = ERROR_WRONG_DISK,
859   sharing_buffer_exceeded = ERROR_SHARING_BUFFER_EXCEEDED,
860   handle_eof = ERROR_HANDLE_EOF,
861   handle_disk_full= ERROR_HANDLE_DISK_FULL,
862   rem_not_list = ERROR_REM_NOT_LIST,
863   dup_name = ERROR_DUP_NAME,
864   bad_net_path = ERROR_BAD_NETPATH,
865   network_busy = ERROR_NETWORK_BUSY,
866   // ...
867   file_exists = ERROR_FILE_EXISTS,
868   cannot_make = ERROR_CANNOT_MAKE,
869   // ...
870   broken_pipe = ERROR_BROKEN_PIPE,
871   open_failed = ERROR_OPEN_FAILED,
872   buffer_overflow = ERROR_BUFFER_OVERFLOW,
873   disk_full= ERROR_DISK_FULL,
874   // ...
875   lock_failed = ERROR_LOCK_FAILED,
876   busy = ERROR_BUSY,
877   cancel_violation = ERROR_CANCEL_VIOLATION,
878   already_exists = ERROR_ALREADY_EXISTS
879   // ...
880
881   // TODO: add more Windows errors
882 };
883   _ v_;
884
885   windows_error(_ v) : v_(v) {}
886   explicit windows_error(DWORD v) : v_(_(v)) {}
887   operator int() const {return v_;}
888 };
889
890
891 template <> struct is_error_code_enum<windows_error> : true_type { };
892
893 template <> struct is_error_code_enum<windows_error::_> : true_type { };
894
895 inline error_code make_error_code(windows_error e) {
896   return error_code(static_cast<int>(e), system_category());
897 }
898
899 } // end namespace llvm
900
901 #endif // LLVM_ON_WINDOWS
902
903 #endif