adjacency_list_io.hpp

来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 376 行

HPP
376
字号
//=======================================================================// Copyright 2001 Universite Joseph Fourier, Grenoble.// Author: Fran鏾is Faure//// This file is part of the Boost Graph Library//// You should have received a copy of the License Agreement for the// Boost Graph Library along with the software; see the file LICENSE.// If not, contact Office of Research, University of Notre Dame, Notre// Dame, IN 46556.//// Permission to modify the code and to distribute modified code is// granted, provided the text of this NOTICE is retained, a notice that// the code was modified is included with the above COPYRIGHT NOTICE and// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE// file is distributed with the modified code.//// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.// By way of example, but not limitation, Licensor MAKES NO// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS// OR OTHER RIGHTS.//=======================================================================#ifndef ______adj_list_io_______#define ______adj_list_io_______#include <iostream>#include <vector>#include <boost/graph/adjacency_list.hpp>#include <cctype>// Method read to parse an adjacency list from an input stream. Examples:// cin >> read( G );// cin >> read( G, NodePropertySubset(), EdgepropertySubset() );//// Method write to print an adjacency list to an output stream. Examples:// cout << write( G );// cout << write( G, NodePropertySubset(), EdgepropertySubset() );namespace boost {/* outline        - basic property input        - get property subset        - graph parser        - property printer        - graph printer        - user methods*///===========================================================================// basic property inputtemplate<class Tag, class Value, class Next>std::istream& operator >> ( std::istream& in, property<Tag,Value,Next>& p ){        in >> p.m_value >> *(static_cast<Next*>(&p)); // houpla !!        return in;}template<class Tag, class Value>std::istream& operator >> ( std::istream& in, property<Tag,Value,no_property>& p ){        in >> p.m_value;        return in;}inline std::istream& operator >> ( std::istream& in, no_property& ){        return in;}// basic property input//===========================================================================// get property subsets// get a single property tagged Stagtemplate<class Tag, class Value, class Next, class V, class Stag>void get( property<Tag,Value,Next>& p, const V& v, Stag s ){        get( *(static_cast<Next*>(&p)),v,s );}template<class Value, class Next, class V, class Stag>void get( property<Stag,Value,Next>& p, const V& v, Stag ){        p.m_value = v;}// get a subset of properties tagged Stagtemplate<class Tag, class Value, class Next,         class Stag, class Svalue, class Snext>void getSubset( property<Tag,Value,Next>& p, const property<Stag,Svalue,Snext>& s ){        get( p, s.m_value, Stag() );        getSubset( p, Snext(s) );}template<class Tag, class Value, class Next,         class Stag, class Svalue>void getSubset( property<Tag,Value,Next>& p, const property<Stag,Svalue,no_property>& s ){        get( p, s.m_value, Stag() );}inline void getSubset( no_property& p, const no_property& s ){}//  get property subset//===========================================================================// graph parsertemplate<class Graph_t, class VertexProperty, class EdgeProperty, class VertexPropertySubset,class EdgePropertySubset>struct GraphParser{        typedef Graph_t Graph;                GraphParser( Graph* g ): graph(g)        {}                      GraphParser& operator () ( std::istream& in )        {                typedef typename graph_traits<Graph>::vertex_descriptor Vertex;                std::vector<Vertex> nodes;                typedef enum{ PARSE_NUM_NODES, PARSE_VERTEX, PARSE_EDGE } State;                State state = PARSE_VERTEX;                unsigned int numLine = 1;                char c;                while ( in.get(c) )                {                        if( c== '#' ) skip(in);                        else if( c== 'n' ) state = PARSE_NUM_NODES;                        else if( c== 'v' ) state = PARSE_VERTEX;                        else if( c== 'e' ) state = PARSE_EDGE;                        else if( c== '\n' ) numLine++;                        else if( !std::isspace(c) ){                                in.putback(c);                                if( state == PARSE_VERTEX ){                                        VertexPropertySubset readProp;                                        if( in >> readProp )                                        {                                                VertexProperty vp;                                                getSubset( vp, readProp );                                                nodes.push_back( add_vertex(vp, *graph) );                                        }                                        else                                                std::cerr<<"read vertex, parse error at line"<<numLine<<std::endl;                                }                                else if( state == PARSE_EDGE ) {                                        int source, target;                                        EdgePropertySubset readProp;                                        in >> source >> target;                                        if( in >> readProp )                                         {                                                EdgeProperty ep;                                                getSubset( ep, readProp );                                                add_edge(nodes[source], nodes[target], ep, *graph);                                        }                                        else                                                std::cerr<<"read edge, parse error at line"<<numLine<<std::endl;                                }                                else { // state == PARSE_NUM_NODES                                        int n;                                        if( in >> n ){                                                for( int i=0; i<n; ++i )                                                        nodes.push_back( add_vertex( *graph ));                                        }                                        else                                                 std::cerr<<"read num_nodes, parse error at line "<< numLine << std::endl;                                }                        }                }        return (*this);        }                protected:        Graph* graph;                void skip( std::istream& in )        {                char c = 0;                while( c!='\n' && !in.eof() )                        in.get(c);                in.putback(c);        }};// parser//=======================================================================// property printertemplate<class Graph, class Property>struct PropertyPrinter{        typedef typename Property::value_type Value;        typedef typename Property::tag_type Tag;        typedef typename Property::next_type Next;                PropertyPrinter( Graph& g ):graph(&g){}                template<class Iterator>        PropertyPrinter& operator () ( std::ostream& out, Iterator it )        {                typename property_map<Graph,Tag>::type ps = get(Tag(), *graph);                out << ps[ *it ] <<" ";                PropertyPrinter<Graph,Next> print(*graph);                print(out, it);                return (*this);        }private:        Graph* graph;};template<class Graph>struct PropertyPrinter<Graph, no_property>{        PropertyPrinter( Graph& ){}        template<class Iterator>        PropertyPrinter& operator () ( std::ostream&, Iterator it ){ return *this; }};// property printer//=========================================================================// graph printertemplate<class Graph_t, class EdgeProperty>struct EdgePrinter{        typedef Graph_t Graph;        typedef typename graph_traits<Graph>::vertex_descriptor Vertex;                EdgePrinter( Graph& g )                : graph(g)        {}                      const EdgePrinter& operator () ( std::ostream& out ) const        {                // assign indices to vertices                std::map<Vertex,int> indices;                int num = 0;                typename graph_traits<Graph>::vertex_iterator vi;                for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi){                        indices[*vi] = num++;                }                // write edges                PropertyPrinter<Graph, EdgeProperty> print_Edge(graph);                out << "e" << std::endl;                typename graph_traits<Graph>::edge_iterator ei;                for (ei = edges(graph).first; ei != edges(graph).second; ++ei){                        out << indices[source(*ei,graph)] <<  " " << indices[target(*ei,graph)] << "  ";                         print_Edge(out,ei);                         out << std::endl;                }                out << std::endl;                            return (*this);        }        protected:        Graph& graph;        };template<class Graph, class V, class E>struct GraphPrinter: public EdgePrinter<Graph,E>{        GraphPrinter( Graph& g )          : EdgePrinter<Graph,E>(g)        {}                const GraphPrinter& operator () ( std::ostream& out ) const        {                PropertyPrinter<Graph, V> printNode(this->graph);                out << "v"<<std::endl;                typename graph_traits<Graph>::vertex_iterator vi;                for (vi = vertices(this->graph).first; vi != vertices(this->graph).second; ++vi){                        printNode(out,vi);                         out << std::endl;                }                                EdgePrinter<Graph,E>::operator ()( out );                return (*this);        }};template<class Graph, class E>struct GraphPrinter<Graph,no_property,E>   : public EdgePrinter<Graph,E>{        GraphPrinter( Graph& g )          : EdgePrinter<Graph,E>(g)        {}                const GraphPrinter& operator () ( std::ostream& out ) const        {                out << "n "<< num_vertices(this->graph) << std::endl;                EdgePrinter<Graph,E>::operator ()( out );                return (*this);        }};// graph printer//=========================================================================// user methods/// input stream for reading a graphtemplate<class Graph, class VP, class EP, class VPS, class EPS>std::istream& operator >> ( std::istream& in, GraphParser<Graph,VP,EP,VPS,EPS> gp ) {         gp(in);         return in; }/// graph parser for given subsets of internal vertex and edge propertiestemplate<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS> read( adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS vps, EPS eps ){        return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS>(&g);}/// graph parser for all internal vertex and edge propertiestemplate<class EL, class VL, class D, class VP, class EP, class GP>GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP> read( adjacency_list<EL,VL,D,VP,EP,GP>& g ){        return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP>(&g);}/// output stream for writing a graphtemplate<class Graph, class VP, class EP>std::ostream& operator << ( std::ostream& out, const GraphPrinter<Graph,VP,EP>& gp ) {         gp(out);         return out; }/// write the graph with given property subsetstemplate<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS> write( adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS, EPS ){        return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS>(g);}/// write the graph with all internal vertex and edge propertiestemplate<class EL, class VL, class D, class VP, class EP, class GP>GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP> write( adjacency_list<EL,VL,D,VP,EP,GP>& g ){        return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP>(g);}// user methods//=========================================================================}// boost#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?