diff --git a/include/boost/graph/adjacency_list_io.hpp b/include/boost/graph/adjacency_list_io.hpp new file mode 100644 index 00000000..4b8dc037 --- /dev/null +++ b/include/boost/graph/adjacency_list_io.hpp @@ -0,0 +1,287 @@ +// François Faure, iMAGIS-GRAVIR / UJF, 2001 +#ifndef ______adj_list_io_______ +#define ______adj_list_io_______ + +#include +#include +#include + +// Method parse to read an adjacency list from an input stream, +// example: cin >> read( G ); +// +// Method print to write an adjacency list to an output stream, +// example: cout << write( G ); +// +// The adjacency list may include interior vertex and edge properties. + +namespace boost { + +//=========================================================================== +// basic io +template +std::ostream& operator << ( std::ostream& out, const property& p ) +{ + out << p.m_value << " " << Next(p); + return out; +} + +template +std::ostream& operator << ( std::ostream& out, const property& p ) +{ + out << p.m_value; + return out; +} + +std::ostream& operator << ( std::ostream& out, const no_property& ) +{ + return out; +} + + +template +std::istream& operator >> ( std::istream& in, property& p ) +{ + in >> p.m_value >> *(static_cast(&p)); // houpla !! + return in; +} + +template +std::istream& operator >> ( std::istream& in, property& p ) +{ + in >> p.m_value; + return in; +} + +std::istream& operator >> ( std::istream& in, no_property& ) +{ + return in; +} + +// basic io +//=========================================================================== +// graph parser + +template +struct GraphParser +{ + + typedef Graph_t Graph; + + GraphParser( Graph* g ): graph(g) + {} + + GraphParser& operator () ( std::istream& in ) + { + typedef graph_traits::vertex_descriptor Vertex; + std::vector 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( !isspace(c) ){ + in.putback(c); + if( state == PARSE_VERTEX ){ + VertexProperty vp; + if( in >> vp ) + nodes.push_back( add_vertex(vp, *graph) ); + else + cerr<<"readVertex, parse error at line "<> source >> target; + if( in >> ep ) + add_edge(nodes[source], nodes[target], ep, *graph); + else + cerr<<"readEdge, parse error at line "<> n ){ + for( int i=0; i +std::istream& operator >> ( std::istream& in, GraphParser gp ) +{ + gp(in); + return in; +} + +template +GraphParser,VP,EP> +read( adjacency_list& g ) +{ + return GraphParser,VP,EP>(&g); +} + +// parser +//======================================================================= +// property printer + +template +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 + PropertyPrinter& operator () ( std::ostream& out, Iterator it ) + { + typename property_map::type ps = get(Tag(), *graph); + out << ps[ *it ] <<", "; + PropertyPrinter print(*graph); + print(out, it); + return (*this); + } +private: + Graph* graph; +}; +template +struct PropertyPrinter +{ + PropertyPrinter( Graph& ){} + + template + PropertyPrinter& operator () ( std::ostream&, Iterator it ){ return *this; } +}; + +// property printer +//========================================================================= +// printer + +template +struct EdgePrinter +{ + + typedef Graph_t Graph; + typedef graph_traits::vertex_descriptor Vertex; + + EdgePrinter( Graph& g ) + : graph(g) + {} + + const EdgePrinter& operator () ( std::ostream& out ) const + { + // assign indices to vertices + std::map indices; + int num = 0; + graph_traits::vertex_iterator vi; + for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi){ + indices[*vi] = num++; + } + + // write edges + PropertyPrinter print_Edge(graph); + out << "e" << endl; + graph_traits::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 << endl; + } + out << endl; + return (*this); + } + +protected: + + Graph& graph; + +}; + +template +struct GraphPrinter: public EdgePrinter +{ + GraphPrinter( Graph& g ) + : EdgePrinter(g) + {} + + const GraphPrinter& operator () ( std::ostream& out ) const + { + PropertyPrinter printNode(graph); + out << "v"<::vertex_iterator vi; + for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi){ + printNode(out,vi); + out << endl; + } + out << endl; + + EdgePrinter::operator ()( out ); + return (*this); + } +}; + +template +struct GraphPrinter + : public EdgePrinter +{ + GraphPrinter( G& g ) + : EdgePrinter(g) + {} + + const GraphPrinter& operator () ( std::ostream& out ) const + { + out << "n "<< num_vertices(graph) << endl; + EdgePrinter::operator ()( out ); + return (*this); + } +}; + +template +std::ostream& operator << ( std::ostream& out, const GraphPrinter& gp ) +{ + gp(out); + return out; +} + +template +GraphPrinter,VP,EP> +write( adjacency_list& g ) +{ + return GraphPrinter,VP,EP>(g); +} +// printer +//========================================================================= + +}// boost + + + +#endif