|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r84106 - in trunk: boost/multiprecision boost/multiprecision/cpp_int boost/multiprecision/detail libs/multiprecision/test
From: john_at_[hidden]
Date: 2013-05-02 06:16:58
Author: johnmaddock
Date: 2013-05-02 06:16:57 EDT (Thu, 02 May 2013)
New Revision: 84106
URL: http://svn.boost.org/trac/boost/changeset/84106
Log:
Add tentative support for user-defined-literals.
Added:
trunk/boost/multiprecision/cpp_int/literals.hpp
- copied, changed from r84043, /trunk/boost/multiprecision/cpp_int/cpp_int_config.hpp
trunk/boost/multiprecision/cpp_int/value_pack.hpp
- copied, changed from r84043, /trunk/boost/multiprecision/cpp_int/cpp_int_config.hpp
trunk/libs/multiprecision/test/test_cpp_int_lit.cpp (contents, props changed)
Text files modified:
trunk/boost/multiprecision/cpp_int.hpp | 216 ++++++++------------------
trunk/boost/multiprecision/cpp_int/cpp_int_config.hpp | 16 +
trunk/boost/multiprecision/cpp_int/literals.hpp | 311 +++++++++++++++++++++++----------------
trunk/boost/multiprecision/cpp_int/value_pack.hpp | 151 ++-----------------
trunk/boost/multiprecision/detail/et_ops.hpp | 62 +++---
trunk/boost/multiprecision/detail/no_et_ops.hpp | 16 +-
trunk/boost/multiprecision/number.hpp | 2
trunk/libs/multiprecision/test/Jamfile.v2 | 1
8 files changed, 319 insertions(+), 456 deletions(-)
Modified: trunk/boost/multiprecision/cpp_int.hpp
==============================================================================
--- trunk/boost/multiprecision/cpp_int.hpp (original)
+++ trunk/boost/multiprecision/cpp_int.hpp 2013-05-02 06:16:57 EDT (Thu, 02 May 2013)
@@ -20,10 +20,12 @@
#include <boost/integer/static_min_max.hpp>
#include <boost/type_traits/common_type.hpp>
#include <boost/multiprecision/cpp_int/checked.hpp>
+#ifdef BOOST_MP_USER_DEFINED_LITERALS
+#include <boost/multiprecision/cpp_int/value_pack.hpp>
+#endif
namespace boost{
namespace multiprecision{
-
namespace backends{
#ifdef BOOST_MSVC
@@ -427,6 +429,10 @@
BOOST_CONSTEXPR data_type() : m_first_limb(0) {}
BOOST_CONSTEXPR data_type(limb_type i) : m_first_limb(i) {}
BOOST_CONSTEXPR data_type(double_limb_type i) : m_double_first_limb(i) {}
+#if defined(BOOST_MP_USER_DEFINED_LITERALS)
+ template <limb_type...VALUES>
+ BOOST_CONSTEXPR data_type(literals::detail::value_pack<VALUES...>) : m_data{ VALUES... } {}
+#endif
} m_wrapper;
boost::uint16_t m_limbs;
bool m_sign;
@@ -447,13 +453,22 @@
m_limbs(i < 0 ? (-i > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)),
m_sign(i < 0) {}
#endif
+#if defined(BOOST_MP_USER_DEFINED_LITERALS)
+ template <limb_type...VALUES>
+ BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<VALUES...> i)
+ : m_wrapper(i), m_limbs(sizeof...VALUES), m_sign(false) {}
+ BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<> i)
+ : m_wrapper(i), m_limbs(1), m_sign(false) {}
+ BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& a, const literals::detail::negate_tag&)
+ : m_wrapper(a.m_wrapper), m_limbs(a.m_limbs), m_sign((a.m_limbs == 1) && (*a.limbs() == 0) ? false : !a.m_sign) {}
+#endif
//
// Helper functions for getting at our internal data, and manipulating storage:
//
BOOST_MP_FORCEINLINE unsigned size()const BOOST_NOEXCEPT { return m_limbs; }
BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return m_wrapper.m_data; }
- BOOST_MP_FORCEINLINE const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_wrapper.m_data; }
- BOOST_MP_FORCEINLINE bool sign()const BOOST_NOEXCEPT { return m_sign; }
+ BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_wrapper.m_data; }
+ BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return m_sign; }
BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT
{
m_sign = b;
@@ -479,15 +494,10 @@
}
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() : m_wrapper(limb_type(0u)), m_limbs(1), m_sign(false) {}
- BOOST_MP_FORCEINLINE cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT : m_limbs(o.m_limbs), m_sign(o.m_sign)
- {
-#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
- std::copy(o.limbs(), o.limbs() + o.size(), stdext::checked_array_iterator<limb_pointer>(limbs(), size()));
-#else
- std::copy(o.limbs(), o.limbs() + o.size(), limbs());
-#endif
- }
+ // Defaulted functions:
+ //BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& i)BOOST_NOEXCEPT;
//~cpp_int_base() BOOST_NOEXCEPT {}
+
void assign(const cpp_int_base& o) BOOST_NOEXCEPT
{
if(this != &o)
@@ -570,6 +580,10 @@
BOOST_CONSTEXPR data_type() : m_first_limb(0) {}
BOOST_CONSTEXPR data_type(limb_type i) : m_first_limb(i) {}
BOOST_CONSTEXPR data_type(double_limb_type i) : m_double_first_limb(i) {}
+#if defined(BOOST_MP_USER_DEFINED_LITERALS)
+ template <limb_type...VALUES>
+ BOOST_CONSTEXPR data_type(literals::detail::value_pack<VALUES...>) : m_data{ VALUES... } {}
+#endif
} m_wrapper;
limb_type m_limbs;
@@ -587,12 +601,19 @@
BOOST_MP_FORCEINLINE cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT_IF((Checked == unchecked))
: m_wrapper(double_limb_type(i < 0 ? -i : i)), m_limbs(i < 0 ? (-i > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)) { if(i < 0) negate(); }
#endif
+#if defined(BOOST_MP_USER_DEFINED_LITERALS)
+ template <limb_type...VALUES>
+ BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<VALUES...> i)
+ : m_wrapper(i), m_limbs(sizeof...VALUES) {}
+ BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<>)
+ : m_wrapper(static_cast<limb_type>(0u)), m_limbs(1) {}
+#endif
//
// Helper functions for getting at our internal data, and manipulating storage:
//
BOOST_MP_FORCEINLINE unsigned size()const BOOST_NOEXCEPT { return m_limbs; }
BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return m_wrapper.m_data; }
- BOOST_MP_FORCEINLINE const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_wrapper.m_data; }
+ BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_wrapper.m_data; }
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; }
BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT_IF((Checked == unchecked)) { if(b) negate(); }
BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_NOEXCEPT_IF((Checked == unchecked))
@@ -610,16 +631,10 @@
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT
: m_wrapper(limb_type(0u)), m_limbs(1) {}
- BOOST_MP_FORCEINLINE cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT
- : m_limbs(o.m_limbs)
- {
-#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
- std::copy(o.limbs(), o.limbs() + o.size(), stdext::checked_array_iterator<limb_pointer>(limbs(), size()));
-#else
- std::copy(o.limbs(), o.limbs() + o.size(), limbs());
-#endif
- }
+ // Defaulted functions:
+ //BOOST_MP_FORCEINLINE cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT;
//~cpp_int_base() BOOST_NOEXCEPT {}
+
BOOST_MP_FORCEINLINE void assign(const cpp_int_base& o) BOOST_NOEXCEPT
{
if(this != &o)
@@ -761,12 +776,24 @@
template <class F>
BOOST_MP_FORCEINLINE cpp_int_base(F i, typename enable_if_c<is_floating_point<F>::value && (Checked == checked)>::type const* = 0) BOOST_NOEXCEPT_IF((Checked == unchecked))
: m_data(static_cast<local_limb_type>(std::fabs(i))), m_sign(i < 0) { check_in_range(i); }
+#if defined(BOOST_MP_USER_DEFINED_LITERALS)
+ BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<>)
+ : m_data(static_cast<local_limb_type>(0u)), m_sign(false) {}
+ template <limb_type a>
+ BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a>)
+ : m_data(static_cast<local_limb_type>(a)), m_sign(false) {}
+ template <limb_type a, limb_type b>
+ BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a, b>)
+ : m_data(static_cast<local_limb_type>(a) | (static_cast<local_limb_type>(b) << bits_per_limb)), m_sign(false) {}
+ BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& a, const literals::detail::negate_tag&)
+ : m_data(a.m_data), m_sign(a.m_data ? !a.m_sign : false) {}
+#endif
//
// Helper functions for getting at our internal data, and manipulating storage:
//
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR unsigned size()const BOOST_NOEXCEPT { return 1; }
BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return &m_data; }
- BOOST_MP_FORCEINLINE const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; }
+ BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; }
BOOST_MP_FORCEINLINE bool sign()const BOOST_NOEXCEPT { return m_sign; }
BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT
{
@@ -891,12 +918,22 @@
if(i < 0)
negate();
}
+#if defined(BOOST_MP_USER_DEFINED_LITERALS)
+ BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<>)
+ : m_data(static_cast<local_limb_type>(0u)) {}
+ template <limb_type a>
+ BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a>)
+ : m_data(static_cast<local_limb_type>(a)) {}
+ template <limb_type a, limb_type b>
+ BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a, b>)
+ : m_data(static_cast<local_limb_type>(a) | (static_cast<local_limb_type>(b) << bits_per_limb)) {}
+#endif
//
// Helper functions for getting at our internal data, and manipulating storage:
//
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR unsigned size()const BOOST_NOEXCEPT { return 1; }
BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return &m_data; }
- BOOST_MP_FORCEINLINE const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; }
+ BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; }
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; }
BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT_IF((Checked == unchecked))
{
@@ -949,6 +986,9 @@
#ifdef BOOST_LITTLE_ENDIAN
|| is_same<Arg, double_limb_type>::value || is_same<Arg, signed_double_limb_type>::value
#endif
+#if defined(BOOST_MP_USER_DEFINED_LITERALS)
+ || literals::detail::is_value_pack<Arg>::value
+#endif
|| (is_trivial_cpp_int<Base>::value && is_arithmetic<Arg>::value),
mpl::true_,
mpl::false_
@@ -1095,132 +1135,11 @@
mpl::bool_<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>());
return *this;
}
-#if 0
- template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, class Allocator2>
- cpp_int_backend(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other, typename enable_if_c<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value >::type* = 0)
- : base_type()
- {
- *this = static_cast<
- typename boost::multiprecision::detail::canonical<
- typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>::local_limb_type,
- cpp_int_backend<MinBits, MaxBits, SignType, Allocator>
- >::type
- >(*other.limbs());
- this->sign(other.sign());
- }
- template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, class Allocator2>
- typename enable_if_c<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value, cpp_int_backend&>::type
- operator=(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other)
- {
- *this = static_cast<
- typename boost::multiprecision::detail::canonical<
- typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>::local_limb_type,
- cpp_int_backend<MinBits, MaxBits, SignType, Allocator>
- >::type
- >(*other.limbs());
- this->sign(other.sign());
- return *this;
- }
-
- template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
- cpp_int_backend(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other,
- typename enable_if_c<
- ((is_signed_number<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value || !is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value)
- && (!is_void<Allocator>::value || (is_void<Allocator2>::value && (MinBits >= MinBits2)))
- && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
- && !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value)
- >::type* = 0)
- : base_type()
- {
- this->resize(other.size(), other_size());
-#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
- std::copy(other.limbs(), other.limbs() + (std::min)(other.size(), this->size()), stdext::checked_array_iterator<limb_pointer>(this->limbs(), this->size()));
-#else
- std::copy(other.limbs(), other.limbs() + (std::min)(other.size(), this->size()), this->limbs());
-#endif
- this->sign(other.sign());
- }
-
- template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
- explicit cpp_int_backend(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other,
- typename enable_if_c<
- (!((is_signed_number<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value || !is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value)
- && (!is_void<Allocator>::value || (is_void<Allocator2>::value && (MinBits >= MinBits2))))
- && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
- && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value)
- >::type* = 0)
- : base_type()
- {
- double_limb_type v = *other.limbs();
- if(other.size() > 1)
- v |= static_cast<double_limb_type>(other.limbs()[1]) << bits_per_limb;
- *this = v;
- this->sign(other.sign());
- }
-
- template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
- explicit cpp_int_backend(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other,
- typename enable_if_c<
- (!((is_signed_number<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value || !is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value))
- && (!is_void<Allocator>::value || (is_void<Allocator2>::value && (MinBits >= MinBits2)))
- && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
- && !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value)
- >::type* = 0)
- : base_type()
- {
- this->resize(other.size(), other.size());
-#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
- std::copy(other.limbs(), other.limbs() + (std::min)(other.size(), this->size()), stdext::checked_array_iterator<limb_pointer>(this->limbs(), this->size()));
-#else
- std::copy(other.limbs(), other.limbs() + (std::min)(other.size(), this->size()), this->limbs());
-#endif
- this->sign(other.sign());
- }
-
- template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
- explicit cpp_int_backend(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other,
- typename enable_if_c<
- (!((is_signed_number<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value || !is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value))
- && (!is_void<Allocator>::value || (is_void<Allocator2>::value && (MinBits >= MinBits2)))
- && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
- && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value)
- >::type* = 0)
- : base_type()
- {
- double_limb_type v = *other.limbs();
- if(other.size() > 1)
- v |= static_cast<double_limb_type>(other.limbs()[1]) << bits_per_limb;
- *this = v;
- this->sign(other.sign());
- }
-
- template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
- typename enable_if_c<(!is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
- && !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value), cpp_int_backend&>::type
- operator=(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other)
- {
- this->resize(other.size(), other.size());
-#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
- std::copy(other.limbs(), other.limbs() + (std::min)(other.size(), this->size()), stdext::checked_array_iterator<limb_pointer>(this->limbs(), this->size()));
-#else
- std::copy(other.limbs(), other.limbs() + (std::min)(other.size(), this->size()), this->limbs());
+#ifdef BOOST_MP_USER_DEFINED_LITERALS
+ BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& a, const literals::detail::negate_tag& tag)
+ : base_type(static_cast<const base_type&>(a), tag){}
#endif
- this->sign(other.sign());
- return *this;
- }
- template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
- typename enable_if_c<(!is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
- && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value), cpp_int_backend&>::type
- operator=(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other)
- {
- double_limb_type v = *other.limbs();
- if(other.size() > 1)
- v |= static_cast<double_limb_type>(other.limbs()[1]) << bits_per_limb;
- *this = v;
- this->sign(other.sign());
- }
-#endif
BOOST_MP_FORCEINLINE cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_NOEXCEPT_IF((Checked == unchecked) && boost::is_void<Allocator>::value)
{
this->assign(o);
@@ -1873,5 +1792,8 @@
#include <boost/multiprecision/cpp_int/bitwise.hpp>
#include <boost/multiprecision/cpp_int/misc.hpp>
#include <boost/multiprecision/cpp_int/limits.hpp>
+#ifdef BOOST_MP_USER_DEFINED_LITERALS
+#include <boost/multiprecision/cpp_int/literals.hpp>
+#endif
#endif
Modified: trunk/boost/multiprecision/cpp_int/cpp_int_config.hpp
==============================================================================
--- trunk/boost/multiprecision/cpp_int/cpp_int_config.hpp (original)
+++ trunk/boost/multiprecision/cpp_int/cpp_int_config.hpp 2013-05-02 06:16:57 EDT (Thu, 02 May 2013)
@@ -21,8 +21,8 @@
// These traits calculate the largest type in the list
// [unsigned] long long, long, int, which has the specified number
// of bits. Note that intN_t and boost::int_t<N> find the first
-// member of the above list, not the last. We want the last in the
-// list to ensure that mixed arithmetic operations are as efficient
+// member of the above list, not the last. We want the last in the
+// list to ensure that mixed arithmetic operations are as efficient
// as possible.
//
template <unsigned N>
@@ -74,7 +74,7 @@
inline limb_type block_multiplier(unsigned count)
{
- static const limb_type values[digits_per_block_10]
+ static const limb_type values[digits_per_block_10]
= { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000 };
BOOST_ASSERT(count < digits_per_block_10);
return values[count];
@@ -110,7 +110,7 @@
inline limb_type block_multiplier(unsigned count)
{
- static const limb_type values[digits_per_block_10]
+ static const limb_type values[digits_per_block_10]
= { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
BOOST_ASSERT(count < digits_per_block_10);
return values[count];
@@ -151,5 +151,13 @@
}}
+//
+// Figure out whether to support user-defined-literals or not:
+//
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_USER_DEFINED_LITERALS) \
+ && !defined(BOOST_NO_CXX11_CONSTEXPR)
+# define BOOST_MP_USER_DEFINED_LITERALS
+#endif
+
#endif // BOOST_MP_CPP_INT_CORE_HPP
Copied: trunk/boost/multiprecision/cpp_int/literals.hpp (from r84043, /trunk/boost/multiprecision/cpp_int/cpp_int_config.hpp)
==============================================================================
--- /trunk/boost/multiprecision/cpp_int/cpp_int_config.hpp (original)
+++ trunk/boost/multiprecision/cpp_int/literals.hpp 2013-05-02 06:16:57 EDT (Thu, 02 May 2013)
@@ -1,155 +1,206 @@
///////////////////////////////////////////////////////////////
-// Copyright 2012 John Maddock. Distributed under the Boost
+// Copyright 2013 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
-#ifndef BOOST_MP_CPP_INT_CORE_HPP
-#define BOOST_MP_CPP_INT_CORE_HPP
+#ifndef BOOST_MP_CPP_INT_LITERALS_HPP
+#define BOOST_MP_CPP_INT_LITERALS_HPP
-#include <boost/integer.hpp>
-#include <boost/integer_traits.hpp>
-#include <boost/mpl/if.hpp>
-#include <boost/mpl/int.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/assert.hpp>
+#include <boost/multiprecision/cpp_int/cpp_int_config.hpp>
namespace boost{ namespace multiprecision{
-namespace detail{
+namespace literals{ namespace detail{
-//
-// These traits calculate the largest type in the list
-// [unsigned] long long, long, int, which has the specified number
-// of bits. Note that intN_t and boost::int_t<N> find the first
-// member of the above list, not the last. We want the last in the
-// list to ensure that mixed arithmetic operations are as efficient
-// as possible.
-//
-template <unsigned N>
-struct largest_signed_type
+template <char> struct hex_value;
+template <> struct hex_value<'0'> { static constexpr limb_type value = 0; };
+template <> struct hex_value<'1'> { static constexpr limb_type value = 1; };
+template <> struct hex_value<'2'> { static constexpr limb_type value = 2; };
+template <> struct hex_value<'3'> { static constexpr limb_type value = 3; };
+template <> struct hex_value<'4'> { static constexpr limb_type value = 4; };
+template <> struct hex_value<'5'> { static constexpr limb_type value = 5; };
+template <> struct hex_value<'6'> { static constexpr limb_type value = 6; };
+template <> struct hex_value<'7'> { static constexpr limb_type value = 7; };
+template <> struct hex_value<'8'> { static constexpr limb_type value = 8; };
+template <> struct hex_value<'9'> { static constexpr limb_type value = 9; };
+template <> struct hex_value<'a'> { static constexpr limb_type value = 10; };
+template <> struct hex_value<'b'> { static constexpr limb_type value = 11; };
+template <> struct hex_value<'c'> { static constexpr limb_type value = 12; };
+template <> struct hex_value<'d'> { static constexpr limb_type value = 13; };
+template <> struct hex_value<'e'> { static constexpr limb_type value = 14; };
+template <> struct hex_value<'f'> { static constexpr limb_type value = 15; };
+template <> struct hex_value<'A'> { static constexpr limb_type value = 10; };
+template <> struct hex_value<'B'> { static constexpr limb_type value = 11; };
+template <> struct hex_value<'C'> { static constexpr limb_type value = 12; };
+template <> struct hex_value<'D'> { static constexpr limb_type value = 13; };
+template <> struct hex_value<'E'> { static constexpr limb_type value = 14; };
+template <> struct hex_value<'F'> { static constexpr limb_type value = 15; };
+
+template <class Pack, limb_type value>
+struct combine_value_to_pack;
+template <limb_type first, limb_type...ARGS, limb_type value>
+struct combine_value_to_pack<value_pack<first, ARGS...>, value>
{
- typedef typename mpl::if_c<
- 1 + std::numeric_limits<long long>::digits == N,
- long long,
- typename mpl::if_c<
- 1 + std::numeric_limits<long>::digits == N,
- long,
- typename mpl::if_c<
- 1 + std::numeric_limits<int>::digits == N,
- int,
- typename boost::int_t<N>::exact
- >::type
- >::type
- >::type type;
-};
-
-template <unsigned N>
-struct largest_unsigned_type
-{
- typedef typename mpl::if_c<
- std::numeric_limits<unsigned long long>::digits == N,
- unsigned long long,
- typename mpl::if_c<
- std::numeric_limits<unsigned long>::digits == N,
- unsigned long,
- typename mpl::if_c<
- std::numeric_limits<unsigned int>::digits == N,
- unsigned int,
- typename boost::uint_t<N>::exact
- >::type
- >::type
- >::type type;
-};
-
-} // namespace detail
-
-#if defined(BOOST_HAS_INT128)
-
-typedef detail::largest_unsigned_type<64>::type limb_type;
-typedef detail::largest_signed_type<64>::type signed_limb_type;
-typedef boost::uint128_type double_limb_type;
-typedef boost::int128_type signed_double_limb_type;
-static const limb_type max_block_10 = 1000000000000000000uLL;
-static const limb_type digits_per_block_10 = 18;
-
-inline limb_type block_multiplier(unsigned count)
-{
- static const limb_type values[digits_per_block_10]
- = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000 };
- BOOST_ASSERT(count < digits_per_block_10);
- return values[count];
-}
-
-// Can't do formatted IO on an __int128
-#define BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
-
-// Need to specialise integer_traits for __int128 as it's not a normal native type:
-} // namespace multiprecision
-
-template<>
-class integer_traits<multiprecision::double_limb_type>
- : public std::numeric_limits<multiprecision::double_limb_type>,
- public detail::integer_traits_base<multiprecision::double_limb_type, 0, ~static_cast<multiprecision::double_limb_type>(0)>
-{ };
-template<>
-class integer_traits<multiprecision::signed_double_limb_type>
- : public std::numeric_limits<multiprecision::signed_double_limb_type>,
- public detail::integer_traits_base<multiprecision::signed_double_limb_type, static_cast<multiprecision::signed_double_limb_type>((static_cast<multiprecision::double_limb_type>(1) << 127)), static_cast<multiprecision::signed_double_limb_type>(((~static_cast<multiprecision::double_limb_type>(0)) >> 1))>
-{ };
-
-namespace multiprecision{
-
-#else
-
-typedef detail::largest_unsigned_type<32>::type limb_type;
-typedef detail::largest_signed_type<32>::type signed_limb_type;
-typedef boost::uint64_t double_limb_type;
-typedef boost::int64_t signed_double_limb_type;
-static const limb_type max_block_10 = 1000000000;
-static const limb_type digits_per_block_10 = 9;
-
-inline limb_type block_multiplier(unsigned count)
-{
- static const limb_type values[digits_per_block_10]
- = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
- BOOST_ASSERT(count < digits_per_block_10);
- return values[count];
-}
+ typedef value_pack<first | value, ARGS...> type;
+};
-#endif
+template <char NextChar, char...CHARS>
+struct pack_values
+{
+ static constexpr unsigned chars_per_limb = sizeof(limb_type) * CHAR_BIT / 4;
+ static constexpr unsigned shift = ((sizeof...CHARS) % chars_per_limb) * 4;
+ static constexpr limb_type value_to_add = shift ? hex_value<NextChar>::value << shift : hex_value<NextChar>::value;
+
+ typedef typename pack_values<CHARS...>::type recursive_packed_type;
+ typedef typename boost::mpl::if_c<shift == 0,
+ typename recursive_packed_type::next_type,
+ recursive_packed_type>::type pack_type;
+ typedef typename combine_value_to_pack<pack_type, value_to_add>::type type;
+};
+template <char NextChar>
+struct pack_values<NextChar>
+{
+ static constexpr limb_type value_to_add = hex_value<NextChar>::value;
-static const unsigned bits_per_limb = sizeof(limb_type) * CHAR_BIT;
+ typedef value_pack<value_to_add> type;
+};
template <class T>
-inline void minmax(const T& a, const T& b, T& aa, T& bb)
+struct strip_leading_zeros_from_pack;
+template <limb_type...PACK>
+struct strip_leading_zeros_from_pack<value_pack<PACK...> >
{
- if(a < b)
- {
- aa = a;
- bb = b;
- }
- else
- {
- aa = b;
- bb = a;
- }
-}
+ typedef value_pack<PACK...> type;
+};
+template <limb_type...PACK>
+struct strip_leading_zeros_from_pack<value_pack<0u, PACK...> >
+{
+ typedef typename strip_leading_zeros_from_pack<value_pack<PACK...> >::type type;
+};
+
+template <limb_type v, class PACK>
+struct append_value_to_pack;
+template <limb_type v, limb_type...PACK>
+struct append_value_to_pack<v, value_pack<PACK...> >
+{
+ typedef value_pack<PACK..., v> type;
+};
+
+template <class T>
+struct reverse_value_pack;
+template <limb_type v, limb_type...VALUES>
+struct reverse_value_pack<value_pack<v, VALUES...> >
+{
+ typedef typename reverse_value_pack<value_pack<VALUES...> >::type lead_values;
+ typedef typename append_value_to_pack<v, lead_values>::type type;
+};
+template <limb_type v>
+struct reverse_value_pack<value_pack<v> >
+{
+ typedef value_pack<v> type;
+};
+template <>
+struct reverse_value_pack<value_pack<> >
+{
+ typedef value_pack<> type;
+};
+
+template <char l1, char l2, char...STR>
+struct make_packed_value_from_str
+{
+ BOOST_STATIC_ASSERT_MSG(l1 == '0', "Multi-precision integer literals must be in hexadecimal notation.");
+ BOOST_STATIC_ASSERT_MSG((l2 == 'X') || (l2 == 'x'), "Multi-precision integer literals must be in hexadecimal notation.");
+ typedef typename pack_values<STR...>::type packed_type;
+ typedef typename strip_leading_zeros_from_pack<packed_type>::type stripped_type;
+ typedef typename reverse_value_pack<stripped_type>::type type;
+};
+
+template <class Pack, class B>
+struct make_backend_from_pack
+{
+ static constexpr Pack p = {};
+ static constexpr B value = p;
+};
+
+template <class Pack, class B>
+constexpr B make_backend_from_pack<Pack, B>::value;
-enum cpp_integer_type
+template <unsigned Digits>
+struct signed_cpp_int_literal_result_type
{
- signed_magnitude = 1,
- unsigned_magnitude = 0,
- signed_packed = 3,
- unsigned_packed = 2
+ static constexpr unsigned bits = Digits * 4;
+ typedef boost::multiprecision::backends::cpp_int_backend<bits, bits, signed_magnitude, unchecked, void> backend_type;
+ typedef number<backend_type, et_off> number_type;
};
-enum cpp_int_check_type
+template <unsigned Digits>
+struct unsigned_cpp_int_literal_result_type
{
- checked = 1,
- unchecked = 0
+ static constexpr unsigned bits = Digits * 4;
+ typedef boost::multiprecision::backends::cpp_int_backend<bits, bits, unsigned_magnitude, unchecked, void> backend_type;
+ typedef number<backend_type, et_off> number_type;
};
-}}
+}
+
+template <char... STR>
+constexpr typename boost::multiprecision::literals::detail::signed_cpp_int_literal_result_type<(sizeof...STR) - 2>::number_type operator "" _cppi()
+{
+ typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type pt;
+ return boost::multiprecision::literals::detail::make_backend_from_pack<pt, typename boost::multiprecision::literals::detail::signed_cpp_int_literal_result_type<(sizeof...STR) - 2>::backend_type>::value;
+}
+
+template <char... STR>
+constexpr typename boost::multiprecision::literals::detail::unsigned_cpp_int_literal_result_type<(sizeof...STR) - 2>::number_type operator "" _cppui()
+{
+ typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type pt;
+ return boost::multiprecision::literals::detail::make_backend_from_pack<pt, typename boost::multiprecision::literals::detail::unsigned_cpp_int_literal_result_type<(sizeof...STR) - 2>::backend_type>::value;
+}
+
+#define BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(Bits)\
+template <char... STR> \
+constexpr boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > operator "" BOOST_JOIN(_cppi, Bits)()\
+{\
+ typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type pt;\
+ return boost::multiprecision::literals::detail::make_backend_from_pack<\
+ pt, \
+ boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> \
+ >::value;\
+}\
+template <char... STR> \
+constexpr boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> > operator "" BOOST_JOIN(_cppui, Bits)()\
+{\
+ typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type pt;\
+ return boost::multiprecision::literals::detail::make_backend_from_pack<\
+ pt, \
+ boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>\
+ >::value;\
+}\
+
+BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(128)
+BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(256)
+BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(512)
+BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(1024)
+
+}
+
+//
+// Overload unary minus operator for constexpr use:
+//
+template <unsigned MinBits, cpp_int_check_type Checked>
+constexpr number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>
+ operator - (const number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>& a)
+{
+ return cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>(a.backend(), boost::multiprecision::literals::detail::make_negate_tag());
+}
+template <unsigned MinBits, cpp_int_check_type Checked>
+constexpr number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>
+ operator - (number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>&& a)
+{
+ return cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>(static_cast<const number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>&>(a).backend(), boost::multiprecision::literals::detail::make_negate_tag());
+}
+
+}} // namespaces
#endif // BOOST_MP_CPP_INT_CORE_HPP
Copied: trunk/boost/multiprecision/cpp_int/value_pack.hpp (from r84043, /trunk/boost/multiprecision/cpp_int/cpp_int_config.hpp)
==============================================================================
--- /trunk/boost/multiprecision/cpp_int/cpp_int_config.hpp (original)
+++ trunk/boost/multiprecision/cpp_int/value_pack.hpp 2013-05-02 06:16:57 EDT (Thu, 02 May 2013)
@@ -1,155 +1,36 @@
///////////////////////////////////////////////////////////////
-// Copyright 2012 John Maddock. Distributed under the Boost
+// Copyright 2013 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
-#ifndef BOOST_MP_CPP_INT_CORE_HPP
-#define BOOST_MP_CPP_INT_CORE_HPP
-
-#include <boost/integer.hpp>
-#include <boost/integer_traits.hpp>
-#include <boost/mpl/if.hpp>
-#include <boost/mpl/int.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/assert.hpp>
+#ifndef BOOST_MP_CPP_INT_VP_HPP
+#define BOOST_MP_CPP_INT_VP_HPP
namespace boost{ namespace multiprecision{
-namespace detail{
+namespace literals{ namespace detail{
-//
-// These traits calculate the largest type in the list
-// [unsigned] long long, long, int, which has the specified number
-// of bits. Note that intN_t and boost::int_t<N> find the first
-// member of the above list, not the last. We want the last in the
-// list to ensure that mixed arithmetic operations are as efficient
-// as possible.
-//
-template <unsigned N>
-struct largest_signed_type
+template <limb_type...VALUES>
+struct value_pack
{
- typedef typename mpl::if_c<
- 1 + std::numeric_limits<long long>::digits == N,
- long long,
- typename mpl::if_c<
- 1 + std::numeric_limits<long>::digits == N,
- long,
- typename mpl::if_c<
- 1 + std::numeric_limits<int>::digits == N,
- int,
- typename boost::int_t<N>::exact
- >::type
- >::type
- >::type type;
-};
+ constexpr value_pack(){}
-template <unsigned N>
-struct largest_unsigned_type
-{
- typedef typename mpl::if_c<
- std::numeric_limits<unsigned long long>::digits == N,
- unsigned long long,
- typename mpl::if_c<
- std::numeric_limits<unsigned long>::digits == N,
- unsigned long,
- typename mpl::if_c<
- std::numeric_limits<unsigned int>::digits == N,
- unsigned int,
- typename boost::uint_t<N>::exact
- >::type
- >::type
- >::type type;
+ typedef value_pack<0, VALUES...> next_type;
};
+template <class T>
+struct is_value_pack{ static constexpr bool value = false; };
+template <limb_type...VALUES>
+struct is_value_pack<value_pack<VALUES...> >{ static constexpr bool value = true; };
-} // namespace detail
-
-#if defined(BOOST_HAS_INT128)
-
-typedef detail::largest_unsigned_type<64>::type limb_type;
-typedef detail::largest_signed_type<64>::type signed_limb_type;
-typedef boost::uint128_type double_limb_type;
-typedef boost::int128_type signed_double_limb_type;
-static const limb_type max_block_10 = 1000000000000000000uLL;
-static const limb_type digits_per_block_10 = 18;
-
-inline limb_type block_multiplier(unsigned count)
-{
- static const limb_type values[digits_per_block_10]
- = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000 };
- BOOST_ASSERT(count < digits_per_block_10);
- return values[count];
-}
-
-// Can't do formatted IO on an __int128
-#define BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
-
-// Need to specialise integer_traits for __int128 as it's not a normal native type:
-} // namespace multiprecision
-
-template<>
-class integer_traits<multiprecision::double_limb_type>
- : public std::numeric_limits<multiprecision::double_limb_type>,
- public detail::integer_traits_base<multiprecision::double_limb_type, 0, ~static_cast<multiprecision::double_limb_type>(0)>
-{ };
-template<>
-class integer_traits<multiprecision::signed_double_limb_type>
- : public std::numeric_limits<multiprecision::signed_double_limb_type>,
- public detail::integer_traits_base<multiprecision::signed_double_limb_type, static_cast<multiprecision::signed_double_limb_type>((static_cast<multiprecision::double_limb_type>(1) << 127)), static_cast<multiprecision::signed_double_limb_type>(((~static_cast<multiprecision::double_limb_type>(0)) >> 1))>
-{ };
-
-namespace multiprecision{
-
-#else
-
-typedef detail::largest_unsigned_type<32>::type limb_type;
-typedef detail::largest_signed_type<32>::type signed_limb_type;
-typedef boost::uint64_t double_limb_type;
-typedef boost::int64_t signed_double_limb_type;
-static const limb_type max_block_10 = 1000000000;
-static const limb_type digits_per_block_10 = 9;
-
-inline limb_type block_multiplier(unsigned count)
-{
- static const limb_type values[digits_per_block_10]
- = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
- BOOST_ASSERT(count < digits_per_block_10);
- return values[count];
-}
-
-#endif
-
-static const unsigned bits_per_limb = sizeof(limb_type) * CHAR_BIT;
+struct negate_tag{};
-template <class T>
-inline void minmax(const T& a, const T& b, T& aa, T& bb)
+constexpr negate_tag make_negate_tag()
{
- if(a < b)
- {
- aa = a;
- bb = b;
- }
- else
- {
- aa = b;
- bb = a;
- }
+ return negate_tag();
}
-enum cpp_integer_type
-{
- signed_magnitude = 1,
- unsigned_magnitude = 0,
- signed_packed = 3,
- unsigned_packed = 2
-};
-
-enum cpp_int_check_type
-{
- checked = 1,
- unchecked = 0
-};
-}}
+}}}} // namespaces
#endif // BOOST_MP_CPP_INT_CORE_HPP
Modified: trunk/boost/multiprecision/detail/et_ops.hpp
==============================================================================
--- trunk/boost/multiprecision/detail/et_ops.hpp (original)
+++ trunk/boost/multiprecision/detail/et_ops.hpp 2013-05-02 06:16:57 EDT (Thu, 02 May 2013)
@@ -14,20 +14,20 @@
// Unary operators first:
//
template <class B, expression_template_option ExpressionTemplates>
-inline const number<B, ExpressionTemplates>& operator + (const number<B, ExpressionTemplates>& v) { return v; }
+inline BOOST_CONSTEXPR const number<B, ExpressionTemplates>& operator + (const number<B, ExpressionTemplates>& v) { return v; }
template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
-inline const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& operator + (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return v; }
+inline BOOST_CONSTEXPR const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& operator + (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return v; }
template <class B>
-inline detail::expression<detail::negate, number<B, et_on> > operator - (const number<B, et_on>& v)
+inline detail::expression<detail::negate, number<B, et_on> > operator - (const number<B, et_on>& v)
{
BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
- return detail::expression<detail::negate, number<B, et_on> >(v);
+ return detail::expression<detail::negate, number<B, et_on> >(v);
}
template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
-inline detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v)
-{
+inline detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v)
+{
BOOST_STATIC_ASSERT_MSG((is_signed_number<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value), "Negating an unsigned type results in ill-defined behavior.");
- return detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v);
+ return detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v);
}
template <class B>
inline typename enable_if_c<number_category<B>::value == number_kind_integer,
@@ -92,14 +92,14 @@
// Fused multiply add:
//
template <class V, class Arg1, class Arg2, class Arg3, class Arg4>
-inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
+inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type
operator + (const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
{
return detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(b.left(), b.right(), a);
}
template <class Arg1, class Arg2, class Arg3, class Arg4, class V>
-inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
+inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
detail::expression<detail::multiply_add, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type
operator + (const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
{
@@ -121,7 +121,7 @@
// Fused multiply subtract:
//
template <class V, class Arg1, class Arg2, class Arg3, class Arg4>
-inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
+inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
detail::expression<detail::negate, detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> > >::type
operator - (const V& a, const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& b)
{
@@ -129,7 +129,7 @@
(detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V>(b.left(), b.right(), a));
}
template <class Arg1, class Arg2, class Arg3, class Arg4, class V>
-inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
+inline typename enable_if<is_compatible_arithmetic_type<V, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::result_type>,
detail::expression<detail::multiply_subtract, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::left_type, typename detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>::right_type, V> >::type
operator - (const detail::expression<detail::multiply_immediates, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
{
@@ -534,14 +534,14 @@
return detail::expression<detail::modulus_immediates, number<B, et_on>, number<B, et_on> >(a, b);
}
template <class B, class V>
-inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
+inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
detail::expression<detail::modulus_immediates, number<B, et_on>, V > >::type
operator % (const number<B, et_on>& a, const V& b)
{
return detail::expression<detail::modulus_immediates, number<B, et_on>, V >(a, b);
}
template <class V, class B>
-inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
+inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value && (number_category<B>::value == number_kind_integer),
detail::expression<detail::modulus_immediates, V, number<B, et_on> > >::type
operator % (const V& a, const number<B, et_on>& b)
{
@@ -569,8 +569,8 @@
return detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, detail::expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
}
template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
-inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
- && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
+inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
+ && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
detail::expression<detail::modulus, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
operator % (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
{
@@ -578,7 +578,7 @@
}
template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
- && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
+ && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
detail::expression<detail::modulus, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
operator % (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
{
@@ -594,7 +594,7 @@
return detail::expression<detail::shift_left, number<B, et_on>, I>(a, b);
}
template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I>
-inline typename enable_if_c<is_integral<I>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
+inline typename enable_if_c<is_integral<I>::value && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
detail::expression<detail::shift_left, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type
operator << (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b)
{
@@ -604,15 +604,15 @@
// Right shift:
//
template <class B, class I>
-inline typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer),
+inline typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer),
detail::expression<detail::shift_right, number<B, et_on>, I > >::type
operator >> (const number<B, et_on>& a, const I& b)
{
return detail::expression<detail::shift_right, number<B, et_on>, I>(a, b);
}
template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I>
-inline typename enable_if_c<is_integral<I>::value
- && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
+inline typename enable_if_c<is_integral<I>::value
+ && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
detail::expression<detail::shift_right, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type
operator >> (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b)
{
@@ -630,7 +630,7 @@
}
template <class B, class V>
inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
- && (number_category<B>::value == number_kind_integer),
+ && (number_category<B>::value == number_kind_integer),
detail::expression<detail::bitwise_and_immediates, number<B, et_on>, V > >::type
operator & (const number<B, et_on>& a, const V& b)
{
@@ -638,7 +638,7 @@
}
template <class V, class B>
inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
- && (number_category<B>::value == number_kind_integer),
+ && (number_category<B>::value == number_kind_integer),
detail::expression<detail::bitwise_and_immediates, V, number<B, et_on> > >::type
operator & (const V& a, const number<B, et_on>& b)
{
@@ -667,7 +667,7 @@
}
template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
- && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
+ && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
detail::expression<detail::bitwise_and, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
operator & (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
{
@@ -675,7 +675,7 @@
}
template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
- && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
+ && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
detail::expression<detail::bitwise_and, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
operator & (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
{
@@ -693,7 +693,7 @@
}
template <class B, class V>
inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
- && (number_category<B>::value == number_kind_integer),
+ && (number_category<B>::value == number_kind_integer),
detail::expression<detail::bitwise_or_immediates, number<B, et_on>, V > >::type
operator| (const number<B, et_on>& a, const V& b)
{
@@ -701,7 +701,7 @@
}
template <class V, class B>
inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
- && (number_category<B>::value == number_kind_integer),
+ && (number_category<B>::value == number_kind_integer),
detail::expression<detail::bitwise_or_immediates, V, number<B, et_on> > >::type
operator| (const V& a, const number<B, et_on>& b)
{
@@ -730,7 +730,7 @@
}
template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
- && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
+ && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
detail::expression<detail::bitwise_or, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
operator| (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
{
@@ -738,7 +738,7 @@
}
template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
- && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
+ && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
detail::expression<detail::bitwise_or, V, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > >::type
operator| (const V& a, const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& b)
{
@@ -756,7 +756,7 @@
}
template <class B, class V>
inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
- && (number_category<B>::value == number_kind_integer),
+ && (number_category<B>::value == number_kind_integer),
detail::expression<detail::bitwise_xor_immediates, number<B, et_on>, V > >::type
operator^ (const number<B, et_on>& a, const V& b)
{
@@ -764,7 +764,7 @@
}
template <class V, class B>
inline typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_on> >::value
- && (number_category<B>::value == number_kind_integer),
+ && (number_category<B>::value == number_kind_integer),
detail::expression<detail::bitwise_xor_immediates, V, number<B, et_on> > >::type
operator^ (const V& a, const number<B, et_on>& b)
{
@@ -793,7 +793,7 @@
}
template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
inline typename enable_if_c<is_compatible_arithmetic_type<V, typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value
- && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
+ && (number_category<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value == number_kind_integer),
detail::expression<detail::bitwise_xor, detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
operator^ (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
{
Modified: trunk/boost/multiprecision/detail/no_et_ops.hpp
==============================================================================
--- trunk/boost/multiprecision/detail/no_et_ops.hpp (original)
+++ trunk/boost/multiprecision/detail/no_et_ops.hpp 2013-05-02 06:16:57 EDT (Thu, 02 May 2013)
@@ -20,19 +20,19 @@
// NOTE: these operators have to be defined after the methods in default_ops.hpp.
//
template <class B>
-BOOST_MP_FORCEINLINE number<B, et_off> operator - (const number<B, et_off>& v)
+BOOST_MP_FORCEINLINE number<B, et_off> operator - (const number<B, et_off>& v)
{
BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
number<B, et_off> result(v);
result.backend().negate();
- return BOOST_MP_MOVE(result);
+ return BOOST_MP_MOVE(result);
}
template <class B>
-BOOST_MP_FORCEINLINE number<B, et_off> operator ~ (const number<B, et_off>& v)
+BOOST_MP_FORCEINLINE number<B, et_off> operator ~ (const number<B, et_off>& v)
{
number<B, et_off> result;
eval_complement(result.backend(), v.backend());
- return BOOST_MP_MOVE(result);
+ return BOOST_MP_MOVE(result);
}
//
// Addition:
@@ -303,17 +303,17 @@
// semantics help a great deal in return by value, so performance is still pretty good...
//
template <class B>
-BOOST_MP_FORCEINLINE number<B, et_off> operator - (number<B, et_off>&& v)
+BOOST_MP_FORCEINLINE number<B, et_off> operator - (number<B, et_off>&& v)
{
BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
v.backend().negate();
- return static_cast<number<B, et_off>&&>(v);
+ return static_cast<number<B, et_off>&&>(v);
}
template <class B>
-BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator ~ (number<B, et_off>&& v)
+BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator ~ (number<B, et_off>&& v)
{
eval_complement(v.backend(), v.backend());
- return static_cast<number<B, et_off>&&>(v);
+ return static_cast<number<B, et_off>&&>(v);
}
//
// Addition:
Modified: trunk/boost/multiprecision/number.hpp
==============================================================================
--- trunk/boost/multiprecision/number.hpp (original)
+++ trunk/boost/multiprecision/number.hpp 2013-05-02 06:16:57 EDT (Thu, 02 May 2013)
@@ -669,7 +669,7 @@
{
return m_backend;
}
- BOOST_MP_FORCEINLINE const Backend& backend()const BOOST_NOEXCEPT
+ BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const Backend& backend()const BOOST_NOEXCEPT
{
return m_backend;
}
Modified: trunk/libs/multiprecision/test/Jamfile.v2
==============================================================================
--- trunk/libs/multiprecision/test/Jamfile.v2 (original)
+++ trunk/libs/multiprecision/test/Jamfile.v2 2013-05-02 06:16:57 EDT (Thu, 02 May 2013)
@@ -324,6 +324,7 @@
: test_move_cpp_int ;
run test_test.cpp ;
+run test_cpp_int_lit.cpp ;
compile test_constexpr.cpp : [ check-target-builds ../config//has_float128 : <define>HAVE_FLOAT128 : ] [ check-target-builds ../config//has_intel_quad : <define>HAVE_FLOAT128 : ] ;
run test_float_io.cpp
Added: trunk/libs/multiprecision/test/test_cpp_int_lit.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/multiprecision/test/test_cpp_int_lit.cpp 2013-05-02 06:16:57 EDT (Thu, 02 May 2013)
@@ -0,0 +1,57 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2013 John Maddock. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/multiprecision/cpp_int.hpp>
+#include "test.hpp"
+
+
+#ifdef BOOST_MP_USER_DEFINED_LITERALS
+
+
+using namespace boost::multiprecision;
+
+template <class T>
+void test_literal(T val, const char* p)
+{
+ BOOST_CHECK_EQUAL(val, cpp_int(p));
+}
+
+#define TEST_LITERAL(x)\
+{\
+ constexpr auto val1 = BOOST_JOIN(x, _cppi);\
+ constexpr int1024_t val2 = BOOST_JOIN(x, _cppi1024);\
+ constexpr auto val3 = BOOST_JOIN(x, _cppui);\
+ constexpr uint1024_t val4 = BOOST_JOIN(x, _cppui1024);\
+ test_literal(val1, BOOST_STRINGIZE(x));\
+ test_literal(val2, BOOST_STRINGIZE(x));\
+ test_literal(val3, BOOST_STRINGIZE(x));\
+ test_literal(val4, BOOST_STRINGIZE(x));\
+ /* Negative values: */\
+ constexpr auto val5 = -BOOST_JOIN(x, _cppi);\
+ constexpr int1024_t val6 = -BOOST_JOIN(x, _cppi1024);\
+ constexpr auto val7 = -val1;\
+ constexpr int1024_t val8 = -val2;\
+ BOOST_CHECK_EQUAL(val5, -cpp_int(val1));\
+ BOOST_CHECK_EQUAL(val6, -cpp_int(val1));\
+ BOOST_CHECK_EQUAL(val7, -cpp_int(val1));\
+ BOOST_CHECK_EQUAL(val8, -cpp_int(val1));\
+}\
+
+int main()
+{
+ using namespace boost::multiprecision::literals;
+ TEST_LITERAL(0x0);
+ TEST_LITERAL(0x00000);
+ TEST_LITERAL(0x10000000);
+ TEST_LITERAL(0x1234500000000123450000000123345000678000000456000000567000000fefabc00000000000000);
+ return boost::report_errors();
+}
+
+#else
+
+int main() { return 0; }
+
+
+#endif
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