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 <string>
40 #include <iostream>
41 #include <list> // For Polygon<>::operator>>()
42 
43 #include <cassert>
44 
45 namespace WFMath {
46 
47 // sstream vs. strstream compatibility wrapper
48 
49 namespace _IOWrapper {
50 
51  // Need separate read/write classes, since one is const C& and the other is C&
52 
53  class BaseRead {
54  public:
55  virtual ~BaseRead() {}
56 
57  virtual void read(std::istream& is) = 0;
58  };
59 
60  class BaseWrite {
61  public:
62  virtual ~BaseWrite() {}
63 
64  virtual void write(std::ostream& os) const = 0;
65  };
66 
67  template<class C>
68  class ImplRead : public BaseRead {
69  public:
70  ImplRead(C& c) : m_data(c) {}
71  virtual ~ImplRead() {}
72 
73  virtual void read(std::istream& is) {is >> m_data;}
74 
75  private:
76  C &m_data;
77  };
78 
79  template<class C>
80  class ImplWrite : public BaseWrite {
81  public:
82  ImplWrite(const C& c) : m_data(c) {}
83  virtual ~ImplWrite() {}
84 
85  virtual void write(std::ostream& os) const {os << m_data;}
86 
87  private:
88  const C &m_data;
89  };
90 
91  std::string ToStringImpl(const BaseWrite& b, std::streamsize precision);
92  void FromStringImpl(BaseRead& b, const std::string& s, std::streamsize precision);
93 }
94 
96 
99 template<class C>
100 inline std::string ToString(const C& c, std::streamsize precision = 6)
101 {
102  return _IOWrapper::ToStringImpl(_IOWrapper::ImplWrite<C>(c), precision);
103 }
104 
106 
109 template<class C>
110 inline void FromString(C& c, const std::string& s, std::streamsize = 6)
111 {
113  _IOWrapper::FromStringImpl(i, s, 6);
114 }
115 
116 void ReadCoordList(std::istream& is, CoordType* d, const int num);
117 void WriteCoordList(std::ostream& os, const CoordType* d, const int num);
118 CoordType GetEpsilon(std::istream& is);
119 
120 template<int dim>
121 inline std::ostream& operator<<(std::ostream& os, const Vector<dim>& v)
122 {
123  WriteCoordList(os, v.m_elem, dim);
124  return os;
125 }
126 
127 template<int dim>
128 inline std::istream& operator>>(std::istream& is, Vector<dim>& v)
129 {
130  ReadCoordList(is, v.m_elem, dim);
131  v.m_valid = true;
132  return is;
133 }
134 
135 template<int dim>
136 inline std::ostream& operator<<(std::ostream& os, const RotMatrix<dim>& m)
137 {
138  os << '(';
139 
140  for(int i = 0; i < dim; ++i) {
141  WriteCoordList(os, m.m_elem[i], dim);
142  os << (i < (dim - 1) ? ',' : ')');
143  }
144 
145  return os;
146 }
147 
148 template<int dim>
149 inline std::istream& operator>>(std::istream& is, RotMatrix<dim>& m)
150 {
151  CoordType d[dim*dim];
152  char next;
153 
154  is >> next;
155  if(next != '(')
156  throw ParseError();
157 
158  for(int i = 0; i < dim; ++i) {
159  ReadCoordList(is, d + i * dim, dim);
160  is >> next;
161  char want = (i == dim - 1) ? ')' : ',';
162  if(next != want)
163  throw ParseError();
164  }
165 
166  if(!m._setVals(d, FloatMax(numeric_constants<CoordType>::epsilon(), GetEpsilon(is))))
167  throw ParseError();
168 
169  return is;
170 }
171 
172 template<int dim>
173 inline std::ostream& operator<<(std::ostream& os, const Point<dim>& p)
174 {
175  WriteCoordList(os, p.m_elem, dim);
176  return os;
177 }
178 
179 template<int dim>
180 inline std::istream& operator>>(std::istream& is, Point<dim>& p)
181 {
182  ReadCoordList(is, p.m_elem, dim);
183  p.m_valid = true;
184  return is;
185 }
186 
187 template<int dim>
188 inline std::ostream& operator<<(std::ostream& os, const AxisBox<dim>& a)
189 {
190  return os << "AxisBox: m_low = " << a.m_low << ", m_high = " << a.m_high;
191 }
192 
193 template<int dim>
194 inline std::istream& operator>>(std::istream& is, AxisBox<dim>& a)
195 {
196  char next;
197 
198  do {
199  is >> next;
200  } while(next != '=');
201 
202  is >> a.m_low;
203 
204  do {
205  is >> next;
206  } while(next != '=');
207 
208  is >> a.m_high;
209 
210  return is;
211 }
212 
213 template<int dim>
214 inline std::ostream& operator<<(std::ostream& os, const Ball<dim>& b)
215 {
216  return os << "Ball: m_center = " << b.m_center <<
217  + ", m_radius = " << b.m_radius;
218 }
219 
220 template<int dim>
221 inline std::istream& operator>>(std::istream& is, Ball<dim>& b)
222 {
223  char next;
224 
225  do {
226  is >> next;
227  } while(next != '=');
228 
229  is >> b.m_center;
230 
231  do {
232  is >> next;
233  } while(next != '=');
234 
235  is >> b.m_radius;
236 
237  return is;
238 }
239 
240 template<int dim>
241 inline std::ostream& operator<<(std::ostream& os, const Segment<dim>& s)
242 {
243  return os << "Segment: m_p1 = " << s.m_p1 << ", m_p2 = " << s.m_p2;
244 }
245 
246 template<int dim>
247 inline std::istream& operator>>(std::istream& is, Segment<dim>& s)
248 {
249  char next;
250 
251  do {
252  is >> next;
253  } while(next != '=');
254 
255  is >> s.m_p1;
256 
257  do {
258  is >> next;
259  } while(next != '=');
260 
261  is >> s.m_p2;
262 
263  return is;
264 }
265 
266 template<int dim>
267 inline std::ostream& operator<<(std::ostream& os, const RotBox<dim>& r)
268 {
269  return os << "RotBox: m_corner0 = " << r.m_corner0
270  << ", m_size = " << r.m_size
271  << ", m_orient = " << r.m_orient;
272 }
273 
274 template<int dim>
275 inline std::istream& operator>>(std::istream& is, RotBox<dim>& r)
276 {
277  char next;
278 
279  do {
280  is >> next;
281  } while(next != '=');
282 
283  is >> r.m_corner0;
284 
285  do {
286  is >> next;
287  } while(next != '=');
288 
289  is >> r.m_size;
290 
291  do {
292  is >> next;
293  } while(next != '=');
294 
295  is >> r.m_orient;
296 
297  return is;
298 }
299 
300 template<> std::ostream& operator<<(std::ostream& os, const Polygon<2>& r);
301 template<> std::istream& operator>>(std::istream& is, Polygon<2>& r);
302 
303 
304 
305 
306 template<int dim>
307 inline std::ostream& operator<<(std::ostream& os, const Line<dim>& r)
308 {
309  size_t size = r.numCorners();
310 
311  if(size == 0) {
312  os << "<empty>";
313  return os;
314  }
315 
316  os << "Line: (";
317 
318  for(size_t i = 0; i < size; ++i)
319  os << r.getCorner(i) << (i < (dim - 1) ? ',' : ')');
320 
321  return os;
322 }
323 
324 } // namespace WFMath
325 
326 #endif // WFMATH_STREAM_H
Generic library namespace.
Definition: shape.h:41
A dim dimensional axis-aligned box.
Definition: axisbox.h:63
A dim dimensional rotation matrix. Technically, a member of the group O(dim).
Definition: const.h:53
double CoordType
Basic floating point type.
Definition: const.h:140
A dim dimensional box, lying at an arbitrary angle.
Definition: const.h:52
A dim dimensional vector.
Definition: const.h:55
The 2D specialization of the Polygon<> template.
Definition: polygon.h:47
void FromString(C &c, const std::string &s, std::streamsize=6)
Parse a WFMath type from a string.
Definition: stream.h:110
A line segment embedded in dim dimensions.
Definition: const.h:54
An error thrown by operator>>() when it fails to parse wfmath types.
Definition: error.h:54
A dim dimensional point.
Definition: const.h:50
std::string ToString(const C &c, std::streamsize precision=6)
Output a WFMath type as a string.
Definition: stream.h:100
A dim dimensional ball.
Definition: ball.h:34