$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r78321 - in sandbox/big_number: boost/multiprecision/detail boost/multiprecision/detail/functions libs/multiprecision/test
From: john_at_[hidden]
Date: 2012-05-04 04:20:36
Author: johnmaddock
Date: 2012-05-04 04:20:33 EDT (Fri, 04 May 2012)
New Revision: 78321
URL: http://svn.boost.org/trac/boost/changeset/78321
Log:
Change non-member functions to use enable_if so they're restricted to the number type to which they apply (better error messages).  Enhance concept checks to check things which weren't previously tested.
Text files modified: 
   sandbox/big_number/boost/multiprecision/detail/default_ops.hpp          |   283 +++++++++++++++++++++++++++++---------- 
   sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp        |     6                                         
   sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp       |     4                                         
   sandbox/big_number/libs/multiprecision/test/mp_number_concept_check.cpp |   114 ++++++++++++++++                        
   4 files changed, 326 insertions(+), 81 deletions(-)
Modified: sandbox/big_number/boost/multiprecision/detail/default_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/default_ops.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/detail/default_ops.hpp	2012-05-04 04:20:33 EDT (Fri, 04 May 2012)
@@ -484,6 +484,68 @@
    }
 }
 
+template<class T, class A> 
+inline typename enable_if<is_floating_point<A>, void>::type eval_pow(T& result, const T& x, const A& a)
+{
+   // Note this one is resticted to float arguments since pow.hpp already has a version for
+   // integer powers....
+   typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+   typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+   cast_type c;
+   c = a;
+   eval_pow(result, x, c);
+}
+
+template<class T, class A> 
+inline typename enable_if<is_arithmetic<A>, void>::type eval_pow(T& result, const A& x, const T& a)
+{
+   typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+   typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+   cast_type c;
+   c = x;
+   eval_pow(result, c, a);
+}
+
+template<class T, class A> 
+inline typename enable_if<is_arithmetic<A>, void>::type eval_fmod(T& result, const T& x, const A& a)
+{
+   typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+   typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+   cast_type c;
+   c = a;
+   eval_fmod(result, x, c);
+}
+
+template<class T, class A> 
+inline typename enable_if<is_arithmetic<A>, void>::type eval_fmod(T& result, const A& x, const T& a)
+{
+   typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+   typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+   cast_type c;
+   c = x;
+   eval_fmod(result, c, a);
+}
+
+template<class T, class A> 
+inline typename enable_if<is_arithmetic<A>, void>::type eval_atan2(T& result, const T& x, const A& a)
+{
+   typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+   typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+   cast_type c;
+   c = a;
+   eval_atan2(result, x, c);
+}
+
+template<class T, class A> 
+inline typename enable_if<is_arithmetic<A>, void>::type eval_atan2(T& result, const A& x, const T& a)
+{
+   typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+   typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+   cast_type c;
+   c = x;
+   eval_atan2(result, c, a);
+}
+
 template <class T, class Arithmetic>
 inline typename enable_if<is_integral<Arithmetic> >::type eval_gcd(T& result, const T& a, const Arithmetic& b)
 {
@@ -861,7 +923,7 @@
 }
 #endif
 
-#define UNARY_OP_FUNCTOR(func)\
+#define UNARY_OP_FUNCTOR(func, category)\
 namespace detail{\
 template <class Backend> \
 struct BOOST_JOIN(func, _funct)\
@@ -876,11 +938,12 @@
 }\
 \
 template <class tag, class A1, class A2, class A3> \
-inline detail::mp_exp<\
+inline typename enable_if_c<number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category,\
+   detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
-  , detail::mp_exp<tag, A1, A2, A3> \
-> \
+  , detail::mp_exp<tag, A1, A2, A3> >\
+>::type \
 func(const detail::mp_exp<tag, A1, A2, A3>& arg)\
 {\
     return detail::mp_exp<\
@@ -893,11 +956,12 @@
     );\
 }\
 template <class Backend> \
