Boost logo

Boost-Commit :

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 @@
 
 */
 
-
-
-
-
-


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk