$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r66798 - in sandbox/math_constants: boost/math/constants libs/math/test
From: john_at_[hidden]
Date: 2010-11-27 12:16:33
Author: johnmaddock
Date: 2010-11-27 12:16:31 EST (Sat, 27 Nov 2010)
New Revision: 66798
URL: http://svn.boost.org/trac/boost/changeset/66798
Log:
Policy enable the getter functions.
Text files modified: 
   sandbox/math_constants/boost/math/constants/constants.hpp |    69 ++++++++++++++++++++++++--------------- 
   sandbox/math_constants/libs/math/test/test_constants.cpp  |    63 +++++++++++++++++++++++++++++++++++     
   2 files changed, 104 insertions(+), 28 deletions(-)
Modified: sandbox/math_constants/boost/math/constants/constants.hpp
==============================================================================
--- sandbox/math_constants/boost/math/constants/constants.hpp	(original)
+++ sandbox/math_constants/boost/math/constants/constants.hpp	2010-11-27 12:16:31 EST (Sat, 27 Nov 2010)
@@ -17,7 +17,10 @@
 #ifdef BOOST_MSVC
 #pragma warning(pop)
 #endif
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
 #include <boost/mpl/int.hpp>
+#include <boost/type_traits/is_convertible.hpp>
 
 namespace boost{ namespace math
 {
@@ -39,37 +42,49 @@
 
    enum construction_method
    {
-      construct_from_float = 0,
-      construct_from_double = 1,
-      construct_from_long_double = 2,
-      construct_from_string = 3,
-      construct_from_calculation = 4,
+      construct_from_float = 1,
+      construct_from_double = 2,
+      construct_from_long_double = 3,
+      construct_from_string = 4,
    };
 
-   template <class Real>
+   //
+   // Max number of binary digits in the string representations
+   // of our constants:
+   //
+   BOOST_STATIC_CONSTANT(int, max_string_digits = (101 * 1000L) / 301L);
+
+   template <class Real, class Policy>
    struct construction_traits
    {
-      BOOST_STATIC_CONSTANT(construction_method, value = construct_from_string);
-   };
-   template <>
-   struct construction_traits<float>
-   {
-      BOOST_STATIC_CONSTANT(construction_method, value = construct_from_float);
-   };
-   template <>
-   struct construction_traits<double>
-   {
-      BOOST_STATIC_CONSTANT(construction_method, value = construct_from_double);
-   };
-   template <>
-   struct construction_traits<long double>
-   {
-      BOOST_STATIC_CONSTANT(construction_method, value = construct_from_long_double);
+   private:
+      typedef typename policies::precision<Real, Policy>::type t1;
+      typedef typename policies::precision<float, Policy>::type t2;
+      typedef typename policies::precision<double, Policy>::type t3;
+      typedef typename policies::precision<long double, Policy>::type t4;
+   public:
+      typedef typename mpl::if_<
+         mpl::and_<boost::is_convertible<float, Real>, mpl::bool_< t1::value <= t2::value>, mpl::bool_<0 != t1::value> >,
+         mpl::int_<construct_from_float>,
+         typename mpl::if_<
+            mpl::and_<boost::is_convertible<double, Real>, mpl::bool_< t1::value <= t3::value>, mpl::bool_<0 != t1::value> >,
+            mpl::int_<construct_from_double>,
+            typename mpl::if_<
+               mpl::and_<boost::is_convertible<long double, Real>, mpl::bool_< t1::value <= t4::value>, mpl::bool_<0 != t1::value> >,
+               mpl::int_<construct_from_long_double>,
+               typename mpl::if_<
+                  mpl::and_<mpl::bool_< t1::value <= max_string_digits>, mpl::bool_<0 != t1::value> >,
+                  mpl::int_<construct_from_string>,
+                  mpl::int_<t1::value>
+               >::type
+            >::type
+         >::type
+      >::type type;
    };
 
    #define BOOST_DEFINE_MATH_CONSTANT(name, x, y, exp)\
    /* Forward declaration of the calculation method, just in case it's not been provided yet */ \
-   template <class T> T BOOST_JOIN(calculate_, name)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)); \
+   template <class T> T BOOST_JOIN(calculate_, name)(int BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T)); \
    /* The default implementations come next: */ \
    template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_string>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))\
    {\
@@ -82,13 +97,13 @@
    { return BOOST_JOIN(x, BOOST_JOIN(e, exp)); }\
    template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_long_double>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
    { return BOOST_JOIN(BOOST_JOIN(x, BOOST_JOIN(e, exp)), L); }\
-   template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_calculation>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
-   { static const T result = BOOST_JOIN(calculate_, name)<T>(); return result; }\
+   template <class T, int N> inline T BOOST_JOIN(get_, name)(const mpl::int_<N>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
+   { static const T result = BOOST_JOIN(calculate_, name)<T>(N ? N : tools::digits<T>()); return result; }\
    /* The actual forwarding function: */ \
+   template <class T, class Policy> inline T name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy))\
+   { return BOOST_JOIN(get_, name)<T>(typename construction_traits<T, Policy>::type()); }\
    template <class T> inline T name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
    { return name<T, boost::math::policies::policy<> >(); }\
-   template <class T, class Policy> inline T name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy))\
-   { return BOOST_JOIN(get_, name)<T>(mpl::int_<construction_traits<T>::value>()); }\
    /* Now the namespace specific versions: */ \
    } namespace float_constants{ static const float name = BOOST_JOIN(BOOST_JOIN(x, BOOST_JOIN(e, exp)), F); }\
    namespace double_constants{ static const double name = BOOST_JOIN(x, BOOST_JOIN(e, exp)); } \
