dyn_bitset_unit_tests4.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // -----------------------------------------------------------
  2. // Copyright (c) 2001 Jeremy Siek
  3. // Copyright (c) 2003-2006 Gennaro Prota
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // -----------------------------------------------------------
  10. #include <fstream>
  11. #include <string>
  12. #include <cstddef> // for std::size_t
  13. #include <stdexcept> // for std::logic_error
  14. #include <assert.h>
  15. #include <boost/config.hpp>
  16. #if !defined (BOOST_NO_STRINGSTREAM)
  17. # include <sstream>
  18. #endif
  19. #include "bitset_test.hpp"
  20. #include <boost/dynamic_bitset/dynamic_bitset.hpp>
  21. #include <boost/config/workaround.hpp>
  22. // Codewarrior 8.3 for Win fails without this.
  23. // Thanks Howard Hinnant ;)
  24. #if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x
  25. # pragma parse_func_templ off
  26. #endif
  27. #if defined BOOST_NO_STD_WSTRING || defined BOOST_NO_STD_LOCALE
  28. # define BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
  29. #endif
  30. #if !defined BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
  31. std::wstring widen_string( const std::string & str,
  32. const std::locale & loc = std::locale() )
  33. {
  34. std::wstring result;
  35. const std::string::size_type len = str.length();
  36. if(len != 0) {
  37. typedef std::ctype<wchar_t> ct_type;
  38. typedef std::wstring::traits_type tr_type;
  39. const ct_type & ct = BOOST_USE_FACET(ct_type, loc);
  40. result.resize(len);
  41. for (std::size_t i = 0; i < len; ++i)
  42. tr_type::assign(result[i], ct.widen(str[i]));
  43. }
  44. return result;
  45. }
  46. #endif
  47. template <typename Block>
  48. void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
  49. {
  50. typedef boost::dynamic_bitset<Block> bitset_type;
  51. typedef bitset_test<bitset_type> Tests;
  52. //=====================================================================
  53. // Test stream operator<<
  54. {
  55. // The test "variables" are: the stream type and its state, the
  56. // exception mask, the width, the fill char and the padding side (left/right)
  57. std::ios::iostate masks[] = {
  58. std::ios::goodbit,
  59. std::ios::eofbit,
  60. std::ios::failbit,
  61. std::ios::eofbit | std::ios::failbit
  62. };
  63. static std::string strings[] = {
  64. std::string(""),
  65. std::string("0"),
  66. std::string("1"),
  67. std::string("11100"),
  68. get_long_string()
  69. };
  70. char fill_chars[] = { '*', 'x', ' ' };
  71. std::size_t num_masks = sizeof(masks) / sizeof(masks[0]);
  72. std::size_t num_strings = sizeof(strings) / sizeof(strings[0]);
  73. std::size_t num_chars = sizeof(fill_chars) / sizeof(fill_chars[0]);
  74. std::fstream not_good_stream("dynamic_bitset_tests - this file shouldn't exist",
  75. std::ios::in);
  76. for (std::size_t mi = 0; mi < num_masks; ++mi) {
  77. for (std::size_t si = 0; si < num_strings; ++si) {
  78. std::streamsize slen = (std::streamsize)(strings[si].length());
  79. assert( (std::numeric_limits<std::streamsize>::max)()
  80. >=(std::streamsize)(1+slen*2) );
  81. for (std::size_t ci = 0; ci < num_chars; ++ci) {
  82. // note how "negative widths" are tested too
  83. const std::streamsize widths[] = { -1 - slen/2, 0, slen/2, 1 + slen*2 };
  84. std::size_t num_widths = sizeof(widths) / sizeof(widths[0]);
  85. for (std::size_t wi = 0; wi < num_widths; ++wi) {
  86. std::streamsize w = widths[wi];
  87. {
  88. // test 0 - stream !good()
  89. if(not_good_stream.good())
  90. throw std::logic_error("Error in operator << tests"
  91. " - please, double check");
  92. bitset_type b(strings[si]);
  93. not_good_stream.width(w);
  94. not_good_stream.fill(fill_chars[ci]);
  95. try { not_good_stream.exceptions(masks[mi]); } catch(...) {}
  96. Tests::stream_inserter(b, not_good_stream, "<unused_string>");
  97. }
  98. {
  99. // test 1a - file stream
  100. scoped_temp_file stf;
  101. bitset_type b(strings[si]);
  102. std::ofstream file(stf.path().string().c_str(), std::ios::trunc);
  103. file.width(w);
  104. file.fill(fill_chars[ci]);
  105. file.exceptions(masks[mi]);
  106. Tests::stream_inserter(b, file, stf.path().string().c_str());
  107. }
  108. {
  109. //NOTE: there are NO string stream tests
  110. }
  111. #if !defined (BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS)
  112. {
  113. // test 1b - wide file stream
  114. scoped_temp_file stf;
  115. bitset_type b(strings[si]);
  116. std::wofstream file(stf.path().string().c_str());
  117. file.width(w);
  118. file.fill(fill_chars[ci]);
  119. file.exceptions(masks[mi]);
  120. Tests::stream_inserter(b, file, stf.path().string().c_str());
  121. }
  122. #endif
  123. }
  124. }
  125. }
  126. } // for (; mi..)
  127. }
  128. //=====================================================================
  129. // Test stream operator>>
  130. {
  131. // The test "variables" are: the stream type, the exception mask,
  132. // the actual contents (and/or state) of the stream, and width.
  133. //
  134. // With few exceptions, each test case consists of writing a different
  135. // assortment of digits and "whitespaces" to a text stream and then checking
  136. // that what was written gets read back unchanged. That's NOT guaranteed by
  137. // the standard, unless the assortment always ends with a '\n' and satisfies
  138. // other conditions (see C99, 7.19.2/2), however it works in practice and is
  139. // a good "real life" test. Some characters, such as '\v' and '\f', are not
  140. // used exactly because they are the ones which will most likely give problems
  141. // on some systems (for instance '\f' could actually be written as a sequence
  142. // of new-lines, and we could never be able to read it back)
  143. //
  144. // Note how the bitset object is not initially empty. That helps checking
  145. // that it isn't erroneously clear()ed by operator>>.
  146. std::ios::iostate masks[] = {
  147. std::ios::goodbit,
  148. std::ios::eofbit,
  149. std::ios::failbit,
  150. std::ios::eofbit | std::ios::failbit
  151. };
  152. const std::string spaces = "\t\n "; //"\t\n\v\f ";
  153. const std::string long_string = get_long_string();
  154. /*const*/ static std::string strings[] = {
  155. // NOTE: "const" gives the usual problems with Borland
  156. // (in Tests::stream_extractor instantiation)
  157. #if !(defined __BORLANDC__ \
  158. && BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)))
  159. // Borland 5.5.1 with RW library crashes
  160. // empty string
  161. std::string(""),
  162. // no bitset
  163. spaces,
  164. #endif
  165. // no bitset
  166. std::string("x"),
  167. std::string("\t xyz"),
  168. // bitset of size 1
  169. std::string("0"),
  170. std::string("1"),
  171. std::string(" 0 "),
  172. std::string(" 1 "),
  173. spaces + "1",
  174. "1" + spaces,
  175. spaces + "1" + spaces,
  176. std::string(" x1x "),
  177. std::string(" 1x "),
  178. // long bitset
  179. long_string,
  180. " " + long_string + " xyz",
  181. spaces + long_string,
  182. spaces + long_string + spaces
  183. };
  184. //-----------------------------------------------------
  185. std::stringstream not_good_stream;
  186. not_good_stream << "test";
  187. std::string sink;
  188. not_good_stream >> sink; // now the stream should be in eof state
  189. const std::size_t num_masks = sizeof(masks) / sizeof(masks[0]);
  190. const std::size_t num_strings = sizeof(strings) / sizeof(strings[0]);
  191. for (std::size_t mi = 0; mi < num_masks; ++mi) {
  192. for (std::size_t si = 0; si < num_strings; ++si) {
  193. const std::streamsize slen = (std::streamsize)(strings[si].length());
  194. assert((std::numeric_limits<std::streamsize>::max)() >= (std::streamsize)(1+slen*2));
  195. std::streamsize widths[] = { -1, 0, slen/2, slen, 1 + slen*2 };
  196. std::size_t num_widths = sizeof(widths) / sizeof(widths[0]);
  197. for(std::size_t wi = 0; wi < num_widths; ++wi) {
  198. const std::streamsize w = widths[wi];
  199. // test 0 - !good() stream
  200. {
  201. if(not_good_stream.good())
  202. throw std::logic_error("Error in operator >> tests"
  203. " - please, double check");
  204. bitset_type b(1, 15ul); // note: b is not empty
  205. not_good_stream.width(w);
  206. try { not_good_stream.exceptions(masks[mi]); } catch(...) {}
  207. std::string irrelevant;
  208. Tests::stream_extractor(b, not_good_stream, irrelevant);
  209. }
  210. // test 1a - (narrow) file stream
  211. {
  212. scoped_temp_file stf;
  213. bitset_type b(1, 255ul);
  214. {
  215. std::ofstream f(stf.path().string().c_str());
  216. f << strings[si];
  217. }
  218. std::ifstream f(stf.path().string().c_str());
  219. f.width(w);
  220. f.exceptions(masks[mi]);
  221. Tests::stream_extractor(b, f, strings[si]);
  222. }
  223. #if !defined(BOOST_NO_STRINGSTREAM)
  224. // test 2a - stringstream
  225. {
  226. bitset_type b(1, 255ul);
  227. std::istringstream stream(strings[si]);
  228. stream.width(w);
  229. stream.exceptions(masks[mi]);
  230. Tests::stream_extractor(b, stream, strings[si]);
  231. }
  232. #endif
  233. #if !defined(BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS)
  234. // test 1b - wchar_t file stream
  235. {
  236. scoped_temp_file stf;
  237. std::wstring wstr = widen_string(strings[si]);
  238. bitset_type b(1, 255ul);
  239. {
  240. std::basic_ofstream<wchar_t> of(stf.path().string().c_str());
  241. of << wstr;
  242. }
  243. std::basic_ifstream<wchar_t> f(stf.path().string().c_str());
  244. f.width(w);
  245. f.exceptions(masks[mi]);
  246. Tests::stream_extractor(b, f, wstr);
  247. }
  248. // test 2b - wstringstream
  249. {
  250. bitset_type b(1, 255ul);
  251. std::wstring wstr = widen_string(strings[si]);
  252. std::wistringstream wstream(wstr);
  253. wstream.width(w);
  254. wstream.exceptions(masks[mi]);
  255. Tests::stream_extractor(b, wstream, wstr);
  256. }
  257. #endif // BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
  258. }
  259. }
  260. } // for ( mi = 0; ...)
  261. }
  262. //=====================================================================
  263. // << Any other tests go here >>
  264. // .....
  265. }
  266. int
  267. main()
  268. {
  269. run_test_cases<unsigned char>();
  270. run_test_cases<unsigned short>();
  271. run_test_cases<unsigned int>();
  272. run_test_cases<unsigned long>();
  273. # ifdef BOOST_HAS_LONG_LONG
  274. run_test_cases< ::boost::ulong_long_type>();
  275. # endif
  276. return boost::report_errors();
  277. }