35 #include <unordered_set>
36 #include "DGtal/kernel/PointVector.h"
37 #include "DGtal/kernel/UnorderedSetByBlock.h"
38 #include "DGtalCatch.h"
42 using namespace DGtal;
44 template <
typename Po
int >
49 p[ i ] = (rand() % S) - S/2;
58 SCENARIO(
"UnorderedSetByBlock< PointVector< 2, int > unit tests with 32 bits blocks",
"[unorderedsetbyblock][2d]" )
61 typedef std::unordered_set< Point > StdUnorderedSet;
64 const size_t nb_inserted = 100;
65 const size_t nb_sought = 200;
66 const size_t nb_erased = 100;
68 StdUnorderedSet stdSet;
69 BlockUnorderedSet blkSet;
70 for (
size_t i = 0; i < nb_inserted; i++ )
72 Point p = randomPoint<Point>( 10 );
76 WHEN(
"Inserting identical elements in std::unordered_set<> and in UnorderedSetByBlock<>, they contains the same number of elements" ) {
77 REQUIRE( blkSet.size() <= nb_inserted );
78 REQUIRE( blkSet.size() == stdSet.size() );
80 WHEN(
"Cloning identical std::unordered_set<> and UnorderedSetByBlock<>, they contains the same number of elements" ) {
81 StdUnorderedSet stdSet2( stdSet );
82 BlockUnorderedSet blkSet2( blkSet );
83 REQUIRE( blkSet2.size() == blkSet.size() );
84 REQUIRE( blkSet2.size() == stdSet2.size() );
86 WHEN(
"Traversing identical std::unordered_set<> and UnorderedSetByBlock<>, they traverse the same elements" ) {
87 std::vector< Point > stdTrv;
88 std::vector< Point > blkTrv;
89 for (
auto&& p : stdSet ) stdTrv.push_back( p );
90 for (
auto&& p : blkSet ) blkTrv.push_back( p );
91 REQUIRE( blkTrv.size() == stdTrv.size() );
92 std::sort( stdTrv.begin(), stdTrv.end() );
93 std::sort( blkTrv.begin(), blkTrv.end() );
94 REQUIRE( std::equal( stdTrv.cbegin(), stdTrv.cend(), blkTrv.cbegin() ) );
96 WHEN(
"Looking for elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are find with method `count`" ) {
97 std::vector< Point > stdFound, stdNotFound;
98 std::vector< Point > blkFound, blkNotFound;
99 for (
size_t i = 0; i < nb_sought; i++ )
101 Point p = randomPoint<Point>( 10 );
102 if ( stdSet.count( p ) != 0 ) stdFound.push_back( p );
103 else stdNotFound.push_back( p );
104 if ( blkSet.count( p ) != 0 ) blkFound.push_back( p );
105 else blkNotFound.push_back( p );
107 REQUIRE( blkFound .size() == stdFound .size() );
108 REQUIRE( blkNotFound.size() == stdNotFound.size() );
109 std::sort( stdFound .begin(), stdFound .end() );
110 std::sort( stdNotFound.begin(), stdNotFound.end() );
111 std::sort( blkFound .begin(), blkFound .end() );
112 std::sort( blkNotFound.begin(), blkNotFound.end() );
113 REQUIRE( std::equal( stdFound.cbegin(), stdFound.cend(),
114 blkFound.cbegin() ) );
115 REQUIRE( std::equal( stdNotFound.cbegin(), stdNotFound.cend(),
116 blkNotFound.cbegin() ) );
118 WHEN(
"Looking for elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are find with method `find`" ) {
119 std::vector< Point > stdFound, stdNotFound;
120 std::vector< Point > blkFound, blkNotFound;
121 size_t std_nb_value_ok = 0;
122 size_t blk_nb_value_ok = 0;
123 for (
size_t i = 0; i < nb_sought; i++ )
125 Point p = randomPoint<Point>( 10 );
126 const auto stdIt = stdSet.find( p );
127 if ( stdIt != stdSet.end() )
129 stdFound.push_back( p );
130 std_nb_value_ok += ( *stdIt == p ) ? 1 : 0;
132 else stdNotFound.push_back( p );
133 const auto blkIt = blkSet.find( p );
134 if ( blkIt != blkSet.end() )
136 blkFound.push_back( p );
137 blk_nb_value_ok += ( *blkIt == p ) ? 1 : 0;
139 else blkNotFound.push_back( p );
141 REQUIRE( blkFound .size() == stdFound .size() );
142 REQUIRE( blkNotFound.size() == stdNotFound.size() );
143 std::sort( stdFound .begin(), stdFound .end() );
144 std::sort( stdNotFound.begin(), stdNotFound.end() );
145 std::sort( blkFound .begin(), blkFound .end() );
146 std::sort( blkNotFound.begin(), blkNotFound.end() );
147 REQUIRE( std::equal( stdFound.cbegin(), stdFound.cend(),
148 blkFound.cbegin() ) );
149 REQUIRE( std::equal( stdNotFound.cbegin(), stdNotFound.cend(),
150 blkNotFound.cbegin() ) );
151 REQUIRE( std_nb_value_ok == stdFound.size() );
152 REQUIRE( blk_nb_value_ok == std_nb_value_ok );
153 REQUIRE( blk_nb_value_ok == blkFound.size() );
155 WHEN(
"Erasing elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are left" ) {
156 std::vector< Point > stdErase;
157 std::vector< Point > blkErase;
158 size_t std_nb_erase_ok = 0;
159 size_t blk_nb_erase_ok = 0;
160 for (
size_t i = 0; i < nb_erased; i++ )
162 Point p = randomPoint<Point>( 10 );
163 auto stdFindIt = stdSet.find ( p );
164 auto stdIsErased = stdSet.erase( p );
165 if ( stdFindIt != stdSet.cend() )
167 std_nb_erase_ok += ( stdIsErased != 0 ) ? 1 : 0;
168 stdErase.push_back( p );
170 else std_nb_erase_ok += ( stdIsErased == 0 ) ? 1 : 0;
171 auto blkFindIt = blkSet.find ( p );
172 auto blkIsErased = blkSet.erase( p );
173 if ( blkFindIt != blkSet.cend() )
175 blk_nb_erase_ok += ( blkIsErased != 0 ) ? 1 : 0;
176 blkErase.push_back( p );
178 else blk_nb_erase_ok += ( blkIsErased == 0 ) ? 1 : 0;
180 REQUIRE( blkSet .size() == stdSet .size() );
181 REQUIRE( blkErase.size() == stdErase.size() );
182 REQUIRE( blk_nb_erase_ok == std_nb_erase_ok );
183 std::vector< Point > stdTrv;
184 std::vector< Point > blkTrv;
185 for (
auto&& p : stdSet ) stdTrv.push_back( p );
186 for (
auto&& p : blkSet ) blkTrv.push_back( p );
187 REQUIRE( blkTrv.size() == stdTrv.size() );
188 std::sort( stdTrv.begin(), stdTrv.end() );
189 std::sort( blkTrv.begin(), blkTrv.end() );
190 REQUIRE( std::equal( stdTrv.cbegin(), stdTrv.cend(), blkTrv.cbegin() ) );
192 WHEN(
"Erasing a range in identical std::unordered_set<> and UnorderedSetByBlock<>, the same number of elements is left" ) {
193 auto nb_std_before = stdSet.size();
194 auto nb_blk_before = blkSet.size();
195 auto stdItB = stdSet.begin(); std::advance( stdItB, 10 );
196 auto blkItB = blkSet.begin(); std::advance( blkItB, 10 );
197 auto stdItE = stdItB; std::advance( stdItE, 20 );
198 auto blkItE = blkItB; std::advance( blkItE, 20 );
199 stdSet.erase( stdItB, stdItE );
200 blkSet.erase( blkItB, blkItE );
201 size_t nb_std = std::distance(stdSet.begin(), stdSet.end());
202 size_t nb_blk = std::distance(blkSet.begin(), blkSet.end());
203 REQUIRE( stdSet.size() == nb_std );
204 REQUIRE( stdSet.size() == nb_std_before - 20 );
205 REQUIRE( blkSet.size() == nb_blk );
206 REQUIRE( blkSet.size() == nb_blk_before - 20 );
207 REQUIRE( blkSet.size() == stdSet.size() );
209 THEN(
"The memory usage of UnorderedSetByBlock<> is inferior to the one of std::unordered_set<>" ) {
210 const auto stdMem = blkSet.memory_usage_unordered_set();
211 const auto blkMem = blkSet.memory_usage();
216 THEN(
"Conparisons and valid assignments between iterator and const_iterator should be seamless for the user" ) {
217 BlockUnorderedSet::iterator itB = blkSet.begin();
218 BlockUnorderedSet::const_iterator citB = blkSet.begin();
219 BlockUnorderedSet::const_iterator citBp = blkSet.cbegin();
220 BlockUnorderedSet::iterator itE = blkSet.end();
221 BlockUnorderedSet::const_iterator citE = blkSet.end();
222 BlockUnorderedSet::const_iterator citEp = blkSet.cend();
223 REQUIRE( itB == blkSet.begin() );
224 REQUIRE( itB == blkSet.cbegin() );
225 REQUIRE( citB == blkSet.begin() );
226 REQUIRE( citB == blkSet.cbegin() );
227 REQUIRE( citBp == blkSet.cbegin() );
228 REQUIRE( itE == blkSet.end() );
229 REQUIRE( itE == blkSet.cend() );
230 REQUIRE( citE == blkSet.end() );
231 REQUIRE( citE == blkSet.cend() );
232 REQUIRE( citEp == blkSet.cend() );
246 SCENARIO(
"UnorderedSetByBlock< PointVector< 3, int64 > unit tests with 32 bits blocks",
"[unorderedsetbyblock][3d]" )
249 typedef std::unordered_set< Point > StdUnorderedSet;
252 const size_t nb_inserted = 1000;
253 const size_t nb_sought = 2000;
254 const size_t nb_erased = 1000;
256 StdUnorderedSet stdSet;
257 BlockUnorderedSet blkSet;
258 for (
size_t i = 0; i < nb_inserted; i++ )
260 Point p = randomPoint<Point>( 10 );
264 WHEN(
"Inserting identical elements in std::unordered_set<> and in UnorderedSetByBlock<>, they contains the same number of elements" ) {
265 REQUIRE( blkSet.size() <= nb_inserted );
266 REQUIRE( blkSet.size() == stdSet.size() );
268 WHEN(
"Cloning identical std::unordered_set<> and UnorderedSetByBlock<>, they contains the same number of elements" ) {
269 StdUnorderedSet stdSet2( stdSet );
270 BlockUnorderedSet blkSet2( blkSet );
271 REQUIRE( blkSet2.size() == blkSet.size() );
272 REQUIRE( blkSet2.size() == stdSet2.size() );
274 WHEN(
"Traversing identical std::unordered_set<> and UnorderedSetByBlock<>, they traverse the same elements" ) {
275 std::vector< Point > stdTrv;
276 std::vector< Point > blkTrv;
277 for (
auto&& p : stdSet ) stdTrv.push_back( p );
278 for (
auto&& p : blkSet ) blkTrv.push_back( p );
279 REQUIRE( blkTrv.size() == stdTrv.size() );
280 std::sort( stdTrv.begin(), stdTrv.end() );
281 std::sort( blkTrv.begin(), blkTrv.end() );
282 REQUIRE( std::equal( stdTrv.cbegin(), stdTrv.cend(), blkTrv.cbegin() ) );
284 WHEN(
"Looking for elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are find with method `count`" ) {
285 std::vector< Point > stdFound, stdNotFound;
286 std::vector< Point > blkFound, blkNotFound;
287 for (
size_t i = 0; i < nb_sought; i++ )
289 Point p = randomPoint<Point>( 10 );
290 if ( stdSet.count( p ) != 0 ) stdFound.push_back( p );
291 else stdNotFound.push_back( p );
292 if ( blkSet.count( p ) != 0 ) blkFound.push_back( p );
293 else blkNotFound.push_back( p );
295 REQUIRE( blkFound .size() == stdFound .size() );
296 REQUIRE( blkNotFound.size() == stdNotFound.size() );
297 std::sort( stdFound .begin(), stdFound .end() );
298 std::sort( stdNotFound.begin(), stdNotFound.end() );
299 std::sort( blkFound .begin(), blkFound .end() );
300 std::sort( blkNotFound.begin(), blkNotFound.end() );
301 REQUIRE( std::equal( stdFound.cbegin(), stdFound.cend(),
302 blkFound.cbegin() ) );
303 REQUIRE( std::equal( stdNotFound.cbegin(), stdNotFound.cend(),
304 blkNotFound.cbegin() ) );
306 WHEN(
"Looking for elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are find with method `find`" ) {
307 std::vector< Point > stdFound, stdNotFound;
308 std::vector< Point > blkFound, blkNotFound;
309 size_t std_nb_value_ok = 0;
310 size_t blk_nb_value_ok = 0;
311 for (
size_t i = 0; i < nb_sought; i++ )
313 Point p = randomPoint<Point>( 10 );
314 const auto stdIt = stdSet.find( p );
315 if ( stdIt != stdSet.end() )
317 stdFound.push_back( p );
318 std_nb_value_ok += ( *stdIt == p ) ? 1 : 0;
320 else stdNotFound.push_back( p );
321 const auto blkIt = blkSet.find( p );
322 if ( blkIt != blkSet.end() )
324 blkFound.push_back( p );
325 blk_nb_value_ok += ( *blkIt == p ) ? 1 : 0;
327 else blkNotFound.push_back( p );
329 REQUIRE( blkFound .size() == stdFound .size() );
330 REQUIRE( blkNotFound.size() == stdNotFound.size() );
331 std::sort( stdFound .begin(), stdFound .end() );
332 std::sort( stdNotFound.begin(), stdNotFound.end() );
333 std::sort( blkFound .begin(), blkFound .end() );
334 std::sort( blkNotFound.begin(), blkNotFound.end() );
335 REQUIRE( std::equal( stdFound.cbegin(), stdFound.cend(),
336 blkFound.cbegin() ) );
337 REQUIRE( std::equal( stdNotFound.cbegin(), stdNotFound.cend(),
338 blkNotFound.cbegin() ) );
339 REQUIRE( std_nb_value_ok == stdFound.size() );
340 REQUIRE( blk_nb_value_ok == std_nb_value_ok );
341 REQUIRE( blk_nb_value_ok == blkFound.size() );
343 WHEN(
"Erasing elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are left" ) {
344 std::vector< Point > stdErase;
345 std::vector< Point > blkErase;
346 size_t std_nb_erase_ok = 0;
347 size_t blk_nb_erase_ok = 0;
348 for (
size_t i = 0; i < nb_erased; i++ )
350 Point p = randomPoint<Point>( 10 );
351 auto stdFindIt = stdSet.find ( p );
352 auto stdIsErased = stdSet.erase( p );
353 if ( stdFindIt != stdSet.cend() )
355 std_nb_erase_ok += ( stdIsErased != 0 ) ? 1 : 0;
356 stdErase.push_back( p );
358 else std_nb_erase_ok += ( stdIsErased == 0 ) ? 1 : 0;
359 auto blkFindIt = blkSet.find ( p );
360 auto blkIsErased = blkSet.erase( p );
361 if ( blkFindIt != blkSet.cend() )
363 blk_nb_erase_ok += ( blkIsErased != 0 ) ? 1 : 0;
364 blkErase.push_back( p );
366 else blk_nb_erase_ok += ( blkIsErased == 0 ) ? 1 : 0;
368 REQUIRE( blkSet .size() == stdSet .size() );
369 REQUIRE( blkErase.size() == stdErase.size() );
370 REQUIRE( blk_nb_erase_ok == std_nb_erase_ok );
371 std::vector< Point > stdTrv;
372 std::vector< Point > blkTrv;
373 for (
auto&& p : stdSet ) stdTrv.push_back( p );
374 for (
auto&& p : blkSet ) blkTrv.push_back( p );
375 REQUIRE( blkTrv.size() == stdTrv.size() );
376 std::sort( stdTrv.begin(), stdTrv.end() );
377 std::sort( blkTrv.begin(), blkTrv.end() );
378 REQUIRE( std::equal( stdTrv.cbegin(), stdTrv.cend(), blkTrv.cbegin() ) );
380 WHEN(
"Erasing a range in identical std::unordered_set<> and UnorderedSetByBlock<>, the same number of elements is left" ) {
381 auto nb_std_before = stdSet.size();
382 auto nb_blk_before = blkSet.size();
383 auto stdItB = stdSet.begin(); std::advance( stdItB, 10 );
384 auto blkItB = blkSet.begin(); std::advance( blkItB, 10 );
385 auto stdItE = stdItB; std::advance( stdItE, 20 );
386 auto blkItE = blkItB; std::advance( blkItE, 20 );
387 stdSet.erase( stdItB, stdItE );
388 blkSet.erase( blkItB, blkItE );
389 size_t nb_std = std::distance(stdSet.begin(), stdSet.end());
390 size_t nb_blk = std::distance(blkSet.begin(), blkSet.end());
391 REQUIRE( stdSet.size() == nb_std );
392 REQUIRE( stdSet.size() == nb_std_before - 20 );
393 REQUIRE( blkSet.size() == nb_blk );
394 REQUIRE( blkSet.size() == nb_blk_before - 20 );
395 REQUIRE( blkSet.size() == stdSet.size() );
397 THEN(
"The memory usage of UnorderedSetByBlock<> is inferior to the one of std::unordered_set<>" ) {
398 const auto stdMem = blkSet.memory_usage_unordered_set();
399 const auto blkMem = blkSet.memory_usage();
404 THEN(
"Conparisons and valid assignments between iterator and const_iterator should be seamless for the user" ) {
405 BlockUnorderedSet::iterator itB = blkSet.begin();
406 BlockUnorderedSet::const_iterator citB = blkSet.begin();
407 BlockUnorderedSet::const_iterator citBp = blkSet.cbegin();
408 BlockUnorderedSet::iterator itE = blkSet.end();
409 BlockUnorderedSet::const_iterator citE = blkSet.end();
410 BlockUnorderedSet::const_iterator citEp = blkSet.cend();
411 REQUIRE( itB == blkSet.begin() );
412 REQUIRE( itB == blkSet.cbegin() );
413 REQUIRE( citB == blkSet.begin() );
414 REQUIRE( citB == blkSet.cbegin() );
415 REQUIRE( citBp == blkSet.cbegin() );
416 REQUIRE( itE == blkSet.end() );
417 REQUIRE( itE == blkSet.cend() );
418 REQUIRE( citE == blkSet.end() );
419 REQUIRE( citE == blkSet.cend() );
420 REQUIRE( citEp == blkSet.cend() );
433 SCENARIO(
"UnorderedSetByBlock< PointVector< 2, int > unit tests with 64 bits blocks",
"[unorderedsetbyblock][2d]" )
436 typedef std::unordered_set< Point > StdUnorderedSet;
440 const size_t nb_inserted = 10000;
441 const size_t nb_sought = 200;
442 const size_t nb_erased = 100;
444 StdUnorderedSet stdSet;
445 BlockUnorderedSet blkSet;
446 for (
size_t i = 0; i < nb_inserted; i++ )
448 Point p = randomPoint<Point>( 200 );
452 WHEN(
"Inserting identical elements in std::unordered_set<> and in UnorderedSetByBlock<>, they contains the same number of elements" ) {
453 REQUIRE( blkSet.size() <= nb_inserted );
454 REQUIRE( blkSet.size() == stdSet.size() );
456 WHEN(
"Cloning identical std::unordered_set<> and UnorderedSetByBlock<>, they contains the same number of elements" ) {
457 StdUnorderedSet stdSet2( stdSet );
458 BlockUnorderedSet blkSet2( blkSet );
459 REQUIRE( blkSet2.size() == blkSet.size() );
460 REQUIRE( blkSet2.size() == stdSet2.size() );
462 WHEN(
"Traversing identical std::unordered_set<> and UnorderedSetByBlock<>, they traverse the same elements" ) {
463 std::vector< Point > stdTrv;
464 std::vector< Point > blkTrv;
465 for (
auto&& p : stdSet ) stdTrv.push_back( p );
466 for (
auto&& p : blkSet ) blkTrv.push_back( p );
467 REQUIRE( blkTrv.size() == stdTrv.size() );
468 std::sort( stdTrv.begin(), stdTrv.end() );
469 std::sort( blkTrv.begin(), blkTrv.end() );
470 REQUIRE( std::equal( stdTrv.cbegin(), stdTrv.cend(), blkTrv.cbegin() ) );
472 WHEN(
"Looking for elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are find with method `count`" ) {
473 std::vector< Point > stdFound, stdNotFound;
474 std::vector< Point > blkFound, blkNotFound;
475 for (
size_t i = 0; i < nb_sought; i++ )
477 Point p = randomPoint<Point>( 10 );
478 if ( stdSet.count( p ) != 0 ) stdFound.push_back( p );
479 else stdNotFound.push_back( p );
480 if ( blkSet.count( p ) != 0 ) blkFound.push_back( p );
481 else blkNotFound.push_back( p );
483 REQUIRE( blkFound .size() == stdFound .size() );
484 REQUIRE( blkNotFound.size() == stdNotFound.size() );
485 std::sort( stdFound .begin(), stdFound .end() );
486 std::sort( stdNotFound.begin(), stdNotFound.end() );
487 std::sort( blkFound .begin(), blkFound .end() );
488 std::sort( blkNotFound.begin(), blkNotFound.end() );
489 REQUIRE( std::equal( stdFound.cbegin(), stdFound.cend(),
490 blkFound.cbegin() ) );
491 REQUIRE( std::equal( stdNotFound.cbegin(), stdNotFound.cend(),
492 blkNotFound.cbegin() ) );
494 WHEN(
"Looking for elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are find with method `find`" ) {
495 std::vector< Point > stdFound, stdNotFound;
496 std::vector< Point > blkFound, blkNotFound;
497 size_t std_nb_value_ok = 0;
498 size_t blk_nb_value_ok = 0;
499 for (
size_t i = 0; i < nb_sought; i++ )
501 Point p = randomPoint<Point>( 10 );
502 const auto stdIt = stdSet.find( p );
503 if ( stdIt != stdSet.end() )
505 stdFound.push_back( p );
506 std_nb_value_ok += ( *stdIt == p ) ? 1 : 0;
508 else stdNotFound.push_back( p );
509 const auto blkIt = blkSet.find( p );
510 if ( blkIt != blkSet.end() )
512 blkFound.push_back( p );
513 blk_nb_value_ok += ( *blkIt == p ) ? 1 : 0;
515 else blkNotFound.push_back( p );
517 REQUIRE( blkFound .size() == stdFound .size() );
518 REQUIRE( blkNotFound.size() == stdNotFound.size() );
519 std::sort( stdFound .begin(), stdFound .end() );
520 std::sort( stdNotFound.begin(), stdNotFound.end() );
521 std::sort( blkFound .begin(), blkFound .end() );
522 std::sort( blkNotFound.begin(), blkNotFound.end() );
523 REQUIRE( std::equal( stdFound.cbegin(), stdFound.cend(),
524 blkFound.cbegin() ) );
525 REQUIRE( std::equal( stdNotFound.cbegin(), stdNotFound.cend(),
526 blkNotFound.cbegin() ) );
527 REQUIRE( std_nb_value_ok == stdFound.size() );
528 REQUIRE( blk_nb_value_ok == std_nb_value_ok );
529 REQUIRE( blk_nb_value_ok == blkFound.size() );
531 WHEN(
"Erasing elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are left" ) {
532 std::vector< Point > stdErase;
533 std::vector< Point > blkErase;
534 size_t std_nb_erase_ok = 0;
535 size_t blk_nb_erase_ok = 0;
536 for (
size_t i = 0; i < nb_erased; i++ )
538 Point p = randomPoint<Point>( 10 );
539 auto stdFindIt = stdSet.find ( p );
540 auto stdIsErased = stdSet.erase( p );
541 if ( stdFindIt != stdSet.cend() )
543 std_nb_erase_ok += ( stdIsErased != 0 ) ? 1 : 0;
544 stdErase.push_back( p );
546 else std_nb_erase_ok += ( stdIsErased == 0 ) ? 1 : 0;
547 auto blkFindIt = blkSet.find ( p );
548 auto blkIsErased = blkSet.erase( p );
549 if ( blkFindIt != blkSet.cend() )
551 blk_nb_erase_ok += ( blkIsErased != 0 ) ? 1 : 0;
552 blkErase.push_back( p );
554 else blk_nb_erase_ok += ( blkIsErased == 0 ) ? 1 : 0;
556 REQUIRE( blkSet .size() == stdSet .size() );
557 REQUIRE( blkErase.size() == stdErase.size() );
558 REQUIRE( blk_nb_erase_ok == std_nb_erase_ok );
559 std::vector< Point > stdTrv;
560 std::vector< Point > blkTrv;
561 for (
auto&& p : stdSet ) stdTrv.push_back( p );
562 for (
auto&& p : blkSet ) blkTrv.push_back( p );
563 REQUIRE( blkTrv.size() == stdTrv.size() );
564 std::sort( stdTrv.begin(), stdTrv.end() );
565 std::sort( blkTrv.begin(), blkTrv.end() );
566 REQUIRE( std::equal( stdTrv.cbegin(), stdTrv.cend(), blkTrv.cbegin() ) );
568 WHEN(
"Erasing a range in identical std::unordered_set<> and UnorderedSetByBlock<>, the same number of elements is left" ) {
569 auto nb_std_before = stdSet.size();
570 auto nb_blk_before = blkSet.size();
571 auto stdItB = stdSet.begin(); std::advance( stdItB, 10 );
572 auto blkItB = blkSet.begin(); std::advance( blkItB, 10 );
573 auto stdItE = stdItB; std::advance( stdItE, 20 );
574 auto blkItE = blkItB; std::advance( blkItE, 20 );
575 stdSet.erase( stdItB, stdItE );
576 blkSet.erase( blkItB, blkItE );
577 size_t nb_std = std::distance(stdSet.begin(), stdSet.end());
578 size_t nb_blk = std::distance(blkSet.begin(), blkSet.end());
579 REQUIRE( stdSet.size() == nb_std );
580 REQUIRE( stdSet.size() == nb_std_before - 20 );
581 REQUIRE( blkSet.size() == nb_blk );
582 REQUIRE( blkSet.size() == nb_blk_before - 20 );
583 REQUIRE( blkSet.size() == stdSet.size() );
585 THEN(
"The memory usage of UnorderedSetByBlock<> is inferior to the one of std::unordered_set<>" ) {
586 const auto stdMem = blkSet.memory_usage_unordered_set();
587 const auto blkMem = blkSet.memory_usage();
592 THEN(
"Conparisons and valid assignments between iterator and const_iterator should be seamless for the user" ) {
593 BlockUnorderedSet::iterator itB = blkSet.begin();
594 BlockUnorderedSet::const_iterator citB = blkSet.begin();
595 BlockUnorderedSet::const_iterator citBp = blkSet.cbegin();
596 BlockUnorderedSet::iterator itE = blkSet.end();
597 BlockUnorderedSet::const_iterator citE = blkSet.end();
598 BlockUnorderedSet::const_iterator citEp = blkSet.cend();
599 REQUIRE( itB == blkSet.begin() );
600 REQUIRE( itB == blkSet.cbegin() );
601 REQUIRE( citB == blkSet.begin() );
602 REQUIRE( citB == blkSet.cbegin() );
603 REQUIRE( citBp == blkSet.cbegin() );
604 REQUIRE( itE == blkSet.end() );
605 REQUIRE( itE == blkSet.cend() );
606 REQUIRE( citE == blkSet.end() );
607 REQUIRE( citE == blkSet.cend() );
608 REQUIRE( citEp == blkSet.cend() );
622 SCENARIO(
"UnorderedSetByBlock< PointVector< 3, int64 > unit tests with 64 bits blocks",
"[unorderedsetbyblock][3d]" )
625 typedef std::unordered_set< Point > StdUnorderedSet;
629 const size_t nb_inserted = 40000;
630 const size_t nb_sought = 2000;
631 const size_t nb_erased = 1000;
633 StdUnorderedSet stdSet;
634 BlockUnorderedSet blkSet;
635 for (
size_t i = 0; i < nb_inserted; i++ )
637 Point p = randomPoint<Point>( 100 );
641 WHEN(
"Inserting identical elements in std::unordered_set<> and in UnorderedSetByBlock<>, they contains the same number of elements" ) {
642 REQUIRE( blkSet.size() <= nb_inserted );
643 REQUIRE( blkSet.size() == stdSet.size() );
645 WHEN(
"Cloning identical std::unordered_set<> and UnorderedSetByBlock<>, they contains the same number of elements" ) {
646 StdUnorderedSet stdSet2( stdSet );
647 BlockUnorderedSet blkSet2( blkSet );
648 REQUIRE( blkSet2.size() == blkSet.size() );
649 REQUIRE( blkSet2.size() == stdSet2.size() );
651 WHEN(
"Traversing identical std::unordered_set<> and UnorderedSetByBlock<>, they traverse the same elements" ) {
652 std::vector< Point > stdTrv;
653 std::vector< Point > blkTrv;
654 for (
auto&& p : stdSet ) stdTrv.push_back( p );
655 for (
auto&& p : blkSet ) blkTrv.push_back( p );
656 REQUIRE( blkTrv.size() == stdTrv.size() );
657 std::sort( stdTrv.begin(), stdTrv.end() );
658 std::sort( blkTrv.begin(), blkTrv.end() );
659 REQUIRE( std::equal( stdTrv.cbegin(), stdTrv.cend(), blkTrv.cbegin() ) );
661 WHEN(
"Looking for elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are find with method `count`" ) {
662 std::vector< Point > stdFound, stdNotFound;
663 std::vector< Point > blkFound, blkNotFound;
664 for (
size_t i = 0; i < nb_sought; i++ )
666 Point p = randomPoint<Point>( 10 );
667 if ( stdSet.count( p ) != 0 ) stdFound.push_back( p );
668 else stdNotFound.push_back( p );
669 if ( blkSet.count( p ) != 0 ) blkFound.push_back( p );
670 else blkNotFound.push_back( p );
672 REQUIRE( blkFound .size() == stdFound .size() );
673 REQUIRE( blkNotFound.size() == stdNotFound.size() );
674 std::sort( stdFound .begin(), stdFound .end() );
675 std::sort( stdNotFound.begin(), stdNotFound.end() );
676 std::sort( blkFound .begin(), blkFound .end() );
677 std::sort( blkNotFound.begin(), blkNotFound.end() );
678 REQUIRE( std::equal( stdFound.cbegin(), stdFound.cend(),
679 blkFound.cbegin() ) );
680 REQUIRE( std::equal( stdNotFound.cbegin(), stdNotFound.cend(),
681 blkNotFound.cbegin() ) );
683 WHEN(
"Looking for elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are find with method `find`" ) {
684 std::vector< Point > stdFound, stdNotFound;
685 std::vector< Point > blkFound, blkNotFound;
686 size_t std_nb_value_ok = 0;
687 size_t blk_nb_value_ok = 0;
688 for (
size_t i = 0; i < nb_sought; i++ )
690 Point p = randomPoint<Point>( 10 );
691 const auto stdIt = stdSet.find( p );
692 if ( stdIt != stdSet.end() )
694 stdFound.push_back( p );
695 std_nb_value_ok += ( *stdIt == p ) ? 1 : 0;
697 else stdNotFound.push_back( p );
698 const auto blkIt = blkSet.find( p );
699 if ( blkIt != blkSet.end() )
701 blkFound.push_back( p );
702 blk_nb_value_ok += ( *blkIt == p ) ? 1 : 0;
704 else blkNotFound.push_back( p );
706 REQUIRE( blkFound .size() == stdFound .size() );
707 REQUIRE( blkNotFound.size() == stdNotFound.size() );
708 std::sort( stdFound .begin(), stdFound .end() );
709 std::sort( stdNotFound.begin(), stdNotFound.end() );
710 std::sort( blkFound .begin(), blkFound .end() );
711 std::sort( blkNotFound.begin(), blkNotFound.end() );
712 REQUIRE( std::equal( stdFound.cbegin(), stdFound.cend(),
713 blkFound.cbegin() ) );
714 REQUIRE( std::equal( stdNotFound.cbegin(), stdNotFound.cend(),
715 blkNotFound.cbegin() ) );
716 REQUIRE( std_nb_value_ok == stdFound.size() );
717 REQUIRE( blk_nb_value_ok == std_nb_value_ok );
718 REQUIRE( blk_nb_value_ok == blkFound.size() );
720 WHEN(
"Erasing elements in identical std::unordered_set<> and UnorderedSetByBlock<>, the same elements are left" ) {
721 std::vector< Point > stdErase;
722 std::vector< Point > blkErase;
723 size_t std_nb_erase_ok = 0;
724 size_t blk_nb_erase_ok = 0;
725 for (
size_t i = 0; i < nb_erased; i++ )
727 Point p = randomPoint<Point>( 10 );
728 auto stdFindIt = stdSet.find ( p );
729 auto stdIsErased = stdSet.erase( p );
730 if ( stdFindIt != stdSet.cend() )
732 std_nb_erase_ok += ( stdIsErased != 0 ) ? 1 : 0;
733 stdErase.push_back( p );
735 else std_nb_erase_ok += ( stdIsErased == 0 ) ? 1 : 0;
736 auto blkFindIt = blkSet.find ( p );
737 auto blkIsErased = blkSet.erase( p );
738 if ( blkFindIt != blkSet.cend() )
740 blk_nb_erase_ok += ( blkIsErased != 0 ) ? 1 : 0;
741 blkErase.push_back( p );
743 else blk_nb_erase_ok += ( blkIsErased == 0 ) ? 1 : 0;
745 REQUIRE( blkSet .size() == stdSet .size() );
746 REQUIRE( blkErase.size() == stdErase.size() );
747 REQUIRE( blk_nb_erase_ok == std_nb_erase_ok );
748 std::vector< Point > stdTrv;
749 std::vector< Point > blkTrv;
750 for (
auto&& p : stdSet ) stdTrv.push_back( p );
751 for (
auto&& p : blkSet ) blkTrv.push_back( p );
752 REQUIRE( blkTrv.size() == stdTrv.size() );
753 std::sort( stdTrv.begin(), stdTrv.end() );
754 std::sort( blkTrv.begin(), blkTrv.end() );
755 REQUIRE( std::equal( stdTrv.cbegin(), stdTrv.cend(), blkTrv.cbegin() ) );
757 WHEN(
"Erasing a range in identical std::unordered_set<> and UnorderedSetByBlock<>, the same number of elements is left" ) {
758 auto nb_std_before = stdSet.size();
759 auto nb_blk_before = blkSet.size();
760 auto stdItB = stdSet.begin(); std::advance( stdItB, 10 );
761 auto blkItB = blkSet.begin(); std::advance( blkItB, 10 );
762 auto stdItE = stdItB; std::advance( stdItE, 20 );
763 auto blkItE = blkItB; std::advance( blkItE, 20 );
764 stdSet.erase( stdItB, stdItE );
765 blkSet.erase( blkItB, blkItE );
766 size_t nb_std = std::distance(stdSet.begin(), stdSet.end());
767 size_t nb_blk = std::distance(blkSet.begin(), blkSet.end());
768 REQUIRE( stdSet.size() == nb_std );
769 REQUIRE( stdSet.size() == nb_std_before - 20 );
770 REQUIRE( blkSet.size() == nb_blk );
771 REQUIRE( blkSet.size() == nb_blk_before - 20 );
772 REQUIRE( blkSet.size() == stdSet.size() );
774 THEN(
"The memory usage of UnorderedSetByBlock<> is inferior to the one of std::unordered_set<>" ) {
775 const auto stdMem = blkSet.memory_usage_unordered_set();
776 const auto blkMem = blkSet.memory_usage();
781 THEN(
"Conparisons and valid assignments between iterator and const_iterator should be seamless for the user" ) {
782 BlockUnorderedSet::iterator itB = blkSet.begin();
783 BlockUnorderedSet::const_iterator citB = blkSet.begin();
784 BlockUnorderedSet::const_iterator citBp = blkSet.cbegin();
785 BlockUnorderedSet::iterator itE = blkSet.end();
786 BlockUnorderedSet::const_iterator citE = blkSet.end();
787 BlockUnorderedSet::const_iterator citEp = blkSet.cend();
788 REQUIRE( itB == blkSet.begin() );
789 REQUIRE( itB == blkSet.cbegin() );
790 REQUIRE( citB == blkSet.begin() );
791 REQUIRE( citB == blkSet.cbegin() );
792 REQUIRE( citBp == blkSet.cbegin() );
793 REQUIRE( itE == blkSet.end() );
794 REQUIRE( itE == blkSet.cend() );
795 REQUIRE( citE == blkSet.end() );
796 REQUIRE( citE == blkSet.cend() );
797 REQUIRE( citEp == blkSet.cend() );
Aim: Implements basic operations that will be used in Point and Vector classes.
DGtal is the top-level namespace which contains all DGtal functions and types.
DGtal::uint32_t Dimension
REQUIRE(domain.isInside(aPoint))
SCENARIO("UnorderedSetByBlock< PointVector< 2, int > unit tests with 32 bits blocks", "[unorderedsetbyblock][2d]")