DGtal  1.5.beta
testObjectBoostGraphInterface.cpp File Reference
#include "DGtalCatch.h"
#include <iostream>
#include <queue>
#include <boost/property_map/property_map.hpp>
#include <boost/pending/queue.hpp>
#include "DGtal/base/Common.h"
#include "DGtal/graph/ObjectBoostGraphInterface.h"
#include "DGtal/helpers/StdDefs.h"
#include "DGtal/topology/Object.h"
#include "DGtal/topology/DigitalTopology.h"
#include "DGtal/topology/SurfelAdjacency.h"
#include <boost/graph/graph_concepts.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/connected_components.hpp>
#include <boost/graph/stoer_wagner_min_cut.hpp>
#include <boost/graph/boykov_kolmogorov_max_flow.hpp>
#include <boost/graph/filtered_graph.hpp>
Include dependency graph for testObjectBoostGraphInterface.cpp:

Go to the source code of this file.

Typedefs

using VertexProperties = boost::property< boost::vertex_index_t, std::size_t, boost::property< vertex_position_t, vertex_position > >
 

Functions

 TEST_CASE_METHOD (Fixture_object_diamond_with_hole, "Basic Graph functions", "[interface]")
 
 TEST_CASE_METHOD (Fixture_object_diamond_with_hole, "Boost Graph Concepts", "[concepts]")
 
 TEST_CASE_METHOD (Fixture_object_diamond_with_hole, "Breadth first visit and search", "[breadth]")
 
 TEST_CASE_METHOD (Fixture_object_diamond_with_hole, "Connected Components", "[connected]")
 
 TEST_CASE_METHOD (Fixture_object_diamond_with_hole, "Copy graph", "[copy]")
 

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
Pablo Hernandez-Cerdan. Institute of Fundamental Sciences. Massey University. Palmerston North, New Zealand
Date
2016/02/01

Functions for testing class ObjectBoostGraphInterface.

This file is part of the DGtal library.

Definition in file testObjectBoostGraphInterface.cpp.

Typedef Documentation

◆ VertexProperties

using VertexProperties = boost::property< boost::vertex_index_t, std::size_t, boost::property<vertex_position_t, vertex_position> >

Definition at line 121 of file testObjectBoostGraphInterface.cpp.

Function Documentation

◆ TEST_CASE_METHOD() [1/5]

TEST_CASE_METHOD ( Fixture_object_diamond_with_hole  ,
"Basic Graph functions"  ,
""  [interface] 
)

Definition at line 160 of file testObjectBoostGraphInterface.cpp.

160  {
161  GIVEN( "A diamond object with graph properties" ){
162  THEN( "Vertices, Num Vertices" ){
163  auto num_verts = boost::num_vertices(obj_fixture);
164  auto verts = boost::vertices(obj_fixture);
165  size_t count_verts{0};
166  for(auto v = verts.first; v != verts.second; ++v, ++count_verts){};
167  REQUIRE(count_verts == num_verts);
168  }
169  THEN( "Edges, Num Edges" ){
170  auto num_edges = boost::num_edges(obj_fixture);
171  auto edges = boost::edges(obj_fixture);
172  size_t count_edges{0};
173  for(auto v = edges.first; v != edges.second; ++v, ++count_edges){};
174  REQUIRE(count_edges == num_edges);
175  }
176  THEN( "Out Edges, Out Degree, Degree, and Adjacencies of a vertex" ){
177  // Map relating point and known degree in the diamond.
178  std::map<Point, size_t> point_numedges;
179  Point north{ 0 , 0 , 3 };
180  point_numedges[north] = 5;
181 
182  Point x3{ 3 , 0 , 0 };
183  point_numedges[x3] = 5;
184 
185  Point x1y1z1{ 1 , 1 , 1 };
186  point_numedges[x1y1z1] = 15;
187 
188  Point cz2{ 0 , 0 , 2 };
189  point_numedges[cz2] = 14;
190 
191  Point cz1{ 0 , 0 , 1 };
192  point_numedges[cz1] = 21;
193 
194  for(auto && pm : point_numedges){
195  auto out_edges = boost::out_edges(pm.first, obj_fixture);
196  size_t count_edges{0};
197  for(auto v = out_edges.first; v != out_edges.second; ++v, ++count_edges){};
198  REQUIRE(count_edges == pm.second);
199  auto out_degree = boost::out_degree(pm.first, obj_fixture);
200  REQUIRE(out_degree == count_edges);
201  auto degree = obj_fixture.degree(pm.first);
202  REQUIRE(degree == out_degree);
203  auto adj_vp = boost::adjacent_vertices(pm.first, obj_fixture);
204  size_t count_verts{0};
205  for(auto v = adj_vp.first; v != adj_vp.second; ++v, ++count_verts){};
206  REQUIRE(count_verts == degree);
207  }
208  }
209  }
210 }
std::pair< typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::edge_iterator, typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::edge_iterator > edges(const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)
graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::edges_size_type num_edges(const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)
std::pair< typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::adjacency_iterator, typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::adjacency_iterator > adjacent_vertices(typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_descriptor u, const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)
graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertices_size_type num_vertices(const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)
graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::degree_size_type out_degree(typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_descriptor u, const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)
std::pair< typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::out_edge_iterator, typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::out_edge_iterator > out_edges(typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_descriptor u, const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)
std::pair< typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_iterator, typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_iterator > vertices(const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)
MyPointD Point
Definition: testClone2.cpp:383
GIVEN("A cubical complex with random 3-cells")
REQUIRE(domain.isInside(aPoint))

