Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Tiago Peixoto
graph-tool
Commits
afae7aa1
Commit
afae7aa1
authored
Sep 12, 2015
by
Tiago Peixoto
Browse files
Significantly improve speed of vertex/edge iterators and descriptors in python interface
parent
973d73cf
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
src/graph/graph.hh
View file @
afae7aa1
...
...
@@ -151,7 +151,8 @@ public:
// internal access
multigraph_t
&
GetGraph
()
{
return
*
_mg
;}
multigraph_t
&
GetGraph
()
{
return
*
_mg
;}
std
::
shared_ptr
<
multigraph_t
>
GetGraphPtr
()
{
return
_mg
;}
vertex_index_map_t
GetVertexIndex
()
{
return
_vertex_index
;}
edge_index_map_t
GetEdgeIndex
()
{
return
_edge_index
;}
size_t
GetMaxEdgeIndex
(){
return
_mg
->
get_last_index
();}
...
...
@@ -160,6 +161,7 @@ public:
// Gets the encapsulated graph view. See graph_filtering.cc for details
boost
::
any
GetGraphView
()
const
;
vector
<
boost
::
any
>&
GetGraphViews
()
{
return
_graph_views
;}
private:
...
...
@@ -167,11 +169,6 @@ private:
template
<
class
Action
,
class
GraphViews
,
class
Wrap
,
class
...
TRS
>
friend
struct
detail
::
graph_action
;
// python interface
friend
class
PythonVertex
;
template
<
class
Graph
>
friend
class
PythonEdge
;
// this is the main graph
shared_ptr
<
multigraph_t
>
_mg
;
...
...
@@ -206,6 +203,7 @@ private:
bool
_edge_filter_active
;
};
}
//namespace graph_tool
#endif
src/graph/graph_filtering.cc
View file @
afae7aa1
...
...
@@ -67,34 +67,10 @@ const char * graph_tool::ActionNotFound::what () const throw ()
return
error
.
c_str
();
}
// this function retrieves a graph view stored in graph_views, or stores one if
// non-existent
template
<
class
Graph
>
typename
std
::
remove_const
<
Graph
>::
type
&
retrieve_graph
(
vector
<
boost
::
any
>&
graph_views
,
Graph
&
init
)
{
typedef
typename
std
::
remove_const
<
Graph
>::
type
g_t
;
size_t
index
=
boost
::
mpl
::
find
<
all_graph_views
,
g_t
>::
type
::
pos
::
value
;
if
(
index
>=
graph_views
.
size
())
graph_views
.
resize
(
index
+
1
);
boost
::
any
gview
=
graph_views
[
index
];
std
::
shared_ptr
<
g_t
>*
gptr
=
any_cast
<
std
::
shared_ptr
<
g_t
>
>
(
&
gview
);
if
(
gptr
==
0
)
{
std
::
shared_ptr
<
g_t
>
new_g
(
new
g_t
(
init
));
gptr
=
&
new_g
;
gview
=
new_g
;
graph_views
[
index
]
=
gview
;
}
return
**
gptr
;
}
// this will check whether a graph is reversed and return the proper view
// encapsulated
template
<
class
Graph
>
boost
::
any
check_reverse
(
const
Graph
&
g
,
bool
reverse
,
vector
<
boost
::
any
>&
graph_views
)
boost
::
any
check_reverse
(
const
Graph
&
g
,
bool
reverse
,
GraphInterface
&
gi
)
{
if
(
reverse
)
{
...
...
@@ -104,26 +80,26 @@ boost::any check_reverse(const Graph &g, bool reverse,
reverse_graph_t
;
reverse_graph_t
rg
(
g
);
return
&
retrieve_graph
(
graph
_view
s
,
rg
);
return
retrieve_graph_view
(
gi
,
rg
)
.
get
()
;
}
return
boost
::
any
(
&
const_cast
<
Graph
&
>
(
g
));
return
boost
::
any
(
const_cast
<
Graph
*
>
(
&
g
));
};
// this will check whether a graph is directed and return the proper view
// encapsulated
template
<
class
Graph
>
boost
::
any
check_directed
(
const
Graph
&
g
,
bool
reverse
,
bool
directed
,
vector
<
boost
::
any
>&
graph_views
)
GraphInterface
&
gi
)
{
if
(
directed
)
{
return
check_reverse
(
g
,
reverse
,
g
raph_views
);
return
check_reverse
(
g
,
reverse
,
g
i
);
}
typedef
UndirectedAdaptor
<
Graph
>
ug_t
;
ug_t
ug
(
g
);
return
&
retrieve_graph
(
graph
_view
s
,
ug
);
return
retrieve_graph_view
(
gi
,
ug
)
.
get
()
;
};
// this will check whether a graph is filtered and return the proper view
...
...
@@ -133,7 +109,7 @@ boost::any
check_filtered
(
const
Graph
&
g
,
const
EdgeFilter
&
edge_filter
,
const
bool
&
e_invert
,
bool
e_active
,
size_t
max_eindex
,
const
VertexFilter
&
vertex_filter
,
const
bool
&
v_invert
,
bool
v_active
,
vector
<
boost
::
any
>&
graph_views
,
bool
reverse
,
bool
v_active
,
GraphInterface
&
gi
,
bool
reverse
,
bool
directed
)
{
#ifndef NO_GRAPH_FILTERING
...
...
@@ -152,20 +128,20 @@ check_filtered(const Graph &g, const EdgeFilter& edge_filter,
typedef
filtered_graph
<
Graph
,
MaskFilter
<
EdgeFilter
>
,
MaskFilter
<
VertexFilter
>
>
fg_t
;
fg_t
init
(
g
,
e_filter
,
v_filter
);
fg_t
&
fg
=
retrieve_graph
(
graph
_view
s
,
init
);
fg_t
&
fg
=
*
retrieve_graph_view
(
gi
,
init
)
.
get
()
;
fg
.
m_edge_pred
=
e_filter
;
fg
.
m_vertex_pred
=
v_filter
;
return
check_directed
(
fg
,
reverse
,
directed
,
g
raph_views
);
return
check_directed
(
fg
,
reverse
,
directed
,
g
i
);
}
else
{
if
(
v_active
)
throw
GraphException
(
"Vertex filter is active but edge filter is not. This is a bug."
);
return
check_directed
(
g
,
reverse
,
directed
,
g
raph_views
);
return
check_directed
(
g
,
reverse
,
directed
,
g
i
);
}
#else
return
check_directed
(
g
,
reverse
,
directed
,
g
raph_views
);
return
check_directed
(
g
,
reverse
,
directed
,
g
i
);
#endif
}
...
...
@@ -177,7 +153,7 @@ boost::any GraphInterface::GetGraphView() const
_edge_filter_active
,
_mg
->
get_last_index
(),
_vertex_filter_map
,
_vertex_filter_invert
,
_vertex_filter_active
,
const_cast
<
vector
<
boost
::
any
>&>
(
_graph_view
s
),
_reversed
,
const_cast
<
GraphInterface
&>
(
*
thi
s
),
_reversed
,
_directed
);
return
graph
;
}
...
...
src/graph/graph_filtering.hh
View file @
afae7aa1
...
...
@@ -515,6 +515,43 @@ struct run_action
// returns true if graph filtering was enabled at compile time
bool
graph_filtering_enabled
();
template
<
class
Graph
,
class
GraphInit
>
std
::
shared_ptr
<
Graph
>
get_graph_ptr
(
GraphInterface
&
gi
,
GraphInit
&
,
std
::
true_type
)
{
return
gi
.
GetGraphPtr
();
}
template
<
class
Graph
,
class
GraphInit
>
std
::
shared_ptr
<
Graph
>
get_graph_ptr
(
GraphInterface
&
,
GraphInit
&
g
,
std
::
false_type
)
{
return
std
::
shared_ptr
<
Graph
>
(
new
Graph
(
g
));
}
// this function retrieves a graph view stored in graph_views, or stores one if
// non-existent
template
<
class
Graph
>
typename
std
::
shared_ptr
<
Graph
>
retrieve_graph_view
(
GraphInterface
&
gi
,
Graph
&
init
)
{
typedef
typename
std
::
remove_const
<
Graph
>::
type
g_t
;
size_t
index
=
boost
::
mpl
::
find
<
detail
::
all_graph_views
,
g_t
>::
type
::
pos
::
value
;
auto
&
graph_views
=
gi
.
GetGraphViews
();
if
(
index
>=
graph_views
.
size
())
graph_views
.
resize
(
index
+
1
);
boost
::
any
&
gview
=
graph_views
[
index
];
std
::
shared_ptr
<
g_t
>*
gptr
=
boost
::
any_cast
<
std
::
shared_ptr
<
g_t
>>
(
&
gview
);
if
(
gptr
==
0
)
{
std
::
shared_ptr
<
g_t
>
new_g
=
get_graph_ptr
<
g_t
>
(
gi
,
init
,
std
::
is_same
<
g_t
,
GraphInterface
::
multigraph_t
>
());
gptr
=
&
new_g
;
gview
=
new_g
;
}
return
*
gptr
;
}
}
//graph_tool namespace
#endif // FILTERING_HH
src/graph/graph_python_interface.cc
View file @
afae7aa1
This diff is collapsed.
Click to expand it.
src/graph/graph_python_interface.hh
View file @
afae7aa1
...
...
@@ -58,24 +58,23 @@ namespace graph_tool
// generic iterator adaptor which can be used to iterate vertices, edges,
// out_edges and in_edges through python
template
<
class
Descriptor
,
class
Iterator
>
template
<
class
Graph
,
class
Descriptor
,
class
Iterator
>
class
PythonIterator
{
public:
PythonIterator
(
const
boo
st
::
python
::
object
&
g
,
PythonIterator
(
st
d
::
shared_ptr
<
Graph
>
&
g
p
,
std
::
pair
<
Iterator
,
Iterator
>
e
)
:
_
w
g
(
g
),
_g
(
g
()
),
_e
(
e
)
{}
:
_g
(
g
p
),
_e
(
e
)
{}
Descriptor
Next
()
{
if
(
_e
.
first
==
_e
.
second
)
boost
::
python
::
objects
::
stop_iteration_error
();
Descriptor
e
(
_
w
g
,
*
_e
.
first
);
Descriptor
e
(
_g
,
*
_e
.
first
);
++
_e
.
first
;
return
e
;
}
private:
boost
::
python
::
object
_wg
;
boost
::
python
::
object
_g
;
std
::
shared_ptr
<
Graph
>
_g
;
std
::
pair
<
Iterator
,
Iterator
>
_e
;
};
...
...
@@ -84,27 +83,24 @@ private:
template
<
class
Graph
>
class
PythonEdge
;
class
VertexBase
{};
// useful to unite all vertex
// below are classes related to the PythonVertex type
class
PythonVertex
template
<
class
Graph
>
class
PythonVertex
:
public
VertexBase
{
public:
PythonVertex
(
const
boost
::
python
::
object
&
g
,
GraphInterface
::
vertex_t
v
)
:
_g
(
g
),
_v
(
v
),
_valid
(
true
)
{}
PythonVertex
(
std
::
shared_ptr
<
Graph
>
g
,
GraphInterface
::
vertex_t
v
)
:
_g
(
g
),
_v
(
v
)
{}
bool
IsValid
()
const
{
if
(
_g
().
ptr
()
==
Py_None
)
std
::
shared_ptr
<
Graph
>
gp
(
_g
);
Graph
*
g
=
gp
.
get
();
if
(
g
==
nullptr
)
return
false
;
GraphInterface
&
gi
=
boost
::
python
::
extract
<
GraphInterface
&>
(
_g
().
attr
(
"_Graph__graph"
));
return
_valid
&&
(
_v
!=
boost
::
graph_traits
<
GraphInterface
::
multigraph_t
>::
null_vertex
())
&&
(
_v
<
num_vertices
(
*
gi
.
_mg
));
}
void
SetValid
(
bool
valid
)
{
_valid
=
valid
;
return
((
_v
!=
boost
::
graph_traits
<
Graph
>::
null_vertex
())
&&
(
_v
<
num_vertices
(
*
g
)));
}
void
CheckValid
()
const
...
...
@@ -114,11 +110,6 @@ public:
boost
::
lexical_cast
<
string
>
(
_v
));
}
boost
::
python
::
object
GetGraph
()
const
{
return
_g
();
}
GraphInterface
::
vertex_t
GetDescriptor
()
const
{
return
_v
;
...
...
@@ -127,7 +118,6 @@ public:
template
<
class
DegSelector
>
struct
get_degree
{
template
<
class
Graph
>
void
operator
()(
const
Graph
&
g
,
typename
boost
::
graph_traits
<
Graph
>::
vertex_descriptor
v
,
size_t
&
deg
)
const
...
...
@@ -135,120 +125,100 @@ public:
deg
=
DegSelector
()(
v
,
g
);
}
template
<
class
Graph
,
class
PMap
>
template
<
class
PMap
>
void
operator
()(
const
Graph
&
g
,
typename
boost
::
graph_traits
<
Graph
>::
vertex_descriptor
v
,
const
PMap
&
weight
,
boo
st
::
python
::
object
&
deg
)
const
const
boost
::
any
&
a
weight
,
boost
::
python
::
object
&
deg
,
boo
l
&
found
,
PMap
)
const
{
deg
=
boost
::
python
::
object
(
DegSelector
()(
v
,
g
,
weight
));
try
{
const
PMap
&
weight
=
boost
::
any_cast
<
const
PMap
&>
(
aweight
);
deg
=
boost
::
python
::
object
(
DegSelector
()(
v
,
g
,
weight
));
found
=
true
;
}
catch
(
boost
::
bad_any_cast
&
)
{}
}
};
size_t
GetInDegree
()
const
{
CheckValid
();
GraphInterface
&
gi
=
boost
::
python
::
extract
<
GraphInterface
&>
(
_g
().
attr
(
"_Graph__graph"
));
std
::
shared_ptr
<
Graph
>
gp
(
_g
);
Graph
&
g
=
*
gp
.
get
();
size_t
in_deg
;
run_action
<>
()(
gi
,
std
::
bind
(
get_degree
<
in_degreeS
>
(),
std
::
placeholders
::
_1
,
_v
,
std
::
ref
(
in_deg
)))();
get_degree
<
in_degreeS
>
()(
g
,
_v
,
in_deg
);
return
in_deg
;
}
boost
::
python
::
object
GetWeightedInDegree
(
boost
::
any
pmap
)
const
{
if
(
!
belongs
<
edge_scalar_properties
>
()(
pmap
))
throw
ValueException
(
"edge weight property must be of scalar type"
);
CheckValid
();
GraphInterface
&
gi
=
boost
::
python
::
extract
<
GraphInterface
&>
(
_g
().
attr
(
"_Graph__graph"
));
std
::
shared_ptr
<
Graph
>
gp
(
_g
);
Graph
&
g
=
*
gp
.
get
();
boost
::
python
::
object
in_deg
;
run_action
<>
()(
gi
,
std
::
bind
(
get_degree
<
in_degreeS
>
(),
std
::
placeholders
::
_1
,
_v
,
std
::
placeholders
::
_2
,
std
::
ref
(
in_deg
)),
edge_scalar_properties
())(
pmap
);
bool
found
=
false
;
boost
::
mpl
::
for_each
<
edge_scalar_properties
>
(
std
::
bind
(
get_degree
<
in_degreeS
>
(),
std
::
ref
(
g
),
_v
,
std
::
ref
(
pmap
),
std
::
ref
(
in_deg
),
std
::
ref
(
found
),
std
::
placeholders
::
_1
));
if
(
!
found
)
throw
ValueException
(
"edge weight property must be of scalar type"
);
return
in_deg
;
}
size_t
GetOutDegree
()
const
{
CheckValid
();
GraphInterface
&
gi
=
boost
::
python
::
extract
<
GraphInterface
&>
(
_g
().
attr
(
"_Graph__graph"
));
std
::
shared_ptr
<
Graph
>
gp
(
_g
);
Graph
&
g
=
*
gp
.
get
();
size_t
out_deg
;
run_action
<>
()(
gi
,
std
::
bind
(
get_degree
<
out_degreeS
>
(),
std
::
placeholders
::
_1
,
_v
,
std
::
ref
(
out_deg
)))();
get_degree
<
out_degreeS
>
()(
g
,
_v
,
out_deg
);
return
out_deg
;
}
boost
::
python
::
object
GetWeightedOutDegree
(
boost
::
any
pmap
)
const
{
if
(
!
belongs
<
edge_scalar_properties
>
()(
pmap
))
throw
ValueException
(
"edge weight property must be of scalar type"
);
CheckValid
();
GraphInterface
&
gi
=
boost
::
python
::
extract
<
GraphInterface
&>
(
_g
().
attr
(
"_Graph__graph"
));
std
::
shared_ptr
<
Graph
>
gp
(
_g
);
Graph
&
g
=
*
gp
.
get
();
boost
::
python
::
object
out_deg
;
run_action
<>
()(
gi
,
std
::
bind
(
get_degree
<
out_degreeS
>
(),
std
::
placeholders
::
_1
,
_v
,
std
::
placeholders
::
_2
,
std
::
ref
(
out_deg
)),
edge_scalar_properties
())(
pmap
);
bool
found
=
false
;
boost
::
mpl
::
for_each
<
edge_scalar_properties
>
(
std
::
bind
(
get_degree
<
out_degreeS
>
(),
std
::
ref
(
g
),
_v
,
std
::
ref
(
pmap
),
std
::
ref
(
out_deg
),
std
::
ref
(
found
),
std
::
placeholders
::
_1
));
if
(
!
found
)
throw
ValueException
(
"edge weight property must be of scalar type"
);
return
out_deg
;
}
// provide iterator support for out_edges
struct
get_out_edges
{
template
<
class
Graph
>
void
operator
()(
const
Graph
&
g
,
const
boost
::
python
::
object
&
pg
,
typename
boost
::
graph_traits
<
Graph
>::
vertex_descriptor
v
,
boost
::
python
::
object
&
iter
)
const
{
typedef
typename
boost
::
graph_traits
<
Graph
>::
out_edge_iterator
out_edge_iterator
;
iter
=
boost
::
python
::
object
(
PythonIterator
<
PythonEdge
<
Graph
>
,
out_edge_iterator
>
(
pg
,
out_edges
(
v
,
g
)));
}
};
boost
::
python
::
object
OutEdges
()
const
{
CheckValid
();
GraphInterface
&
gi
=
boost
::
python
::
extract
<
GraphInterface
&>
(
_g
().
attr
(
"_Graph__graph"
));
boost
::
python
::
object
iter
;
run_action
<>
()(
gi
,
std
::
bind
(
get_out_edges
(),
std
::
placeholders
::
_1
,
std
::
ref
(
_g
),
_v
,
std
::
ref
(
iter
)))();
return
iter
;
std
::
shared_ptr
<
Graph
>
pg
(
_g
);
Graph
&
g
=
*
pg
;
typedef
typename
boost
::
graph_traits
<
Graph
>::
out_edge_iterator
out_edge_iterator
;
return
boost
::
python
::
object
(
PythonIterator
<
Graph
,
PythonEdge
<
Graph
>
,
out_edge_iterator
>
(
pg
,
out_edges
(
_v
,
g
)));
}
struct
get_in_edges
{
template
<
class
Graph
>
void
operator
()(
const
Graph
&
g
,
const
boost
::
python
::
object
&
pg
,
typename
boost
::
graph_traits
<
Graph
>::
vertex_descriptor
v
,
boost
::
python
::
object
&
iter
)
const
{
typedef
typename
in_edge_iteratorS
<
Graph
>::
type
in_edge_iterator
;
iter
=
boost
::
python
::
object
(
PythonIterator
<
PythonEdge
<
Graph
>
,
in_edge_iterator
>
(
pg
,
in_edge_iteratorS
<
Graph
>::
get_edges
(
v
,
g
)));
}
};
boost
::
python
::
object
InEdges
()
const
{
CheckValid
();
GraphInterface
&
gi
=
boost
::
python
::
extract
<
GraphInterface
&>
(
_g
().
attr
(
"_Graph__graph"
));
boost
::
python
::
object
iter
;
run_action
<>
()(
gi
,
std
::
bind
(
get_in_edges
(),
placeholders
::
_1
,
std
::
ref
(
_g
),
_v
,
std
::
ref
(
iter
)))();
return
iter
;
std
::
shared_ptr
<
Graph
>
pg
(
_g
);
Graph
&
g
=
*
pg
;
typedef
typename
in_edge_iteratorS
<
Graph
>::
type
in_edge_iterator
;
return
boost
::
python
::
object
(
PythonIterator
<
Graph
,
PythonEdge
<
Graph
>
,
in_edge_iterator
>
(
pg
,
in_edge_iteratorS
<
Graph
>::
get_edges
(
_v
,
g
)));
}
std
::
string
GetString
()
const
...
...
@@ -267,10 +237,34 @@ public:
return
_v
;
}
size_t
GetGraphPtr
()
const
{
std
::
shared_ptr
<
Graph
>
pg
(
_g
);
return
size_t
(
pg
.
get
());
}
std
::
string
GetGraphType
()
const
{
using
boost
::
python
::
detail
::
gcc_demangle
;
return
gcc_demangle
(
typeid
(
Graph
).
name
());
}
template
<
class
OGraph
>
bool
operator
==
(
const
PythonVertex
<
OGraph
>&
other
)
const
{
return
_v
==
other
.
_v
;
}
template
<
class
OGraph
>
bool
operator
!=
(
const
PythonVertex
<
OGraph
>&
other
)
const
{
return
_v
!=
other
.
_v
;
}
template
<
class
OGraph
>
bool
operator
<
(
const
PythonVertex
<
OGraph
>&
other
)
const
{
return
_v
<
other
.
_v
;
}
template
<
class
OGraph
>
bool
operator
<=
(
const
PythonVertex
<
OGraph
>&
other
)
const
{
return
_v
<=
other
.
_v
;
}
template
<
class
OGraph
>
bool
operator
>
(
const
PythonVertex
<
OGraph
>&
other
)
const
{
return
_v
>
other
.
_v
;
}
template
<
class
OGraph
>
bool
operator
>=
(
const
PythonVertex
<
OGraph
>&
other
)
const
{
return
_v
>=
other
.
_v
;
}
private:
boo
st
::
python
::
object
_g
;
st
d
::
weak_ptr
<
Graph
>
_g
;
GraphInterface
::
vertex_t
_v
;
bool
_valid
;
};
// below are classes related to the PythonEdge type
...
...
@@ -282,35 +276,23 @@ class PythonEdge : public EdgeBase
{
public:
typedef
typename
boost
::
graph_traits
<
Graph
>::
edge_descriptor
edge_descriptor
;
PythonEdge
(
const
boost
::
python
::
object
&
g
,
edge_descriptor
e
)
:
_g
(
g
),
_e
(
e
),
_valid
(
true
)
{
}
PythonEdge
(
std
::
shared_ptr
<
Graph
>
g
,
edge_descriptor
e
)
:
_g
(
g
),
_e
(
e
)
{}
bool
IsValid
()
const
{
boost
::
python
::
object
g
=
_g
();
if
(
g
.
ptr
()
==
Py_None
||
!
_valid
)
std
::
shared_ptr
<
Graph
>
gp
(
_g
);
Graph
*
g
=
gp
.
get
();
if
(
g
==
nullptr
)
return
false
;
GraphInterface
&
gi
=
boost
::
python
::
extract
<
GraphInterface
&>
(
g
.
attr
(
"_Graph__graph"
));
GraphInterface
::
edge_t
e
(
_e
);
typename
GraphInterface
::
multigraph_t
::
vertex_t
s
,
t
;
s
=
source
(
e
,
*
gi
.
_mg
);
t
=
target
(
e
,
*
gi
.
_mg
);
bool
valid
=
((
s
!=
boost
::
graph_traits
<
GraphInterface
::
multigraph_t
>::
null_vertex
())
&&
(
s
<
num_vertices
(
*
gi
.
_mg
))
&&
(
t
!=
boost
::
graph_traits
<
GraphInterface
::
multigraph_t
>::
null_vertex
())
&&
(
t
<
num_vertices
(
*
gi
.
_mg
))
&&
gi
.
GetEdgeIndex
()[
e
]
<=
gi
.
GetMaxEdgeIndex
());
auto
s
=
source
(
_e
,
*
g
);
auto
t
=
target
(
_e
,
*
g
);
return
valid
;
}
void
SetValid
(
bool
valid
)
{
_valid
=
valid
;
return
((
s
!=
boost
::
graph_traits
<
Graph
>::
null_vertex
())
&&
(
s
<
num_vertices
(
*
g
))
&&
(
t
!=
boost
::
graph_traits
<
Graph
>::
null_vertex
())
&&
(
t
<
num_vertices
(
*
g
)));
}
void
CheckValid
()
const
...
...
@@ -319,79 +301,95 @@ public:
throw
ValueException
(
"invalid edge descriptor"
);
}
boost
::
python
::
object
GetGraph
()
const
{
return
_g
();
}
GraphInterface
::
edge_t
GetDescriptor
()
const
{
return
_e
;
}
struct
get_source
PythonVertex
<
Graph
>
GetSource
()
const
{
template
<
class
GraphType
>
void
operator
()(
const
GraphType
&
g
,
const
boost
::
python
::
object
&
pg
,
const
edge_descriptor
&
edge
,
boost
::
python
::
object
&
vertex
)
const
{
typedef
typename
boost
::
graph_traits
<
GraphType
>::
edge_descriptor
edge_t
;
vertex
=
boost
::
python
::
object
(
PythonVertex
(
pg
,
source
(
edge_t
(
edge
),
g
)));
}
};
CheckValid
();
std
::
shared_ptr
<
Graph
>
pg
(
_g
);
Graph
&
g
=
*
pg
;
return
PythonVertex
<
Graph
>
(
pg
,
source
(
_e
,
g
));
}
boost
::
python
::
object
GetSource
()
const
PythonVertex
<
Graph
>
GetTarget
()
const
{
CheckValid
();
GraphInterface
&
gi
=
boost
::
python
::
extract
<
GraphInterface
&>
(
_g
().
attr
(
"_Graph__graph"
));
boost
::
python
::
object
v
;
run_action
<>
()(
gi
,
std
::
bind
(
get_source
(),
std
::
placeholders
::
_1
,
std
::
ref
(
_g
),
std
::
ref
(
_e
),
std
::
ref
(
v
)))();
return
v
;
std
::
shared_ptr
<
Graph
>
pg
(
_g
);
Graph
&
g
=
*
pg
;
return
PythonVertex
<
Graph
>
(
pg
,
target
(
_e
,
g
));
}
st
ruct
get_targe
t
st
d
::
string
GetString
()
cons
t
{
template
<
class
GraphType
>
void
operator
()(
const
GraphType
&
g
,
const
boost
::
python
::
object
&
pg
,
const
edge_descriptor
&
edge
,
boost
::
python
::
object
&
vertex
)
const
{
typedef
typename
boost
::
graph_traits
<
GraphType
>::
edge_descriptor
edge_t
;