00001 #ifndef _theplu_yat_utility_utility_
00002 #define _theplu_yat_utility_utility_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00033
00034 #include "deprecate.h"
00035 #include "Exception.h"
00036
00037 #include <cmath>
00038 #include <limits>
00039 #include <istream>
00040 #include <string>
00041 #include <stdexcept>
00042 #include <sstream>
00043 #include <utility>
00044 #include <vector>
00045
00046 namespace theplu {
00047 namespace yat {
00048 namespace utility {
00049
00060 template<typename InputIterator, typename OutputIterator>
00061 bool binary_weight(InputIterator first, InputIterator last,
00062 OutputIterator result);
00063
00064
00070 template<typename T>
00071 T convert(const std::string& s);
00072
00078 template<typename T>
00079 bool is(const std::string& s);
00080
00087 bool is_double(const std::string&) YAT_DEPRECATE;
00088
00097 bool is_equal(std::string s, std::string other);
00098
00105 bool is_float(const std::string&) YAT_DEPRECATE;
00106
00113 bool is_int(const std::string&) YAT_DEPRECATE;
00114
00118 bool is_nan(const std::string& s);
00119
00155 template<typename T>
00156 void load(std::istream& is, std::vector<std::vector<T> >& vec, char sep='\0',
00157 char line_sep='\n', bool ignore_empty=false, bool rectangle=true);
00158
00180 template<typename T>
00181 void load(std::istream& is, std::vector<T>& vec, char sep='\0');
00182
00183
00184 namespace detail {
00185
00195 template<typename T>
00196 bool convert(const std::string& s, T& t);
00197
00201 template<typename T>
00202 struct VectorPusher
00203 {
00209 void operator()(const std::string& element, std::vector<T>& vec)
00210 {
00211 if (!element.size())
00212 vec.push_back(std::numeric_limits<T>::quiet_NaN());
00213 else {
00214 vec.push_back(theplu::yat::utility::convert<T>(element));
00215 }
00216 }
00217 };
00218
00224 template<>
00225 struct VectorPusher<std::string>
00226 {
00230 void operator()(const std::string& element, std::vector<std::string>& vec)
00231 {
00232 vec.push_back(element);
00233 }
00234 };
00235
00236 }
00237
00238
00239
00240
00241 template<typename InputIterator, typename OutputIterator>
00242 bool binary_weight(InputIterator first, InputIterator last,
00243 OutputIterator result)
00244 {
00245 bool nan=false;
00246 while (first!=last) {
00247 if (std::isnan(*first)) {
00248 *result=0;
00249 nan=true;
00250 }
00251 else
00252 *result = 1.0;
00253 ++first;
00254 ++result;
00255 }
00256 return nan;
00257 }
00258
00259
00260
00261 template<typename T>
00262 T convert(const std::string& s)
00263 {
00264 T result;
00265 if (!detail::convert(s, result))
00266 throw runtime_error(std::string("yat::utility::convert(\"")+s+
00267 std::string("\")"));
00268 return result;
00269 }
00270
00271
00272 template<typename T>
00273 bool is(const std::string& s)
00274 {
00275 T tmp;
00276 return detail::convert(s, tmp);
00277 }
00278
00279
00280 template<typename T>
00281 void load(std::istream& is, std::vector<std::vector<T> >& matrix,
00282 char sep, char line_sep, bool ignore_empty,
00283 bool rectangle)
00284 {
00285 size_t nof_columns=0;
00286 std::string line;
00287 while(getline(is, line, line_sep)){
00288 if (line.empty() && ignore_empty)
00289 continue;
00290 matrix.push_back(std::vector<T>());
00291 std::vector<T>& v=matrix.back();
00292 v.reserve(nof_columns);
00293 std::stringstream ss(line);
00294 load(ss, v, sep);
00295
00296 detail::VectorPusher<T> pusher;
00297 if(sep!='\0' && !line.empty() && line[line.size()-1]==sep)
00298 pusher("", v);
00299
00300 if (rectangle && nof_columns && v.size()!=nof_columns) {
00301 std::ostringstream s;
00302 s << "load stream error: "
00303 << "line " << matrix.size() << " has " << v.size()
00304 << " columns; expected " << nof_columns << " columns.";
00305 throw utility::IO_error(s.str());
00306 }
00307 nof_columns = std::max(nof_columns, v.size());
00308 }
00309
00310
00311 is.clear(std::ios::goodbit);
00312 }
00313
00314 template<typename T>
00315 void load(std::istream& is, std::vector<T>& vec, char sep='\0')
00316 {
00317 detail::VectorPusher<T> pusher;
00318 std::string element;
00319 bool ok=true;
00320 while(true) {
00321 if(sep=='\0')
00322 ok=(is>>element);
00323 else
00324 ok=getline(is, element, sep);
00325 if(!ok)
00326 break;
00327 pusher(element, vec);
00328 }
00329 }
00330
00331
00332 namespace detail {
00333 template<typename T>
00334 bool convert(const std::string& s, T& result)
00335 {
00336 std::istringstream ss(s);
00337 ss >> result;
00338 if (ss.fail()) {
00339 if (is_nan(s)) {
00340 result = std::numeric_limits<T>::quiet_NaN();
00341 return true;
00342 }
00343 if (is_equal(s, "inf")) {
00344 result = std::numeric_limits<T>::infinity();
00345 return true;
00346 }
00347 if (std::numeric_limits<T>::is_signed && is_equal(s, "-inf")) {
00348 result = -std::numeric_limits<T>::infinity();
00349 return true;
00350 }
00351 return false;
00352 }
00353
00354 std::string b;
00355 ss >> b;
00356 return b.empty();
00357 }
00358 }
00359
00360 }}}
00361
00362 #endif