References boost::adjacent_vertices(), boost::edges(), GIVEN(), boost::num_edges(), boost::num_vertices(), boost::out_degree(), boost::out_edges(), REQUIRE(), and boost::vertices().

◆ TEST_CASE_METHOD() [2/5]

TEST_CASE_METHOD ( Fixture_object_diamond_with_hole  ,
"Boost Graph Concepts"  ,
""  [concepts] 
)

Definition at line 212 of file testObjectBoostGraphInterface.cpp.

212  {
213  GIVEN( "A diamond object with graph properties" ){
214  using Graph = FixtureObject ;
215 
216  THEN( "Check Graph Concepts" ){
217 
218  BOOST_CONCEPT_ASSERT(( boost::VertexListGraphConcept<Graph> ));
219  BOOST_CONCEPT_ASSERT(( boost::AdjacencyGraphConcept<Graph> ));
220  BOOST_CONCEPT_ASSERT(( boost::IncidenceGraphConcept<Graph> ));
221  BOOST_CONCEPT_ASSERT(( boost::EdgeListGraphConcept<Graph> ));
222  // BOOST_CONCEPT_ASSERT(( boost::BidirectionalGraphConcept<Graph> ));
223  }
224  }
225 }
Go to http://www.boost.org/doc/libs/1_52_0/libs/graph/doc/AdjacencyGraph.html.
Definition: Boost.dox:165
Go to http://www.boost.org/doc/libs/1_52_0/libs/graph/doc/EdgeListGraph.html.
Definition: Boost.dox:171
Go to http://www.boost.org/doc/libs/1_52_0/libs/graph/doc/IncidenceGraph.html.
Definition: Boost.dox:168
Go to http://www.boost.org/doc/libs/1_52_0/libs/graph/doc/VertexListGraph.html.
Definition: Boost.dox:162

References GIVEN().

◆ TEST_CASE_METHOD() [3/5]

TEST_CASE_METHOD ( Fixture_object_diamond_with_hole  ,
"Breadth first visit and search"  ,
""  [breadth] 
)

Definition at line 227 of file testObjectBoostGraphInterface.cpp.