-inline detail::mp_exp<\
+inline typename enable_if_c<number_category<Backend>::value == category,\
+   detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
-  , mp_number<Backend> \
-> \
+  , mp_number<Backend> >\
+>::type \
 func(const mp_number<Backend>& arg)\
 {\
     return detail::mp_exp<\
@@ -910,7 +974,9 @@
     );\
 }\
 template <class Backend> \
-inline mp_number<Backend, false> \
+inline typename boost::enable_if_c<\
+   boost::multiprecision::number_category<Backend>::value == category,\
+   mp_number<Backend, false> >::type \
 func(const mp_number<Backend, false>& arg)\
 {\
    mp_number<Backend, false> result;\
@@ -919,7 +985,7 @@
    return result;\
 }
 
-#define BINARY_OP_FUNCTOR(func)\
+#define BINARY_OP_FUNCTOR(func, category)\
 namespace detail{\
 template <class Backend> \
 struct BOOST_JOIN(func, _funct)\
@@ -945,12 +1011,13 @@
 \
 }\
 template <class Backend> \
-inline detail::mp_exp<\
+inline typename enable_if_c<number_category<Backend>::value == category,\
+   detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
   , mp_number<Backend> \
-  , mp_number<Backend> \
-> \
+  , mp_number<Backend> > \
+>::type \
 func(const mp_number<Backend>& arg, const mp_number<Backend>& a)\
 {\
     return detail::mp_exp<\
@@ -965,12 +1032,14 @@
     );\
 }\
 template <class Backend, class tag, class A1, class A2, class A3> \
-inline detail::mp_exp<\
+inline typename enable_if_c<\
+   (number_category<Backend>::value == category) && (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category),\
+   detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
   , mp_number<Backend> \
-  , detail::mp_exp<tag, A1, A2, A3> \
-> \
+  , detail::mp_exp<tag, A1, A2, A3> > \
+>::type \
 func(const mp_number<Backend>& arg, const detail::mp_exp<tag, A1, A2, A3>& a)\
 {\
     return detail::mp_exp<\
@@ -985,12 +1054,14 @@
     );\
 }\
 template <class tag, class A1, class A2, class A3, class Backend> \
-inline detail::mp_exp<\
+inline typename enable_if_c<\
+   (number_category<Backend>::value == category) && (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category),\
+   detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
   , detail::mp_exp<tag, A1, A2, A3> \
-  , mp_number<Backend> \
-> \
+  , mp_number<Backend> > \
+>::type \
 func(const detail::mp_exp<tag, A1, A2, A3>& arg, const mp_number<Backend>& a)\
 {\
     return detail::mp_exp<\
@@ -1005,12 +1076,14 @@
     );\
 }\
 template <class tag, class A1, class A2, class A3, class tagb, class A1b, class A2b, class A3b> \
-inline detail::mp_exp<\
+inline typename enable_if_c<\
+      (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category) && (number_category<detail::mp_exp<tagb, A1b, A2b, A3b> >::value == category),\
+   detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
   , detail::mp_exp<tag, A1, A2, A3> \
-  , detail::mp_exp<tagb, A1b, A2b, A3b> \
-> \
+  , detail::mp_exp<tagb, A1b, A2b, A3b> > \
+>::type \
 func(const detail::mp_exp<tag, A1, A2, A3>& arg, const detail::mp_exp<tagb, A1b, A2b, A3b>& a)\
 {\
     return detail::mp_exp<\
@@ -1025,8 +1098,8 @@
     );\
 }\
 template <class Backend, class Arithmetic> \
-inline typename enable_if<\
-   is_arithmetic<Arithmetic>,\
+inline typename enable_if_c<\
+   is_arithmetic<Arithmetic>::value && (number_category<Backend>::value == category),\
    detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
@@ -1048,8 +1121,8 @@
     );\
 }\
 template <class tag, class A1, class A2, class A3, class Arithmetic> \
-inline typename enable_if<\
-   is_arithmetic<Arithmetic>,\
+inline typename enable_if_c<\
+   is_arithmetic<Arithmetic>::value && (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category),\
    detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
@@ -1071,8 +1144,8 @@
     );\
 }\
 template <class Backend, class Arithmetic> \
