• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright John Maddock 2010.
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 
6 #ifdef _MSC_VER
7 #  pragma once
8 #endif
9 
10 #ifndef BOOST_MATH_CONSTANTS_INFO_INCLUDED
11 #define BOOST_MATH_CONSTANTS_INFO_INCLUDED
12 
13 #include <boost/math/constants/constants.hpp>
14 #include <iostream>
15 #include <iomanip>
16 #include <typeinfo>
17 
18 namespace boost{ namespace math{ namespace constants{
19 
20    namespace detail{
21 
22       template <class T>
nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC (T))23       const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
24       {
25          return typeid(T).name();
26       }
27       template <>
nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC (float))28       const char* nameof<float>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(float))
29       {
30          return "float";
31       }
32       template <>
nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC (double))33       const char* nameof<double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(double))
34       {
35          return "double";
36       }
37       template <>
nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC (long double))38       const char* nameof<long double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(long double))
39       {
40          return "long double";
41       }
42 
43    }
44 
45 template <class T, class Policy>
print_info_on_type(std::ostream & os=std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC (T)BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC (Policy))46 void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy))
47 {
48    using detail::nameof;
49 #ifdef BOOST_MSVC
50 #pragma warning(push)
51 #pragma warning(disable:4127)
52 #endif
53    os <<
54       "Information on the Implementation and Handling of \n"
55       "Mathematical Constants for Type " << nameof<T>() <<
56       "\n\n"
57       "Checking for std::numeric_limits<" << nameof<T>() << "> specialisation: " <<
58       (std::numeric_limits<T>::is_specialized ? "yes" : "no") << std::endl;
59    if(std::numeric_limits<T>::is_specialized)
60    {
61       os <<
62          "std::numeric_limits<" << nameof<T>() << ">::digits reports that the radix is " << std::numeric_limits<T>::radix << ".\n";
63       if (std::numeric_limits<T>::radix == 2)
64       {
65       os <<
66          "std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n" << std::numeric_limits<T>::digits << " binary digits.\n";
67       }
68       else if (std::numeric_limits<T>::radix == 10)
69       {
70          os <<
71          "std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n" << std::numeric_limits<T>::digits10 << " decimal digits.\n";
72          os <<
73          "std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n"
74          << std::numeric_limits<T>::digits * 1000L /301L << " binary digits.\n";  // divide by log2(10) - about 3 bits per decimal digit.
75       }
76       else
77       {
78         os << "Unknown radix = " << std::numeric_limits<T>::radix << "\n";
79       }
80    }
81    typedef typename boost::math::policies::precision<T, Policy>::type precision_type;
82    if(precision_type::value)
83    {
84       if (std::numeric_limits<T>::radix == 2)
85       {
86        os <<
87        "boost::math::policies::precision<" << nameof<T>() << ", " << nameof<Policy>() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n";
88       }
89       else if (std::numeric_limits<T>::radix == 10)
90       {
91          os <<
92          "boost::math::policies::precision<" << nameof<T>() << ", " << nameof<Policy>() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n";
93       }
94       else
95       {
96         os << "Unknown radix = " << std::numeric_limits<T>::radix <<  "\n";
97       }
98    }
99    else
100    {
101       os <<
102          "boost::math::policies::precision<" << nameof<T>() << ", Policy> \n"
103          "reports that there is no compile type precision available.\n"
104          "boost::math::tools::digits<" << nameof<T>() << ">() \n"
105          "reports that the current runtime precision is \n" <<
106          boost::math::tools::digits<T>() << " binary digits.\n";
107    }
108 
109    typedef typename construction_traits<T, Policy>::type construction_type;
110 
111    switch(construction_type::value)
112    {
113    case 0:
114       os <<
115          "No compile time precision is available, the construction method \n"
116          "will be decided at runtime and results will not be cached \n"
117          "- this may lead to poor runtime performance.\n"
118          "Current runtime precision indicates that\n";
119       if(boost::math::tools::digits<T>() > max_string_digits)
120       {
121          os << "the constant will be recalculated on each call.\n";
122       }
123       else
124       {
125          os << "the constant will be constructed from a string on each call.\n";
126       }
127       break;
128    case 1:
129       os <<
130          "The constant will be constructed from a float.\n";
131       break;
132    case 2:
133       os <<
134          "The constant will be constructed from a double.\n";
135       break;
136    case 3:
137       os <<
138          "The constant will be constructed from a long double.\n";
139       break;
140    case 4:
141       os <<
142          "The constant will be constructed from a string (and the result cached).\n";
143       break;
144    default:
145       os <<
146          "The constant will be calculated (and the result cached).\n";
147       break;
148    }
149    os << std::endl;
150 #ifdef BOOST_MSVC
151 #pragma warning(pop)
152 #endif
153 }
154 
155 template <class T>
print_info_on_type(std::ostream & os=std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC (T))156 void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
157 {
158    print_info_on_type<T, boost::math::policies::policy<> >(os);
159 }
160 
161 }}} // namespaces
162 
163 #endif // BOOST_MATH_CONSTANTS_INFO_INCLUDED
164