The CyMeAlg Software (Release 0.01)
readwrite.h
Go to the documentation of this file.
1 /// @addtogroup cymealg
2 /// @{
3 
4 /////////////////////////////////////////////////////////////////////////////
5 ///
6 /// @file
7 ///
8 /// This header file contains functions for reading and writing digraphs
9 /// from and to human-readable text streams.
10 ///
11 /// @author Pawel Pilarczyk
12 ///
13 /////////////////////////////////////////////////////////////////////////////
14 
15 // Copyright (C) 1997-2020 by Pawel Pilarczyk.
16 //
17 // This file is part of my research software. This is free software:
18 // you can redistribute it and/or modify it under the terms of the GNU
19 // General Public License as published by the Free Software Foundation,
20 // either version 3 of the License, or (at your option) any later version.
21 //
22 // This software is distributed in the hope that it will be useful,
23 // but WITHOUT ANY WARRANTY; without even the implied warranty of
24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 // GNU General Public License for more details.
26 //
27 // You should have received a copy of the GNU General Public License
28 // along with this software; see the file "license.txt". If not,
29 // please, see <http://www.gnu.org/licenses/>.
30 
31 // Started in January 2006. Last revision: August 23, 2019.
32 
33 
34 #ifndef _CYMEALG_READWRITE_H_
35 #define _CYMEALG_READWRITE_H_
36 
37 // include selected header files from the CHomP library
38 #include "chomp/system/config.h"
39 #include "chomp/system/textfile.h"
40 
41 namespace cymealg {
42 
43 /// Reads a graph in the text mode from an input stream.
44 /// The graph must be initially empty, or otherwise the graph
45 /// read from the input stream is appended to the existing graph.
46 template <class inType, class Graph>
47 inline inType &read (inType &in, Graph &g)
48 {
49  chomp::homology::ignorecomments (in);
50 
51  // the number of vertices in the input graph (optional);
52  // necessary if there are no outgoing edges from the last vertex
53  int_t nVertices (-1);
54 
55  // read all the edges in the graph and add them
56  int_t curVertex (g. countVertices () - 1);
57  int_t curEdge (0);
58  while (!in. eof ())
59  {
60  // read the source vertex number
61  int_t vertex (-1);
62  in >> vertex;
63  chomp::homology::ignorecomments (in);
64 
65  // if this was the number of vertices then remember it
66  if ((nVertices < 0) && (in. peek () != '-'))
67  {
68  nVertices = vertex;
69  chomp::homology::ignoreline (in);
70  chomp::homology::ignorecomments (in);
71  continue;
72  }
73 
74  // read the arrow "->"
75  if (in. peek () == '-')
76  in. get ();
77  if (in. peek () == '>')
78  in. get ();
79  chomp::homology::ignorecomments (in);
80 
81  // read the target vertex number of the edge
82  int_t target (-1);
83  in >> target;
84  chomp::homology::ignorecomments (in);
85 
86  // read the edge weight if it is provided
87  typename Graph::weight_type weight;
88  bool weightRead (false);
89  if (in. peek () == '[')
90  {
91  in. get ();
92  in >> weight;
93  weightRead = true;
94  if (in. peek () == ']')
95  in. get ();
96  }
97  chomp::homology::ignorecomments (in);
98 
99  // add as many vertices to the graph as necessary
100  if (vertex < curVertex)
101  throw "Wrong order of vertices in the input stream.";
102  while (vertex > curVertex)
103  {
104  g. addVertex ();
105  ++ curVertex;
106  curEdge = 0;
107  }
108 
109  // add the edge to the graph
110  g. addEdge (target);
111 
112  // add the weight of the edge if it was read
113  if (weightRead)
114  g. setWeight (curVertex, curEdge, weight);
115 
116  // increase the counter of edges of the current vertex
117  ++ curEdge;
118  }
119 
120  // add the remaining vertices to the graph
121  while (g. countVertices () < nVertices)
122  g. addVertex ();
123 
124  return in;
125 } /* read */
126 
127 // --------------------------------------------------
128 
129 /// Reads a graph in the text mode from an input stream.
130 template <class wType>
131 inline std::istream &operator >> (std::istream &in, diGraph<wType> &g)
132 {
133  return read (in, g);
134 } /* operator >> */
135 
136 // --------------------------------------------------
137 
138 /// Outputs the graph to a text stream in a human-readable format.
139 template <class outType, class Graph>
140 inline outType &write (outType &out, const Graph &g, bool writeWeights)
141 {
142  int_t nVertices (g. countVertices ());
143  out << "; Directed graph.\n";
144  out << nVertices << " vertices.\n";
145  for (int_t i = 0; i < nVertices; ++ i)
146  {
147  int_t nEdges (g. countEdges (i));
148  for (int_t j = 0; j < nEdges; ++ j)
149  {
150  out << i << " -> " << g. getEdge (i, j);
151  if (writeWeights)
152  out << " [" << g. getWeight (i, j) << "]\n";
153  else
154  out << "\n";
155  }
156  }
157  out << "; This is the end of the graph.\n";
158  return out;
159 } /* write */
160 
161 // --------------------------------------------------
162 
163 /// Writes a graph in the text mode to an output stream.
164 template <class wType>
165 inline std::ostream &operator << (std::ostream &out, const diGraph<wType> &g)
166 {
167  return write (out, g, true);
168 } /* operator << */
169 
170 
171 } // namespace cymealg
172 
173 #endif // _CYMEALG_READWRITE_H_
174 
175 /// @}
176 
This class defines a weighted directed graph with very limited number of operations.
Definition: digraph.h:75
inType & read(inType &in, Graph &g)
Reads a graph in the text mode from an input stream.
Definition: readwrite.h:47
std::istream & operator>>(std::istream &in, diGraph< wType > &g)
Reads a graph in the text mode from an input stream.
Definition: readwrite.h:131
outType & write(outType &out, const Graph &g, bool writeWeights)
Outputs the graph to a text stream in a human-readable format.
Definition: readwrite.h:140