170 lines · plain
1// Copyright John Maddock 2010.2// Use, modification and distribution are subject to the3// Boost Software License, Version 1.0. (See accompanying file4// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)5 6#ifdef _MSC_VER7# pragma once8#endif9 10#ifndef BOOST_MATH_CONSTANTS_INFO_INCLUDED11#define BOOST_MATH_CONSTANTS_INFO_INCLUDED12 13#include <boost/math/constants/constants.hpp>14#include <iostream>15#include <iomanip>16#ifndef BOOST_MATH_NO_RTTI17#include <typeinfo>18#endif19 20namespace boost{ namespace math{ namespace constants{21 22 namespace detail{23 24 template <class T>25 const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T))26 {27 #ifndef BOOST_MATH_NO_RTTI28 return typeid(T).name();29 #else30 return "unknown";31 #endif32 }33 template <>34 const char* nameof<float>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(float))35 {36 return "float";37 }38 template <>39 const char* nameof<double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(double))40 {41 return "double";42 }43 template <>44 const char* nameof<long double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(long double))45 {46 return "long double";47 }48 49 }50 51template <class T, class Policy>52void 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))53{54 using detail::nameof;55#ifdef _MSC_VER56#pragma warning(push)57#pragma warning(disable:4127)58#endif59 os <<60 "Information on the Implementation and Handling of \n"61 "Mathematical Constants for Type " << nameof<T>() <<62 "\n\n"63 "Checking for std::numeric_limits<" << nameof<T>() << "> specialisation: " <<64 (std::numeric_limits<T>::is_specialized ? "yes" : "no") << std::endl;65 if(std::numeric_limits<T>::is_specialized)66 {67 os <<68 "std::numeric_limits<" << nameof<T>() << ">::digits reports that the radix is " << std::numeric_limits<T>::radix << ".\n";69 if (std::numeric_limits<T>::radix == 2)70 {71 os <<72 "std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n" << std::numeric_limits<T>::digits << " binary digits.\n";73 }74 else if (std::numeric_limits<T>::radix == 10)75 {76 os <<77 "std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n" << std::numeric_limits<T>::digits10 << " decimal digits.\n";78 os <<79 "std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n"80 << std::numeric_limits<T>::digits * 1000L /301L << " binary digits.\n"; // divide by log2(10) - about 3 bits per decimal digit.81 }82 else83 {84 os << "Unknown radix = " << std::numeric_limits<T>::radix << "\n";85 }86 }87 typedef typename boost::math::policies::precision<T, Policy>::type precision_type;88 if(precision_type::value)89 {90 if (std::numeric_limits<T>::radix == 2)91 {92 os <<93 "boost::math::policies::precision<" << nameof<T>() << ", " << nameof<Policy>() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n";94 }95 else if (std::numeric_limits<T>::radix == 10)96 {97 os <<98 "boost::math::policies::precision<" << nameof<T>() << ", " << nameof<Policy>() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n";99 }100 else101 {102 os << "Unknown radix = " << std::numeric_limits<T>::radix << "\n";103 }104 }105 else106 {107 os <<108 "boost::math::policies::precision<" << nameof<T>() << ", Policy> \n"109 "reports that there is no compile type precision available.\n"110 "boost::math::tools::digits<" << nameof<T>() << ">() \n"111 "reports that the current runtime precision is \n" <<112 boost::math::tools::digits<T>() << " binary digits.\n";113 }114 115 typedef typename construction_traits<T, Policy>::type construction_type;116 117 switch(construction_type::value)118 {119 case 0:120 os <<121 "No compile time precision is available, the construction method \n"122 "will be decided at runtime and results will not be cached \n"123 "- this may lead to poor runtime performance.\n"124 "Current runtime precision indicates that\n";125 if(boost::math::tools::digits<T>() > max_string_digits)126 {127 os << "the constant will be recalculated on each call.\n";128 }129 else130 {131 os << "the constant will be constructed from a string on each call.\n";132 }133 break;134 case 1:135 os <<136 "The constant will be constructed from a float.\n";137 break;138 case 2:139 os <<140 "The constant will be constructed from a double.\n";141 break;142 case 3:143 os <<144 "The constant will be constructed from a long double.\n";145 break;146 case 4:147 os <<148 "The constant will be constructed from a string (and the result cached).\n";149 break;150 default:151 os <<152 "The constant will be calculated (and the result cached).\n";153 break;154 }155 os << std::endl;156#ifdef _MSC_VER157#pragma warning(pop)158#endif159}160 161template <class T>162void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))163{164 print_info_on_type<T, boost::math::policies::policy<> >(os);165}166 167}}} // namespaces168 169#endif // BOOST_MATH_CONSTANTS_INFO_INCLUDED170