-inline typename enable_if<\
-   is_arithmetic<Arithmetic>,\
+inline typename enable_if_c<\
+   is_arithmetic<Arithmetic>::value && (number_category<Backend>::value == category),\
    detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
@@ -1094,8 +1167,8 @@
     );\
 }\
 template <class tag, class A1, class A2, class A3, class Arithmetic> \
-inline typename enable_if<\
-   is_arithmetic<Arithmetic>,\
+inline typename enable_if_c<\
+   is_arithmetic<Arithmetic>::value && (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category),\
    detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
@@ -1117,7 +1190,8 @@
     );\
 }\
 template <class Backend> \
-inline mp_number<Backend, false> \
+inline typename enable_if_c<(number_category<Backend>::value == category),\
+   mp_number<Backend, false> >::type \
 func(const mp_number<Backend, false>& arg, const mp_number<Backend, false>& a)\
 {\
    mp_number<Backend, false> result;\
@@ -1126,8 +1200,8 @@
    return result;\
 }\
 template <class Backend, class Arithmetic> \
-inline typename enable_if<\
-   is_arithmetic<Arithmetic>,\
+inline typename enable_if_c<\
+   is_arithmetic<Arithmetic>::value && (number_category<Backend>::value == category),\
    mp_number<Backend, false> \
 >::type \
 func(const mp_number<Backend, false>& arg, const Arithmetic& a)\
@@ -1139,8 +1213,8 @@
    return result;\
 }\
 template <class Backend, class Arithmetic> \
-inline typename enable_if<\
-   is_arithmetic<Arithmetic>,\
+inline typename enable_if_c<\
+   is_arithmetic<Arithmetic>::value && (number_category<Backend>::value == category),\
    mp_number<Backend, false> \
 >::type \
 func(const Arithmetic& a, const mp_number<Backend, false>& arg)\
@@ -1153,14 +1227,16 @@
 }\
 
 
-#define HETERO_BINARY_OP_FUNCTOR_B(func, Arg2)\
+#define HETERO_BINARY_OP_FUNCTOR_B(func, Arg2, category)\
 template <class tag, class A1, class A2, class A3> \
-inline detail::mp_exp<\
+inline typename enable_if_c<\
+   (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category),\
+   detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
   , detail::mp_exp<tag, A1, A2, A3> \
-  , Arg2\
-> \
+  , Arg2> \
+>::type \
 func(const detail::mp_exp<tag, A1, A2, A3>& arg, Arg2 const& a)\
 {\
     return detail::mp_exp<\
@@ -1174,12 +1250,14 @@
     );\
 }\
 template <class Backend> \
-inline detail::mp_exp<\
+inline typename enable_if_c<\
+   (number_category<Backend>::value == category),\
+  detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
   , mp_number<Backend> \
-  , Arg2\
-> \
+  , Arg2> \
+>::type \
 func(const mp_number<Backend>& arg, Arg2 const& a)\
 {\
     return detail::mp_exp<\
@@ -1194,7 +1272,9 @@
     );\
 }\
 template <class Backend> \
-inline mp_number<Backend, false> \
+inline typename enable_if_c<\
+  (number_category<Backend>::value == category),\
+  mp_number<Backend, false> >::type \
 func(const mp_number<Backend, false>& arg, Arg2 const& a)\
 {\
    mp_number<Backend, false> result;\
@@ -1203,7 +1283,7 @@
    return result;\
 }\
 
-#define HETERO_BINARY_OP_FUNCTOR(func, Arg2)\
+#define HETERO_BINARY_OP_FUNCTOR(func, Arg2, category)\
 namespace detail{\
 template <class Backend> \
 struct BOOST_JOIN(func, _funct)\
@@ -1218,44 +1298,97 @@
 \
 }\
 \
-HETERO_BINARY_OP_FUNCTOR_B(func, Arg2)
+HETERO_BINARY_OP_FUNCTOR_B(func, Arg2, category)
+
+namespace detail{
+template <class Backend>
+struct abs_funct
+{
+   void operator()(Backend& result, const Backend& arg)const
+   {
+      using default_ops::eval_abs;
+      eval_abs(result, arg);
+   }
+};
+
+}
 
