wfmath  1.0.3
A math library for the Worldforge system.
stream.h
1 // stream.h (Functions in the WFMath library that use streams)
2 //
3 // The WorldForge Project
4 // Copyright (C) 2001,2002 The WorldForge Project
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // For information about WorldForge and its authors, please contact
21 // the Worldforge Web Site at http://www.worldforge.org.
22 
23 // Author: Ron Steinke
24 // Created: 2001-12-7
25 
26 #ifndef WFMATH_STREAM_H
27 #define WFMATH_STREAM_H
28 
29 #include <wfmath/vector.h>
30 #include <wfmath/rotmatrix.h>
31 #include <wfmath/point.h>
32 #include <wfmath/axisbox.h>
33 #include <wfmath/ball.h>
34 #include <wfmath/segment.h>
35 #include <wfmath/rotbox.h>
36 #include <wfmath/polygon.h>
37 #include <wfmath/line.h>
38 #include <wfmath/error.h>
39 #include <iostream>
40 
41 
42 namespace WFMath {
43 
44 // sstream vs. strstream compatibility wrapper
45 
46 namespace _IOWrapper {
47 
48  // Need separate read/write classes, since one is const C& and the other is C&
49 
50  class BaseRead {
51  public:
52  virtual ~BaseRead() {}
53 
54  virtual void read(std::istream& is) = 0;
55  };
56 
57  class BaseWrite {
58  public:
59  virtual ~BaseWrite() {}
60 
61  virtual void write(std::ostream& os) const = 0;
62  };
63 
64  template<class C>
65  class ImplRead : public BaseRead {
66  public:
67  ImplRead(C& c) : m_data(c) {}
68  virtual ~ImplRead() {}
69 
70  virtual void read(std::istream& is) {is >> m_data;}
71 
72  private:
73  C &m_data;
74  };
75 
76  template<class C>
77  class ImplWrite : public BaseWrite {
78  public:
79  ImplWrite(const C& c) : m_data(c) {}
80  virtual ~ImplWrite() {}
81 
82  virtual void write(std::ostream& os) const {os << m_data;}
83 
84  private:
85  const C &m_data;
86  };
87 
88  std::string ToStringImpl(const BaseWrite& b, std::streamsize precision);
89  void FromStringImpl(BaseRead& b, const std::string& s, std::streamsize precision);
90 }
91 
93 
96 template<class C>
97 inline std::string ToString(const C& c, std::streamsize precision = 6)
98 {
99  return _IOWrapper::ToStringImpl(_IOWrapper::ImplWrite<C>(c), precision);
100 }
101 
103 
106 template<class C>
107 inline void FromString(C& c, const std::string& s, std::streamsize = 6)
108 {
110  _IOWrapper::FromStringImpl(i, s, 6);
111 }
112 
113 void ReadCoordList(std::istream& is, CoordType* d, const int num);
114 void WriteCoordList(std::ostream& os, const CoordType* d, const int num);
115 CoordType GetEpsilon(std::istream& is);
116 
117 template<int dim>
118 inline std::ostream& operator<<(std::ostream& os, const Vector<dim>& v)
119 {
120  WriteCoordList(os, v.m_elem, dim);
121  return os;
122 }
123 
124 template<int dim>
125 inline std::istream& operator>>(std::istream& is, Vector<dim>& v)
126 {
127  ReadCoordList(is, v.m_elem, dim);
128  v.m_valid = true;
129  return is;
130 }
131 
132 template<int dim>
133 inline std::ostream& operator<<(std::ostream& os, const RotMatrix<dim>& m)
134 {
135  os << '(';
136 
137  for(int i = 0; i < dim; ++i) {
138  WriteCoordList(os, m.m_elem[i], dim);
139  os << (i < (dim - 1) ? ',' : ')');
140  }
141 
142  return os;
143 }
144 
145 template<int dim>
146 inline std::istream& operator>>(std::istream& is, RotMatrix<dim>& m)
147 {
148  CoordType d[dim*dim];
149  char next;
150 
151  is >> next;
152  if(next != '(')
153  throw ParseError();
154 
155  for(int i = 0; i < dim; ++i) {
156  ReadCoordList(is, d + i * dim, dim);
157  is >> next;
158  char want = (i == dim - 1) ? ')' : ',';
159  if(next != want)
160  throw ParseError();
161  }
162 
163  if(!m._setVals(d, FloatMax(numeric_constants<CoordType>::epsilon(), GetEpsilon(is))))
164  throw ParseError();
165 
166  return is;
167 }
168 
169 template<int dim>
170 inline std::ostream& operator<<(std::ostream& os, const Point<dim>& p)
171 {
172  WriteCoordList(os, p.m_elem, dim);
173  return os;
174 }
175 
176 template<int dim>
177 inline std::istream& operator>>(std::istream& is, Point<dim>& p)
178 {
179  ReadCoordList(is, p.m_elem, dim);
180  p.m_valid = true;
181  return is;
182 }
183 
184 template<int dim>
185 inline std::ostream& operator<<(std::ostream& os, const AxisBox<dim>& a)
186 {
187  return os << "AxisBox: m_low = " << a.m_low << ", m_high = " << a.m_high;
188 }
189 
190 template<int dim>
191 inline std::istream& operator>>(std::istream& is, AxisBox<dim>& a)
192 {
193  char next;
194 
195  do {
196  is >> next;
197  } while(next != '=');
198 
199  is >> a.m_low;
200 
201  do {
202  is >> next;
203  } while(next != '=');
204 
205  is >> a.m_high;
206 
207  return is;
208 }
209 
210 template<int dim>
211 inline std::ostream& operator<<(std::ostream& os, const Ball<dim>& b)
212 {
213  return os << "Ball: m_center = " << b.m_center <<
214  + ", m_radius = " << b.m_radius;
215 }
216 
217 template<int dim>
218 inline std::istream& operator>>(std::istream& is, Ball<dim>& b)
219 {
220  char next;
221 
222  do {
223  is >> next;
224  } while(next != '=');
225 
226  is >> b.m_center;
227 
228  do {
229  is >> next;
230  } while(next != '=');
231 
232  is >> b.m_radius;
233 
234  return is;
235 }
236 
237 template<int dim>
238 inline std::ostream& operator<<(std::ostream& os, const Segment<dim>& s)
239 {
240  return os << "Segment: m_p1 = " << s.m_p1 << ", m_p2 = " << s.m_p2;
241 }
242 
243 template<int dim>
244 inline std::istream& operator>>(std::istream& is, Segment<dim>& s)
245 {
246  char next;
247 
248  do {
249  is >> next;
250  } while(next != '=');
251 
252  is >> s.m_p1;
253 
254  do {
255  is >> next;
256  } while(next != '=');
257 
258  is >> s.m_p2;
259 
260  return is;
261 }
262 
263 template<int dim>
264 inline std::ostream& operator<<(std::ostream& os, const RotBox<dim>& r)
265 {
266  return os << "RotBox: m_corner0 = " << r.m_corner0
267  << ", m_size = " << r.m_size
268  << ", m_orient = " << r.m_orient;
269 }
270 
271 template<int dim>
272 inline std::istream& operator>>(std::istream& is, RotBox<dim>& r)
273 {
274  char next;
275 
276  do {
277  is >> next;
278  } while(next != '=');
279 
280  is >> r.m_corner0;
281 
282  do {
283  is >> next;
284  } while(next != '=');
285 
286  is >> r.m_size;
287 
288  do {
289  is >> next;
290  } while(next != '=');
291 
292  is >> r.m_orient;
293 
294  return is;
295 }
296 
297 template<> std::ostream& operator<<(std::ostream& os, const Polygon<2>& r);
298 template<> std::istream& operator>>(std::istream& is, Polygon<2>& r);
299 
300 
301 
302 
303 template<int dim>
304 inline std::ostream& operator<<(std::ostream& os, const Line<dim>& r)
305 {
306  size_t size = r.numCorners();
307 
308  if(size == 0) {
309  os << "<empty>";
310  return os;
311  }
312 
313  os << "Line: (";
314 
315  for(size_t i = 0; i < size; ++i)
316  os << r.getCorner(i) << (i < (dim - 1) ? ',' : ')');
317 
318  return os;
319 }
320 
321 } // namespace WFMath
322 
323 #endif // WFMATH_STREAM_H
Generic library namespace.
Definition: shape.h:41
double CoordType
Basic floating point type.
Definition: const.h:140
void FromString(C &c, const std::string &s, std::streamsize=6)
Parse a WFMath type from a string.
Definition: stream.h:107
std::string ToString(const C &c, std::streamsize precision=6)
Output a WFMath type as a string.
Definition: stream.h:97
static FloatType epsilon()
This is the attempted precision of the library.