big_constant.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // Copyright (c) 2011 John Maddock
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_MATH_TOOLS_BIG_CONSTANT_HPP
  6. #define BOOST_MATH_TOOLS_BIG_CONSTANT_HPP
  7. #include <boost/math/tools/config.hpp>
  8. #ifndef BOOST_MATH_NO_LEXICAL_CAST
  9. #include <boost/lexical_cast.hpp>
  10. #endif
  11. #include <boost/type_traits/is_convertible.hpp>
  12. namespace boost{ namespace math{
  13. namespace tools{
  14. template <class T>
  15. inline BOOST_CONSTEXPR_OR_CONST T make_big_value(long double v, const char*, mpl::true_ const&, mpl::false_ const&)
  16. {
  17. return static_cast<T>(v);
  18. }
  19. template <class T>
  20. inline BOOST_CONSTEXPR_OR_CONST T make_big_value(long double v, const char*, mpl::true_ const&, mpl::true_ const&)
  21. {
  22. return static_cast<T>(v);
  23. }
  24. #ifndef BOOST_MATH_NO_LEXICAL_CAST
  25. template <class T>
  26. inline T make_big_value(long double, const char* s, mpl::false_ const&, mpl::false_ const&)
  27. {
  28. return boost::lexical_cast<T>(s);
  29. }
  30. #endif
  31. template <class T>
  32. inline BOOST_CONSTEXPR const char* make_big_value(long double, const char* s, mpl::false_ const&, mpl::true_ const&)
  33. {
  34. return s;
  35. }
  36. //
  37. // For constants which might fit in a long double (if it's big enough):
  38. //
  39. #define BOOST_MATH_BIG_CONSTANT(T, D, x)\
  40. boost::math::tools::make_big_value<T>(\
  41. BOOST_JOIN(x, L), \
  42. BOOST_STRINGIZE(x), \
  43. mpl::bool_< (is_convertible<long double, T>::value) && \
  44. ((D <= std::numeric_limits<long double>::digits) \
  45. || is_floating_point<T>::value \
  46. || (std::numeric_limits<T>::is_specialized && \
  47. (std::numeric_limits<T>::digits10 <= std::numeric_limits<long double>::digits10))) >(), \
  48. boost::is_convertible<const char*, T>())
  49. //
  50. // For constants too huge for any conceivable long double (and which generate compiler errors if we try and declare them as such):
  51. //
  52. #define BOOST_MATH_HUGE_CONSTANT(T, D, x)\
  53. boost::math::tools::make_big_value<T>(0.0L, BOOST_STRINGIZE(x), \
  54. mpl::bool_<is_floating_point<T>::value || (std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::max_exponent <= std::numeric_limits<long double>::max_exponent && std::numeric_limits<T>::digits <= std::numeric_limits<long double>::digits)>(), \
  55. boost::is_convertible<const char*, T>())
  56. }}} // namespaces
  57. #endif