+template <class tag, class A1, class A2, class A3>
+inline detail::mp_exp<
+    detail::function
+  , detail::abs_funct<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>
+  , detail::mp_exp<tag, A1, A2, A3> >
+abs(const detail::mp_exp<tag, A1, A2, A3>& arg)
+{
+    return detail::mp_exp<
+    detail::function
+  , detail::abs_funct<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>
+  , detail::mp_exp<tag, A1, A2, A3>
+> (
+        detail::abs_funct<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>()
+      , arg
+    );
+}
+template <class Backend>
+inline detail::mp_exp<
+    detail::function
+  , detail::abs_funct<Backend>
+  , mp_number<Backend> >
+abs(const mp_number<Backend>& arg)
+{
+    return detail::mp_exp<
+    detail::function
+  , detail::abs_funct<Backend>
+  , mp_number<Backend>
+  >(
+        detail::abs_funct<Backend>()
+      , arg
+    );
+}
+template <class Backend>
+inline mp_number<Backend, false>
+abs(const mp_number<Backend, false>& arg)
+{
+   mp_number<Backend, false> result;
+   using default_ops::eval_abs;
+   eval_abs(result.backend(), arg.backend());
+   return result;
+}
 
-UNARY_OP_FUNCTOR(abs)
-UNARY_OP_FUNCTOR(fabs)
-UNARY_OP_FUNCTOR(sqrt)
-UNARY_OP_FUNCTOR(floor)
-UNARY_OP_FUNCTOR(ceil)
-UNARY_OP_FUNCTOR(trunc)
-UNARY_OP_FUNCTOR(round)
-UNARY_OP_FUNCTOR(exp)
-UNARY_OP_FUNCTOR(log)
-UNARY_OP_FUNCTOR(log10)
-UNARY_OP_FUNCTOR(cos)
-UNARY_OP_FUNCTOR(sin)
-UNARY_OP_FUNCTOR(tan)
-UNARY_OP_FUNCTOR(asin)
-UNARY_OP_FUNCTOR(acos)
-UNARY_OP_FUNCTOR(atan)
-UNARY_OP_FUNCTOR(cosh)
-UNARY_OP_FUNCTOR(sinh)
-UNARY_OP_FUNCTOR(tanh)
-
-HETERO_BINARY_OP_FUNCTOR(ldexp, int)
-HETERO_BINARY_OP_FUNCTOR(frexp, int*)
-HETERO_BINARY_OP_FUNCTOR_B(ldexp, long)
-HETERO_BINARY_OP_FUNCTOR_B(frexp, long*)
-HETERO_BINARY_OP_FUNCTOR_B(ldexp, long long)
-HETERO_BINARY_OP_FUNCTOR_B(frexp, long long*)
-BINARY_OP_FUNCTOR(pow)
-BINARY_OP_FUNCTOR(fmod)
-BINARY_OP_FUNCTOR(atan2)
+UNARY_OP_FUNCTOR(fabs, number_kind_floating_point)
+UNARY_OP_FUNCTOR(sqrt, number_kind_floating_point)
+UNARY_OP_FUNCTOR(floor, number_kind_floating_point)
+UNARY_OP_FUNCTOR(ceil, number_kind_floating_point)
+UNARY_OP_FUNCTOR(trunc, number_kind_floating_point)
+UNARY_OP_FUNCTOR(round, number_kind_floating_point)
+UNARY_OP_FUNCTOR(exp, number_kind_floating_point)
+UNARY_OP_FUNCTOR(log, number_kind_floating_point)
+UNARY_OP_FUNCTOR(log10, number_kind_floating_point)
+UNARY_OP_FUNCTOR(cos, number_kind_floating_point)
+UNARY_OP_FUNCTOR(sin, number_kind_floating_point)
+UNARY_OP_FUNCTOR(tan, number_kind_floating_point)
+UNARY_OP_FUNCTOR(asin, number_kind_floating_point)
+UNARY_OP_FUNCTOR(acos, number_kind_floating_point)
+UNARY_OP_FUNCTOR(atan, number_kind_floating_point)
+UNARY_OP_FUNCTOR(cosh, number_kind_floating_point)
+UNARY_OP_FUNCTOR(sinh, number_kind_floating_point)
+UNARY_OP_FUNCTOR(tanh, number_kind_floating_point)
+
+HETERO_BINARY_OP_FUNCTOR(ldexp, int, number_kind_floating_point)
+HETERO_BINARY_OP_FUNCTOR(frexp, int*, number_kind_floating_point)
+HETERO_BINARY_OP_FUNCTOR_B(ldexp, long, number_kind_floating_point)
+HETERO_BINARY_OP_FUNCTOR_B(frexp, long*, number_kind_floating_point)
+HETERO_BINARY_OP_FUNCTOR_B(ldexp, long long, number_kind_floating_point)
+HETERO_BINARY_OP_FUNCTOR_B(frexp, long long*, number_kind_floating_point)
+BINARY_OP_FUNCTOR(pow, number_kind_floating_point)
+BINARY_OP_FUNCTOR(fmod, number_kind_floating_point)
+BINARY_OP_FUNCTOR(atan2, number_kind_floating_point)
 
 //
 // Integer functions:
 //