227  {
228  GIVEN( "A diamond object with graph properties" ){
229  using Graph = FixtureObject ;
230  using vertex_descriptor = boost::graph_traits<Graph>::vertex_descriptor ; // ie Object::Vertex
231  using vertex_iterator = boost::graph_traits<Graph>::vertex_iterator ;
232 
233  // get the property map for coloring vertices.
234  using StdColorMap = std::map< vertex_descriptor, boost::default_color_type > ;
235  StdColorMap colorMap;
236  boost::associative_property_map< StdColorMap > propColorMap( colorMap );
237  // get the property map for storing distances
238  using StdDistanceMap = std::map< vertex_descriptor, uint64_t > ;
239  StdDistanceMap distanceMap;
240  boost::associative_property_map< StdDistanceMap > propDistanceMap( distanceMap );
241  boost::queue< vertex_descriptor > Q; // std::queue does not have top().
242  // Start in +z corner of diamond.
243  vertex_descriptor start { Point{ 0, 0, 3 } };
244 
245  THEN( "Test IncidenceGraph interface with breadth_first_search" ){
246  using PredecessorMap = std::map< vertex_descriptor, vertex_descriptor > ;
247  PredecessorMap predecessorMap;
248  boost::associative_property_map< PredecessorMap >
249  propPredecessorMap( predecessorMap );
250 
251  boost::breadth_first_search(
252  obj_fixture,
253  start,
254  Q,
255  boost::make_bfs_visitor( boost::record_predecessors( propPredecessorMap, boost::on_tree_edge() ) ), // only record predecessors
256  propColorMap // necessary for the visiting vertices
257  );
258 
259  INFO( "predecessorMap" );
260  INFO( "starting point: " << *( obj_fixture.begin() ) );
261  size_t visited{0};
262  for(auto && v : predecessorMap){
263  ++visited;
264  INFO( v.first << " : " << v.second );
265  }
266  // +1 to count the starting point;
267  CHECK((visited + 1) == obj_fixture.size());
268  }
269 
270  THEN( "Test IncidenceGraph interface with breadth_first_visit" ){
271 
272  trace.beginBlock ( "Testing IncidenceGraph interface with breadth_first_visit..." );
273  boost::breadth_first_visit // boost graph breadth first visiting algorithm.
274  ( obj_fixture, // the graph
275  start, // the starting vertex
276  Q, // the buffer for breadth first queueing
277  boost::make_bfs_visitor( boost::record_distances( propDistanceMap, boost::on_tree_edge() ) ), // only record distances
278  propColorMap // necessary for the visiting vertices
279  );
280 
281  uint64_t maxD = 0;
282  vertex_descriptor furthest = start;
283  uint64_t nbV = 0;
284  for ( std::pair<vertex_iterator, vertex_iterator>
285  vp = boost::vertices( obj_fixture ); vp.first != vp.second; ++vp.first, ++nbV )
286  {
287  uint64_t d = boost::get( propDistanceMap, *vp.first );
288  if ( d > maxD )
289  {
290  maxD = d;
291  furthest = *vp.first;
292  }
293  }
294 
295  REQUIRE( nbV == obj_fixture.size() );
296  trace.info() << "- Start: d[ " << start << " ] = " << boost::get( propDistanceMap, start) << std::endl;
297  trace.info() << "- Furthest: d[ " << furthest << " ] = " << maxD << std::endl;
298  CHECK( maxD == 6 );
299  trace.endBlock();
300 
301  THEN( "Test Wagner Stoer min-cut"){
302 
303  using vertices_size_type = boost::graph_traits<Graph>::vertices_size_type ; // ie Object::Size
304  using edge_descriptor = boost::graph_traits<Graph>::edge_descriptor ; // ie Object::Edge
305 
306  trace.beginBlock ( "Testing UndirectedGraph interface with Wagner-Stoer min cut ..." );
307  // get the property map for weighting edges.
308  using weight_type = double ;
309  using StdWeightMap = std::map< edge_descriptor, weight_type > ;
310  StdWeightMap weightMap;
311  boost::associative_property_map< StdWeightMap > propWeightMap( weightMap );
312  using StdVertexIndexMap = std::map< vertex_descriptor, vertices_size_type > ;
313  StdVertexIndexMap vertexIndexMap;
314  boost::associative_property_map< StdVertexIndexMap > propVertexIndexMap( vertexIndexMap );
315  vertices_size_type idxV = 0;
316  // The weight is smaller for edges traversing plane z=0 than anywhere else.
317  // The min cut thus cuts the diamond in two approximate halves.
318  for ( auto vp = boost::vertices( obj_fixture );
319  vp.first != vp.second; ++vp.first, ++idxV )
320  {
321  vertex_descriptor v1 = *vp.first;
322  vertexIndexMap[ v1 ] = idxV;
323  for ( auto ve = boost::out_edges( v1, obj_fixture );
324  ve.first != ve.second; ++ve.first )
325  {
326  auto v2 = boost::target( *ve.first, obj_fixture );
327  if ( v1 < v2 )
328  {
329  weight_type weight = (
330  (v1[2] == Approx(0) && v2[2] != Approx(0) ) ||
331  (v2[2] == Approx(0) && v1[2] != Approx(0) )
332  ) ? 0.01 : 1.0;
333  weightMap[ *ve.first ] = weight;
334  weightMap[ obj_fixture.opposite( *ve.first ) ] = weight;
335  }
336  }
337  }
338  // get the parity map for assigning a set to each vertex.
339  using StdParityMap = std::map< vertex_descriptor, bool > ;
340  StdParityMap parityMap;
341  boost::associative_property_map< StdParityMap > propParityMap( parityMap );
342 
343  weight_type total_weight =
344  boost::stoer_wagner_min_cut // boost wagner stoer min cut algorithm.
345  ( obj_fixture, // the graph
346  propWeightMap, // the mapping edge -> weight
347  boost::parity_map( propParityMap ) // this map stores the vertex assignation
348  .vertex_index_map( propVertexIndexMap )
349  );
350  INFO( "- total weight = " << total_weight);
351  uint64_t nb0 = 0;
352  uint64_t nb1 = 0;
353  for ( auto vp = boost::vertices( obj_fixture );
354  vp.first != vp.second; ++vp.first, ++idxV )
355  {
356  vertex_descriptor v1 = *vp.first;
357  if ( parityMap[ v1 ] ) ++nb1;
358  else ++nb0;
359  }
360  trace.info() << "parityMap: True components: " << nb1 << " False: " << nb0 << std::endl;
361  trace.info() << "- parity[ " << start << " ] = " << parityMap[ start ] << std::endl;
362  trace.info() << "- parity[ " << furthest << " ] = " << parityMap[ furthest ] << std::endl;
363  CHECK( parityMap[start] != parityMap[furthest]);
364  CHECK( total_weight < 1.0);
365 
366  trace.endBlock();
367 
368  THEN( "Test Boykov-Kolmogorov max flow"){
369 
370  using edge_iterator = boost::graph_traits<Graph>::edge_iterator ;
371  trace.beginBlock ( "Testing EdgeListGraph and IncidenceGraph interfaces with Boykov-Kolmogorov max flow ..." );
372  using capacity_type = double ;
373  // get the property map for edge capacity.
374  using StdEdgeCapacityMap = std::map< edge_descriptor, weight_type > ;
375  StdEdgeCapacityMap edgeCapacityMap;
376  boost::associative_property_map< StdEdgeCapacityMap > propEdgeCapacityMap( edgeCapacityMap );
377  // get the property map for edge residual capacity.
378  using StdEdgeResidualCapacityMap = std::map< edge_descriptor, weight_type > ;
379  StdEdgeResidualCapacityMap edgeResidualCapacityMap;
380  boost::associative_property_map< StdEdgeResidualCapacityMap > propEdgeResidualCapacityMap( edgeResidualCapacityMap );
381  // get the property map for reverse edge.
382  using StdReversedEdgeMap = std::map< edge_descriptor, edge_descriptor > ;
383  StdReversedEdgeMap reversedEdgeMap;
384  boost::associative_property_map< StdReversedEdgeMap > propReversedEdgeMap( reversedEdgeMap );
385  // get the property map for vertex predecessor.
386  using StdPredecessorMap = std::map< vertex_descriptor, edge_descriptor > ;
387  StdPredecessorMap predecessorMap;
388  boost::associative_property_map< StdPredecessorMap > propPredecessorMap( predecessorMap );
389  // We already have vertex color map, vertex distance map and vertex index map.
390  uint64_t nbEdges = 0;
391  // The weight is smaller for edges traversing plane z=0 than anywhere else.
392  // The min cut thus cuts the diamond in two approximate halves.
393  for ( std::pair<edge_iterator, edge_iterator>
394  ve = boost::edges( obj_fixture ); ve.first != ve.second; ++ve.first, ++nbEdges )
395  {
396  edge_descriptor e = *ve.first;
397  edge_descriptor rev_e = obj_fixture.opposite( e );
398  vertex_descriptor v1 = boost::source( e, obj_fixture );
399  vertex_descriptor v2 = boost::target( e, obj_fixture );
400  ASSERT( boost::source( rev_e, obj_fixture ) == v2 );
401  ASSERT( boost::target( rev_e, obj_fixture ) == v1 );
402  if ( v1 < v2 )
403  {
404  capacity_type capacity = (
405  (v1[2] == Approx(0) && v2[2] != Approx(0) ) ||
406  (v2[2] == Approx(0) && v1[2] != Approx(0) )
407  ) ? 0.01 : 1.0;
408  edgeCapacityMap[ e ] = capacity;
409  edgeCapacityMap[ obj_fixture.opposite( e ) ] = capacity;
410  reversedEdgeMap[ e ] = obj_fixture.opposite( e );
411  reversedEdgeMap[ obj_fixture.opposite( e ) ] = e;
412  }
413  }
414  trace.info() << "- nb edges = " << nbEdges << std::endl;
415  distanceMap.clear();
416  colorMap.clear();
417  capacity_type max_flow =
418  boost::boykov_kolmogorov_max_flow // boykov kolmogorov max flow algorithm.
419  ( obj_fixture, // the graph
420  propEdgeCapacityMap, propEdgeResidualCapacityMap,
421  propReversedEdgeMap, propPredecessorMap, propColorMap, propDistanceMap, propVertexIndexMap,
422  start, furthest );
423  trace.info() << "- max flow = " << max_flow << std::endl;
424  CHECK(abs(max_flow) == Approx(total_weight));
425  trace.endBlock();
426  }// maxflow
427  }// mincut
428  }// breath_visit
429  }// given
430 }// scenario
void beginBlock(const std::string &keyword="")
std::ostream & info()
double endBlock()
Trace trace
Definition: Common.h:153
boost::uint64_t uint64_t
unsigned 64-bit integer.
Definition: BasicTypes.h:65
graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_descriptor source(typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::edge_descriptor edge, const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)
graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_descriptor target(typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::edge_descriptor edge, const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)

