DGtal  1.1.0
Functions
testUnorderedSetByBlock.cpp File Reference
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <unordered_set>
#include "DGtal/kernel/PointVector.h"
#include "DGtal/kernel/UnorderedSetByBlock.h"
#include "DGtalCatch.h"
Include dependency graph for testUnorderedSetByBlock.cpp:

Go to the source code of this file.

Functions

template<typename Point >
Point randomPoint (int S)
 
 SCENARIO ("UnorderedSetByBlock< PointVector< 2, int > unit tests with 32 bits blocks", "[unorderedsetbyblock][2d]")
 

Detailed Description

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Author
Jacques-Olivier Lachaud (jacqu.nosp@m.es-o.nosp@m.livie.nosp@m.r.la.nosp@m.chaud.nosp@m.@uni.nosp@m.v-sav.nosp@m.oie..nosp@m.fr ) Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
Date
2019/01/04

Functions for testing class UnorderedSetByBlock.

This file is part of the DGtal library.

Definition in file testUnorderedSetByBlock.cpp.

Function Documentation

◆ randomPoint()

template<typename Point >
Point randomPoint ( int  S)

Definition at line 45 of file testUnorderedSetByBlock.cpp.

46 {
47  Point p;
48  for ( DGtal::Dimension i = 0; i < Point::dimension; i++ )
49  p[ i ] = (rand() % S) - S/2;
50  return p;
51 }

◆ SCENARIO()

SCENARIO ( )

Definition at line 58 of file testUnorderedSetByBlock.cpp.

59 {
61  typedef std::unordered_set< Point > StdUnorderedSet;
62  typedef UnorderedSetByBlock< Point > BlockUnorderedSet;
63 
64  const int nb_inserted = 100;
65  const int nb_sought = 200;
66  const int nb_erased = 100;
67 
68  StdUnorderedSet stdSet;
69  BlockUnorderedSet blkSet;
70  for ( int i = 0; i < nb_inserted; i++ )
71  {
72  Point p = randomPoint<Point>( 10 );
73  stdSet.insert( p );
74  blkSet.insert( p );
75  }
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() );
79  }
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() );
85  }
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() ) );
95  }
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 ( int i = 0; i < nb_sought; i++ )
100  {
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 );
106  }
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() ) );
117  }
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  int std_nb_value_ok = 0;
122  int blk_nb_value_ok = 0;
123  for ( int i = 0; i < nb_sought; i++ )
124  {
125  Point p = randomPoint<Point>( 10 );
126  const auto stdIt = stdSet.find( p );
127  if ( stdIt != stdSet.end() )
128  {
129  stdFound.push_back( p );
130  std_nb_value_ok += ( *stdIt == p ) ? 1 : 0;
131  }
132  else stdNotFound.push_back( p );
133  const auto blkIt = blkSet.find( p );
134  if ( blkIt != blkSet.end() )
135  {
136  blkFound.push_back( p );
137  blk_nb_value_ok += ( *blkIt == p ) ? 1 : 0;
138  }
139  else blkNotFound.push_back( p );
140  }
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() );
154  }
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  int std_nb_erase_ok = 0;
159  int blk_nb_erase_ok = 0;
160  for ( int i = 0; i < nb_erased; i++ )
161  {
162  Point p = randomPoint<Point>( 10 );
163  auto stdFindIt = stdSet.find ( p );
164  auto stdIsErased = stdSet.erase( p );
165  if ( stdFindIt != stdSet.cend() )
166  {
167  std_nb_erase_ok += ( stdIsErased != 0 ) ? 1 : 0;
168  stdErase.push_back( p );
169  }
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() )
174  {
175  blk_nb_erase_ok += ( blkIsErased != 0 ) ? 1 : 0;
176  blkErase.push_back( p );
177  }
178  else blk_nb_erase_ok += ( blkIsErased == 0 ) ? 1 : 0;
179  }
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() ) );
191  }
192  WHEN( "Erasing a range in identical std::unordered_set<> and UnorderedSetByBlock<>, the same number of elements is left" ) {
193  int nb_std_before = stdSet.size();
194  int 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  int nb_std = std::distance(stdSet.begin(), stdSet.end());
202  int 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() );
208  }
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();
212  REQUIRE( blkMem <= stdMem );
213  }
214 
215 
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() );
233  REQUIRE( itB != itE );
234  REQUIRE( itB != citE );
235  REQUIRE( itB != citEp );
236  REQUIRE( citB != itE );
237  REQUIRE( citB != citE );
238  REQUIRE( citB != citEp );
239  REQUIRE( citBp != itE );
240  REQUIRE( citBp != citE );
241  REQUIRE( citBp != citEp );
242  }
243 }

References REQUIRE().

DGtal::Dimension
DGtal::uint32_t Dimension
Definition: Common.h:133
REQUIRE
REQUIRE(domain.isInside(aPoint))
DGtal::PointVector
Aim: Implements basic operations that will be used in Point and Vector classes.
Definition: PointVector.h:593
DGtal::UnorderedSetByBlock
Definition: UnorderedSetByBlock.h:163
Point
MyPointD Point
Definition: testClone2.cpp:383