-BINARY_OP_FUNCTOR(gcd)
-BINARY_OP_FUNCTOR(lcm)
+BINARY_OP_FUNCTOR(gcd, number_kind_integer)
+BINARY_OP_FUNCTOR(lcm, number_kind_integer)
 
 
 #undef BINARY_OP_FUNCTOR
Modified: sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp	2012-05-04 04:20:33 EDT (Fri, 04 May 2012)
@@ -84,11 +84,9 @@
 } // namespace detail
 
 template<typename T, typename U> 
-inline void eval_pow(T& result, const T& t, const U& p)
+inline typename enable_if<is_integral<U> >::type eval_pow(T& result, const T& t, const U& p)
 {
-   BOOST_STATIC_ASSERT_MSG(number_category<T>::value == number_kind_floating_point, "The pow function is only valid for floating point types.");
-   typedef typename is_integral<U>::type tag_type;
-   detail::pow_imp(result, t, p, tag_type());
+   detail::pow_imp(result, t, p, mpl::true_());
 }
 
 template <class T>
Modified: sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp	2012-05-04 04:20:33 EDT (Fri, 04 May 2012)
@@ -766,7 +766,7 @@
          eval_add(result, get_constant_pi<T>());
    }
 }
-
+/*
 template <class T, class Arithmetic>
 typename disable_if<is_same<T, Arithmetic> >::type eval_atan2(T& result, const T& a, const Arithmetic& b)
 {
@@ -775,4 +775,4 @@
    x = static_cast<typename boost::multiprecision::detail::canonical<Arithmetic, T>::type>(b);
    eval_atan2(result, a, x);
 }
-
+*/
Modified: sandbox/big_number/libs/multiprecision/test/mp_number_concept_check.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/mp_number_concept_check.cpp	(original)
+++ sandbox/big_number/libs/multiprecision/test/mp_number_concept_check.cpp	2012-05-04 04:20:33 EDT (Fri, 04 May 2012)
@@ -59,34 +59,148 @@
 #include <boost/math/concepts/real_type_concept.hpp>
 #include "libs/math/test/compile_test/instantiate.hpp"
 
