2
0

split_bitstring.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  1. // Copyright (c) 2006-2018 Maxim Khizhinsky
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #include <cds/algo/split_bitstring.h>
  6. #include <cds_test/ext_gtest.h>
  7. namespace {
  8. bool is_big_endian()
  9. {
  10. union {
  11. uint32_t ui;
  12. uint8_t ch;
  13. } byte_order;
  14. byte_order.ui = 0xFF000001;
  15. return byte_order.ch != 0x01;
  16. }
  17. class Split_bitstrig : public ::testing::Test
  18. {
  19. protected:
  20. void cut_uint_le()
  21. {
  22. typedef cds::algo::split_bitstring< size_t, 0, size_t > split_bitstring;
  23. size_t src = sizeof(src) == 8 ? 0xFEDCBA9876543210 : 0x76543210;
  24. split_bitstring splitter( src );
  25. size_t res;
  26. // Trivial case
  27. ASSERT_FALSE( splitter.eos());
  28. ASSERT_FALSE( !splitter );
  29. res = splitter.cut( sizeof( src ) * 8 );
  30. EXPECT_EQ( res, src );
  31. ASSERT_TRUE( splitter.eos());
  32. ASSERT_TRUE( !splitter );
  33. EXPECT_EQ( splitter.safe_cut( sizeof( src ) * 8 ), 0u );
  34. ASSERT_TRUE( splitter.eos());
  35. ASSERT_TRUE( !splitter );
  36. splitter.reset();
  37. ASSERT_FALSE( splitter.eos());
  38. ASSERT_FALSE( !splitter );
  39. res = splitter.cut( sizeof( src ) * 8 );
  40. EXPECT_EQ( res, src );
  41. ASSERT_TRUE( splitter.eos());
  42. ASSERT_TRUE( !splitter );
  43. EXPECT_EQ( splitter.safe_cut( sizeof( src ) * 8 ), 0u );
  44. ASSERT_TRUE( splitter.eos());
  45. ASSERT_TRUE( !splitter );
  46. EXPECT_EQ( *splitter.source(), src );
  47. EXPECT_EQ( splitter.rest_count(), 0u );
  48. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  49. // Cut each hex digit
  50. splitter.reset();
  51. for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) {
  52. ASSERT_FALSE( splitter.eos());
  53. ASSERT_FALSE( !splitter );
  54. ASSERT_EQ( splitter.cut( 4 ), i );
  55. }
  56. ASSERT_TRUE( splitter.eos());
  57. ASSERT_FALSE( splitter );
  58. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  59. EXPECT_EQ( *splitter.source(), src );
  60. EXPECT_EQ( splitter.rest_count(), 0u );
  61. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  62. // by one bit
  63. {
  64. splitter.reset();
  65. EXPECT_EQ( *splitter.source(), src );
  66. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  67. EXPECT_EQ( splitter.bit_offset(), 0u );
  68. res = 0;
  69. for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) {
  70. ASSERT_FALSE( splitter.eos());
  71. ASSERT_FALSE( !splitter );
  72. res |= splitter.cut( 1 ) << i;
  73. }
  74. ASSERT_TRUE( splitter.eos());
  75. ASSERT_TRUE( !splitter );
  76. EXPECT_EQ( res, src );
  77. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  78. EXPECT_EQ( *splitter.source(), src );
  79. EXPECT_EQ( splitter.rest_count(), 0u );
  80. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  81. }
  82. // random cut
  83. {
  84. for ( size_t k = 0; k < 100; ++k ) {
  85. splitter.reset();
  86. EXPECT_EQ( *splitter.source(), src );
  87. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  88. EXPECT_EQ( splitter.bit_offset(), 0u );
  89. res = 0;
  90. size_t shift = 0;
  91. while ( splitter ) {
  92. ASSERT_FALSE( splitter.eos());
  93. ASSERT_FALSE( !splitter );
  94. int bits = std::rand() % 16;
  95. res |= splitter.safe_cut( bits ) << shift;
  96. shift += bits;
  97. }
  98. ASSERT_TRUE( splitter.eos());
  99. ASSERT_TRUE( !splitter );
  100. EXPECT_EQ( res, src );
  101. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  102. EXPECT_EQ( *splitter.source(), src );
  103. EXPECT_EQ( splitter.rest_count(), 0u );
  104. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  105. }
  106. }
  107. }
  108. void cut_uint_be()
  109. {
  110. typedef cds::algo::split_bitstring< size_t, 0, size_t > split_bitstring;
  111. size_t src = sizeof(src) == 8 ? 0xFEDCBA9876543210 : 0x76543210;
  112. split_bitstring splitter( src );
  113. size_t res;
  114. // Trivial case
  115. ASSERT_FALSE( splitter.eos());
  116. ASSERT_FALSE( !splitter );
  117. res = splitter.cut( sizeof( src ) * 8 );
  118. ASSERT_EQ( res, src );
  119. ASSERT_TRUE( splitter.eos());
  120. ASSERT_TRUE( !splitter );
  121. EXPECT_EQ( splitter.safe_cut( sizeof( src ) * 8 ), 0u );
  122. ASSERT_TRUE( splitter.eos());
  123. ASSERT_TRUE( !splitter );
  124. splitter.reset();
  125. ASSERT_FALSE( splitter.eos());
  126. ASSERT_FALSE( !splitter );
  127. res = splitter.cut( sizeof( src ) * 8 );
  128. EXPECT_EQ( res, src );
  129. ASSERT_TRUE( splitter.eos());
  130. ASSERT_TRUE( !splitter );
  131. EXPECT_EQ( splitter.safe_cut( sizeof( src ) * 8 ), 0u );
  132. ASSERT_TRUE( splitter.eos());
  133. ASSERT_TRUE( !splitter );
  134. EXPECT_EQ( *splitter.source(), src );
  135. EXPECT_EQ( splitter.rest_count(), 0u );
  136. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  137. // Cut each hex digit
  138. splitter.reset();
  139. for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) {
  140. ASSERT_FALSE( splitter.eos());
  141. ASSERT_FALSE( !splitter );
  142. if ( i % 2 == 0 ) {
  143. // even - least half-byte
  144. EXPECT_EQ( splitter.cut( 4 ), 0x0E - i ) << "i=" << i;
  145. }
  146. else {
  147. // odd - most half-byte
  148. EXPECT_EQ( splitter.cut( 4 ), 0x0F - i + 1 ) << "i=" << i;
  149. }
  150. }
  151. ASSERT_TRUE( splitter.eos());
  152. ASSERT_TRUE( !splitter );
  153. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  154. EXPECT_EQ( *splitter.source(), src );
  155. EXPECT_EQ( splitter.rest_count(), 0u );
  156. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  157. // by one bit
  158. {
  159. splitter.reset();
  160. EXPECT_EQ( *splitter.source(), src );
  161. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  162. EXPECT_EQ( splitter.bit_offset(), 0u );
  163. res = 0;
  164. for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) {
  165. ASSERT_FALSE( splitter.eos());
  166. ASSERT_FALSE( !splitter );
  167. if ( i % 8 == 0 )
  168. res = res << 8;
  169. res |= ( splitter.cut( 1 )) << ( i % 8 );
  170. }
  171. ASSERT_TRUE( splitter.eos());
  172. ASSERT_TRUE( !splitter );
  173. EXPECT_EQ( res, src );
  174. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  175. EXPECT_EQ( *splitter.source(), src );
  176. EXPECT_EQ( splitter.rest_count(), 0u );
  177. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  178. }
  179. // random cut
  180. /*
  181. {
  182. for ( size_t k = 0; k < 100; ++k ) {
  183. splitter.reset();
  184. EXPECT_EQ( *splitter.source(), src );
  185. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  186. EXPECT_EQ( splitter.bit_offset(), 0u );
  187. res = 0;
  188. while ( splitter ) {
  189. ASSERT_FALSE( splitter.eos());
  190. ASSERT_FALSE( !splitter );
  191. unsigned bits = std::rand() % 16;
  192. size_t shift = splitter.rest_count();
  193. if ( shift > bits )
  194. shift = bits;
  195. res = (res << shift) | splitter.safe_cut( bits );
  196. }
  197. ASSERT_TRUE( splitter.eos());
  198. ASSERT_TRUE( !splitter );
  199. EXPECT_EQ( res, src );
  200. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  201. EXPECT_EQ( *splitter.source(), src );
  202. EXPECT_EQ( splitter.rest_count(), 0u );
  203. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  204. }
  205. }
  206. */
  207. }
  208. template <typename PartUInt>
  209. void cut_small_le()
  210. {
  211. typedef PartUInt part_uint;
  212. typedef cds::algo::split_bitstring< uint64_t, 0, part_uint > split_bitstring;
  213. uint64_t src = 0xFEDCBA9876543210;
  214. split_bitstring splitter(src);
  215. uint64_t res;
  216. EXPECT_EQ( *splitter.source(), src );
  217. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  218. EXPECT_EQ( splitter.bit_offset(), 0u );
  219. // Cut each hex digit
  220. splitter.reset();
  221. for ( size_t i = 0; i < sizeof(src) * 2; ++i ) {
  222. ASSERT_FALSE( splitter.eos());
  223. ASSERT_FALSE( !splitter );
  224. EXPECT_EQ( static_cast<size_t>(splitter.cut( 4 )), i );
  225. }
  226. ASSERT_TRUE( splitter.eos());
  227. ASSERT_TRUE( !splitter );
  228. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  229. EXPECT_EQ( *splitter.source(), src );
  230. EXPECT_EQ( splitter.rest_count(), 0u );
  231. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  232. // by one bit
  233. {
  234. splitter.reset();
  235. EXPECT_EQ( *splitter.source(), src );
  236. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  237. EXPECT_EQ( splitter.bit_offset(), 0u );
  238. res = 0;
  239. for ( size_t i = 0; i < sizeof(src) * 8; ++i ) {
  240. ASSERT_FALSE( splitter.eos());
  241. ASSERT_FALSE( !splitter );
  242. res += static_cast<uint64_t>(splitter.cut( 1 )) << i;
  243. }
  244. ASSERT_TRUE( splitter.eos());
  245. ASSERT_TRUE( !splitter );
  246. EXPECT_EQ( res, src );
  247. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  248. EXPECT_EQ( *splitter.source(), src );
  249. EXPECT_EQ( splitter.rest_count(), 0u );
  250. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  251. }
  252. // random cut
  253. {
  254. for ( size_t k = 0; k < 100; ++k ) {
  255. splitter.reset();
  256. EXPECT_EQ( *splitter.source(), src );
  257. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  258. EXPECT_EQ( splitter.bit_offset(), 0u );
  259. res = 0;
  260. size_t shift = 0;
  261. while ( splitter ) {
  262. ASSERT_FALSE( splitter.eos());
  263. ASSERT_FALSE( !splitter );
  264. int bits = std::rand() % 16;
  265. res += static_cast<uint64_t>(splitter.safe_cut( bits )) << shift;
  266. shift += bits;
  267. }
  268. ASSERT_TRUE( splitter.eos());
  269. ASSERT_TRUE( !splitter );
  270. EXPECT_EQ( res, src );
  271. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  272. EXPECT_EQ( *splitter.source(), src );
  273. EXPECT_EQ( splitter.rest_count(), 0u );
  274. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  275. }
  276. }
  277. }
  278. template <typename PartUInt>
  279. void cut_small_be()
  280. {
  281. typedef PartUInt part_uint;
  282. typedef cds::algo::split_bitstring< uint64_t, 0, part_uint > split_bitstring;
  283. uint64_t src = 0xFEDCBA9876543210;
  284. split_bitstring splitter(src);
  285. uint64_t res;
  286. EXPECT_EQ( *splitter.source(), src );
  287. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  288. EXPECT_EQ( splitter.bit_offset(), 0u );
  289. // Cut each hex digit
  290. splitter.reset();
  291. for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) {
  292. ASSERT_FALSE( splitter.eos());
  293. ASSERT_FALSE( !splitter );
  294. if ( i % 2 == 0 ) {
  295. EXPECT_EQ( splitter.cut( 4 ), 0x0E - i );
  296. }
  297. else {
  298. EXPECT_EQ( splitter.cut( 4 ), 0x0F - i + 1 );
  299. }
  300. }
  301. ASSERT_TRUE( splitter.eos());
  302. ASSERT_TRUE( !splitter );
  303. // by one bit
  304. {
  305. splitter.reset();
  306. EXPECT_EQ( *splitter.source(), src );
  307. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  308. EXPECT_EQ( splitter.bit_offset(), 0u );
  309. res = 0;
  310. for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) {
  311. ASSERT_FALSE( splitter.eos());
  312. ASSERT_FALSE( !splitter );
  313. if ( i % 8 == 0 )
  314. res = res << 8;
  315. res |= ( splitter.cut( 1 )) << ( i % 8 );
  316. }
  317. ASSERT_TRUE( splitter.eos());
  318. ASSERT_TRUE( !splitter );
  319. EXPECT_EQ( res, src );
  320. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  321. EXPECT_EQ( *splitter.source(), src );
  322. EXPECT_EQ( splitter.rest_count(), 0u );
  323. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  324. }
  325. // random cut
  326. /*
  327. {
  328. for ( size_t k = 0; k < 100; ++k ) {
  329. splitter.reset();
  330. EXPECT_EQ( *splitter.source(), src );
  331. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  332. EXPECT_EQ( splitter.bit_offset(), 0u );
  333. res = 0;
  334. while ( splitter ) {
  335. ASSERT_FALSE( splitter.eos());
  336. ASSERT_FALSE( !splitter );
  337. unsigned bits = std::rand() % 16;
  338. size_t shift = splitter.rest_count();
  339. if ( shift > bits )
  340. shift = bits;
  341. res = ( res << shift ) | splitter.safe_cut( bits );
  342. }
  343. ASSERT_TRUE( splitter.eos());
  344. ASSERT_TRUE( !splitter );
  345. EXPECT_EQ( res, src );
  346. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  347. EXPECT_EQ( *splitter.source(), src );
  348. EXPECT_EQ( splitter.rest_count(), 0u );
  349. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  350. }
  351. }
  352. */
  353. }
  354. struct int48 {
  355. uint32_t n32;
  356. uint16_t n16;
  357. #if 0
  358. friend bool operator ==( int48 lhs, int48 rhs )
  359. {
  360. return lhs.n32 == rhs.n32 && lhs.n16 == rhs.n16;
  361. }
  362. #endif
  363. uint64_t to64() const
  364. {
  365. # ifdef CDS_ARCH_LITTLE_ENDIAN
  366. return ( static_cast<uint64_t>( n16 ) << 32 ) + n32;
  367. # else
  368. return ( static_cast<uint64_t>( n32 ) << 16 ) + n16;
  369. # endif
  370. }
  371. };
  372. static constexpr size_t int48_size = 6;
  373. void cut_int48_le()
  374. {
  375. int48 src;
  376. src.n32 = 0x76543210;
  377. src.n16 = 0xBA98;
  378. uint64_t res;
  379. #if CDS_BUILD_BITS == 64
  380. {
  381. typedef cds::algo::split_bitstring< int48, int48_size, size_t > split_bitstring;
  382. split_bitstring splitter( src );
  383. // Trivial case
  384. ASSERT_FALSE( splitter.eos());
  385. ASSERT_FALSE( !splitter );
  386. res = splitter.cut( int48_size * 8 );
  387. EXPECT_EQ( res, src.to64());
  388. ASSERT_TRUE( splitter.eos());
  389. ASSERT_TRUE( !splitter );
  390. EXPECT_EQ( splitter.safe_cut( int48_size * 8 ), 0u );
  391. ASSERT_TRUE( splitter.eos());
  392. ASSERT_TRUE( !splitter );
  393. splitter.reset();
  394. ASSERT_FALSE( splitter.eos());
  395. ASSERT_FALSE( !splitter );
  396. res = splitter.cut( int48_size * 8 );
  397. EXPECT_EQ( res, src.to64());
  398. ASSERT_TRUE( splitter.eos());
  399. ASSERT_TRUE( !splitter );
  400. EXPECT_EQ( splitter.safe_cut( int48_size * 8 ), 0u );
  401. ASSERT_TRUE( splitter.eos());
  402. ASSERT_TRUE( !splitter );
  403. }
  404. #endif
  405. typedef cds::algo::split_bitstring< int48, int48_size, size_t > split_bitstring;
  406. split_bitstring splitter( src );
  407. EXPECT_EQ( splitter.source()->to64(), src.to64());
  408. EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
  409. EXPECT_EQ( splitter.bit_offset(), 0u );
  410. // Cut each hex digit
  411. splitter.reset();
  412. for ( size_t i = 0; i < int48_size * 2; ++i ) {
  413. ASSERT_FALSE( splitter.eos());
  414. ASSERT_FALSE( !splitter );
  415. ASSERT_EQ( splitter.cut( 4 ), i );
  416. }
  417. ASSERT_TRUE( splitter.eos());
  418. ASSERT_FALSE( splitter );
  419. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  420. EXPECT_EQ( splitter.source()->to64(), src.to64());
  421. EXPECT_EQ( splitter.rest_count(), 0u );
  422. EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
  423. // by one bit
  424. {
  425. splitter.reset();
  426. EXPECT_EQ( splitter.source()->to64(), src.to64());
  427. EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
  428. EXPECT_EQ( splitter.bit_offset(), 0u );
  429. res = 0;
  430. for ( size_t i = 0; i < int48_size * 8; ++i ) {
  431. ASSERT_FALSE( splitter.eos());
  432. ASSERT_FALSE( !splitter );
  433. #if CDS_BUILD_BITS == 64
  434. res |= splitter.cut( 1 ) << i;
  435. #else
  436. res |= static_cast<decltype(res)>( splitter.cut( 1 )) << i;
  437. #endif
  438. }
  439. ASSERT_TRUE( splitter.eos());
  440. ASSERT_TRUE( !splitter );
  441. EXPECT_EQ( res, src.to64());
  442. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  443. EXPECT_EQ( splitter.source()->to64(), src.to64());
  444. EXPECT_EQ( splitter.rest_count(), 0u );
  445. EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
  446. }
  447. // random cut
  448. {
  449. for ( size_t k = 0; k < 100; ++k ) {
  450. splitter.reset();
  451. EXPECT_EQ( splitter.source()->to64(), src.to64());
  452. EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
  453. EXPECT_EQ( splitter.bit_offset(), 0u );
  454. res = 0;
  455. size_t shift = 0;
  456. while ( splitter ) {
  457. ASSERT_FALSE( splitter.eos());
  458. ASSERT_FALSE( !splitter );
  459. int bits = std::rand() % 16;
  460. #if CDS_BUILD_BITS == 64
  461. res |= splitter.safe_cut( bits ) << shift;
  462. #else
  463. res |= static_cast<decltype(res)>( splitter.safe_cut( bits )) << shift;
  464. #endif
  465. shift += bits;
  466. }
  467. ASSERT_TRUE( splitter.eos());
  468. ASSERT_TRUE( !splitter );
  469. EXPECT_EQ( res, src.to64());
  470. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  471. EXPECT_EQ( splitter.source()->to64(), src.to64());
  472. EXPECT_EQ( splitter.rest_count(), 0u );
  473. EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
  474. }
  475. }
  476. }
  477. void cut_int48_be()
  478. {
  479. int48 src;
  480. src.n32 = 0xBA987654;
  481. src.n16 = 0x3210;
  482. uint64_t res;
  483. #if CDS_BUILD_BITS == 64
  484. {
  485. typedef cds::algo::split_bitstring< int48, int48_size, size_t > split_bitstring;
  486. split_bitstring splitter( src );
  487. // Trivial case
  488. ASSERT_FALSE( splitter.eos());
  489. ASSERT_FALSE( !splitter );
  490. res = splitter.cut( int48_size * 8 );
  491. ASSERT_EQ( res, src.to64());
  492. ASSERT_TRUE( splitter.eos());
  493. ASSERT_TRUE( !splitter );
  494. EXPECT_EQ( splitter.safe_cut( int48_size * 8 ), 0u );
  495. ASSERT_TRUE( splitter.eos());
  496. ASSERT_TRUE( !splitter );
  497. splitter.reset();
  498. ASSERT_FALSE( splitter.eos());
  499. ASSERT_FALSE( !splitter );
  500. res = splitter.cut( int48_size * 8 );
  501. EXPECT_EQ( res, src.to64());
  502. ASSERT_TRUE( splitter.eos());
  503. ASSERT_TRUE( !splitter );
  504. EXPECT_EQ( splitter.safe_cut( int48_size * 8 ), 0u );
  505. ASSERT_TRUE( splitter.eos());
  506. ASSERT_TRUE( !splitter );
  507. }
  508. #endif
  509. typedef cds::algo::split_bitstring< int48, int48_size, size_t > split_bitstring;
  510. split_bitstring splitter( src );
  511. EXPECT_EQ( splitter.source()->to64(), src.to64());
  512. EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
  513. EXPECT_EQ( splitter.bit_offset(), 0u );
  514. // Cut each hex digit
  515. splitter.reset();
  516. for ( size_t i = 0; i < int48_size * 2; ++i ) {
  517. ASSERT_FALSE( splitter.eos());
  518. ASSERT_FALSE( !splitter );
  519. if ( i % 2 == 0 ) {
  520. EXPECT_EQ( splitter.cut( 4 ), 0x0A - i );
  521. }
  522. else {
  523. EXPECT_EQ( splitter.cut( 4 ), 0x0B - i + 1 );
  524. }
  525. }
  526. ASSERT_TRUE( splitter.eos());
  527. ASSERT_TRUE( !splitter );
  528. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  529. EXPECT_EQ( splitter.source()->to64(), src.to64());
  530. EXPECT_EQ( splitter.rest_count(), 0u );
  531. EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
  532. // by one bit
  533. {
  534. splitter.reset();
  535. EXPECT_EQ( splitter.source()->to64(), src.to64());
  536. EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
  537. EXPECT_EQ( splitter.bit_offset(), 0u );
  538. res = 0;
  539. for ( size_t i = 0; i < int48_size * 8; ++i ) {
  540. ASSERT_FALSE( splitter.eos());
  541. ASSERT_FALSE( !splitter );
  542. #if CDS_BUILD_BITS == 64
  543. if ( i % 8 == 0 )
  544. res = res << 8;
  545. res |= ( splitter.cut( 1 )) << ( i % 8 );
  546. #else
  547. res = ( res << 1 ) | static_cast<decltype(res)>( splitter.cut( 1 ));
  548. #endif
  549. }
  550. ASSERT_TRUE( splitter.eos());
  551. ASSERT_TRUE( !splitter );
  552. EXPECT_EQ( res, src.to64());
  553. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  554. EXPECT_EQ( splitter.source()->to64(), src.to64());
  555. EXPECT_EQ( splitter.rest_count(), 0u );
  556. EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
  557. }
  558. // random cut
  559. /*
  560. {
  561. for ( size_t k = 0; k < 100; ++k ) {
  562. splitter.reset();
  563. EXPECT_EQ( splitter.source()->to64(), src.to64());
  564. EXPECT_EQ( splitter.rest_count(), int48_size * 8 );
  565. EXPECT_EQ( splitter.bit_offset(), 0u );
  566. res = 0;
  567. while ( splitter ) {
  568. ASSERT_FALSE( splitter.eos());
  569. ASSERT_FALSE( !splitter );
  570. unsigned bits = std::rand() % 16;
  571. size_t shift = splitter.rest_count();
  572. if ( shift > bits )
  573. shift = bits;
  574. #if CDS_BUILD_BITS == 64
  575. res = ( res << shift ) | splitter.safe_cut( bits );
  576. #else
  577. res = ( res << shift ) | static_cast<decltype(res)>( splitter.safe_cut( bits ));
  578. #endif
  579. }
  580. ASSERT_TRUE( splitter.eos());
  581. ASSERT_TRUE( !splitter );
  582. EXPECT_EQ( res, src.to64());
  583. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  584. EXPECT_EQ( splitter.source()->to64(), src.to64());
  585. EXPECT_EQ( splitter.rest_count(), 0u );
  586. EXPECT_EQ( splitter.bit_offset(), int48_size * 8 );
  587. }
  588. }
  589. */
  590. }
  591. void cut_byte_le()
  592. {
  593. size_t src = sizeof( src ) == 8 ? 0xFEDCBA9876543210 : 0x76543210;
  594. typedef cds::algo::byte_splitter< size_t > splitter_type;
  595. splitter_type splitter( src );
  596. ASSERT_TRUE( !splitter.eos());
  597. EXPECT_EQ( *splitter.source(), src );
  598. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  599. EXPECT_EQ( splitter.bit_offset(), 0u );
  600. EXPECT_TRUE( splitter.is_correct( 8 ));
  601. EXPECT_FALSE( splitter.is_correct( 4 ));
  602. unsigned expected = 0x10;
  603. for ( unsigned i = 0; i < splitter_type::c_bitstring_size; ++i ) {
  604. auto part = splitter.cut( 8 );
  605. EXPECT_EQ( part, expected );
  606. expected += 0x22;
  607. }
  608. ASSERT_TRUE( splitter.eos());
  609. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  610. EXPECT_EQ( *splitter.source(), src );
  611. EXPECT_EQ( splitter.rest_count(), 0u );
  612. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  613. }
  614. void cut_byte_be()
  615. {
  616. size_t src = sizeof( src ) == 8 ? 0xFEDCBA9876543210 : 0x76543210;
  617. typedef cds::algo::byte_splitter< size_t > splitter_type;
  618. splitter_type splitter( src );
  619. ASSERT_TRUE( !splitter.eos());
  620. EXPECT_EQ( *splitter.source(), src );
  621. EXPECT_EQ( splitter.rest_count(), sizeof( src ) * 8 );
  622. EXPECT_EQ( splitter.bit_offset(), 0u );
  623. EXPECT_TRUE( splitter.is_correct( 8 ));
  624. EXPECT_FALSE( splitter.is_correct( 4 ));
  625. unsigned expected = 0xFE;
  626. for ( unsigned i = 0; i < splitter_type::c_bitstring_size; ++i ) {
  627. auto part = splitter.cut( 8 );
  628. EXPECT_EQ( part, expected );
  629. expected -= 0x22;
  630. }
  631. ASSERT_TRUE( splitter.eos());
  632. EXPECT_EQ( splitter.safe_cut( 8 ), 0u );
  633. EXPECT_EQ( *splitter.source(), src );
  634. EXPECT_EQ( splitter.rest_count(), 0u );
  635. EXPECT_EQ( splitter.bit_offset(), sizeof( src ) * 8 );
  636. }
  637. };
  638. class Split_number: public ::testing::Test
  639. {
  640. protected:
  641. template <typename Int>
  642. void split( Int const n )
  643. {
  644. cds::algo::number_splitter< Int > splitter( n );
  645. // split by hex digit
  646. for ( unsigned count = 4; count < sizeof( Int ) * 8; count += 4 ) {
  647. EXPECT_EQ( splitter.cut( 4 ), static_cast<Int>( count / 4 - 1 ));
  648. }
  649. // random cut
  650. for ( int i = 0; i < 100; ++i ) {
  651. splitter.reset();
  652. EXPECT_EQ( splitter.source(), n );
  653. EXPECT_EQ( splitter.bit_offset(), 0u );
  654. EXPECT_EQ( splitter.rest_count(), sizeof( Int ) * 8 );
  655. unsigned total = 0;
  656. Int result = 0;
  657. while ( total < sizeof( Int ) * 8 ) {
  658. unsigned count = std::rand() % 16;
  659. unsigned shift = count;
  660. if ( total + count > sizeof( Int ) * 8 )
  661. shift = sizeof( Int ) * 8 - total;
  662. result += splitter.safe_cut( count ) << total;
  663. total += shift;
  664. }
  665. EXPECT_EQ( result, n );
  666. EXPECT_EQ( splitter.bit_offset(), sizeof( Int ) * 8 );
  667. EXPECT_EQ( splitter.rest_count(), 0u );
  668. }
  669. }
  670. };
  671. TEST_F( Split_bitstrig, cut_uint )
  672. {
  673. if ( is_big_endian())
  674. cut_uint_be();
  675. else
  676. cut_uint_le();
  677. }
  678. TEST_F( Split_bitstrig, cut_uint16 )
  679. {
  680. if ( is_big_endian())
  681. cut_small_be<uint16_t>();
  682. else
  683. cut_small_le<uint16_t>();
  684. }
  685. TEST_F( Split_bitstrig, cut_int48 )
  686. {
  687. if ( is_big_endian())
  688. cut_int48_be();
  689. else
  690. cut_int48_le();
  691. }
  692. TEST_F( Split_bitstrig, cut_byte )
  693. {
  694. if ( is_big_endian())
  695. cut_byte_be();
  696. else
  697. cut_byte_le();
  698. }
  699. TEST_F( Split_number, split_int )
  700. {
  701. split( (int)0x76543210 );
  702. }
  703. TEST_F( Split_number, split_uint )
  704. {
  705. split( (unsigned)0x76543210 );
  706. }
  707. TEST_F( Split_number, split_short )
  708. {
  709. split( (short int)0x3210 );
  710. }
  711. TEST_F( Split_number, split_ushort )
  712. {
  713. split( (unsigned short)0x3210 );
  714. }
  715. TEST_F( Split_number, split_long )
  716. {
  717. if ( sizeof( long ) == 8 )
  718. split( (long)0xFEDCBA9876543210 );
  719. else
  720. split( (long)0x76543210 );
  721. }
  722. TEST_F( Split_number, split_ulong )
  723. {
  724. if ( sizeof( long ) == 8 )
  725. split( (unsigned long)0xFEDCBA9876543210 );
  726. else
  727. split( (unsigned long)0x76543210 );
  728. }
  729. TEST_F( Split_number, split_int64 )
  730. {
  731. split( (int64_t)0xFEDCBA9876543210 );
  732. }
  733. TEST_F( Split_number, split_uint64 )
  734. {
  735. split( (uint64_t)0xFEDCBA9876543210 );
  736. }
  737. } // namespace