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
45namespace WFMath {
46
47// sstream vs. strstream compatibility wrapper
48
49namespace _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
99template<class C>
100inline std::string ToString(const C& c, std::streamsize precision = 6)
101{
102 return _IOWrapper::ToStringImpl(_IOWrapper::ImplWrite<C>(c), precision);
103}
104
106
109template<class C>
110inline void FromString(C& c, const std::string& s, std::streamsize = 6)
111{
113 _IOWrapper::FromStringImpl(i, s, 6);
114}
115
116void ReadCoordList(std::istream& is, CoordType* d, const int num);
117void WriteCoordList(std::ostream& os, const CoordType* d, const int num);
118CoordType GetEpsilon(std::istream& is);
119
120template<int dim>
121inline std::ostream& operator<<(std::ostream& os, const Vector<dim>& v)
122{
123 WriteCoordList(os, v.m_elem, dim);
124 return os;
125}
126
127template<int dim>
128inline 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
135template<int dim>
136inline 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
148template<int dim>
149inline 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
172template<int dim>
173inline std::ostream& operator<<(std::ostream& os, const Point<dim>& p)
174{
175 WriteCoordList(os, p.m_elem, dim);
176 return os;
177}
178
179template<int dim>
180inline 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
187template<int dim>
188inline 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
193template<int dim>
194inline 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
213template<int dim>
214inline 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
220template<int dim>
221inline 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
240template<int dim>
241inline 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
246template<int dim>
247inline 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
266template<int dim>
267inline 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
274template<int dim>
275inline 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
300template<> std::ostream& operator<<(std::ostream& os, const Polygon<2>& r);
301template<> std::istream& operator>>(std::istream& is, Polygon<2>& r);
302
303
304
305
306template<int dim>
307inline 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
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:110
std::string ToString(const C &c, std::streamsize precision=6)
Output a WFMath type as a string.
Definition: stream.h:100
static FloatType epsilon()
This is the attempted precision of the library.