error_code_user_test.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. // error_code_user_test.cpp ------------------------------------------------//
  2. // Copyright Beman Dawes 2006
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. // See library home page at http://www.boost.org/libs/system
  6. // ------------------------------------------------------------------------ //
  7. // This program demonstrates creation and use of new categories of error
  8. // codes. Several scenarios are demonstrated and tested.
  9. // Motivation was a Boost posting by Christopher Kohlhoff on June 28, 2006.
  10. #include <boost/system/error_code.hpp>
  11. #include <boost/cerrno.hpp>
  12. #include <string>
  13. #include <cstdio>
  14. #include <boost/detail/lightweight_test.hpp>
  15. #ifdef BOOST_POSIX_API
  16. # include <sys/stat.h>
  17. #else
  18. # include <windows.h>
  19. #endif
  20. // ------------------------------------------------------------------------ //
  21. // Library 1: User function passes through an error code from the
  22. // operating system.
  23. boost::system::error_code my_mkdir( const std::string & path )
  24. {
  25. return boost::system::error_code(
  26. # ifdef BOOST_POSIX_API
  27. ::mkdir( path.c_str(), S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH ) == 0 ? 0 : errno,
  28. # else
  29. ::CreateDirectoryA( path.c_str(), 0 ) != 0 ? 0 : ::GetLastError(),
  30. # endif
  31. boost::system::system_category() );
  32. }
  33. // ------------------------------------------------------------------------ //
  34. // Library 2: User function passes through errno from the C-runtime.
  35. #include <cstdio>
  36. boost::system::error_code my_remove( const std::string & path )
  37. {
  38. return boost::system::error_code(
  39. std::remove( path.c_str() ) == 0 ? 0 : errno,
  40. boost::system::generic_category() ); // OK for both Windows and POSIX
  41. // Alternatively, could use generic_category()
  42. // on Windows and system_category() on
  43. // POSIX-based systems.
  44. }
  45. // ------------------------------------------------------------------------ //
  46. // Library 3: Library uses enum to identify library specific errors.
  47. // This particular example is for a library within the parent namespace. For
  48. // an example of a library not within the parent namespace, see library 4.
  49. // header lib3.hpp:
  50. namespace boost
  51. {
  52. namespace lib3
  53. {
  54. // lib3 has its own error_category:
  55. const boost::system::error_category & get_lib3_error_category() BOOST_SYSTEM_NOEXCEPT;
  56. const boost::system::error_category & lib3_error_category = get_lib3_error_category();
  57. enum error
  58. {
  59. boo_boo=123,
  60. big_boo_boo
  61. };
  62. }
  63. namespace system
  64. {
  65. template<> struct is_error_code_enum<boost::lib3::error>
  66. { static const bool value = true; };
  67. }
  68. namespace lib3
  69. {
  70. inline boost::system::error_code make_error_code(error e)
  71. { return boost::system::error_code(e,lib3_error_category); }
  72. }
  73. }
  74. // implementation file lib3.cpp:
  75. // #include <lib3.hpp>
  76. namespace boost
  77. {
  78. namespace lib3
  79. {
  80. class lib3_error_category_imp : public boost::system::error_category
  81. {
  82. public:
  83. lib3_error_category_imp() : boost::system::error_category() { }
  84. const char * name() const BOOST_SYSTEM_NOEXCEPT
  85. {
  86. return "lib3";
  87. }
  88. boost::system::error_condition default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT
  89. {
  90. return ev == boo_boo
  91. ? boost::system::error_condition( boost::system::errc::io_error,
  92. boost::system::generic_category() )
  93. : boost::system::error_condition( ev,
  94. boost::lib3::lib3_error_category );
  95. }
  96. std::string message( int ev ) const
  97. {
  98. if ( ev == boo_boo ) return std::string("boo boo");
  99. if ( ev == big_boo_boo ) return std::string("big boo boo");
  100. return std::string("unknown error");
  101. }
  102. };
  103. const boost::system::error_category & get_lib3_error_category() BOOST_SYSTEM_NOEXCEPT
  104. {
  105. static const lib3_error_category_imp l3ecat;
  106. return l3ecat;
  107. }
  108. }
  109. }
  110. // ------------------------------------------------------------------------ //
  111. // Library 4: Library uses const error_code's to identify library specific
  112. // errors.
  113. // This particular example is for a library not within the parent namespace.
  114. // For an example of a library within the parent namespace, see library 3.
  115. // header lib4.hpp:
  116. namespace lib4
  117. {
  118. // lib4 has its own error_category:
  119. const boost::system::error_category & get_lib4_error_category() BOOST_SYSTEM_NOEXCEPT;
  120. const boost::system::error_category & lib4_error_category = get_lib4_error_category();
  121. extern const boost::system::error_code boo_boo;
  122. extern const boost::system::error_code big_boo_boo;
  123. }
  124. // implementation file lib4.cpp:
  125. // #include <lib4.hpp>
  126. namespace lib4
  127. {
  128. class lib4_error_category_imp : public boost::system::error_category
  129. {
  130. public:
  131. lib4_error_category_imp() : boost::system::error_category() { }
  132. const char * name() const BOOST_SYSTEM_NOEXCEPT
  133. {
  134. return "lib4";
  135. }
  136. boost::system::error_condition default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT
  137. {
  138. return ev == boo_boo.value()
  139. ? boost::system::error_condition( boost::system::errc::io_error,
  140. boost::system::generic_category() )
  141. : boost::system::error_condition( ev, lib4::lib4_error_category );
  142. }
  143. std::string message( int ev ) const
  144. {
  145. if ( ev == boo_boo.value() ) return std::string("boo boo");
  146. if ( ev == big_boo_boo.value() ) return std::string("big boo boo");
  147. return std::string("unknown error");
  148. }
  149. };
  150. const boost::system::error_category & get_lib4_error_category() BOOST_SYSTEM_NOEXCEPT
  151. {
  152. static const lib4_error_category_imp l4ecat;
  153. return l4ecat;
  154. }
  155. const boost::system::error_code boo_boo( 456, lib4_error_category );
  156. const boost::system::error_code big_boo_boo( 789, lib4_error_category );
  157. }
  158. // ------------------------------------------------------------------------ //
  159. // Chris Kolhoff's Test3, modified to work with error_code.hpp
  160. // Test3
  161. // =====
  162. // Define error classes to check for success, permission_denied and
  163. // out_of_memory, but add additional mappings for a user-defined error category.
  164. //
  165. //namespace test3 {
  166. // enum user_err
  167. // {
  168. // user_success = 0,
  169. // user_permission_denied,
  170. // user_out_of_memory
  171. // };
  172. //
  173. // class user_error_category_imp : public boost::system::error_category
  174. // {
  175. // public:
  176. // const std::string & name() const
  177. // {
  178. // static std::string s( "test3" );
  179. // return s;
  180. // }
  181. //
  182. // boost::system::error_code portable_error_code( int ev ) const
  183. // {
  184. // switch (ev)
  185. // {
  186. // case user_success:
  187. // return boost::system::error_code(boost::system::errc::success, boost::system::generic_category());
  188. // case user_permission_denied:
  189. // return boost::system::error_code(boost::system::errc::permission_denied, boost::system::generic_category());
  190. // case user_out_of_memory:
  191. // return boost::system::error_code(boost::system::errc::not_enough_memory, boost::system::generic_category());
  192. // default:
  193. // break;
  194. // }
  195. // return boost::system::error_code(boost::system::errc::no_posix_equivalent, boost::system::generic_category());
  196. // }
  197. //
  198. // };
  199. //
  200. // const user_error_category_imp user_error_category_const;
  201. //
  202. // const boost::system::error_category & user_error_category
  203. // = user_error_category_const;
  204. //
  205. // template<> inline boost::system::error_code make_error_code(user_err e)
  206. // {
  207. // return boost::system::error_code(e, user_error_category);
  208. // }
  209. //
  210. // // test code
  211. //
  212. // void check_success(const boost::system::error_code& ec, bool expect)
  213. // {
  214. // BOOST_TEST( (ec == boost::system::errc::success) == expect );
  215. // if (ec == boost::system::errc::success)
  216. // std::cout << "yes... " << (expect ? "ok" : "fail") << '\n';
  217. // else
  218. // std::cout << "no... " << (expect ? "fail" : "ok") << '\n';
  219. // }
  220. //
  221. // void check_permission_denied(const boost::system::error_code& ec, bool expect)
  222. // {
  223. // BOOST_TEST( (ec == boost::system::errc::permission_denied) == expect );
  224. // if (ec == boost::system::errc::permission_denied)
  225. // std::cout << "yes... " << (expect ? "ok" : "fail") << '\n';
  226. // else
  227. // std::cout << "no... " << (expect ? "fail" : "ok") << '\n';
  228. // }
  229. //
  230. // void check_out_of_memory(const boost::system::error_code& ec, bool expect)
  231. // {
  232. // BOOST_TEST( (ec == boost::system::errc::not_enough_memory) == expect );
  233. // if (ec == boost::system::errc::not_enough_memory)
  234. // std::cout << "yes... " << (expect ? "ok" : "fail") << '\n';
  235. // else
  236. // std::cout << "no... " << (expect ? "fail" : "ok") << '\n';
  237. // }
  238. //
  239. // void run()
  240. // {
  241. // printf("Test3\n");
  242. // printf("=====\n");
  243. // boost::system::error_code ec;
  244. // check_success(ec, true);
  245. // check_success(boost::system::errc::success, true);
  246. // check_success(boost::system::errc::permission_denied, false);
  247. // check_success(boost::system::errc::not_enough_memory, false);
  248. // check_success(user_success, true);
  249. // check_success(user_permission_denied, false);
  250. // check_success(user_out_of_memory, false);
  251. // check_permission_denied(ec, false);
  252. // check_permission_denied(boost::system::errc::success, false);
  253. // check_permission_denied(boost::system::errc::permission_denied, true);
  254. // check_permission_denied(boost::system::errc::not_enough_memory, false);
  255. // check_permission_denied(user_success, false);
  256. // check_permission_denied(user_permission_denied, true);
  257. // check_permission_denied(user_out_of_memory, false);
  258. // check_out_of_memory(ec, false);
  259. // check_out_of_memory(boost::system::errc::success, false);
  260. // check_out_of_memory(boost::system::errc::permission_denied, false);
  261. // check_out_of_memory(boost::system::errc::not_enough_memory, true);
  262. // check_out_of_memory(user_success, false);
  263. // check_out_of_memory(user_permission_denied, false);
  264. // check_out_of_memory(user_out_of_memory, true);
  265. //
  266. //# ifdef BOOST_WINDOWS_API
  267. // check_success(boost::system::windows::success, true);
  268. // check_success(boost::system::windows::access_denied, false);
  269. // check_success(boost::system::windows::not_enough_memory, false);
  270. // check_permission_denied(boost::system::windows::success, false);
  271. // check_permission_denied(boost::system::windows::access_denied, true);
  272. // check_permission_denied(boost::system::windows::not_enough_memory, false);
  273. // check_out_of_memory(boost::system::windows::success, false);
  274. // check_out_of_memory(boost::system::windows::access_denied, false);
  275. // check_out_of_memory(boost::system::windows::not_enough_memory, true);
  276. //# endif
  277. //
  278. // printf("\n");
  279. // }
  280. //
  281. //} // namespace test3
  282. // ------------------------------------------------------------------------ //
  283. int main( int, char *[] )
  284. {
  285. boost::system::error_code ec;
  286. // Library 1 tests:
  287. ec = my_mkdir( "/no-such-file-or-directory/will-not-succeed" );
  288. std::cout << "ec.value() is " << ec.value() << '\n';
  289. BOOST_TEST( ec );
  290. BOOST_TEST( ec == boost::system::errc::no_such_file_or_directory );
  291. BOOST_TEST( ec.category() == boost::system::system_category() );
  292. // Library 2 tests:
  293. ec = my_remove( "/no-such-file-or-directory" );
  294. std::cout << "ec.value() is " << ec.value() << '\n';
  295. BOOST_TEST( ec );
  296. BOOST_TEST( ec == boost::system::errc::no_such_file_or_directory );
  297. BOOST_TEST( ec.category() == boost::system::generic_category() );
  298. // Library 3 tests:
  299. ec = boost::lib3::boo_boo;
  300. std::cout << "ec.value() is " << ec.value() << '\n';
  301. BOOST_TEST( ec );
  302. BOOST_TEST( ec == boost::lib3::boo_boo );
  303. BOOST_TEST( ec.value() == boost::lib3::boo_boo );
  304. BOOST_TEST( ec.category() == boost::lib3::lib3_error_category );
  305. BOOST_TEST( ec == boost::system::errc::io_error );
  306. boost::system::error_code ec3( boost::lib3::boo_boo+100,
  307. boost::lib3::lib3_error_category );
  308. BOOST_TEST( ec3.category() == boost::lib3::lib3_error_category );
  309. BOOST_TEST( ec3.default_error_condition().category()
  310. == boost::lib3::lib3_error_category );
  311. // Library 4 tests:
  312. ec = lib4::boo_boo;
  313. std::cout << "ec.value() is " << ec.value() << '\n';
  314. BOOST_TEST( ec );
  315. BOOST_TEST( ec == lib4::boo_boo );
  316. BOOST_TEST( ec.value() == lib4::boo_boo.value() );
  317. BOOST_TEST( ec.category() == lib4::lib4_error_category );
  318. BOOST_TEST( ec == boost::system::errc::io_error );
  319. boost::system::error_code ec4( lib4::boo_boo.value()+100,
  320. lib4::lib4_error_category );
  321. BOOST_TEST( ec4.default_error_condition().category()
  322. == lib4::lib4_error_category );
  323. // Test 3
  324. //test3::run();
  325. return ::boost::report_errors();
  326. }