mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-02-19 14:32:35 +00:00
Add explicit conversion operators and tests to expression templates.
This commit is contained in:
@@ -360,11 +360,36 @@ struct expression<tag, Arg1, void, void, void>
|
||||
|
||||
static const unsigned depth = left_type::depth + 1;
|
||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||
explicit operator bool()const
|
||||
# if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)) || (defined(BOOST_INTEL) && (BOOST_INTEL <= 1500))
|
||||
//
|
||||
// Horrible workaround for gcc-4.6.x which always prefers the template
|
||||
// operator bool() rather than the non-template operator when converting to
|
||||
// an arithmetic type:
|
||||
//
|
||||
template <class T, typename boost::enable_if<is_same<T, bool>, int>::type = 0>
|
||||
explicit operator T ()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return static_cast<bool>(r);
|
||||
}
|
||||
template <class T, typename boost::disable_if_c<is_same<T, bool>::value || is_void<T>::value || is_number<T>::value, int>::type = 0>
|
||||
explicit operator T ()const
|
||||
{
|
||||
return static_cast<T>(static_cast<result_type>(*this));
|
||||
}
|
||||
# else
|
||||
template <class T, typename boost::disable_if_c<is_number<T>::value, int>::type = 0>
|
||||
explicit operator T()const
|
||||
{
|
||||
return static_cast<T>(static_cast<result_type>(*this));
|
||||
}
|
||||
BOOST_MP_FORCEINLINE explicit operator bool()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return static_cast<bool>(r);
|
||||
}
|
||||
explicit operator void()const {}
|
||||
# endif
|
||||
#else
|
||||
operator unmentionable_type()const
|
||||
{
|
||||
@@ -373,6 +398,13 @@ struct expression<tag, Arg1, void, void, void>
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
T convert_to()
|
||||
{
|
||||
result_type r(*this);
|
||||
return r.template convert_to<T>();
|
||||
}
|
||||
|
||||
private:
|
||||
typename expression_storage<Arg1>::type arg;
|
||||
expression& operator=(const expression&);
|
||||
@@ -392,10 +424,36 @@ struct expression<terminal, Arg1, void, void, void>
|
||||
static const unsigned depth = 0;
|
||||
|
||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||
explicit operator bool()const
|
||||
# if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)) || (defined(BOOST_INTEL) && (BOOST_INTEL <= 1500))
|
||||
//
|
||||
// Horrible workaround for gcc-4.6.x which always prefers the template
|
||||
// operator bool() rather than the non-template operator when converting to
|
||||
// an arithmetic type:
|
||||
//
|
||||
template <class T, typename boost::enable_if<is_same<T, bool>, int>::type = 0>
|
||||
explicit operator T ()const
|
||||
{
|
||||
return static_cast<bool>(arg);
|
||||
result_type r(*this);
|
||||
return static_cast<bool>(r);
|
||||
}
|
||||
template <class T, typename boost::disable_if_c<is_same<T, bool>::value || is_void<T>::value || is_number<T>::value, int>::type = 0>
|
||||
explicit operator T ()const
|
||||
{
|
||||
return static_cast<T>(static_cast<result_type>(*this));
|
||||
}
|
||||
# else
|
||||
template <class T, typename boost::disable_if_c<is_number<T>::value, int>::type = 0>
|
||||
explicit operator T()const
|
||||
{
|
||||
return static_cast<T>(static_cast<result_type>(*this));
|
||||
}
|
||||
BOOST_MP_FORCEINLINE explicit operator bool()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return static_cast<bool>(r);
|
||||
}
|
||||
explicit operator void()const {}
|
||||
# endif
|
||||
#else
|
||||
operator unmentionable_type()const
|
||||
{
|
||||
@@ -403,6 +461,13 @@ struct expression<terminal, Arg1, void, void, void>
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
T convert_to()
|
||||
{
|
||||
result_type r(*this);
|
||||
return r.template convert_to<T>();
|
||||
}
|
||||
|
||||
private:
|
||||
typename expression_storage<Arg1>::type arg;
|
||||
expression& operator=(const expression&);
|
||||
@@ -427,11 +492,36 @@ struct expression<tag, Arg1, Arg2, void, void>
|
||||
const Arg2& right_ref()const BOOST_NOEXCEPT { return arg2; }
|
||||
|
||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||
explicit operator bool()const
|
||||
# if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)) || (defined(BOOST_INTEL) && (BOOST_INTEL <= 1500))
|
||||
//
|
||||
// Horrible workaround for gcc-4.6.x which always prefers the template
|
||||
// operator bool() rather than the non-template operator when converting to
|
||||
// an arithmetic type:
|
||||
//
|
||||
template <class T, typename boost::enable_if<is_same<T, bool>, int>::type = 0>
|
||||
explicit operator T ()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return static_cast<bool>(r);
|
||||
}
|
||||
template <class T, typename boost::disable_if_c<is_same<T, bool>::value || is_void<T>::value || is_number<T>::value, int>::type = 0>
|
||||
explicit operator T ()const
|
||||
{
|
||||
return static_cast<T>(static_cast<result_type>(*this));
|
||||
}
|
||||
# else
|
||||
template <class T, typename boost::disable_if_c<is_number<T>::value, int>::type = 0>
|
||||
explicit operator T()const
|
||||
{
|
||||
return static_cast<T>(static_cast<result_type>(*this));
|
||||
}
|
||||
BOOST_MP_FORCEINLINE explicit operator bool()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return static_cast<bool>(r);
|
||||
}
|
||||
explicit operator void()const {}
|
||||
# endif
|
||||
#else
|
||||
operator unmentionable_type()const
|
||||
{
|
||||
@@ -439,6 +529,13 @@ struct expression<tag, Arg1, Arg2, void, void>
|
||||
return r ? &unmentionable::proc : 0;
|
||||
}
|
||||
#endif
|
||||
template <class T>
|
||||
T convert_to()
|
||||
{
|
||||
result_type r(*this);
|
||||
return r.template convert_to<T>();
|
||||
}
|
||||
|
||||
static const unsigned left_depth = left_type::depth + 1;
|
||||
static const unsigned right_depth = right_type::depth + 1;
|
||||
static const unsigned depth = left_depth > right_depth ? left_depth : right_depth;
|
||||
@@ -474,11 +571,36 @@ struct expression<tag, Arg1, Arg2, Arg3, void>
|
||||
const Arg3& right_ref()const BOOST_NOEXCEPT { return arg3; }
|
||||
|
||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||
explicit operator bool()const
|
||||
# if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)) || (defined(BOOST_INTEL) && (BOOST_INTEL <= 1500))
|
||||
//
|
||||
// Horrible workaround for gcc-4.6.x which always prefers the template
|
||||
// operator bool() rather than the non-template operator when converting to
|
||||
// an arithmetic type:
|
||||
//
|
||||
template <class T, typename boost::enable_if<is_same<T, bool>, int>::type = 0>
|
||||
explicit operator T ()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return static_cast<bool>(r);
|
||||
}
|
||||
template <class T, typename boost::disable_if_c<is_same<T, bool>::value || is_void<T>::value || is_number<T>::value, int>::type = 0>
|
||||
explicit operator T ()const
|
||||
{
|
||||
return static_cast<T>(static_cast<result_type>(*this));
|
||||
}
|
||||
# else
|
||||
template <class T, typename boost::disable_if_c<is_number<T>::value, int>::type = 0>
|
||||
explicit operator T()const
|
||||
{
|
||||
return static_cast<T>(static_cast<result_type>(*this));
|
||||
}
|
||||
BOOST_MP_FORCEINLINE explicit operator bool()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return static_cast<bool>(r);
|
||||
}
|
||||
explicit operator void()const {}
|
||||
# endif
|
||||
#else
|
||||
operator unmentionable_type()const
|
||||
{
|
||||
@@ -486,6 +608,13 @@ struct expression<tag, Arg1, Arg2, Arg3, void>
|
||||
return r ? &unmentionable::proc : 0;
|
||||
}
|
||||
#endif
|
||||
template <class T>
|
||||
T convert_to()
|
||||
{
|
||||
result_type r(*this);
|
||||
return r.template convert_to<T>();
|
||||
}
|
||||
|
||||
static const unsigned left_depth = left_type::depth + 1;
|
||||
static const unsigned middle_depth = middle_type::depth + 1;
|
||||
static const unsigned right_depth = right_type::depth + 1;
|
||||
@@ -530,11 +659,36 @@ struct expression
|
||||
const Arg4& right_ref()const BOOST_NOEXCEPT { return arg4; }
|
||||
|
||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||
explicit operator bool()const
|
||||
# if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)) || (defined(BOOST_INTEL) && (BOOST_INTEL <= 1500))
|
||||
//
|
||||
// Horrible workaround for gcc-4.6.x which always prefers the template
|
||||
// operator bool() rather than the non-template operator when converting to
|
||||
// an arithmetic type:
|
||||
//
|
||||
template <class T, typename boost::enable_if<is_same<T, bool>, int>::type = 0>
|
||||
explicit operator T ()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return static_cast<bool>(r);
|
||||
}
|
||||
template <class T, typename boost::disable_if_c<is_same<T, bool>::value || is_void<T>::value || is_number<T>::value, int>::type = 0>
|
||||
explicit operator T ()const
|
||||
{
|
||||
return static_cast<T>(static_cast<result_type>(*this));
|
||||
}
|
||||
# else
|
||||
template <class T, typename boost::disable_if_c<is_number<T>::value, int>::type = 0>
|
||||
explicit operator T()const
|
||||
{
|
||||
return static_cast<T>(static_cast<result_type>(*this));
|
||||
}
|
||||
BOOST_MP_FORCEINLINE explicit operator bool()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return static_cast<bool>(r);
|
||||
}
|
||||
explicit operator void()const {}
|
||||
# endif
|
||||
#else
|
||||
operator unmentionable_type()const
|
||||
{
|
||||
@@ -542,6 +696,13 @@ struct expression
|
||||
return r ? &unmentionable::proc : 0;
|
||||
}
|
||||
#endif
|
||||
template <class T>
|
||||
T convert_to()
|
||||
{
|
||||
result_type r(*this);
|
||||
return r.template convert_to<T>();
|
||||
}
|
||||
|
||||
static const unsigned left_depth = left_type::depth + 1;
|
||||
static const unsigned left_middle_depth = left_middle_type::depth + 1;
|
||||
static const unsigned right_middle_depth = right_middle_type::depth + 1;
|
||||
|
||||
@@ -958,6 +958,17 @@ void test_negative_mixed(boost::mpl::true_ const&)
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>(Real(n2)) , n2);
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>(Real(n3)) , n3);
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>(Real(n4)) , n4);
|
||||
#endif
|
||||
// Conversions when source is an expression template:
|
||||
BOOST_CHECK_EQUAL((Real(n1) + 0).template convert_to<Num>() , n1);
|
||||
BOOST_CHECK_EQUAL((Real(n2) + 0).template convert_to<Num>(), n2);
|
||||
BOOST_CHECK_EQUAL((Real(n3) + 0).template convert_to<Num>(), n3);
|
||||
BOOST_CHECK_EQUAL((Real(n4) + 0).template convert_to<Num>(), n4);
|
||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>((Real(n1) + 0)), n1);
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>((Real(n2) + 0)), n2);
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>((Real(n3) + 0)), n3);
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>((Real(n4) + 0)), n4);
|
||||
#endif
|
||||
#if defined(TEST_MPFR)
|
||||
Num tol = 10 * std::numeric_limits<Num>::epsilon();
|
||||
@@ -1250,7 +1261,18 @@ void test_mixed(const boost::mpl::true_&)
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>(Real(n3)) , n3);
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>(Real(n4)) , n4);
|
||||
#endif
|
||||
BOOST_CHECK_EQUAL(static_cast<cast_type>(n1) , Real(n1));
|
||||
// Again with expression templates:
|
||||
BOOST_CHECK_EQUAL((Real(n1) + 0).template convert_to<Num>(), n1);
|
||||
BOOST_CHECK_EQUAL((Real(n2) + 0).template convert_to<Num>(), n2);
|
||||
BOOST_CHECK_EQUAL((Real(n3) + 0).template convert_to<Num>(), n3);
|
||||
BOOST_CHECK_EQUAL((Real(n4) + 0).template convert_to<Num>(), n4);
|
||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>(Real(n1) + 0), n1);
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>(Real(n2) + 0), n2);
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>(Real(n3) + 0), n3);
|
||||
BOOST_CHECK_EQUAL(static_cast<Num>(Real(n4) + 0), n4);
|
||||
#endif
|
||||
BOOST_CHECK_EQUAL(static_cast<cast_type>(n1), Real(n1));
|
||||
BOOST_CHECK_EQUAL(static_cast<cast_type>(n2) , Real(n2));
|
||||
BOOST_CHECK_EQUAL(static_cast<cast_type>(n3) , Real(n3));
|
||||
BOOST_CHECK_EQUAL(static_cast<cast_type>(n4) , Real(n4));
|
||||
|
||||
Reference in New Issue
Block a user