dyn_bitset_unit_tests1.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. // -----------------------------------------------------------
  2. // Copyright (c) 2001 Jeremy Siek
  3. // Copyright (c) 2003-2006 Gennaro Prota
  4. // Copyright (c) 2014 Ahmed Charles
  5. // Copyright (c) 2014 Riccardo Marcangelo
  6. //
  7. // Copyright (c) 2014 Glen Joseph Fernandes
  8. // (glenjofe@gmail.com)
  9. //
  10. // Distributed under the Boost Software License, Version 1.0.
  11. // (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. //
  14. // -----------------------------------------------------------
  15. #include "bitset_test.hpp"
  16. #include <boost/dynamic_bitset/dynamic_bitset.hpp>
  17. #include <boost/limits.hpp>
  18. #include <boost/config.hpp>
  19. #include <boost/config/workaround.hpp>
  20. #if !defined(BOOST_NO_CXX11_ALLOCATOR)
  21. #include <cstdlib>
  22. template<class T>
  23. class minimal_allocator {
  24. public:
  25. typedef T value_type;
  26. minimal_allocator() {}
  27. template <typename U>
  28. minimal_allocator(const minimal_allocator<U>&) {}
  29. T* allocate(std::size_t n) {
  30. void* p = std::malloc(sizeof(T) * n);
  31. if (!p) {
  32. throw std::bad_alloc();
  33. }
  34. return static_cast<T*>(p);
  35. }
  36. void deallocate(T* p, std::size_t) {
  37. std::free(p);
  38. }
  39. };
  40. #endif
  41. #define BOOST_BITSET_TEST_COUNT(x) (sizeof(x)/sizeof(x[0]))
  42. // Codewarrior 8.3 for Win fails without this.
  43. // Thanks Howard Hinnant ;)
  44. #if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x
  45. # pragma parse_func_templ off
  46. #endif
  47. template <typename Tests, typename String>
  48. void run_string_tests(const String& s
  49. BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tests)
  50. )
  51. {
  52. const std::size_t len = s.length();
  53. const std::size_t step = len/4 ? len/4 : 1;
  54. // bitset length determined by the string-related arguments
  55. std::size_t i;
  56. for (i = 0; i <= len/2 ; i += step) {
  57. Tests::from_string(s, i, len/2); // len/2 - i bits
  58. Tests::from_string(s, i, len); // len - i bits
  59. Tests::from_string(s, i, 1 + len*2); // len - i bits
  60. }
  61. // bitset length explicitly specified
  62. for (i = 0; i <= len/2; i += step) {
  63. for (std::size_t sz = 0; sz <= len*4; sz+= step*2) {
  64. Tests::from_string(s, i, len/2, sz);
  65. Tests::from_string(s, i, len, sz);
  66. Tests::from_string(s, i, 1 + len*2, sz);
  67. }
  68. }
  69. }
  70. // tests the do-the-right-thing constructor dispatch
  71. template <typename Tests, typename T>
  72. void run_numeric_ctor_tests( BOOST_EXPLICIT_TEMPLATE_TYPE(Tests)
  73. BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T) )
  74. {
  75. const int bits_per_block = Tests::bits_per_block;
  76. const int width = std::numeric_limits<T>::digits;
  77. const T ma = (std::numeric_limits<T>::max)();
  78. const T mi = (std::numeric_limits<T>::min)();
  79. int sizes[] = {
  80. 0, 7*width/10, width, 13*width/10, 3*width,
  81. 7*bits_per_block/10, bits_per_block, 13*bits_per_block/10, 3*bits_per_block
  82. };
  83. const T numbers[] = {
  84. T(-1), T(-3), T(-8), T(-15), T(mi/2), T(mi),
  85. T(0), T(1), T(3), T(8), T(15), T(ma/2), T(ma)
  86. };
  87. for (std::size_t s = 0; s < BOOST_BITSET_TEST_COUNT(sizes); ++s) {
  88. for (std::size_t n = 0; n < BOOST_BITSET_TEST_COUNT(numbers); ++n ) {
  89. // can match ctor from ulong or templated one
  90. Tests::from_unsigned_long(sizes[s], numbers[n]);
  91. typedef std::size_t compare_type;
  92. const compare_type sz = sizes[s];
  93. // this condition is to be sure that size is representable in T, so
  94. // that for signed T's we avoid implementation-defined behavior [if ma
  95. // is larger than what std::size_t can hold then this is ok for our
  96. // purposes: our sizes are anyhow < max(size_t)], which in turn could
  97. // make the first argument of from_unsigned_long() a small negative,
  98. // later converted to a very large unsigned. Example: signed 8-bit
  99. // char (CHAR_MAX=127), bits_per_block=64, sz = 192 > 127.
  100. const bool fits =
  101. sz <= static_cast<compare_type>(ma);
  102. if (fits) {
  103. // can match templated ctor only (so we test dispatching)
  104. Tests::from_unsigned_long(static_cast<T>(sizes[s]), numbers[n]);
  105. }
  106. }
  107. }
  108. }
  109. template <typename Block>
  110. void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
  111. {
  112. typedef boost::dynamic_bitset<Block> bitset_type;
  113. typedef bitset_test<bitset_type> Tests;
  114. const int bits_per_block = bitset_type::bits_per_block;
  115. const std::string long_string = get_long_string();
  116. const Block all_1s = static_cast<Block>(-1);
  117. //=====================================================================
  118. // Test construction from unsigned long
  119. {
  120. // NOTE:
  121. //
  122. // 1. keep this in sync with the numeric types supported
  123. // for constructor dispatch (of course)
  124. // 2. bool is tested separately; ugly and inelegant, but
  125. // we don't have much time to think of a better solution
  126. // which is likely to work on broken compilers
  127. //
  128. const int sizes[] = {
  129. 0, 1, 3,
  130. 7*bits_per_block/10, bits_per_block, 13*bits_per_block/10, 3*bits_per_block
  131. };
  132. const bool values[] = { false, true };
  133. for (std::size_t s = 0; s < BOOST_BITSET_TEST_COUNT(sizes); ++s) {
  134. for (std::size_t v = 0; v < BOOST_BITSET_TEST_COUNT(values); ++v) {
  135. Tests::from_unsigned_long(sizes[s], values[v]);
  136. Tests::from_unsigned_long(sizes[s] != 0, values[v]);
  137. }
  138. }
  139. run_numeric_ctor_tests<Tests, char>();
  140. #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
  141. run_numeric_ctor_tests<Tests, wchar_t>();
  142. #endif
  143. run_numeric_ctor_tests<Tests, signed char>();
  144. run_numeric_ctor_tests<Tests, short int>();
  145. run_numeric_ctor_tests<Tests, int>();
  146. run_numeric_ctor_tests<Tests, long int>();
  147. run_numeric_ctor_tests<Tests, unsigned char>();
  148. run_numeric_ctor_tests<Tests, unsigned short>();
  149. run_numeric_ctor_tests<Tests, unsigned int>();
  150. run_numeric_ctor_tests<Tests, unsigned long>();
  151. #if defined(BOOST_HAS_LONG_LONG)
  152. run_numeric_ctor_tests<Tests, ::boost::long_long_type>();
  153. run_numeric_ctor_tests<Tests, ::boost::ulong_long_type>();
  154. #endif
  155. }
  156. //=====================================================================
  157. // Test construction from a string
  158. {
  159. run_string_tests<Tests>(std::string("")); // empty string
  160. run_string_tests<Tests>(std::string("1"));
  161. run_string_tests<Tests>(long_string);
  162. # if !defined BOOST_NO_STD_WSTRING
  163. // I need to decide what to do for non "C" locales here. On
  164. // one hand I should have better tests. On the other one
  165. // I don't want tests for dynamic_bitset to cope with locales,
  166. // ctype::widen, etc. (but that's what you deserve when you
  167. // don't separate concerns at the library level)
  168. //
  169. run_string_tests<Tests>(
  170. std::wstring(L"11111000000111111111010101010101010101010111111"));
  171. # endif
  172. // Note that these are _valid_ arguments
  173. Tests::from_string(std::string("x11y"), 1, 2);
  174. Tests::from_string(std::string("x11"), 1, 10);
  175. Tests::from_string(std::string("x11"), 1, 10, 10);
  176. }
  177. //=====================================================================
  178. // test from_block_range
  179. {
  180. std::vector<Block> blocks;
  181. Tests::from_block_range(blocks);
  182. }
  183. {
  184. std::vector<Block> blocks(3);
  185. blocks[0] = static_cast<Block>(0);
  186. blocks[1] = static_cast<Block>(1);
  187. blocks[2] = all_1s;
  188. Tests::from_block_range(blocks);
  189. }
  190. {
  191. const unsigned int n = (std::numeric_limits<unsigned char>::max)();
  192. std::vector<Block> blocks(n);
  193. for (typename std::vector<Block>::size_type i = 0; i < n; ++i)
  194. blocks[i] = static_cast<Block>(i);
  195. Tests::from_block_range(blocks);
  196. }
  197. //=====================================================================
  198. // test to_block_range
  199. {
  200. bitset_type b;
  201. Tests::to_block_range(b);
  202. }
  203. {
  204. bitset_type b(1, 1ul);
  205. Tests::to_block_range(b);
  206. }
  207. {
  208. bitset_type b(long_string);
  209. Tests::to_block_range(b);
  210. }
  211. //=====================================================================
  212. // Test copy constructor
  213. {
  214. boost::dynamic_bitset<Block> b;
  215. Tests::copy_constructor(b);
  216. }
  217. {
  218. boost::dynamic_bitset<Block> b(std::string("0"));
  219. Tests::copy_constructor(b);
  220. }
  221. {
  222. boost::dynamic_bitset<Block> b(long_string);
  223. Tests::copy_constructor(b);
  224. }
  225. //=====================================================================
  226. // Test copy assignment operator
  227. {
  228. bitset_type a, b;
  229. Tests::copy_assignment_operator(a, b);
  230. }
  231. {
  232. bitset_type a(std::string("1")), b(std::string("0"));
  233. Tests::copy_assignment_operator(a, b);
  234. }
  235. {
  236. bitset_type a(long_string), b(long_string);
  237. Tests::copy_assignment_operator(a, b);
  238. }
  239. {
  240. bitset_type a;
  241. bitset_type b(long_string); // b greater than a, a empty
  242. Tests::copy_assignment_operator(a, b);
  243. }
  244. {
  245. bitset_type a(std::string("0"));
  246. bitset_type b(long_string); // b greater than a
  247. Tests::copy_assignment_operator(a, b);
  248. }
  249. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  250. //=====================================================================
  251. // Test move constructor
  252. {
  253. boost::dynamic_bitset<Block> b;
  254. Tests::move_constructor(b);
  255. }
  256. {
  257. boost::dynamic_bitset<Block> b(std::string("0"));
  258. Tests::move_constructor(b);
  259. }
  260. {
  261. boost::dynamic_bitset<Block> b(long_string);
  262. Tests::move_constructor(b);
  263. }
  264. //=====================================================================
  265. // Test move assignment operator
  266. {
  267. bitset_type a, b;
  268. Tests::move_assignment_operator(a, b);
  269. }
  270. {
  271. bitset_type a(std::string("1")), b(std::string("0"));
  272. Tests::move_assignment_operator(a, b);
  273. }
  274. {
  275. bitset_type a(long_string), b(long_string);
  276. Tests::move_assignment_operator(a, b);
  277. }
  278. {
  279. bitset_type a;
  280. bitset_type b(long_string); // b greater than a, a empty
  281. Tests::move_assignment_operator(a, b);
  282. }
  283. {
  284. bitset_type a(std::string("0"));
  285. bitset_type b(long_string); // b greater than a
  286. Tests::move_assignment_operator(a, b);
  287. }
  288. #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
  289. //=====================================================================
  290. // Test swap
  291. {
  292. bitset_type a;
  293. bitset_type b(std::string("1"));
  294. Tests::swap(a, b);
  295. Tests::swap(b, a);
  296. Tests::swap(a, a);
  297. }
  298. {
  299. bitset_type a;
  300. bitset_type b(long_string);
  301. Tests::swap(a, b);
  302. Tests::swap(b, a);
  303. }
  304. {
  305. bitset_type a(std::string("0"));
  306. bitset_type b(long_string);
  307. Tests::swap(a, b);
  308. Tests::swap(b, a);
  309. Tests::swap(a, a);
  310. Tests::swap(b, b);
  311. }
  312. //=====================================================================
  313. // Test resize
  314. {
  315. boost::dynamic_bitset<Block> a;
  316. Tests::resize(a);
  317. }
  318. {
  319. boost::dynamic_bitset<Block> a(std::string("0"));
  320. Tests::resize(a);
  321. }
  322. {
  323. boost::dynamic_bitset<Block> a(std::string("1"));
  324. Tests::resize(a);
  325. }
  326. {
  327. boost::dynamic_bitset<Block> a(long_string);
  328. Tests::resize(a);
  329. }
  330. //=====================================================================
  331. // Test clear
  332. {
  333. boost::dynamic_bitset<Block> a;
  334. Tests::clear(a);
  335. }
  336. {
  337. boost::dynamic_bitset<Block> a(long_string);
  338. Tests::clear(a);
  339. }
  340. //=====================================================================
  341. // Test pop back
  342. {
  343. boost::dynamic_bitset<Block> a(std::string("01"));
  344. Tests::pop_back(a);
  345. }
  346. {
  347. boost::dynamic_bitset<Block> a(std::string("10"));
  348. Tests::pop_back(a);
  349. }
  350. {
  351. const int size_to_fill_all_blocks = 4 * bits_per_block;
  352. boost::dynamic_bitset<Block> a(size_to_fill_all_blocks, 255ul);
  353. Tests::pop_back(a);
  354. }
  355. {
  356. boost::dynamic_bitset<Block> a(long_string);
  357. Tests::pop_back(a);
  358. }
  359. //=====================================================================
  360. // Test append bit
  361. {
  362. boost::dynamic_bitset<Block> a;
  363. Tests::append_bit(a);
  364. }
  365. {
  366. boost::dynamic_bitset<Block> a(std::string("0"));
  367. Tests::append_bit(a);
  368. }
  369. {
  370. boost::dynamic_bitset<Block> a(std::string("1"));
  371. Tests::append_bit(a);
  372. }
  373. {
  374. const int size_to_fill_all_blocks = 4 * bits_per_block;
  375. boost::dynamic_bitset<Block> a(size_to_fill_all_blocks, 255ul);
  376. Tests::append_bit(a);
  377. }
  378. {
  379. boost::dynamic_bitset<Block> a(long_string);
  380. Tests::append_bit(a);
  381. }
  382. //=====================================================================
  383. // Test append block
  384. {
  385. boost::dynamic_bitset<Block> a;
  386. Tests::append_block(a);
  387. }
  388. {
  389. boost::dynamic_bitset<Block> a(std::string("0"));
  390. Tests::append_block(a);
  391. }
  392. {
  393. boost::dynamic_bitset<Block> a(std::string("1"));
  394. Tests::append_block(a);
  395. }
  396. {
  397. const int size_to_fill_all_blocks = 4 * bits_per_block;
  398. boost::dynamic_bitset<Block> a(size_to_fill_all_blocks, 15ul);
  399. Tests::append_block(a);
  400. }
  401. {
  402. boost::dynamic_bitset<Block> a(long_string);
  403. Tests::append_block(a);
  404. }
  405. //=====================================================================
  406. // Test append block range
  407. {
  408. boost::dynamic_bitset<Block> a;
  409. std::vector<Block> blocks;
  410. Tests::append_block_range(a, blocks);
  411. }
  412. {
  413. boost::dynamic_bitset<Block> a(std::string("0"));
  414. std::vector<Block> blocks(3);
  415. blocks[0] = static_cast<Block>(0);
  416. blocks[1] = static_cast<Block>(1);
  417. blocks[2] = all_1s;
  418. Tests::append_block_range(a, blocks);
  419. }
  420. {
  421. boost::dynamic_bitset<Block> a(std::string("1"));
  422. const unsigned int n = (std::numeric_limits<unsigned char>::max)();
  423. std::vector<Block> blocks(n);
  424. for (typename std::vector<Block>::size_type i = 0; i < n; ++i)
  425. blocks[i] = static_cast<Block>(i);
  426. Tests::append_block_range(a, blocks);
  427. }
  428. {
  429. boost::dynamic_bitset<Block> a;
  430. a.append(Block(1));
  431. a.append(Block(2));
  432. Block x[] = {3, 4, 5};
  433. std::size_t sz = sizeof(x) / sizeof(x[0]);
  434. std::vector<Block> blocks(x, x + sz);
  435. Tests::append_block_range(a, blocks);
  436. }
  437. {
  438. boost::dynamic_bitset<Block> a(long_string);
  439. std::vector<Block> blocks(3);
  440. blocks[0] = static_cast<Block>(0);
  441. blocks[1] = static_cast<Block>(1);
  442. blocks[2] = all_1s;
  443. Tests::append_block_range(a, blocks);
  444. }
  445. //=====================================================================
  446. // Test bracket operator
  447. {
  448. boost::dynamic_bitset<Block> b1;
  449. std::vector<bool> bitvec1;
  450. Tests::operator_bracket(b1, bitvec1);
  451. }
  452. {
  453. boost::dynamic_bitset<Block> b(std::string("1"));
  454. std::vector<bool> bit_vec(1, true);
  455. Tests::operator_bracket(b, bit_vec);
  456. }
  457. {
  458. boost::dynamic_bitset<Block> b(long_string);
  459. std::size_t n = long_string.size();
  460. std::vector<bool> bit_vec(n);
  461. for (std::size_t i = 0; i < n; ++i)
  462. bit_vec[i] = long_string[n - 1 - i] == '0' ? 0 : 1;
  463. Tests::operator_bracket(b, bit_vec);
  464. }
  465. #if !defined(BOOST_NO_CXX11_ALLOCATOR)
  466. {
  467. typedef boost::dynamic_bitset<Block,
  468. minimal_allocator<Block> > Bitset;
  469. Bitset b;
  470. bitset_test<Bitset>::max_size(b);
  471. }
  472. #endif
  473. // Test copy-initialize with default constructor
  474. {
  475. boost::dynamic_bitset<Block> b[1] = {};
  476. (void)b;
  477. }
  478. }
  479. int
  480. main()
  481. {
  482. run_test_cases<unsigned char>();
  483. run_test_cases<unsigned short>();
  484. run_test_cases<unsigned int>();
  485. run_test_cases<unsigned long>();
  486. # ifdef BOOST_HAS_LONG_LONG
  487. run_test_cases< ::boost::ulong_long_type>();
  488. # endif
  489. return boost::report_errors();
  490. }