2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "cppunit/cppunit_proxy.h"
33 #include <cds/algo/split_bitstring.h>
35 class Split_bitstrig : public CppUnitMini::TestCase
44 byte_order.ui = 0xFF000001;
46 return byte_order.ch != 0x01;
52 if ( is_big_endian() )
60 if ( is_big_endian() )
61 cut_small_be<uint16_t>();
63 cut_small_le<uint16_t>();
68 CPPUNIT_MSG("little-endian byte order");
70 typedef cds::algo::split_bitstring< size_t > split_bitstring;
72 size_t src = sizeof(src) == 8 ? 0xFEDCBA9876543210 : 0x76543210;
73 split_bitstring splitter(src);
77 CPPUNIT_ASSERT( !splitter.eos() );
78 CPPUNIT_ASSERT( splitter );
79 res = splitter.cut(sizeof(src) * 8);
80 CPPUNIT_ASSERT_EX( res == src, "src=" << src << ", result=" << res );
81 CPPUNIT_ASSERT( splitter.eos() );
82 CPPUNIT_ASSERT( !splitter );
83 CPPUNIT_ASSERT(splitter.safe_cut(sizeof(src) * 8) == 0 );
84 CPPUNIT_ASSERT( splitter.eos() );
85 CPPUNIT_ASSERT( !splitter );
87 CPPUNIT_ASSERT( !splitter.eos() );
88 CPPUNIT_ASSERT( splitter );
89 res = splitter.cut(sizeof(src) * 8);
90 CPPUNIT_ASSERT_EX( res == src, "src=" << src << ", result=" << res );
91 CPPUNIT_ASSERT( splitter.eos() );
92 CPPUNIT_ASSERT( !splitter );
93 CPPUNIT_ASSERT(splitter.safe_cut(sizeof(src) * 8) == 0 );
94 CPPUNIT_ASSERT( splitter.eos() );
95 CPPUNIT_ASSERT( !splitter );
99 for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) {
100 CPPUNIT_ASSERT( !splitter.eos() );
101 CPPUNIT_ASSERT( splitter );
102 CPPUNIT_ASSERT( splitter.cut( 4 ) == i );
104 CPPUNIT_ASSERT( splitter.eos() );
105 CPPUNIT_ASSERT( !splitter );
111 for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) {
112 CPPUNIT_ASSERT( !splitter.eos() );
113 CPPUNIT_ASSERT( splitter );
114 res = res + (splitter.cut( 1 ) << i);
116 CPPUNIT_ASSERT( splitter.eos() );
117 CPPUNIT_ASSERT( !splitter );
118 CPPUNIT_ASSERT( res == src );
123 for ( size_t k = 0; k < 100; ++k ) {
128 CPPUNIT_ASSERT( !splitter.eos() );
129 CPPUNIT_ASSERT( splitter );
130 int bits = rand() % 16;
131 res = res + ( splitter.safe_cut( bits ) << shift );
134 CPPUNIT_ASSERT( splitter.eos() );
135 CPPUNIT_ASSERT( !splitter );
136 CPPUNIT_ASSERT( res == src );
143 CPPUNIT_MSG("big-endian byte order");
145 typedef cds::algo::split_bitstring< size_t > split_bitstring;
147 size_t src = sizeof(src) == 8 ? 0xFEDCBA9876543210 : 0x76543210;
148 split_bitstring splitter(src);
152 CPPUNIT_ASSERT( !splitter.eos() );
153 CPPUNIT_ASSERT( splitter );
154 res = splitter.cut(sizeof(src) * 8);
155 CPPUNIT_ASSERT_EX( res == src, "src=" << src << ", result=" << res );
156 CPPUNIT_ASSERT( splitter.eos() );
157 CPPUNIT_ASSERT( !splitter );
158 CPPUNIT_ASSERT(splitter.safe_cut(sizeof(src) * 8) == 0 );
159 CPPUNIT_ASSERT( splitter.eos() );
160 CPPUNIT_ASSERT( !splitter );
162 CPPUNIT_ASSERT( !splitter.eos() );
163 CPPUNIT_ASSERT( splitter );
164 res = splitter.cut(sizeof(src) * 8);
165 CPPUNIT_ASSERT_EX( res == src, "src=" << src << ", result=" << res );
166 CPPUNIT_ASSERT( splitter.eos() );
167 CPPUNIT_ASSERT( !splitter );
168 CPPUNIT_ASSERT(splitter.safe_cut(sizeof(src) * 8) == 0 );
169 CPPUNIT_ASSERT( splitter.eos() );
170 CPPUNIT_ASSERT( !splitter );
172 // Cut each hex digit
174 for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) {
175 CPPUNIT_ASSERT( !splitter.eos() );
176 CPPUNIT_ASSERT( splitter );
177 CPPUNIT_ASSERT( splitter.cut( 4 ) == 0x0F - i );
179 CPPUNIT_ASSERT( splitter.eos() );
180 CPPUNIT_ASSERT( !splitter );
186 for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) {
187 CPPUNIT_ASSERT( !splitter.eos() );
188 CPPUNIT_ASSERT( splitter );
189 res = (res << 1) + splitter.cut( 1 );
191 CPPUNIT_ASSERT( splitter.eos() );
192 CPPUNIT_ASSERT( !splitter );
193 CPPUNIT_ASSERT( res == src );
198 for ( size_t k = 0; k < 100; ++k ) {
202 CPPUNIT_ASSERT( !splitter.eos() );
203 CPPUNIT_ASSERT( splitter );
204 int bits = rand() % 16;
205 res = (res << bits) + splitter.safe_cut( bits );
207 CPPUNIT_ASSERT( splitter.eos() );
208 CPPUNIT_ASSERT( !splitter );
209 CPPUNIT_ASSERT( res == src );
216 template <typename PartUInt>
219 CPPUNIT_MSG("little-endian byte order");
220 typedef PartUInt part_uint;
222 typedef cds::algo::split_bitstring< uint64_t, part_uint > split_bitstring;
224 uint64_t src = 0xFEDCBA9876543210;
225 split_bitstring splitter(src);
228 // Cut each hex digit
230 for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) {
231 CPPUNIT_ASSERT( !splitter.eos() );
232 CPPUNIT_ASSERT( splitter );
233 CPPUNIT_ASSERT( static_cast<size_t>(splitter.cut( 4 )) == i );
235 CPPUNIT_ASSERT( splitter.eos() );
236 CPPUNIT_ASSERT( !splitter );
242 for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) {
243 CPPUNIT_ASSERT( !splitter.eos() );
244 CPPUNIT_ASSERT( splitter );
245 res = res + ( static_cast<uint64_t>(splitter.cut( 1 )) << i);
247 CPPUNIT_ASSERT( splitter.eos() );
248 CPPUNIT_ASSERT( !splitter );
249 CPPUNIT_ASSERT( res == src );
254 for ( size_t k = 0; k < 100; ++k ) {
259 CPPUNIT_ASSERT( !splitter.eos() );
260 CPPUNIT_ASSERT( splitter );
261 int bits = rand() % 16;
262 res = res + ( static_cast<uint64_t>(splitter.safe_cut( bits )) << shift );
265 CPPUNIT_ASSERT( splitter.eos() );
266 CPPUNIT_ASSERT( !splitter );
267 CPPUNIT_ASSERT( res == src );
272 template <typename PartUInt>
275 CPPUNIT_MSG("big-endian byte order");
276 typedef PartUInt part_uint;
278 typedef cds::algo::split_bitstring< uint64_t, part_uint > split_bitstring;
280 uint64_t src = 0xFEDCBA9876543210;
281 split_bitstring splitter(src);
284 // Cut each hex digit
286 for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) {
287 CPPUNIT_ASSERT( !splitter.eos() );
288 CPPUNIT_ASSERT( splitter );
289 CPPUNIT_ASSERT( splitter.cut( 4 ) == 0x0F - i );
291 CPPUNIT_ASSERT( splitter.eos() );
292 CPPUNIT_ASSERT( !splitter );
298 for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) {
299 CPPUNIT_ASSERT( !splitter.eos() );
300 CPPUNIT_ASSERT( splitter );
301 res = (res << 1) + splitter.cut( 1 );
303 CPPUNIT_ASSERT( splitter.eos() );
304 CPPUNIT_ASSERT( !splitter );
305 CPPUNIT_ASSERT( res == src );
310 for ( size_t k = 0; k < 100; ++k ) {
314 CPPUNIT_ASSERT( !splitter.eos() );
315 CPPUNIT_ASSERT( splitter );
316 int bits = rand() % 16;
317 res = (res << bits) + splitter.safe_cut( bits );
319 CPPUNIT_ASSERT( splitter.eos() );
320 CPPUNIT_ASSERT( !splitter );
321 CPPUNIT_ASSERT( res == src );
327 CPPUNIT_TEST_SUITE(Split_bitstrig);
328 CPPUNIT_TEST(cut_uint)
329 CPPUNIT_TEST(cut_uint16)
330 CPPUNIT_TEST_SUITE_END();
333 CPPUNIT_TEST_SUITE_REGISTRATION(Split_bitstrig);