]> AND Private Git Repository - canny.git/blob - stc/exp/ml_stc_linux_make_v1.0/include/boost/system/error_code.hpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
16733a4a23275a5baea68b4a87856e06f4233a40
[canny.git] / stc / exp / ml_stc_linux_make_v1.0 / include / boost / system / error_code.hpp
1 //  boost/system/error_code.hpp  ---------------------------------------------//\r
2 \r
3 //  Copyright Beman Dawes 2006, 2007\r
4 //  Copyright Christoper Kohlhoff 2007\r
5 \r
6 //  Distributed under the Boost Software License, Version 1.0. (See accompanying\r
7 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
8 \r
9 //  See library home page at http://www.boost.org/libs/system\r
10 \r
11 #ifndef BOOST_ERROR_CODE_HPP\r
12 #define BOOST_ERROR_CODE_HPP\r
13 \r
14 #include <boost/system/config.hpp>\r
15 #include <boost/cstdint.hpp>\r
16 #include <boost/assert.hpp>\r
17 #include <boost/operators.hpp>\r
18 #include <boost/noncopyable.hpp>\r
19 #include <boost/utility/enable_if.hpp>\r
20 #include <ostream>\r
21 #include <string>\r
22 #include <stdexcept>\r
23 #include <functional>\r
24 \r
25 // TODO: undef these macros if not already defined\r
26 #include <boost/cerrno.hpp> \r
27 \r
28 #if !defined(BOOST_POSIX_API) && !defined(BOOST_WINDOWS_API)\r
29 #  error BOOST_POSIX_API or BOOST_WINDOWS_API must be defined\r
30 #endif\r
31 \r
32 #include <boost/config/abi_prefix.hpp> // must be the last #include\r
33 \r
34 namespace boost\r
35 {\r
36   namespace system\r
37   {\r
38 \r
39     class error_code;\r
40     class error_condition;\r
41 \r
42     //  "Concept" helpers  ---------------------------------------------------//\r
43 \r
44     template< class T >\r
45     struct is_error_code_enum { static const bool value = false; };\r
46 \r
47     template< class T >\r
48     struct is_error_condition_enum { static const bool value = false; };\r
49 \r
50     //  generic error_conditions  --------------------------------------------//\r
51 \r
52     namespace errc\r
53     {\r
54       enum errc_t\r
55       {\r
56         success = 0,\r
57         address_family_not_supported = EAFNOSUPPORT,\r
58         address_in_use = EADDRINUSE,\r
59         address_not_available = EADDRNOTAVAIL,\r
60         already_connected = EISCONN,\r
61         argument_list_too_long = E2BIG,\r
62         argument_out_of_domain = EDOM,\r
63         bad_address = EFAULT,\r
64         bad_file_descriptor = EBADF,\r
65         bad_message = EBADMSG,\r
66         broken_pipe = EPIPE,\r
67         connection_aborted = ECONNABORTED,\r
68         connection_already_in_progress = EALREADY,\r
69         connection_refused = ECONNREFUSED,\r
70         connection_reset = ECONNRESET,\r
71         cross_device_link = EXDEV,\r
72         destination_address_required = EDESTADDRREQ,\r
73         device_or_resource_busy = EBUSY,\r
74         directory_not_empty = ENOTEMPTY,\r
75         executable_format_error = ENOEXEC,\r
76         file_exists = EEXIST,\r
77         file_too_large = EFBIG,\r
78         filename_too_long = ENAMETOOLONG,\r
79         function_not_supported = ENOSYS,\r
80         host_unreachable = EHOSTUNREACH,\r
81         identifier_removed = EIDRM,\r
82         illegal_byte_sequence = EILSEQ,\r
83         inappropriate_io_control_operation = ENOTTY,\r
84         interrupted = EINTR,\r
85         invalid_argument = EINVAL,\r
86         invalid_seek = ESPIPE,\r
87         io_error = EIO,\r
88         is_a_directory = EISDIR,\r
89         message_size = EMSGSIZE,\r
90         network_down = ENETDOWN,\r
91         network_reset = ENETRESET,\r
92         network_unreachable = ENETUNREACH,\r
93         no_buffer_space = ENOBUFS,\r
94         no_child_process = ECHILD,\r
95         no_link = ENOLINK,\r
96         no_lock_available = ENOLCK,\r
97         no_message_available = ENODATA,\r
98         no_message = ENOMSG,\r
99         no_protocol_option = ENOPROTOOPT,\r
100         no_space_on_device = ENOSPC,\r
101         no_stream_resources = ENOSR,\r
102         no_such_device_or_address = ENXIO,\r
103         no_such_device = ENODEV,\r
104         no_such_file_or_directory = ENOENT,\r
105         no_such_process = ESRCH,\r
106         not_a_directory = ENOTDIR,\r
107         not_a_socket = ENOTSOCK,\r
108         not_a_stream = ENOSTR,\r
109         not_connected = ENOTCONN,\r
110         not_enough_memory = ENOMEM,\r
111         not_supported = ENOTSUP,\r
112         operation_canceled = ECANCELED,\r
113         operation_in_progress = EINPROGRESS,\r
114         operation_not_permitted = EPERM,\r
115         operation_not_supported = EOPNOTSUPP,\r
116         operation_would_block = EWOULDBLOCK,\r
117         owner_dead = EOWNERDEAD,\r
118         permission_denied = EACCES,\r
119         protocol_error = EPROTO,\r
120         protocol_not_supported = EPROTONOSUPPORT,\r
121         read_only_file_system = EROFS,\r
122         resource_deadlock_would_occur = EDEADLK,\r
123         resource_unavailable_try_again = EAGAIN,\r
124         result_out_of_range = ERANGE,\r
125         state_not_recoverable = ENOTRECOVERABLE,\r
126         stream_timeout = ETIME,\r
127         text_file_busy = ETXTBSY,\r
128         timed_out = ETIMEDOUT,\r
129         too_many_files_open_in_system = ENFILE,\r
130         too_many_files_open = EMFILE,\r
131         too_many_links = EMLINK,\r
132         too_many_symbolic_link_levels = ELOOP,\r
133         value_too_large = EOVERFLOW,\r
134         wrong_protocol_type = EPROTOTYPE\r
135       };\r
136 \r
137     } // namespace errc\r
138 \r
139 # ifndef BOOST_SYSTEM_NO_DEPRECATED\r
140     namespace posix = errc;\r
141     namespace posix_error = errc;\r
142 # endif\r
143 \r
144     template<> struct is_error_condition_enum<errc::errc_t>\r
145       { static const bool value = true; };\r
146 \r
147 \r
148     //  ----------------------------------------------------------------------//\r
149 \r
150     //  Operating system specific interfaces  --------------------------------//\r
151 \r
152 \r
153     //  The interface is divided into general and system-specific portions to\r
154     //  meet these requirements:\r
155     //\r
156     //  * Code calling an operating system API can create an error_code with\r
157     //    a single category (system_category), even for POSIX-like operating\r
158     //    systems that return some POSIX errno values and some native errno\r
159     //    values. This code should not have to pay the cost of distinguishing\r
160     //    between categories, since it is not yet known if that is needed.\r
161     //\r
162     //  * Users wishing to write system-specific code should be given enums for\r
163     //    at least the common error cases.\r
164     //\r
165     //  * System specific code should fail at compile time if moved to another\r
166     //    operating system.\r
167 \r
168     //  The system specific portions of the interface are located in headers\r
169     //  with names reflecting the operating system. For example,\r
170     //\r
171     //       <boost/system/cygwin_error.hpp>\r
172     //       <boost/system/linux_error.hpp>\r
173     //       <boost/system/windows_error.hpp>\r
174     //\r
175     //  These headers are effectively empty for compiles on operating systems\r
176     //  where they are not applicable.\r
177 \r
178     //  ----------------------------------------------------------------------//\r
179 \r
180     //  class error_category  ------------------------------------------------//\r
181 \r
182     class error_category : public noncopyable\r
183     {\r
184     public:\r
185       virtual ~error_category(){}\r
186 \r
187       virtual const char *     name() const = 0;\r
188       virtual std::string      message( int ev ) const = 0;\r
189       virtual error_condition  default_error_condition( int ev ) const;\r
190       virtual bool             equivalent( int code, \r
191                                            const error_condition & condition ) const;\r
192       virtual bool             equivalent( const error_code & code,\r
193                                            int condition ) const;\r
194 \r
195       bool operator==(const error_category & rhs) const { return this == &rhs; }\r
196       bool operator!=(const error_category & rhs) const { return this != &rhs; }\r
197       bool operator<( const error_category & rhs ) const\r
198       {\r
199         return std::less<const error_category*>()( this, &rhs );\r
200       }\r
201     };\r
202 \r
203     //  predefined error categories  -----------------------------------------//\r
204 \r
205     BOOST_SYSTEM_DECL const error_category &  get_system_category();\r
206     BOOST_SYSTEM_DECL const error_category &  get_generic_category();\r
207 \r
208     static const error_category &  system_category = get_system_category();\r
209     static const error_category &  generic_category = get_generic_category();\r
210     \r
211 # ifndef BOOST_SYSTEM_NO_DEPRECATED\r
212     //  deprecated synonyms\r
213     inline const error_category &  get_posix_category() { return get_generic_category(); }\r
214     static const error_category &  posix_category = get_generic_category();\r
215     static const error_category &  errno_ecat     = get_generic_category();\r
216     static const error_category &  native_ecat    = get_system_category();\r
217 # endif\r
218 \r
219     //  class error_condition  -----------------------------------------------//\r
220 \r
221     //  error_conditions are portable, error_codes are system or library specific\r
222 \r
223     class error_condition\r
224     {\r
225     public:\r
226 \r
227       // constructors:\r
228       error_condition() : m_val(0), m_cat(&get_generic_category()) {}\r
229       error_condition( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {}\r
230 \r
231       template <class ErrorConditionEnum>\r
232         error_condition(ErrorConditionEnum e,\r
233           typename boost::enable_if<is_error_condition_enum<ErrorConditionEnum> >::type* = 0)\r
234       {\r
235         *this = make_error_condition(e);\r
236       }\r
237 \r
238       // modifiers:\r
239 \r
240       void assign( int val, const error_category & cat )\r
241       { \r
242         m_val = val;\r
243         m_cat = &cat;\r
244       }\r
245                                              \r
246       template<typename ErrorConditionEnum>\r
247         typename boost::enable_if<is_error_condition_enum<ErrorConditionEnum>, error_condition>::type &\r
248           operator=( ErrorConditionEnum val )\r
249       { \r
250         *this = make_error_condition(val);\r
251         return *this;\r
252       }\r
253 \r
254       void clear()\r
255       {\r
256         m_val = 0;\r
257         m_cat = &get_generic_category();\r
258       }\r
259 \r
260       // observers:\r
261       int                     value() const    { return m_val; }\r
262       const error_category &  category() const { return *m_cat; }\r
263       std::string             message() const  { return m_cat->message(value()); }\r
264 \r
265       typedef void (*unspecified_bool_type)();\r
266       static void unspecified_bool_true() {}\r
267 \r
268       operator unspecified_bool_type() const  // true if error\r
269       { \r
270         return m_val == 0 ? 0 : unspecified_bool_true;\r
271       }\r
272 \r
273       bool operator!() const  // true if no error\r
274       {\r
275         return m_val == 0;\r
276       }\r
277 \r
278       // relationals:\r
279       //  the more symmetrical non-member syntax allows enum\r
280       //  conversions work for both rhs and lhs.\r
281       inline friend bool operator==( const error_condition & lhs,\r
282                                      const error_condition & rhs )\r
283       {\r
284         return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val;\r
285       }                  \r
286 \r
287       inline friend bool operator<( const error_condition & lhs,\r
288                                     const error_condition & rhs )\r
289         //  the more symmetrical non-member syntax allows enum\r
290         //  conversions work for both rhs and lhs.\r
291       {\r
292         return lhs.m_cat < rhs.m_cat\r
293           || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);\r
294       }\r
295 \r
296     private:\r
297       int                     m_val;\r
298       const error_category *  m_cat;\r
299 \r
300     };\r
301 \r
302     //  class error_code  ----------------------------------------------------//\r
303 \r
304     //  We want error_code to be a value type that can be copied without slicing\r
305     //  and without requiring heap allocation, but we also want it to have\r
306     //  polymorphic behavior based on the error category. This is achieved by\r
307     //  abstract base class error_category supplying the polymorphic behavior,\r
308     //  and error_code containing a pointer to an object of a type derived\r
309     //  from error_category.\r
310     class error_code\r
311     {\r
312     public:\r
313 \r
314       // constructors:\r
315       error_code() : m_val(0), m_cat(&get_system_category()) {}\r
316       error_code( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {}\r
317 \r
318       template <class ErrorCodeEnum>\r
319         error_code(ErrorCodeEnum e,\r
320           typename boost::enable_if<is_error_code_enum<ErrorCodeEnum> >::type* = 0)\r
321       {\r
322         *this = make_error_code(e);\r
323       }\r
324 \r
325       // modifiers:\r
326       void assign( int val, const error_category & cat )\r
327       { \r
328         m_val = val;\r
329         m_cat = &cat;\r
330       }\r
331                                              \r
332       template<typename ErrorCodeEnum>\r
333         typename boost::enable_if<is_error_code_enum<ErrorCodeEnum>, error_code>::type &\r
334           operator=( ErrorCodeEnum val )\r
335       { \r
336         *this = make_error_code(val);\r
337         return *this;\r
338       }\r
339 \r
340       void clear()\r
341       {\r
342         m_val = 0;\r
343         m_cat = &get_system_category();\r
344       }\r
345 \r
346       // observers:\r
347       int                     value() const    { return m_val; }\r
348       const error_category &  category() const { return *m_cat; }\r
349       error_condition         default_error_condition() const  { return m_cat->default_error_condition(value()); }\r
350       std::string             message() const  { return m_cat->message(value()); }\r
351 \r
352       typedef void (*unspecified_bool_type)();\r
353       static void unspecified_bool_true() {}\r
354 \r
355       operator unspecified_bool_type() const  // true if error\r
356       { \r
357         return m_val == 0 ? 0 : unspecified_bool_true;\r
358       }\r
359 \r
360       bool operator!() const  // true if no error\r
361       {\r
362         return m_val == 0;\r
363       }\r
364 \r
365       // relationals:\r
366       inline friend bool operator==( const error_code & lhs,\r
367                                      const error_code & rhs )\r
368         //  the more symmetrical non-member syntax allows enum\r
369         //  conversions work for both rhs and lhs.\r
370       {\r
371         return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val;\r
372       }\r
373 \r
374       inline friend bool operator<( const error_code & lhs,\r
375                                     const error_code & rhs )\r
376         //  the more symmetrical non-member syntax allows enum\r
377         //  conversions work for both rhs and lhs.\r
378       {\r
379         return lhs.m_cat < rhs.m_cat\r
380           || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);\r
381       }\r
382                   \r
383       private:\r
384       int                     m_val;\r
385       const error_category *  m_cat;\r
386 \r
387     };\r
388 \r
389     //  predefined error_code object used as "throw on error" tag\r
390 # ifndef BOOST_SYSTEM_NO_DEPRECATED\r
391     BOOST_SYSTEM_DECL extern error_code throws;\r
392 # endif\r
393 \r
394     //  Moving from a "throws" object to a "throws" function without breaking\r
395     //  existing code is a bit of a problem. The workaround is to place the\r
396     //  "throws" function in namespace boost rather than namespace boost::system.\r
397 \r
398   }  // namespace system\r
399 \r
400   namespace detail { inline system::error_code * throws() { return 0; } }\r
401     //  Misuse of the error_code object is turned into a noisy failure by\r
402     //  poisoning the reference. This particular implementation doesn't\r
403     //  produce warnings or errors from popular compilers, is very efficient\r
404     //  (as determined by inspecting generated code), and does not suffer\r
405     //  from order of initialization problems. In practice, it also seems\r
406     //  cause user function error handling implementation errors to be detected\r
407     //  very early in the development cycle.\r
408 \r
409   inline system::error_code & throws()\r
410     { return *detail::throws(); }\r
411 \r
412   namespace system\r
413   {\r
414     //  non-member functions  ------------------------------------------------//\r
415 \r
416     inline bool operator!=( const error_code & lhs,\r
417                             const error_code & rhs )\r
418     {\r
419       return !(lhs == rhs);\r
420     }\r
421 \r
422     inline bool operator!=( const error_condition & lhs,\r
423                             const error_condition & rhs )\r
424     {\r
425       return !(lhs == rhs);\r
426     }\r
427 \r
428     inline bool operator==( const error_code & code,\r
429                             const error_condition & condition )\r
430     {\r
431       return code.category().equivalent( code.value(), condition )\r
432         || condition.category().equivalent( code, condition.value() );\r
433     }\r
434                 \r
435     inline bool operator!=( const error_code & lhs,\r
436                             const error_condition & rhs )\r
437     {\r
438       return !(lhs == rhs);\r
439     }\r
440                 \r
441     inline bool operator==( const error_condition & condition,\r
442                             const error_code & code )\r
443     {\r
444       return condition.category().equivalent( code, condition.value() )\r
445         || code.category().equivalent( code.value(), condition );\r
446     }\r
447                 \r
448     inline bool operator!=( const error_condition & lhs,\r
449                             const error_code & rhs )\r
450     {\r
451       return !(lhs == rhs);\r
452     }\r
453                   \r
454     // TODO: both of these may move elsewhere, but the LWG hasn't spoken yet.\r
455 \r
456     template <class charT, class traits>\r
457     inline std::basic_ostream<charT,traits>&\r
458       operator<< (std::basic_ostream<charT,traits>& os, error_code ec)\r
459     {\r
460       os << ec.category().name() << ':' << ec.value();\r
461       return os;\r
462     }\r
463 \r
464     inline std::size_t hash_value( const error_code & ec )\r
465     {\r
466       return static_cast<std::size_t>(ec.value())\r
467         + reinterpret_cast<std::size_t>(&ec.category());\r
468     }\r
469 \r
470     //  make_* functions for errc::errc_t  -----------------------------//\r
471 \r
472     namespace errc\r
473     {\r
474       //  explicit conversion:\r
475       inline error_code make_error_code( errc_t e )\r
476         { return error_code( e, get_generic_category() ); }\r
477 \r
478       //  implicit conversion:\r
479       inline error_condition make_error_condition( errc_t e )\r
480         { return error_condition( e, get_generic_category() ); }\r
481     }\r
482 \r
483     //  error_category default implementation  -------------------------------//\r
484 \r
485     inline error_condition error_category::default_error_condition( int ev ) const\r
486     { \r
487       return error_condition( ev, *this );\r
488     }\r
489 \r
490     inline bool error_category::equivalent( int code,\r
491       const error_condition & condition ) const\r
492     {\r
493       return default_error_condition( code ) == condition;\r
494     }\r
495 \r
496     inline bool error_category::equivalent( const error_code & code,\r
497       int condition ) const\r
498     {\r
499       return *this == code.category() && code.value() == condition;\r
500     }\r
501 \r
502   } // namespace system\r
503 } // namespace boost\r
504 \r
505 #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas\r
506 \r
507 # ifdef BOOST_ERROR_CODE_HEADER_ONLY\r
508 #   include <boost/../libs/system/src/error_code.cpp>\r
509 # endif\r
510 \r
511 #endif // BOOST_ERROR_CODE_HPP\r
512 \r
513 \r