error_code.ipp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. // error_code support implementation file --------------------------------------------//
  2. // Copyright Beman Dawes 2002, 2006
  3. // Copyright (c) Microsoft Corporation 2014
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. // See library home page at http://www.boost.org/libs/system
  7. //--------------------------------------------------------------------------------------//
  8. #include <boost/config/warning_disable.hpp>
  9. #include <boost/system/config.hpp>
  10. #include <boost/system/error_code.hpp>
  11. #include <boost/cerrno.hpp>
  12. #include <vector>
  13. #include <cstdlib>
  14. #include <cassert>
  15. #include <cstring> // for strerror/strerror_r
  16. # if defined( BOOST_WINDOWS_API )
  17. # include <boost/winapi/error_codes.hpp>
  18. # include <boost/winapi/error_handling.hpp>
  19. # include <boost/winapi/character_code_conversion.hpp>
  20. # if !BOOST_PLAT_WINDOWS_RUNTIME
  21. # include <boost/system/detail/local_free_on_destruction.hpp>
  22. # endif
  23. # ifndef ERROR_INCORRECT_SIZE
  24. # define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
  25. # endif
  26. # endif
  27. //--------------------------------------------------------------------------------------//
  28. namespace boost
  29. {
  30. namespace system
  31. {
  32. namespace detail
  33. {
  34. #ifdef BOOST_ERROR_CODE_HEADER_ONLY
  35. # define BOOST_SYSTEM_DECL_ inline
  36. #else
  37. # define BOOST_SYSTEM_DECL_ BOOST_SYSTEM_DECL
  38. #endif
  39. // generic_error_category implementation ---------------------------------//
  40. BOOST_SYSTEM_DECL_ std::string generic_error_category::message( int ev ) const
  41. {
  42. using namespace boost::system::errc;
  43. #if defined(__PGI)
  44. using boost::system::errc::invalid_argument;
  45. #endif
  46. static std::string unknown_err( "Unknown error" );
  47. // strerror_r is preferred because it is always thread safe,
  48. // however, we fallback to strerror in certain cases because:
  49. // -- Windows doesn't provide strerror_r.
  50. // -- HP and Sun do provide strerror_r on newer systems, but there is
  51. // no way to tell if is available at runtime and in any case their
  52. // versions of strerror are thread safe anyhow.
  53. // -- Linux only sometimes provides strerror_r.
  54. // -- Tru64 provides strerror_r only when compiled -pthread.
  55. // -- VMS doesn't provide strerror_r, but on this platform, strerror is
  56. // thread safe.
  57. # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\
  58. || (defined(__linux) && (!defined(__USE_XOPEN2K)\
  59. || defined(BOOST_SYSTEM_USE_STRERROR)))\
  60. || (defined(__osf__) && !defined(_REENTRANT))\
  61. || (defined(__INTEGRITY))\
  62. || (defined(__vms))\
  63. || (defined(__QNXNTO__))
  64. const char * c_str = std::strerror( ev );
  65. return c_str
  66. ? std::string( c_str )
  67. : unknown_err;
  68. # else // use strerror_r
  69. char buf[64];
  70. char * bp = buf;
  71. std::size_t sz = sizeof(buf);
  72. # if defined(__CYGWIN__) || defined(__USE_GNU)
  73. // Oddball version of strerror_r
  74. const char * c_str = strerror_r( ev, bp, sz );
  75. return c_str
  76. ? std::string( c_str )
  77. : unknown_err;
  78. # else
  79. // POSIX version of strerror_r
  80. int result;
  81. for (;;)
  82. {
  83. // strerror_r returns 0 on success, otherwise ERANGE if buffer too small,
  84. // invalid_argument if ev not a valid error number
  85. # if defined (__sgi)
  86. const char * c_str = strerror( ev );
  87. result = 0;
  88. return c_str
  89. ? std::string( c_str )
  90. : unknown_err;
  91. # else
  92. result = strerror_r( ev, bp, sz );
  93. # endif
  94. if (result == 0 )
  95. break;
  96. else
  97. {
  98. # if defined(__linux)
  99. // Linux strerror_r returns -1 on error, with error number in errno
  100. result = errno;
  101. # endif
  102. if ( result != ERANGE ) break;
  103. if ( sz > sizeof(buf) ) std::free( bp );
  104. sz *= 2;
  105. if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 )
  106. return std::string( "ENOMEM" );
  107. }
  108. }
  109. std::string msg;
  110. # ifndef BOOST_NO_EXCEPTIONS
  111. try
  112. # endif
  113. {
  114. msg = ( ( result == invalid_argument ) ? "Unknown error" : bp );
  115. }
  116. # ifndef BOOST_NO_EXCEPTIONS
  117. // See ticket #2098
  118. catch(...)
  119. {
  120. // just eat the exception
  121. }
  122. # endif
  123. if ( sz > sizeof(buf) ) std::free( bp );
  124. return msg;
  125. # endif // else POSIX version of strerror_r
  126. # endif // else use strerror_r
  127. }
  128. // system_error_category implementation --------------------------------------------//
  129. BOOST_SYSTEM_DECL_ error_condition system_error_category::default_error_condition( int ev ) const
  130. BOOST_SYSTEM_NOEXCEPT
  131. {
  132. using namespace boost::system::errc;
  133. #if defined(__PGI)
  134. using boost::system::errc::invalid_argument;
  135. #endif
  136. # if defined(BOOST_WINDOWS_API)
  137. # if defined(WINAPI_FAMILY) && ((WINAPI_FAMILY & WINAPI_PARTITION_APP) != 0)
  138. // When using the Windows Runtime, most system errors are reported as HRESULTs.
  139. // We want to map the common Win32 errors to their equivalent error condition,
  140. // whether or not they are reported via an HRESULT.
  141. if ( ev < 0 ) // Check for failed HRESULTs only.
  142. if ( HRESULT_FACILITY( ev ) == FACILITY_WIN32 )
  143. ev = HRESULT_CODE( ev );
  144. # endif
  145. # endif
  146. # if defined(BOOST_WINDOWS_API)
  147. using namespace boost::winapi; // for error codes
  148. # endif
  149. switch ( ev )
  150. {
  151. case 0: return make_error_condition( success );
  152. # if defined(BOOST_POSIX_API)
  153. // POSIX-like O/S -> posix_errno decode table -------------------------------------//
  154. case E2BIG: return make_error_condition( argument_list_too_long );
  155. case EACCES: return make_error_condition( permission_denied );
  156. case EADDRINUSE: return make_error_condition( address_in_use );
  157. case EADDRNOTAVAIL: return make_error_condition( address_not_available );
  158. case EAFNOSUPPORT: return make_error_condition( address_family_not_supported );
  159. case EAGAIN: return make_error_condition( resource_unavailable_try_again );
  160. # if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino
  161. case EALREADY: return make_error_condition( connection_already_in_progress );
  162. # endif
  163. case EBADF: return make_error_condition( bad_file_descriptor );
  164. case EBADMSG: return make_error_condition( bad_message );
  165. case EBUSY: return make_error_condition( device_or_resource_busy );
  166. case ECANCELED: return make_error_condition( operation_canceled );
  167. case ECHILD: return make_error_condition( no_child_process );
  168. case ECONNABORTED: return make_error_condition( connection_aborted );
  169. case ECONNREFUSED: return make_error_condition( connection_refused );
  170. case ECONNRESET: return make_error_condition( connection_reset );
  171. case EDEADLK: return make_error_condition( resource_deadlock_would_occur );
  172. case EDESTADDRREQ: return make_error_condition( destination_address_required );
  173. case EDOM: return make_error_condition( argument_out_of_domain );
  174. case EEXIST: return make_error_condition( file_exists );
  175. case EFAULT: return make_error_condition( bad_address );
  176. case EFBIG: return make_error_condition( file_too_large );
  177. case EHOSTUNREACH: return make_error_condition( host_unreachable );
  178. case EIDRM: return make_error_condition( identifier_removed );
  179. case EILSEQ: return make_error_condition( illegal_byte_sequence );
  180. case EINPROGRESS: return make_error_condition( operation_in_progress );
  181. case EINTR: return make_error_condition( interrupted );
  182. case EINVAL: return make_error_condition( invalid_argument );
  183. case EIO: return make_error_condition( io_error );
  184. case EISCONN: return make_error_condition( already_connected );
  185. case EISDIR: return make_error_condition( is_a_directory );
  186. case ELOOP: return make_error_condition( too_many_symbolic_link_levels );
  187. case EMFILE: return make_error_condition( too_many_files_open );
  188. case EMLINK: return make_error_condition( too_many_links );
  189. case EMSGSIZE: return make_error_condition( message_size );
  190. case ENAMETOOLONG: return make_error_condition( filename_too_long );
  191. case ENETDOWN: return make_error_condition( network_down );
  192. case ENETRESET: return make_error_condition( network_reset );
  193. case ENETUNREACH: return make_error_condition( network_unreachable );
  194. case ENFILE: return make_error_condition( too_many_files_open_in_system );
  195. case ENOBUFS: return make_error_condition( no_buffer_space );
  196. case ENODATA: return make_error_condition( no_message_available );
  197. case ENODEV: return make_error_condition( no_such_device );
  198. case ENOENT: return make_error_condition( no_such_file_or_directory );
  199. case ENOEXEC: return make_error_condition( executable_format_error );
  200. case ENOLCK: return make_error_condition( no_lock_available );
  201. case ENOLINK: return make_error_condition( no_link );
  202. case ENOMEM: return make_error_condition( not_enough_memory );
  203. case ENOMSG: return make_error_condition( no_message );
  204. case ENOPROTOOPT: return make_error_condition( no_protocol_option );
  205. case ENOSPC: return make_error_condition( no_space_on_device );
  206. case ENOSR: return make_error_condition( no_stream_resources );
  207. case ENOSTR: return make_error_condition( not_a_stream );
  208. case ENOSYS: return make_error_condition( function_not_supported );
  209. case ENOTCONN: return make_error_condition( not_connected );
  210. case ENOTDIR: return make_error_condition( not_a_directory );
  211. # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value
  212. case ENOTEMPTY: return make_error_condition( directory_not_empty );
  213. # endif // ENOTEMPTY != EEXIST
  214. # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips
  215. case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable );
  216. # endif // ENOTRECOVERABLE != ECONNRESET
  217. case ENOTSOCK: return make_error_condition( not_a_socket );
  218. case ENOTSUP: return make_error_condition( not_supported );
  219. case ENOTTY: return make_error_condition( inappropriate_io_control_operation );
  220. case ENXIO: return make_error_condition( no_such_device_or_address );
  221. # if EOPNOTSUPP != ENOTSUP
  222. case EOPNOTSUPP: return make_error_condition( operation_not_supported );
  223. # endif // EOPNOTSUPP != ENOTSUP
  224. case EOVERFLOW: return make_error_condition( value_too_large );
  225. # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips
  226. case EOWNERDEAD: return make_error_condition( owner_dead );
  227. # endif // EOWNERDEAD != ECONNABORTED
  228. case EPERM: return make_error_condition( operation_not_permitted );
  229. case EPIPE: return make_error_condition( broken_pipe );
  230. case EPROTO: return make_error_condition( protocol_error );
  231. case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
  232. case EPROTOTYPE: return make_error_condition( wrong_protocol_type );
  233. case ERANGE: return make_error_condition( result_out_of_range );
  234. case EROFS: return make_error_condition( read_only_file_system );
  235. case ESPIPE: return make_error_condition( invalid_seek );
  236. case ESRCH: return make_error_condition( no_such_process );
  237. case ETIME: return make_error_condition( stream_timeout );
  238. case ETIMEDOUT: return make_error_condition( timed_out );
  239. case ETXTBSY: return make_error_condition( text_file_busy );
  240. # if EAGAIN != EWOULDBLOCK
  241. case EWOULDBLOCK: return make_error_condition( operation_would_block );
  242. # endif // EAGAIN != EWOULDBLOCK
  243. case EXDEV: return make_error_condition( cross_device_link );
  244. #else
  245. // Windows system -> posix_errno decode table ---------------------------//
  246. // see WinError.h comments for descriptions of errors
  247. case ERROR_ACCESS_DENIED_: return make_error_condition( permission_denied );
  248. case ERROR_ALREADY_EXISTS_: return make_error_condition( file_exists );
  249. case ERROR_BAD_UNIT_: return make_error_condition( no_such_device );
  250. case ERROR_BUFFER_OVERFLOW_: return make_error_condition( filename_too_long );
  251. case ERROR_BUSY_: return make_error_condition( device_or_resource_busy );
  252. case ERROR_BUSY_DRIVE_: return make_error_condition( device_or_resource_busy );
  253. case ERROR_CANNOT_MAKE_: return make_error_condition( permission_denied );
  254. case ERROR_CANTOPEN_: return make_error_condition( io_error );
  255. case ERROR_CANTREAD_: return make_error_condition( io_error );
  256. case ERROR_CANTWRITE_: return make_error_condition( io_error );
  257. case ERROR_CURRENT_DIRECTORY_: return make_error_condition( permission_denied );
  258. case ERROR_DEV_NOT_EXIST_: return make_error_condition( no_such_device );
  259. case ERROR_DEVICE_IN_USE_: return make_error_condition( device_or_resource_busy );
  260. case ERROR_DIR_NOT_EMPTY_: return make_error_condition( directory_not_empty );
  261. case ERROR_DIRECTORY_: return make_error_condition( invalid_argument );\
  262. // WinError.h: "The directory name is invalid"
  263. case ERROR_DISK_FULL_: return make_error_condition( no_space_on_device );
  264. case ERROR_FILE_EXISTS_: return make_error_condition( file_exists );
  265. case ERROR_FILE_NOT_FOUND_: return make_error_condition( no_such_file_or_directory );
  266. case ERROR_HANDLE_DISK_FULL_: return make_error_condition( no_space_on_device );
  267. case ERROR_INVALID_ACCESS_: return make_error_condition( permission_denied );
  268. case ERROR_INVALID_DRIVE_: return make_error_condition( no_such_device );
  269. case ERROR_INVALID_FUNCTION_: return make_error_condition( function_not_supported );
  270. case ERROR_INVALID_HANDLE_: return make_error_condition( invalid_argument );
  271. case ERROR_INVALID_NAME_: return make_error_condition( invalid_argument );
  272. case ERROR_LOCK_VIOLATION_: return make_error_condition( no_lock_available );
  273. case ERROR_LOCKED_: return make_error_condition( no_lock_available );
  274. case ERROR_NEGATIVE_SEEK_: return make_error_condition( invalid_argument );
  275. case ERROR_NOACCESS_: return make_error_condition( permission_denied );
  276. case ERROR_NOT_ENOUGH_MEMORY_: return make_error_condition( not_enough_memory );
  277. case ERROR_NOT_READY_: return make_error_condition( resource_unavailable_try_again );
  278. case ERROR_NOT_SAME_DEVICE_: return make_error_condition( cross_device_link );
  279. case ERROR_OPEN_FAILED_: return make_error_condition( io_error );
  280. case ERROR_OPEN_FILES_: return make_error_condition( device_or_resource_busy );
  281. case ERROR_OPERATION_ABORTED_: return make_error_condition( operation_canceled );
  282. case ERROR_OUTOFMEMORY_: return make_error_condition( not_enough_memory );
  283. case ERROR_PATH_NOT_FOUND_: return make_error_condition( no_such_file_or_directory );
  284. case ERROR_READ_FAULT_: return make_error_condition( io_error );
  285. case ERROR_RETRY_: return make_error_condition( resource_unavailable_try_again );
  286. case ERROR_SEEK_: return make_error_condition( io_error );
  287. case ERROR_SHARING_VIOLATION_: return make_error_condition( permission_denied );
  288. case ERROR_TOO_MANY_OPEN_FILES_: return make_error_condition( too_many_files_open );
  289. case ERROR_WRITE_FAULT_: return make_error_condition( io_error );
  290. case ERROR_WRITE_PROTECT_: return make_error_condition( permission_denied );
  291. case WSAEACCES_: return make_error_condition( permission_denied );
  292. case WSAEADDRINUSE_: return make_error_condition( address_in_use );
  293. case WSAEADDRNOTAVAIL_: return make_error_condition( address_not_available );
  294. case WSAEAFNOSUPPORT_: return make_error_condition( address_family_not_supported );
  295. case WSAEALREADY_: return make_error_condition( connection_already_in_progress );
  296. case WSAEBADF_: return make_error_condition( bad_file_descriptor );
  297. case WSAECONNABORTED_: return make_error_condition( connection_aborted );
  298. case WSAECONNREFUSED_: return make_error_condition( connection_refused );
  299. case WSAECONNRESET_: return make_error_condition( connection_reset );
  300. case WSAEDESTADDRREQ_: return make_error_condition( destination_address_required );
  301. case WSAEFAULT_: return make_error_condition( bad_address );
  302. case WSAEHOSTUNREACH_: return make_error_condition( host_unreachable );
  303. case WSAEINPROGRESS_: return make_error_condition( operation_in_progress );
  304. case WSAEINTR_: return make_error_condition( interrupted );
  305. case WSAEINVAL_: return make_error_condition( invalid_argument );
  306. case WSAEISCONN_: return make_error_condition( already_connected );
  307. case WSAEMFILE_: return make_error_condition( too_many_files_open );
  308. case WSAEMSGSIZE_: return make_error_condition( message_size );
  309. case WSAENAMETOOLONG_: return make_error_condition( filename_too_long );
  310. case WSAENETDOWN_: return make_error_condition( network_down );
  311. case WSAENETRESET_: return make_error_condition( network_reset );
  312. case WSAENETUNREACH_: return make_error_condition( network_unreachable );
  313. case WSAENOBUFS_: return make_error_condition( no_buffer_space );
  314. case WSAENOPROTOOPT_: return make_error_condition( no_protocol_option );
  315. case WSAENOTCONN_: return make_error_condition( not_connected );
  316. case WSAENOTSOCK_: return make_error_condition( not_a_socket );
  317. case WSAEOPNOTSUPP_: return make_error_condition( operation_not_supported );
  318. case WSAEPROTONOSUPPORT_: return make_error_condition( protocol_not_supported );
  319. case WSAEPROTOTYPE_: return make_error_condition( wrong_protocol_type );
  320. case WSAETIMEDOUT_: return make_error_condition( timed_out );
  321. case WSAEWOULDBLOCK_: return make_error_condition( operation_would_block );
  322. #endif
  323. default: return error_condition( ev, system_category() );
  324. }
  325. }
  326. # if !defined( BOOST_WINDOWS_API )
  327. BOOST_SYSTEM_DECL_ std::string system_error_category::message( int ev ) const
  328. {
  329. return generic_category().message( ev );
  330. }
  331. # else
  332. BOOST_SYSTEM_DECL_ std::string system_error_category::message( int ev ) const
  333. {
  334. #if defined(UNDER_CE) || BOOST_PLAT_WINDOWS_RUNTIME || defined(BOOST_NO_ANSI_APIS)
  335. std::wstring buf(128, wchar_t());
  336. for (;;)
  337. {
  338. boost::winapi::DWORD_ retval = boost::winapi::FormatMessageW(
  339. boost::winapi::FORMAT_MESSAGE_FROM_SYSTEM_ |
  340. boost::winapi::FORMAT_MESSAGE_IGNORE_INSERTS_,
  341. NULL,
  342. ev,
  343. boost::winapi::MAKELANGID_(boost::winapi::LANG_NEUTRAL_,
  344. boost::winapi::SUBLANG_DEFAULT_), // Default language
  345. &buf[0],
  346. static_cast<boost::winapi::DWORD_>(buf.size()),
  347. NULL
  348. );
  349. if (retval > 0)
  350. {
  351. buf.resize(retval);
  352. break;
  353. }
  354. else if (boost::winapi::GetLastError() !=
  355. boost::winapi::ERROR_INSUFFICIENT_BUFFER_)
  356. {
  357. return std::string("Unknown error");
  358. }
  359. else
  360. {
  361. buf.resize(buf.size() + buf.size() / 2);
  362. }
  363. }
  364. int num_chars = static_cast<int>(buf.size() + 1) * 2;
  365. boost::winapi::LPSTR_ narrow_buffer =
  366. #if defined(__GNUC__)
  367. (boost::winapi::LPSTR_)__builtin_alloca(num_chars);
  368. #else
  369. (boost::winapi::LPSTR_)_alloca(num_chars);
  370. #endif
  371. if (boost::winapi::WideCharToMultiByte(boost::winapi::CP_ACP_, 0,
  372. buf.c_str(), -1, narrow_buffer, num_chars, NULL, NULL) == 0)
  373. {
  374. return std::string("Unknown error");
  375. }
  376. std::string str( narrow_buffer );
  377. #else
  378. boost::winapi::LPVOID_ lpMsgBuf = 0;
  379. boost::winapi::DWORD_ retval = boost::winapi::FormatMessageA(
  380. boost::winapi::FORMAT_MESSAGE_ALLOCATE_BUFFER_ |
  381. boost::winapi::FORMAT_MESSAGE_FROM_SYSTEM_ |
  382. boost::winapi::FORMAT_MESSAGE_IGNORE_INSERTS_,
  383. NULL,
  384. ev,
  385. boost::winapi::MAKELANGID_(boost::winapi::LANG_NEUTRAL_,
  386. boost::winapi::SUBLANG_DEFAULT_), // Default language
  387. (boost::winapi::LPSTR_) &lpMsgBuf,
  388. 0,
  389. NULL
  390. );
  391. detail::local_free_on_destruction lfod(lpMsgBuf);
  392. if (retval == 0)
  393. return std::string("Unknown error");
  394. std::string str(static_cast<boost::winapi::LPCSTR_>(lpMsgBuf));
  395. # endif
  396. while ( str.size()
  397. && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
  398. str.erase( str.size()-1 );
  399. if ( str.size() && str[str.size()-1] == '.' )
  400. { str.erase( str.size()-1 ); }
  401. return str;
  402. }
  403. # endif
  404. #undef BOOST_SYSTEM_DECL_
  405. } // namespace detail
  406. # ifdef BOOST_SYSTEM_ENABLE_DEPRECATED
  407. BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code;
  408. // note that it doesn't matter if this
  409. // isn't initialized before use since
  410. // the only use is to take its
  411. // address for comparison purposes
  412. # endif
  413. #if defined(BOOST_ERROR_CODE_HEADER_ONLY)
  414. // defined in error_code.hpp
  415. #elif defined(BOOST_SYSTEM_HAS_CONSTEXPR)
  416. namespace detail
  417. {
  418. BOOST_SYSTEM_REQUIRE_CONST_INIT BOOST_SYSTEM_DECL system_error_category system_category_instance;
  419. BOOST_SYSTEM_REQUIRE_CONST_INIT BOOST_SYSTEM_DECL generic_error_category generic_category_instance;
  420. BOOST_SYSTEM_DECL const error_category & system_category_ncx() BOOST_SYSTEM_NOEXCEPT
  421. {
  422. return system_category_instance;
  423. }
  424. BOOST_SYSTEM_DECL const error_category & generic_category_ncx() BOOST_SYSTEM_NOEXCEPT
  425. {
  426. return generic_category_instance;
  427. }
  428. } // namespace detail
  429. #else
  430. namespace detail
  431. {
  432. BOOST_SYSTEM_DECL const error_category & system_category_ncx() BOOST_SYSTEM_NOEXCEPT
  433. {
  434. static const detail::system_error_category system_category_instance;
  435. return system_category_instance;
  436. }
  437. BOOST_SYSTEM_DECL const error_category & generic_category_ncx() BOOST_SYSTEM_NOEXCEPT
  438. {
  439. static const detail::generic_error_category generic_category_instance;
  440. return generic_category_instance;
  441. }
  442. } // namespace detail
  443. #endif
  444. } // namespace system
  445. } // namespace boost