//======================================================================= // Copyright 2001 Universite Joseph Fourier, Grenoble. // Author: Francois Faure // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= #ifndef BOOST_GRAPH_ADJACENCY_LIST_IO_HPP #define BOOST_GRAPH_ADJACENCY_LIST_IO_HPP #include #include #include #include #include // 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 input template std::istream& operator >> ( std::istream& in, property& p ) { in >> p.m_value >> p.m_base; // houpla !! return in; } template std::istream& operator >> ( std::istream& in, 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 Stag template void get ( property& p, const V& v, Stag s ) { get( p.m_base,v,s ); } template void get ( property& p, const V& v, Stag ) { p.m_value = v; } // get a subset of properties tagged Stag template void getSubset ( property& p, const property& s ) { get( p, s.m_value, Stag() ); getSubset( p, s.m_base ); } template void getSubset ( property& p, const property& s) { get( p, s.m_value, Stag() ); } inline void getSubset ( no_property&, const no_property& ) { } #if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES) template void getSubset(T& p, const U& s) { p = s; } template void getSubset(T&, const no_property&) { } #endif // get property subset //=========================================================================== // graph parser typedef enum{ PARSE_NUM_NODES, PARSE_VERTEX, PARSE_EDGE } GraphParserState; template struct GraphParser { typedef Graph_t Graph; GraphParser( Graph* g ): graph(g) {} GraphParser& operator () ( std::istream& in ) { typedef typename graph_traits::vertex_descriptor Vertex; std::vector nodes; GraphParserState 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"<> 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"<> n ){ for( int i=0; i struct PropertyPrinter { typedef typename Property::value_type Value; typedef typename Property::tag_type Tag; typedef typename Property::next_type Next; PropertyPrinter( const Graph& g ):graph(&g){} template PropertyPrinter& operator () ( std::ostream& out, const Val& v ) { typename property_map::const_type ps = get(Tag(), *graph); out << ps[ v ] <<" "; PropertyPrinter print(*graph); print(out, v); return (*this); } private: const Graph* graph; }; #else template struct PropertyPrinter { PropertyPrinter( const Graph& g ):graph(&g){} template PropertyPrinter& operator () ( std::ostream& out, const Val& v ) { out << (*graph)[ v ] <<" "; return (*this); } private: const Graph* graph; }; template struct PropertyPrinter > { PropertyPrinter( const Graph& g ):graph(&g){} template PropertyPrinter& operator () ( std::ostream& out, const Val& v ) { typename property_map::const_type ps = get(Tag(), *graph); out << ps[ v ] <<" "; PropertyPrinter print(*graph); print(out, v); return (*this); } private: const Graph* graph; }; #endif template struct PropertyPrinter { PropertyPrinter( const Graph& ){} template PropertyPrinter& operator () ( std::ostream&, const Val& ){ return *this; } }; // property printer //========================================================================= // graph printer template struct EdgePrinter { typedef Graph_t Graph; typedef typename graph_traits::vertex_descriptor Vertex; EdgePrinter( const Graph& g ) : graph(g) {} const EdgePrinter& operator () ( std::ostream& out ) const { // assign indices to vertices std::map indices; int num = 0; BGL_FORALL_VERTICES_T(v, graph, Graph) { indices[v] = num++; } // write edges PropertyPrinter print_Edge(graph); out << "e" << std::endl; BGL_FORALL_EDGES_T(e, graph, Graph) { out << indices[source(e,graph)] << " " << indices[target(e,graph)] << " "; print_Edge(out,e); out << std::endl; } out << std::endl; return (*this); } protected: const Graph& graph; }; template struct GraphPrinter: public EdgePrinter { GraphPrinter( const Graph& g ) : EdgePrinter(g) {} const GraphPrinter& operator () ( std::ostream& out ) const { PropertyPrinter printNode(this->graph); out << "v"<graph, Graph) { printNode(out,v); out << std::endl; } EdgePrinter::operator ()( out ); return (*this); } }; template struct GraphPrinter : public EdgePrinter { GraphPrinter( const Graph& g ) : EdgePrinter(g) {} const GraphPrinter& operator () ( std::ostream& out ) const { out << "n "<< num_vertices(this->graph) << std::endl; EdgePrinter::operator ()( out ); return (*this); } }; // graph printer //========================================================================= // user methods /// input stream for reading a graph template std::istream& operator >> ( std::istream& in, GraphParser gp ) { gp(in); return in; } /// graph parser for given subsets of internal vertex and edge properties template GraphParser,VP,EP,VPS,EPS> read( adjacency_list& g, VPS vps, EPS eps ) { return GraphParser,VP,EP,VPS,EPS>(&g); } /// graph parser for all internal vertex and edge properties template GraphParser,VP,EP,VP,EP> read( adjacency_list& g ) { return GraphParser,VP,EP,VP,EP>(&g); } /// output stream for writing a graph template std::ostream& operator << ( std::ostream& out, const GraphPrinter& gp ) { gp(out); return out; } /// write the graph with given property subsets template GraphPrinter,VPS,EPS> write( const adjacency_list& g, VPS, EPS ) { return GraphPrinter,VPS,EPS>(g); } /// write the graph with all internal vertex and edge properties template GraphPrinter,VP,EP> write( const adjacency_list& g ) { return GraphPrinter,VP,EP>(g); } // user methods //========================================================================= }// boost #endif