+template <class T>
+void test_extra(T)
+{
+   T t = 1;
+   t = abs(t);
+   t = abs(t*t);
+
+   t = fabs(t);
+   t = fabs(t*t);
+
+   t = sqrt(t);
+   t = sqrt(t*t);
+
+   t = floor(t);
+   t = floor(t*t);
+
+   t = ceil(t);
+   t = ceil(t*t);
+
+   t = trunc(t);
+   t = trunc(t*t);
+
+   t = round(t);
+   t = round(t*t);
+
+   t = exp(t);
+   t = exp(t*t);
+
+   t = log(t);
+   t = log(t*t);
+
+   t = log10(t);
+   t = log10(t*t);
+
+   t = cos(t);
+   t = cos(t*t);
+
+   t = sin(t);
+   t = sin(t*t);
+
+   t = tan(t);
+   t = tan(t*t);
+
+   t = asin(t);
+   t = asin(t*t);
+
+   t = atan(t);
+   t = atan(t*t);
+
+   t = acos(t);
+   t = acos(t*t);
+
+   t = cosh(t);
+   t = cosh(t*t);
+
+   t = sinh(t);
+   t = sinh(t*t);
+
+   t = tanh(t);
+   t = tanh(t*t);
+
+   double dval = 2;
+   t = pow(t, t);
+   t = pow(t, t*t);
+   t = pow(t, dval);
+   t = pow(t*t, t);
+   t = pow(t*t, t*t);
+   t = pow(t*t, dval);
+   t = pow(dval, t);
+   t = pow(dval, t*t);
+
+   t = atan2(t, t);
+   t = atan2(t, t*t);
+   t = atan2(t, dval);
+   t = atan2(t*t, t);
+   t = atan2(t*t, t*t);
+   t = atan2(t*t, dval);
+   t = atan2(dval, t);
+   t = atan2(dval, t*t);
+
+   t = fmod(t, t);
+   t = fmod(t, t*t);
+   t = fmod(t, dval);
+   t = fmod(t*t, t);
+   t = fmod(t*t, t*t);
+   t = fmod(t*t, dval);
+   t = fmod(dval, t);
+   t = fmod(dval, t*t);
+
+   typedef typename T::backend_type backend_type;
+   typedef typename backend_type::exponent_type exp_type;
+   exp_type e = 0;
+   int i = 0;
+
+   t = ldexp(t, i);
+   t = ldexp(t*t, i);
+   t = ldexp(t, e);
+   t = ldexp(t*t, e);
+
+   t = frexp(t, &i);
+   t = frexp(t*t, &i);
+   t = frexp(t, &e);
+   t = frexp(t*t, &e);
+}
+
 void foo()
 {
 #ifdef TEST_BACKEND
    instantiate(boost::multiprecision::concepts::mp_number_float_architype());
+   test_extra(boost::multiprecision::concepts::mp_number_float_architype());
 #endif
 #ifdef TEST_MPF_50
    instantiate(boost::multiprecision::mpf_float_50());
+   test_extra(boost::multiprecision::mpf_float_50());
 #endif
 #ifdef TEST_MPFR_50
    instantiate(boost::multiprecision::mpfr_float_50());
+   test_extra(boost::multiprecision::mpfr_float_50());
 #endif
 #ifdef TEST_MPFR_6
    instantiate(boost::multiprecision::mp_number<boost::multiprecision::mpfr_float_backend<6> >());
+   test_extra(boost::multiprecision::mp_number<boost::multiprecision::mpfr_float_backend<6> >());
 #endif
 #ifdef TEST_MPFR_15
    instantiate(boost::multiprecision::mp_number<boost::multiprecision::mpfr_float_backend<15> >());
+   test_extra(boost::multiprecision::mp_number<boost::multiprecision::mpfr_float_backend<15> >());
 #endif
 #ifdef TEST_MPFR_17
    instantiate(boost::multiprecision::mp_number<boost::multiprecision::mpfr_float_backend<17> >());
+   test_extra(boost::multiprecision::mp_number<boost::multiprecision::mpfr_float_backend<17> >());
 #endif
 #ifdef TEST_MPFR_30
    instantiate(boost::multiprecision::mp_number<boost::multiprecision::mpfr_float_backend<30> >());
+   test_extra(boost::multiprecision::mp_number<boost::multiprecision::mpfr_float_backend<30> >());
 #endif
 #ifdef TEST_CPP_DEC_FLOAT
    instantiate(boost::multiprecision::cpp_dec_float_50());
+   test_extra(boost::multiprecision::cpp_dec_float_50());
 #endif
 #ifdef TEST_CPP_DEC_FLOAT_NO_ET
    instantiate(boost::multiprecision::mp_number<boost::multiprecision::cpp_dec_float<100>, false>());
+   test_extra(boost::multiprecision::mp_number<boost::multiprecision::cpp_dec_float<100>, false>());
 #endif
 }