source: trunk/yat/utility/utility.h @ 1789

Last change on this file since 1789 was 1789, checked in by Peter, 12 years ago

Speeding up copying from Matrix to MatrixWeighted? using
BinaryWeight?. Moving BinaryWeight? from stl_utility.h to
utility.h. Improved docs in MatrixWeighted?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.5 KB
Line 
1#ifndef _theplu_yat_utility_utility_
2#define _theplu_yat_utility_utility_
3
4// $Id: utility.h 1789 2009-02-10 16:11:04Z 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 Jari Häkkinen, Peter Johansson
10  Copyright (C) 2008 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
28///
29/// \file yat/utility/utility.h
30///
31/// @brief Some useful functions are placed here
32///
33
34#include "deprecate.h"
35
36#include <cmath>
37#include <limits>
38#include <string>
39#include <stdexcept>
40#include <sstream>
41#include <utility>
42#include <vector>
43
44namespace theplu {
45namespace yat {
46namespace utility {
47
48  /**
49     For each element in resulting range assign it to 0.0 if
50     corresponding element in input range is NaN else assign it to
51     1.0.
52
53     \since New in yat 0.5
54   */
55  struct BinaryWeight
56  {
57    /**
58        \return true if there is at least one NaN in input range
59        [first, last).
60     */
61    template<typename InputIterator, typename OutputIterator>
62    bool operator()(InputIterator first, InputIterator last, 
63                    OutputIterator result) const;
64  };
65
66
67  /**
68     \brief convert string to (numerical) type
69
70     \throw runtime_error if conversion fails
71   */
72  template<typename T>
73  T convert(const std::string& s);
74
75  /**
76     \brief check if string is convertible to (numerical) type
77
78     \since New in yat 0.5
79   */
80  template<typename T>
81  bool is(const std::string& s);
82
83  ///
84  /// @return true if string is a double
85  ///
86  /// \deprecated Provided for backward compatibility with the 0.4
87  /// API. Use is<double>(const std::string&)
88  ///
89  bool is_double(const std::string&) YAT_DEPRECATE;
90
91  /**
92     @return true if string \a s fulfills regular expression \verbatim
93     ^\w* \endverbatim \a other \verbatim \w*$ \endverbatim (case
94     insensitive)
95  */
96  bool is_equal(std::string s, std::string other);
97
98  ///
99  /// @return true if string is a float
100  ///
101  /// \deprecated Provided for backward compatibility with the 0.4
102  /// API. Use is<float>(const std::string&)
103  ///
104  bool is_float(const std::string&) YAT_DEPRECATE;
105
106  ///
107  /// @return true if string is an int
108  ///
109  /// \deprecated Provided for backward compatibility with the 0.4
110  /// API. Use is<int>(const std::string&)
111  ///
112  bool is_int(const std::string&) YAT_DEPRECATE;
113
114  ///
115  /// @return true if string is "nan" (case-insensitive)
116  ///
117  bool is_nan(const std::string& s);
118
119
120  template<typename InputIterator, typename OutputIterator>
121  bool BinaryWeight::operator()(InputIterator first, InputIterator last, 
122                                OutputIterator result) const
123  {
124    bool nan=false;
125    while (first!=last) {
126      if (std::isnan(*first)) {
127        *result=0;
128        nan=true;
129      }
130      else
131        *result = 1.0;
132      ++first;
133      ++result;
134    }
135    return nan;
136  }
137
138
139  // template implementations
140  template<typename T>
141  T convert(const std::string& s)
142  {
143    if (is_nan(s))
144      return std::numeric_limits<T>::quiet_NaN();
145    if (is_equal(s, "inf"))
146      return std::numeric_limits<T>::infinity();
147    if (is_equal(s, "-inf"))
148      if (std::numeric_limits<T>::is_signed)
149        return -std::numeric_limits<T>::infinity();
150      else
151        throw std::runtime_error(std::string("convert(\"")+s+
152                                 std::string("\"): type is unsigned") );
153    std::stringstream ss(s);
154    T a;
155    ss >> a;
156    bool ok = true;
157    if(ss.fail()) 
158      ok = false;
159    // Check that nothing is left on stream
160    std::string b;
161    ss >> b;
162    if (!b.empty() || !ok)
163      throw std::runtime_error(std::string("convert(\"")+s+std::string("\")"));
164    return a;
165  }
166
167  template<typename T>
168  bool is(const std::string& s)
169  {
170    if (is_nan(s))
171      return std::numeric_limits<T>::has_quiet_NaN;
172    if (is_equal(s, "inf"))
173      return std::numeric_limits<T>::has_infinity;
174    if (is_equal(s, "-inf"))
175      return std::numeric_limits<T>::has_infinity && 
176        std::numeric_limits<T>::is_signed;
177    std::stringstream ss(s);
178    T a;
179    ss >> a;
180    if(ss.fail())
181      return false;
182    // Check that nothing is left on stream
183    std::string b;
184    ss >> b;
185    return b.empty();
186  }
187
188}}} // of namespace utility, yat, and theplu
189
190#endif
Note: See TracBrowser for help on using the repository browser.