yat  0.9.3pre
utility.h
Go to the documentation of this file.
1 #ifndef _theplu_yat_utility_utility_
2 #define _theplu_yat_utility_utility_
3 
4 // $Id: utility.h 2820 2012-08-30 00:47:58Z peter $
5 
6 /*
7  Copyright (C) 2005 Jari Häkkinen, Peter Johansson, Markus Ringnér
8  Copyright (C) 2006 Jari Häkkinen
9  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
10  Copyright (C) 2009, 2010, 2011, 2012 Peter Johansson
11 
12  This file is part of the yat library, http://dev.thep.lu.se/yat
13 
14  The yat library is free software; you can redistribute it and/or
15  modify it under the terms of the GNU General Public License as
16  published by the Free Software Foundation; either version 3 of the
17  License, or (at your option) any later version.
18 
19  The yat library is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with yat. If not, see <http://www.gnu.org/licenses/>.
26 */
27 
33 
34 #include "deprecate.h"
35 #include "Exception.h"
36 #include "yat_assert.h"
37 
38 #include <algorithm>
39 #include <cctype>
40 #include <cmath>
41 #include <functional>
42 #include <limits>
43 #include <locale>
44 #include <istream>
45 #include <string>
46 #include <stdexcept>
47 #include <sstream>
48 #include <utility>
49 #include <vector>
50 
51 namespace theplu {
52 namespace yat {
53 namespace utility {
54 
65  template<typename InputIterator, typename OutputIterator>
66  bool binary_weight(InputIterator first, InputIterator last,
67  OutputIterator result);
68 
76  template<typename T>
77  std::string convert(T input);
78 
84  template<typename T>
85  T convert(const std::string& s);
86 
92  template<typename T>
93  bool is(const std::string& s);
94 
101  bool is_double(const std::string&) YAT_DEPRECATE;
102 
111  bool is_equal(std::string s, std::string other);
112 
119  bool is_float(const std::string&) YAT_DEPRECATE;
120 
127  bool is_int(const std::string&) YAT_DEPRECATE;
128 
132  bool is_nan(const std::string& s);
133 
169  template<typename T>
170  void load(std::istream& is, std::vector<std::vector<T> >& vec, char sep='\0',
171  char line_sep='\n', bool ignore_empty=false, bool rectangle=true);
172 
194  template<typename T>
195  void load(std::istream& is, std::vector<T>& vec, char sep='\0');
196 
197 // private namespace
198 namespace detail {
199 
209  template<typename T>
210  bool convert(const std::string& s, T& t);
211 
215  template<typename T>
217  {
223  void operator()(const std::string& element, std::vector<T>& vec)
224  {
225  if (!element.size())
226  vec.push_back(std::numeric_limits<T>::quiet_NaN());
227  else {
228  vec.push_back(theplu::yat::utility::convert<T>(element));
229  }
230  }
231  };
232 
238  template<>
239  struct VectorPusher<std::string>
240  {
244  void operator()(const std::string& element, std::vector<std::string>& vec)
245  {
246  vec.push_back(element);
247  }
248  };
249 
250 } // end of namespace detail
251 
252 
253  // template implementations
254 
255  template<typename InputIterator, typename OutputIterator>
256  bool binary_weight(InputIterator first, InputIterator last,
257  OutputIterator result)
258  {
259  bool nan=false;
260  while (first!=last) {
261  if (std::isnan(*first)) {
262  *result=0;
263  nan=true;
264  }
265  else
266  *result = 1.0;
267  ++first;
268  ++result;
269  }
270  return nan;
271  }
272 
273 
274  // template implementations
275  template<typename T>
276  std::string convert(T input)
277  {
278  std::ostringstream ss;
279  ss << input;
280  return ss.str();
281  }
282 
283 
284  template<typename T>
285  T convert(const std::string& s)
286  {
287  T result;
288  if (!detail::convert(s, result))
289  throw runtime_error(std::string("yat::utility::convert(\"")+s+
290  std::string("\")"));
291  return result;
292  }
293 
294 
295  template<typename T>
296  bool is(const std::string& s)
297  {
298  T tmp;
299  return detail::convert(s, tmp);
300  }
301 
302 
303  template<typename T>
304  void load(std::istream& is, std::vector<std::vector<T> >& matrix,
305  char sep, char line_sep, bool ignore_empty,
306  bool rectangle)
307  {
308  size_t nof_columns=0;
309  std::string line;
310  while(getline(is, line, line_sep)){
311  if (line.empty() && ignore_empty)
312  continue;
313  matrix.push_back(std::vector<T>());
314  std::vector<T>& v=matrix.back();
315  v.reserve(nof_columns);
316  std::stringstream ss(line);
317  load(ss, v, sep);
318  // add NaN for final separator (or empty string if T=std::string)
320  if(sep!='\0' && !line.empty() && line[line.size()-1]==sep)
321  pusher("", v);
322 
323  if (rectangle && nof_columns && v.size()!=nof_columns) {
324  std::ostringstream s;
325  s << "load stream error: "
326  << "line " << matrix.size() << " has " << v.size()
327  << " columns; expected " << nof_columns << " columns.";
328  throw utility::IO_error(s.str());
329  }
330  nof_columns = std::max(nof_columns, v.size());
331  }
332 
333  // manipulate the state of the stream to be good
334  is.clear(std::ios::goodbit);
335  }
336 
337  template<typename T>
338  void load(std::istream& is, std::vector<T>& vec, char sep)
339  {
341  std::string element;
342  bool ok=true;
343  while(true) {
344  if(sep=='\0')
345  ok=(is>>element);
346  else
347  ok=getline(is, element, sep);
348  if(!ok)
349  break;
350  pusher(element, vec);
351  }
352  }
353 
354 
355 namespace detail {
356  template<typename T>
357  bool convert(const std::string& s, T& result)
358  {
359  if (!std::numeric_limits<T>::is_signed) {
360  // first non-whitespace character
361  std::string::const_iterator iter = s.begin();
362  while (iter!=s.end() && std::isspace(*iter))
363  ++iter;
364  // unsigned int cannot start with a '-' and with some compilers
365  // operation ss >> result won't fail so catch it like this instead.
366  if (iter==s.end() || *iter=='-')
367  return false;
368  }
369  std::istringstream ss(s);
370  ss >> result;
371  if (ss.fail()) {
372  if (is_nan(s)) {
373  result = std::numeric_limits<T>::quiet_NaN();
374  return true;
375  }
376  if (is_equal(s, "inf")) {
377  result = std::numeric_limits<T>::infinity();
378  return true;
379  }
380  if (is_equal(s, "-inf")) {
381  // unsigned types are caught in prologue
382  YAT_ASSERT(std::numeric_limits<T>::is_signed);
383  result = -std::numeric_limits<T>::infinity();
384  return true;
385  }
386  return false;
387  }
388  // Check that nothing is left on stream
389  std::string b;
390  ss >> b;
391  return b.empty();
392  }
393 } // of namespace detail
394 
395 }}} // of namespace utility, yat, and theplu
396 
397 #endif

Generated on Tue Jan 29 2013 02:33:39 for yat by  doxygen 1.8.1