Modified: sandbox/math_constants/libs/math/test/test_constants.cpp
==============================================================================
--- sandbox/math_constants/libs/math/test/test_constants.cpp	(original)
+++ sandbox/math_constants/libs/math/test/test_constants.cpp	2010-11-27 12:16:31 EST (Sat, 27 Nov 2010)
@@ -16,6 +16,18 @@
 
 #include <boost/math/constants/constants.hpp>
 #include <boost/math/tools/test.hpp> 
+#include <boost/static_assert.hpp>
+
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<float, boost::math::policies::policy<> >::type, boost::mpl::int_<boost::math::constants::construct_from_float> >::value));
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<double, boost::math::policies::policy<> >::type, boost::mpl::int_<boost::math::constants::construct_from_double> >::value));
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<long double, boost::math::policies::policy<> >::type, boost::mpl::int_<(sizeof(double) == sizeof(long double) ? boost::math::constants::construct_from_double : boost::math::constants::construct_from_long_double)> >::value));
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<boost::math::concepts::real_concept, boost::math::policies::policy<> >::type, boost::mpl::int_<0> >::value));
+
+typedef boost::math::policies::policy<boost::math::policies::digits2<LDBL_MANT_DIG> > real_concept_policy_1;
+typedef boost::math::policies::policy<boost::math::policies::digits2<LDBL_MANT_DIG + 2> > real_concept_policy_2;
+
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<boost::math::concepts::real_concept, real_concept_policy_1 >::type, boost::mpl::int_<(sizeof(double) == sizeof(long double) ? boost::math::constants::construct_from_double : boost::math::constants::construct_from_long_double) > >::value));
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<boost::math::concepts::real_concept, real_concept_policy_2 >::type, boost::mpl::int_<boost::math::constants::construct_from_string> >::value));
 
 template <class RealType>
 void test_spots(RealType)
@@ -25,6 +37,10 @@
    RealType tolerance = boost::math::tools::epsilon<RealType>() * 2;  // double
    std::cout << "Tolerance for type " << typeid(RealType).name()  << " is " << tolerance << "." << std::endl;
 
+   //typedef typename boost::math::policies::precision<RealType, boost::math::policies::policy<> >::type t1;
+
+   //std::cout << "Precision for type " << typeid(RealType).name()  << " is " << t1::value << "." << std::endl;
+
    using namespace boost::math::constants;
    using namespace std; // Help ADL of std exp, log...
    using std::exp;
@@ -157,6 +173,47 @@
 
 } // template <class RealType>void test_spots(RealType)
 
+template <class Policy>
+void test_real_concept_policy(const Policy&)
+{
+   // Basic sanity checks for constants.
+
+   boost::math::concepts::real_concept tolerance = boost::math::tools::epsilon<boost::math::concepts::real_concept>() * 2;  // double
+   std::cout << "Tolerance for type " << typeid(boost::math::concepts::real_concept).name()  << " is " << tolerance << "." << std::endl;
+
+   //typedef typename boost::math::policies::precision<boost::math::concepts::real_concept, boost::math::policies::policy<> >::type t1;
+
+   //std::cout << "Precision for type " << typeid(boost::math::concepts::real_concept).name()  << " is " << t1::value << "." << std::endl;
+
+   using namespace boost::math::constants;
+   using namespace std; // Help ADL of std exp, log...
+   using std::exp;
+
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(3.14159265358979323846264338327950288419716939937510L), (pi<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(sqrt(3.14159265358979323846264338327950288419716939937510L)), (root_pi<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(sqrt(3.14159265358979323846264338327950288419716939937510L/2)), (root_half_pi<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(sqrt(3.14159265358979323846264338327950288419716939937510L * 2)), (root_two_pi<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(sqrt(log(4.0L))), (root_ln_four<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(2.71828182845904523536028747135266249775724709369995L), (e<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(0.5), (half<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(0.57721566490153286060651209008240243104259335L), (euler<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(sqrt(2.0L)), (root_two<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(log(2.0L)), (ln_two<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(log(log(2.0L))), (ln_ln_two<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(1)/3, (third<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(2)/3, (twothirds<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(0.14159265358979323846264338327950288419716939937510L), (pi_minus_three<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(4. - 3.14159265358979323846264338327950288419716939937510L), (four_minus_pi<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(pow((4 - 3.14159265358979323846264338327950288419716939937510L), 1.5L)), (pow23_four_minus_pi<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(exp(-0.5L)), (exp_minus_half<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+#else
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(pow((4 - 3.14159265358979323846264338327950288419716939937510), 1.5)), (pow23_four_minus_pi<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+   BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(exp(-0.5)), (exp_minus_half<boost::math::concepts::real_concept, Policy>)(), tolerance); 
+#endif
+
+} // template <class boost::math::concepts::real_concept>void test_spots(boost::math::concepts::real_concept)
+
 int test_main(int, char* [])
 {
    // Basic sanity-check spot values.
@@ -165,13 +222,17 @@
    test_double_spots();
    test_long_double_spots();
 
+   test_real_concept_policy(real_concept_policy_1());
+   test_real_concept_policy(real_concept_policy_2());
+   test_real_concept_policy(boost::math::policies::policy<>());
+
    // (Parameter value, arbitrarily zero, only communicates the floating point type).
    test_spots(0.0F); // Test float. OK at decdigits = 0 tolerance = 0.0001 %
    test_spots(0.0); // Test double. OK at decdigits 7, tolerance = 1e07 %
 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
    test_spots(0.0L); // Test long double.
 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0582))
-   test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
+   //test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
 #endif
 #else
   std::cout << "<note>The long double tests have been disabled on this platform "