numeric_util.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2010-2011 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // Distributed under:
  6. //
  7. // the Boost Software License, Version 1.0.
  8. // (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // or (at your opinion) under:
  12. //
  13. // The MIT License
  14. // (See accompanying file MIT.txt or a copy at
  15. // http://www.opensource.org/licenses/mit-license.php)
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #ifndef CPPDB_NUMERIC_UTIL_H
  19. #define CPPDB_NUMERIC_UTIL_H
  20. #include <cppdb/errors.h>
  21. #include <string>
  22. #include <sstream>
  23. #include <limits>
  24. #include <iomanip>
  25. namespace cppdb {
  26. ///
  27. /// Small utility functions for backends, accepts - source string and stringstream with imbued std::locale
  28. /// it tries to case the value to T in best possible way.
  29. ///
  30. /// For floating point string it casts it to the nearest ineger
  31. ///
  32. template<typename T>
  33. T parse_number(std::string const &s,std::istringstream &ss)
  34. {
  35. ss.clear();
  36. ss.str(s);
  37. if(s.find_first_of(".eEdD")!=std::string::npos) {
  38. long double v;
  39. ss >> v;
  40. if(ss.fail() || !std::ws(ss).eof())
  41. throw bad_value_cast();
  42. #ifdef __BORLANDC__
  43. #pragma warn -8008 // condition always true/false
  44. #pragma warn -8066 // unreachable code
  45. #endif
  46. if(std::numeric_limits<T>::is_integer) {
  47. if(v > (std::numeric_limits<T>::max)() || v < (std::numeric_limits<T>::min)())
  48. throw bad_value_cast();
  49. }
  50. #ifdef __BORLANDC__
  51. #pragma warn .8008
  52. #pragma warn .8066
  53. #endif
  54. return static_cast<T>(v);
  55. }
  56. T v;
  57. ss >> v;
  58. if(ss.fail() || !std::ws(ss).eof())
  59. throw bad_value_cast();
  60. if( std::numeric_limits<T>::is_integer
  61. && !std::numeric_limits<T>::is_signed
  62. && s.find('-') != std::string::npos
  63. && v!=0)
  64. {
  65. throw bad_value_cast();
  66. }
  67. return v;
  68. }
  69. }
  70. #endif