graph_copy.cc 3.38 KB
Newer Older
1 2
// graph-tool -- a general graph modification and manipulation thingy
//
Tiago Peixoto's avatar
Tiago Peixoto committed
3
// Copyright (C) 2007-2012 Tiago de Paula Peixoto <tiago@skewed.de>
4 5 6 7 8 9 10 11 12 13 14 15 16 17
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU 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/>.

18 19
#include <boost/mpl/contains.hpp>
#include <boost/python/extract.hpp>
20 21 22 23 24 25 26 27 28 29 30 31 32 33

#include "graph.hh"
#include "graph_filtering.hh"
#include "graph_properties.hh"

using namespace std;
using namespace boost;
using namespace graph_tool;

struct graph_copy
{
    template <class GraphDst, class GraphSrc, class DstVertexIndexMap,
              class SrcVertexIndexMap,  class DstEdgeIndexMap,
              class SrcEdgeIndexMap>
34 35 36 37 38
    void operator()(const GraphSrc& src, GraphDst& dst,
                    DstVertexIndexMap src_vertex_index,
                    SrcVertexIndexMap dst_vertex_index,
                    DstEdgeIndexMap src_edge_index,
                    SrcEdgeIndexMap dst_edge_index) const
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
    {
        vector<size_t> index_map(num_vertices(src));
        typename graph_traits<GraphSrc>::vertex_iterator v, v_end;
        for (tie(v, v_end) = vertices(src); v != v_end; ++v)
        {
            if (src_vertex_index[*v] >= index_map.size())
                index_map.resize(src_vertex_index[*v]+1);
            typename graph_traits<GraphDst>::vertex_descriptor new_v =
                add_vertex(dst);
            index_map[src_vertex_index[*v]] = dst_vertex_index[new_v];
        }

        typename graph_traits<GraphSrc>::edge_iterator e, e_end;
        for (tie(e, e_end) = edges(src); e != e_end; ++e)
        {
Tiago Peixoto's avatar
Tiago Peixoto committed
54 55
            size_t s = index_map[src_vertex_index[source(*e, src)]];
            size_t t = index_map[src_vertex_index[target(*e, src)]];
56 57
            typename graph_traits<GraphDst>::edge_descriptor new_e =
                add_edge(vertex(s,dst), vertex(t,dst), dst).first;
Tiago Peixoto's avatar
Tiago Peixoto committed
58
            dst_edge_index[new_e] = src_edge_index[*e];
59 60 61 62 63
        }
    }
};

// copy constructor
Tiago Peixoto's avatar
Tiago Peixoto committed
64 65 66 67
GraphInterface::GraphInterface(const GraphInterface& gi, bool keep_ref)
    :_state(keep_ref ? gi._state : shared_ptr<state_t>(new state_t())),
     _vertex_index(get(vertex_index, _state->_mg)),
     _edge_index(get(edge_index_t(), _state->_mg)),
68
     _reversed(gi._reversed),
69 70 71 72 73 74 75 76
     _directed(gi._directed),
     _vertex_filter_map(_vertex_index),
     _vertex_filter_invert(false),
     _vertex_filter_active(false),
     _edge_filter_map(_edge_index),
     _edge_filter_invert(false),
     _edge_filter_active(false)
{
Tiago Peixoto's avatar
Tiago Peixoto committed
77 78
    if (keep_ref)
        return;
Tiago Peixoto's avatar
Tiago Peixoto committed
79 80 81
    _state->_nedges = gi._state->_nedges;
    _state->_max_edge_index = gi._state->_max_edge_index;
    _state->_free_indexes = gi._state->_free_indexes;
82 83 84 85 86 87

    run_action<>()
        (const_cast<GraphInterface&>(gi),
         bind<void>(graph_copy(), _1, ref(_state->_mg),
                    gi._vertex_index, _vertex_index, 
                    gi._edge_index, _edge_index))();
88
    // filters will be copied in python
89
}
90