std_interop_test.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. // Copyright 2017 Peter Dimov.
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. //
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. // See library home page at http://www.boost.org/libs/system
  8. // Avoid spurious VC++ warnings
  9. # define _CRT_SECURE_NO_WARNINGS
  10. #include <boost/system/error_code.hpp>
  11. #include <boost/config.hpp>
  12. #include <boost/config/pragma_message.hpp>
  13. #include <iostream>
  14. #if !defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
  15. BOOST_PRAGMA_MESSAGE( "BOOST_SYSTEM_HAS_SYSTEM_ERROR not defined, test will be skipped" )
  16. int main()
  17. {
  18. std::cout
  19. << "The version of the C++ standard library being used does not"
  20. " support header <system_error> so interoperation will not be tested.\n";
  21. }
  22. #else
  23. #include <boost/core/lightweight_test.hpp>
  24. #include <system_error>
  25. #include <cerrno>
  26. #include <string>
  27. #include <cstdio>
  28. static void test_generic_category()
  29. {
  30. boost::system::error_category const & bt = boost::system::generic_category();
  31. std::error_category const & st = bt;
  32. BOOST_TEST_CSTR_EQ( bt.name(), st.name() );
  33. int ev = ENOENT;
  34. BOOST_TEST_EQ( bt.message( ev ), st.message( ev ) );
  35. {
  36. boost::system::error_code bc( ev, bt );
  37. BOOST_TEST_EQ( bc.value(), ev );
  38. BOOST_TEST_EQ( &bc.category(), &bt );
  39. std::error_code sc( bc );
  40. BOOST_TEST_EQ( sc.value(), ev );
  41. BOOST_TEST_EQ( &sc.category(), &st );
  42. }
  43. {
  44. boost::system::error_condition bn = bt.default_error_condition( ev );
  45. BOOST_TEST_EQ( bn.value(), ev );
  46. BOOST_TEST_EQ( &bn.category(), &bt );
  47. BOOST_TEST( bt.equivalent( ev, bn ) );
  48. std::error_condition sn( bn );
  49. BOOST_TEST_EQ( sn.value(), ev );
  50. BOOST_TEST_EQ( &sn.category(), &st );
  51. BOOST_TEST( st.equivalent( ev, sn ) );
  52. }
  53. }
  54. static void test_system_category()
  55. {
  56. boost::system::error_category const & bt = boost::system::system_category();
  57. std::error_category const & st = bt;
  58. BOOST_TEST_CSTR_EQ( bt.name(), st.name() );
  59. {
  60. int ev = 5;
  61. BOOST_TEST_EQ( bt.message( ev ), st.message( ev ) );
  62. {
  63. boost::system::error_code bc( ev, bt );
  64. BOOST_TEST_EQ( bc.value(), ev );
  65. BOOST_TEST_EQ( &bc.category(), &bt );
  66. std::error_code sc( bc );
  67. BOOST_TEST_EQ( sc.value(), ev );
  68. BOOST_TEST_EQ( &sc.category(), &st );
  69. }
  70. {
  71. boost::system::error_condition bn = bt.default_error_condition( ev );
  72. BOOST_TEST( bt.equivalent( ev, bn ) );
  73. std::error_condition sn( bn );
  74. BOOST_TEST( st.equivalent( ev, sn ) );
  75. }
  76. }
  77. {
  78. int ev = 4;
  79. BOOST_TEST_EQ( bt.message( ev ), st.message( ev ) );
  80. {
  81. boost::system::error_code bc( ev, bt );
  82. BOOST_TEST_EQ( bc.value(), ev );
  83. BOOST_TEST_EQ( &bc.category(), &bt );
  84. std::error_code sc( bc );
  85. BOOST_TEST_EQ( sc.value(), ev );
  86. BOOST_TEST_EQ( &sc.category(), &st );
  87. }
  88. {
  89. boost::system::error_condition bn = bt.default_error_condition( ev );
  90. BOOST_TEST( bt.equivalent( ev, bn ) );
  91. std::error_condition sn( bn );
  92. BOOST_TEST( st.equivalent( ev, sn ) );
  93. }
  94. }
  95. }
  96. // test_user_category
  97. class user_category_impl: public boost::system::error_category
  98. {
  99. public:
  100. virtual const char * name() const BOOST_NOEXCEPT
  101. {
  102. return "user";
  103. }
  104. virtual std::string message( int ev ) const
  105. {
  106. char buffer[ 256 ];
  107. std::sprintf( buffer, "user message %d", ev );
  108. return buffer;
  109. }
  110. virtual boost::system::error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT
  111. {
  112. if( ev == 4 )
  113. {
  114. return boost::system::error_condition( EMFILE, boost::system::generic_category() );
  115. }
  116. else if( ev == 5 )
  117. {
  118. return boost::system::error_condition( EACCES, boost::system::generic_category() );
  119. }
  120. else
  121. {
  122. return boost::system::error_condition( ev, *this );
  123. }
  124. }
  125. virtual bool equivalent( int code, const boost::system::error_condition & condition ) const BOOST_NOEXCEPT
  126. {
  127. if( code == 4 && condition == make_error_condition( boost::system::errc::too_many_files_open_in_system ) )
  128. {
  129. return true;
  130. }
  131. if( code == 4 && condition == make_error_condition( boost::system::errc::too_many_files_open ) )
  132. {
  133. return true;
  134. }
  135. return default_error_condition( code ) == condition;
  136. }
  137. // virtual bool equivalent( const error_code & code, int condition ) const BOOST_NOEXCEPT;
  138. };
  139. boost::system::error_category const & user_category()
  140. {
  141. static user_category_impl cat_;
  142. return cat_;
  143. }
  144. static void test_user_category()
  145. {
  146. boost::system::error_category const & bt = user_category();
  147. std::error_category const & st = bt;
  148. BOOST_TEST_CSTR_EQ( bt.name(), st.name() );
  149. {
  150. int ev = 5;
  151. BOOST_TEST_EQ( bt.message( ev ), st.message( ev ) );
  152. {
  153. boost::system::error_code bc( ev, bt );
  154. BOOST_TEST_EQ( bc.value(), ev );
  155. BOOST_TEST_EQ( &bc.category(), &bt );
  156. std::error_code sc( bc );
  157. BOOST_TEST_EQ( sc.value(), ev );
  158. BOOST_TEST_EQ( &sc.category(), &st );
  159. }
  160. {
  161. boost::system::error_condition bn = bt.default_error_condition( ev );
  162. BOOST_TEST( bt.equivalent( ev, bn ) );
  163. std::error_condition sn( bn );
  164. BOOST_TEST( st.equivalent( ev, sn ) );
  165. }
  166. }
  167. {
  168. int ev = 4;
  169. BOOST_TEST_EQ( bt.message( ev ), st.message( ev ) );
  170. {
  171. boost::system::error_code bc( ev, bt );
  172. BOOST_TEST_EQ( bc.value(), ev );
  173. BOOST_TEST_EQ( &bc.category(), &bt );
  174. std::error_code sc( bc );
  175. BOOST_TEST_EQ( sc.value(), ev );
  176. BOOST_TEST_EQ( &sc.category(), &st );
  177. }
  178. {
  179. boost::system::error_condition bn = bt.default_error_condition( ev );
  180. BOOST_TEST( bt.equivalent( ev, bn ) );
  181. std::error_condition sn( bn );
  182. BOOST_TEST( st.equivalent( ev, sn ) );
  183. }
  184. {
  185. boost::system::error_condition bn = make_error_condition( boost::system::errc::too_many_files_open_in_system );
  186. BOOST_TEST( bt.equivalent( ev, bn ) );
  187. std::error_condition sn( bn );
  188. BOOST_TEST( st.equivalent( ev, sn ) );
  189. }
  190. {
  191. boost::system::error_condition bn = make_error_condition( boost::system::errc::too_many_files_open );
  192. BOOST_TEST( bt.equivalent( ev, bn ) );
  193. std::error_condition sn( bn );
  194. BOOST_TEST( st.equivalent( ev, sn ) );
  195. }
  196. }
  197. }
  198. // test_user2_category
  199. enum user2_errc
  200. {
  201. my_enoent = 1,
  202. my_einval,
  203. my_other
  204. };
  205. class user2_category_impl: public boost::system::error_category
  206. {
  207. public:
  208. virtual const char * name() const BOOST_NOEXCEPT
  209. {
  210. return "user2";
  211. }
  212. virtual std::string message( int ev ) const
  213. {
  214. char buffer[ 256 ];
  215. std::sprintf( buffer, "user2 message %d", ev );
  216. return buffer;
  217. }
  218. virtual boost::system::error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT
  219. {
  220. return boost::system::error_condition( ev, *this );
  221. }
  222. virtual bool equivalent( int code, const boost::system::error_condition & condition ) const BOOST_NOEXCEPT
  223. {
  224. return default_error_condition( code ) == condition;
  225. }
  226. virtual bool equivalent( const boost::system::error_code & code, int condition ) const BOOST_NOEXCEPT
  227. {
  228. if( code.category() == *this )
  229. {
  230. return condition == code.value();
  231. }
  232. else if( condition == my_enoent )
  233. {
  234. return code == boost::system::errc::no_such_file_or_directory;
  235. }
  236. else if( condition == my_einval )
  237. {
  238. return code == boost::system::errc::invalid_argument;
  239. }
  240. else
  241. {
  242. return false;
  243. }
  244. }
  245. };
  246. boost::system::error_category const & user2_category()
  247. {
  248. static user2_category_impl cat_;
  249. return cat_;
  250. }
  251. static void test_user2_category()
  252. {
  253. boost::system::error_category const & bt = user2_category();
  254. std::error_category const & st = bt;
  255. int ev = my_enoent;
  256. boost::system::error_condition bn( ev, bt );
  257. BOOST_TEST_EQ( bn.value(), ev );
  258. BOOST_TEST_EQ( &bn.category(), &bt );
  259. boost::system::error_code bc = make_error_code( boost::system::errc::no_such_file_or_directory );
  260. BOOST_TEST( bc == bn );
  261. std::error_condition sn( bn );
  262. BOOST_TEST_EQ( sn.value(), ev );
  263. BOOST_TEST_EQ( &sn.category(), &st );
  264. std::error_code sc( bc );
  265. BOOST_TEST( sc == sn );
  266. }
  267. //
  268. int main()
  269. {
  270. std::cout
  271. << "The version of the C++ standard library being used"
  272. " supports header <system_error> so interoperation will be tested.\n";
  273. test_generic_category();
  274. test_system_category();
  275. test_user_category();
  276. test_user2_category();
  277. return boost::report_errors();
  278. }
  279. #endif