MIRA
NumericalStream.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
48 #ifndef _MIRA_NUMERICAL_STREAM_H_
49 #define _MIRA_NUMERICAL_STREAM_H_
50 
51 #include <iostream>
52 
53 #include <math/Math.h>
54 
55 namespace mira {
56 
58 
86 {
87 public:
94  NumericalOstream(std::ostream& s) : out(s) {}
95 
96  template <typename T>
97  NumericalOstream& operator<< (const T& val) {
98  out << val;
99  return *this;
100  }
101 
102  // for manipulators like (endl, etc)
103  NumericalOstream& operator<<(std::ostream&(*pf)(std::ostream&)) {
104  out << pf;
105  return *this;
106  }
107 
108  // specializations for all 3 floating point types
110  fpOutput(val);
111  return *this;
112  }
113 
115  fpOutput(val);
116  return *this;
117  }
118 
119  NumericalOstream& operator<< (long double val) {
120  fpOutput(val);
121  return *this;
122  }
123 
124 public:
125 
127  std::ostream& out;
128 
129 private:
130 
131  // handles special cases and writes "nan", "inf", etc.
132  template <typename T>
133  inline void fpOutput(const T& value)
134  {
135  if(boost::math::isnan(value))
136  out << "nan"; // hard coded constants here, since parser is hard coded, too.
137  else if(boost::math::isinf(value)) {
138  if(value>0)
139  out << "inf";
140  else
141  out << "-inf";
142  }
143  else
144  out << value;
145  }
146 };
147 
148 
187 {
188 public:
195  NumericalIstream(std::istream& s) : in(s) {}
196 
197  template <typename T>
199  in >> val;
200  return *this;
201  }
202 
203  // for manipulators
204  NumericalIstream& operator>>(std::istream&(*pf)(std::istream&)) {
205  in >> pf;
206  return *this;
207  }
208 
209  // specializations for all 3 floating point types
211  fpInput(val);
212  return *this;
213  }
214 
216  fpInput(val);
217  return *this;
218  }
219 
220  NumericalIstream& operator>> (long double& val) {
221  fpInput(val);
222  return *this;
223  }
224 
225 public:
226 
228  std::istream& in;
229 
230 private:
231 
232  // handles special cases and parses "nan", "inf", etc.
233  template <typename T>
234  inline void fpInput(T& value)
235  {
236 
237  // read the potential sign and put that character back
238  // we need it only to detect the -inf below.
239  char sign;
240  in >> sign;
241  in.putback(sign);
242 
243  std::streamoff p0 = in.tellg();
244 
245  // try to read the value first
246  in >> value;
247 
248  if(!in.fail())
249  return; // everything was fine
250 
251  // if we reach here, we have no number, try to parse nan, inf, etc. instead
252 
253  in.clear(); // reset error state of stream
254 
255  // if the - sign was not read by the above >> value operator, then eat it now
256  if(sign=='-' && in.tellg()==p0) {
257  in.read(&sign,1);
258  assert(sign=='-');
259  }
260 
261  // read the next 3 chars that may contain nan, inf, etc.
262  char buf[3] = {0,0,0};
263  in.read(buf,3);
264  if(!in.fail()) {
265  // read nan
266  if(buf[0]=='n' && buf[1]=='a' && buf[2]=='n') {
267  value = std::numeric_limits<T>::quiet_NaN();
268  return;
269  }
270 
271  // read inf
272  if(buf[0]=='i' && buf[1]=='n' && buf[2]=='f') {
273  if(sign=='-')
274  value = -std::numeric_limits<T>::infinity();
275  else
276  value = std::numeric_limits<T>::infinity();
277  return;
278  }
279  }
280 
281  // if we reach here we have a parse error
282  in.clear();
283 
284  // putback all chars that we have read
285  while(((std::streamoff)in.tellg()) > p0)
286  in.unget();
287 
288  // and go into fail mode
289  in.setstate(std::ios::badbit);
290  }
291 };
292 
293 
295 
296 }
297 
298 #endif
Numerical stream adapter that can be assigned to any output stream and allows streaming of numerical ...
Definition: NumericalStream.h:85
NumericalOstream & operator<<(const T &val)
Definition: NumericalStream.h:97
std::ostream & out
The underlying output stream.
Definition: NumericalStream.h:127
Includes often needed math headers and methods and provides additional constants. ...
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
NumericalOstream & operator<<(std::ostream &(*pf)(std::ostream &))
Definition: NumericalStream.h:103
Numerical stream adapter that can be assigned to any input stream and allows streaming of numerical v...
Definition: NumericalStream.h:186
NumericalIstream & operator>>(T &val)
Definition: NumericalStream.h:198
NumericalIstream & operator>>(std::istream &(*pf)(std::istream &))
Definition: NumericalStream.h:204
NumericalOstream(std::ostream &s)
Constructs a NumericalOstream around the specified existing std::ostream.
Definition: NumericalStream.h:94
NumericalIstream(std::istream &s)
Constructs a NumericalIstream around the specified existing istream.
Definition: NumericalStream.h:195
std::istream & in
The underlying input stream.
Definition: NumericalStream.h:228