$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r66825 - in sandbox/math_constants: boost/math/constants libs/math/test
From: john_at_[hidden]
Date: 2010-11-28 13:11:13
Author: johnmaddock
Date: 2010-11-28 13:11:05 EST (Sun, 28 Nov 2010)
New Revision: 66825
URL: http://svn.boost.org/trac/boost/changeset/66825
Log:
Add thread safety support, and better caching of values.
Text files modified: 
   sandbox/math_constants/boost/math/constants/calculate_constants.hpp |     5 +++--                                   
   sandbox/math_constants/boost/math/constants/constants.hpp           |    38 +++++++++++++++++++++++++++++++++++---  
   sandbox/math_constants/libs/math/test/test_constants.cpp            |     5 -----                                   
   3 files changed, 38 insertions(+), 10 deletions(-)
Modified: sandbox/math_constants/boost/math/constants/calculate_constants.hpp
==============================================================================
--- sandbox/math_constants/boost/math/constants/calculate_constants.hpp	(original)
+++ sandbox/math_constants/boost/math/constants/calculate_constants.hpp	2010-11-28 13:11:05 EST (Sun, 28 Nov 2010)
@@ -6,7 +6,7 @@
 #ifndef BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED
 #define BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED
 
-namespace boost{ namespace math{ namespace constants{
+namespace boost{ namespace math{ namespace constants{ namespace detail{
 
 template <class T, int N> 
 inline T calculate_pi(const mpl::int_<N>&BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
@@ -71,6 +71,7 @@
 template <class T, int N> 
 inline T calculate_euler(const mpl::int_<N>&BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
 {
+   throw std::runtime_error("A true arbitrary precision Euler's constant is not available - it's too expensive to calculate on the fly - this constant is only supported up to 100 decimal digits.");
    return 0;
 }
 
@@ -154,6 +155,6 @@
    return static_cast<T>(1) / root_two_pi<T, policies::policy<policies::digits2<N> > >();
 }
 
-}}} // namespaces
+}}}} // namespaces
 
 #endif // BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED
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-28 13:11:05 EST (Sun, 28 Nov 2010)
@@ -21,6 +21,9 @@
 #include <boost/mpl/and.hpp>
 #include <boost/mpl/int.hpp>
 #include <boost/type_traits/is_convertible.hpp>
+#ifdef BOOST_HAS_THREADS
+#  include <boost/thread/once.hpp>
+#endif
 
 namespace boost{ namespace math
 {
@@ -82,28 +85,57 @@
       >::type type;
    };
 
+#ifdef BOOST_HAS_THREADS
+#define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix) \
+      boost::once_flag f = BOOST_ONCE_INIT;\
+      boost::call_once(f, &BOOST_JOIN(BOOST_JOIN(string_, get_), name)<T>);
+#else
+#define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix)
+#endif
+
    #define BOOST_DEFINE_MATH_CONSTANT(name, x, y, exp)\
+   namespace detail{\
    /* Forward declaration of the calculation method, just in case it's not been provided yet */ \
    template <class T, int N> T BOOST_JOIN(calculate_, name)(const mpl::int_<N>& 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))\
+   template <class T> inline T BOOST_JOIN(string_get_, name)(BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))\
    {\
       static const T result = ::boost::lexical_cast<T>(BOOST_STRINGIZE(BOOST_JOIN(BOOST_JOIN(x, y), BOOST_JOIN(e, exp))));\
       return result;\
    }\
+   template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_string>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))\
+   {\
+      BOOST_MATH_CONSTANT_THREAD_HELPER(name, string_)\
+      return BOOST_JOIN(string_get_, name)<T>();\
+   }\
    template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_float>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
    { return BOOST_JOIN(BOOST_JOIN(x, BOOST_JOIN(e, exp)), F); }\
    template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_double>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
    { 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, int N> inline T BOOST_JOIN(get_, name)(const mpl::int_<N>& n BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
+   /* This one is for very high precision that is none the less known at compile time: */ \
+   template <class T, int N> inline T BOOST_JOIN(compute_get_, name)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpl::int_<N>) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
    { static const T result = BOOST_JOIN(calculate_, name)<T>(n); return result; }\
+   template <class T, int N> inline T BOOST_JOIN(get_, name)(const mpl::int_<N>& n BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
+   {\
+      BOOST_MATH_CONSTANT_THREAD_HELPER(name, compute_)\
+      BOOST_JOIN(compute_get_, name)<T, N>(); \
+   }\
+   /* This one is for true arbitary precision, which may well vary at runtime: */ \
+   template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<0>& n BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
+   { return tools::digits<T>() > max_string_digits ? BOOST_JOIN(calculate_, name)<T>(n) : BOOST_JOIN(get_, name)<T>(mpl::int_<construct_from_string>()); }\
+   } /* namespace detail */ \
+   \
+   \
    /* 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()); }\
+   { return detail:: 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<> >(); }\
+   \
+   \
    /* 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-28 13:11:05 EST (Sun, 28 Nov 2010)
@@ -254,8 +254,3 @@
 
 */
 
-
-
-
-
-