References DGtal::Trace::beginBlock(), boost::edges(), DGtal::Trace::endBlock(), GIVEN(), DGtal::Trace::info(), boost::out_edges(), REQUIRE(), boost::source(), boost::target(), DGtal::trace, and boost::vertices().

◆ TEST_CASE_METHOD() [4/5]

TEST_CASE_METHOD ( Fixture_object_diamond_with_hole  ,
"Connected Components"  ,
""  [connected] 
)

Definition at line 432 of file testObjectBoostGraphInterface.cpp.

432  {
433  GIVEN( "A diamond object with graph properties and an isolated vertex" ){
434  using Graph = FixtureObject ;
435  using vertex_descriptor = boost::graph_traits<Graph>::vertex_descriptor ; // ie Object::Vertex
436  using edge_descriptor = boost::graph_traits<Graph>::edge_descriptor ; // ie Object::Edge
437  using vertices_size_type = boost::graph_traits<Graph>::vertices_size_type ; // ie Object::Size
438 
439  // Add an isolated point in the domain.
440  obj_fixture.pointSet().insertNew(FixtureObject::Point(0,0,7));
441 
442  THEN( "VertexListGraph interface with connected_components" ){
443  // get the property map for labelling vertices.
444  // get the property map for coloring vertices.
445  using StdColorMap = std::map< vertex_descriptor, boost::default_color_type > ;
446  StdColorMap colorMap;
447  boost::associative_property_map< StdColorMap > propColorMap( colorMap );
448 
449  using StdComponentMap = std::map< vertex_descriptor, vertices_size_type > ;
450  StdComponentMap componentMap;
451  boost::associative_property_map< StdComponentMap > propComponentMap( componentMap );
452  vertices_size_type nbComp =
453  boost::connected_components // boost graph connected components algorithm.
454  ( obj_fixture, // the graph
455  propComponentMap, // the mapping vertex -> label
456  boost::color_map( propColorMap ) // this map is used internally when computing connected components.
457  );
458  CHECK(nbComp == 2);
459 
460  THEN( "Filter graph and get components" ){
461  using ComponentGraph =
462  boost::filtered_graph<
463  Graph,
464  function<bool(edge_descriptor)>,
465  function<bool(vertex_descriptor)>
466  >;
467  auto &g = obj_fixture;
468 
469  std::vector<ComponentGraph> component_graphs;
470 
471  for (size_t i = 0; i < nbComp; i++)
472  component_graphs.emplace_back(g,
473  [componentMap,i,&g](edge_descriptor e) {
474  return componentMap.at(boost::source(e,g) )==i
475  || componentMap.at(boost::target(e,g))==i;
476  },
477  [componentMap,i](vertex_descriptor v) {
478  return componentMap.at(v)==i;
479  });
480 
481 
482  CHECK( component_graphs.size() == 2);
483  std::vector<FixtureObject> obj_components;
484  // Copying object and clear pointSet instead of creating from scratch. Lazy?
485  FixtureObject obj_copy(obj_fixture);
486  obj_copy.pointSet().clear();
487 
488  // Create new object from the component_graph.
489  for (auto && c : component_graphs){
490  obj_components.push_back(obj_copy);
491  for (auto && vp = boost::vertices(c); vp.first != vp.second ; ++vp.first){
492  obj_components.back().pointSet().insertNew(*vp.first);
493  }
494  }
495 
496  }// filtered_graph
497  }// connected_components
498  }//given
499 }//scenario

