I have a boost graph with custom properties. I want to make a copy of it. I tried it by following way.
using BGType = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS,
// Vertex Properties...
vertexProps,
// Edge Propereties...
edgeProps,
// Graph Properties
graphProps>;
vertexProps.h
class vertexProps {
public:
explicit vertexProps(const std::string *moduleName = nullptr, const std::string *name = nullptr,
long refPtr = 0 )
: _refPtr(refPtr),
{
_moduleName = moduleName ? *moduleName : "";
_name = name ? *name : "";
};
std::string _moduleName;
std::string _name;
BGType *_subGraph = nullptr;
BGType *_graph = nullptr;
struct CustomVertexCopy {
BGType const &g1;
BGType &g2;
void operator()(BGType::vertex_descriptor v1, BGType::vertex_descriptor v2) const
{
schVertexProps const &p1 = g1[v1];
schVertexProps &p2 = g2[v2];
p2._subGraph = p1._subGraph;
p2._graph = p1._graph;
p2._moduleName = p1._moduleName;
p2._name = p1._name;
}
};
edgeProps.h
class edgeProps {
public:
explicit edgeProps(std::string name = "")
: _name(name){};
std::string _name;
};
struct CustomEdgeCopy {
BGType const &g1;
BGType &g2;
void operator()(BGType::edge_descriptor e1, BGType::edge_descriptor e2) const { g2[e2]._name = g1[e1]._name; }
};
someFunction.cpp
OnClick(BGType* bgNew)
{
// some code
BGType* oldBg = new BGType;
boost::copy_graph(
*bgNew, *oldBg,
boost::vertex_copy(CustomVertexCopy{*bgNew, *oldBg}).edge_copy(CustomEdgeCopy{*bgNew, *oldBg}));
boost::get_property(*oldBg) = boost::get_property(*bgNew);
// Copying graph properties
DeepCopyOfBG(bgNew, oldBg);
}
void someFunction::DeepCopyOfBG(BGType* bGraph, BGType* oldBg)
{
// Iterate through the source map and copy its contents
for (const auto& entry : (*bGraph)[boost::graph_bundle]._modInfo) {
const std::string& key = entry.first;
const auto& value = entry.second;
// Create a deep copy of value (a tuple containing vectors of schPinInfo)
std::tuple<std::vector<schPinInfo*>, std::vector<schPinInfo*>, std::vector<schPinInfo*>> deepCopyValue = value;
// Add the deep copy to the target map
(*oldBg)[boost::graph_bundle]._modInfo[key] = deepCopyValue;
}
// some more properties.
}
Above way working fine. But it has 1 issue. Vertex property has 1 field which itself is a boost graph.
p2._subGraph = p1._subGraph;
And above line merely copying pointers. So in old boost graph, I am getting new boost graph's sub graph which I dont want. So how to deep copy this _subGraph field ?
It really doesn't. As you noted yourself, it contains pointers to graphs. That's just not the same thing.
I suspect you do want it, because copying graphs for every vertex is expensive. So unless you are using tiny graphs, I'd suggest embracing the indirection by using
shared_ptr<BGType const>which also solves the lifetime problems (your code almost inevitably suffers from memory leaks as it is now).Side note:
looks suspect too. Should it be
p2._graph = &g2;?Solution 1
If you want full copies, the simplest way would be to not use pointers, so the line
actually copies the object.
Solution 2
You can obviously spell it out, introducing fresh opportunities for memory leaks by using raw pointers:
Since you're still doing complicated dances to copy the graph in other spots, you might need to repeat that here. I suggest making a function that does it:
DEMO
I'm going to supply a demo - as customary - but I'm going to base it on my earlier suggestions that show full value-semantics avoiding all the unnecessary complication of copying the graph in the first place.
Now, because there's recursion here (graphs have nodes which contain graphs which contain nodes which ... etc), we have to use some kind of dynamic allocation. I chose a "value_ptr" which is basically a
unique_ptrthat copies by deep-copy:Now the default copy assignment will do what you want, without risk of memory leaks, and without writing over-complicated code.
Because
BGTypeneeds to be forward declared here, we have to define it as a struct - which we can do by inheriting:Now with main like:
We can have the output
Note that the subgraph addresses are distinct. There is no memory leak here.
Full Listing
Live On Coliru