References GIVEN(), and boost::vertices().

◆ TEST_CASE_METHOD() [5/5]

TEST_CASE_METHOD ( Fixture_object_diamond_with_hole  ,
"Copy graph"  ,
""  [copy] 
)

Definition at line 502 of file testObjectBoostGraphInterface.cpp.

502  {
503  GIVEN( "A diamond object with graph properties" ){
504  using Graph = FixtureObject ;
505  using vertex_descriptor = boost::graph_traits<Graph>::vertex_descriptor ; // ie Object::Vertex
506  using vertices_size_type = boost::graph_traits<Graph>::vertices_size_type ; // ie Object::Size
507  THEN( "Test copy_graph"){
508 
509  using StdVertexIndexMap = std::map< vertex_descriptor, vertices_size_type > ;
510  StdVertexIndexMap vertexIndexMap;
511  boost::associative_property_map< StdVertexIndexMap > propVertexIndexMap( vertexIndexMap );
512  using BGraph = boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, VertexProperties > ;
513  BGraph bG;
514  boost::copy_graph( obj_fixture, bG,
515  boost::vertex_copy( my_vertex_copier<Graph,BGraph,StdVertexIndexMap>( obj_fixture, bG, vertexIndexMap ) )
516  .edge_copy( my_edge_copier<Graph,BGraph>( obj_fixture, bG ) )
517  .vertex_index_map( propVertexIndexMap )
518  );
519  using vertex_descriptor_2 = boost::graph_traits< BGraph >::vertex_descriptor ;
520  using vertex_iterator_2 = boost::graph_traits< BGraph >::vertex_iterator ;
521  using GraphVertexPositionMap = boost::property_map< BGraph, vertex_position_t>::type ;
522  GraphVertexPositionMap vertexPos( boost::get( vertex_position_t(), bG) );
523  for ( std::pair<vertex_iterator_2, vertex_iterator_2>
524  vp = boost::vertices( bG ); vp.first != vp.second; ++vp.first )
525  {
526  vertex_descriptor_2 v1 = *vp.first;
527  vertex_position pos = boost::get( vertexPos, v1 );
528  }
529  INFO("after copy: Boost graph has " << num_vertices( bG ) << " vertices.");
530  CHECK(boost::num_vertices( bG ) == boost::num_vertices( obj_fixture ));
531 
532  }
533  }
534 }

References GIVEN(), boost::num_vertices(), and boost::vertices().