forked from boostorg/conversion
lcast_put_unsigned in lexical_cast.hpp header is refactored, duplicate code removed (refs #9046)
[SVN r85499]
This commit is contained in:
@@ -635,7 +635,7 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
template<class T>
|
template<class T>
|
||||||
inline
|
inline
|
||||||
BOOST_DEDUCED_TYPENAME make_unsigned<T>::type lcast_to_unsigned(T value) BOOST_NOEXCEPT
|
BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type lcast_to_unsigned(const T value) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type result_type;
|
typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type result_type;
|
||||||
return static_cast<result_type>(
|
return static_cast<result_type>(
|
||||||
@@ -646,81 +646,89 @@ namespace boost {
|
|||||||
|
|
||||||
namespace detail // lcast_put_unsigned
|
namespace detail // lcast_put_unsigned
|
||||||
{
|
{
|
||||||
template<class Traits, class T, class CharT>
|
template <class Traits, class T, class CharT>
|
||||||
CharT* lcast_put_unsigned(const T n_param, CharT* finish)
|
class lcast_put_unsigned {
|
||||||
{
|
|
||||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
|
||||||
BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME Traits::int_type int_type;
|
typedef BOOST_DEDUCED_TYPENAME Traits::int_type int_type;
|
||||||
CharT const czero = lcast_char_constants<CharT>::zero;
|
|
||||||
int_type const zero = Traits::to_int_type(czero);
|
|
||||||
BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
|
BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
|
||||||
(sizeof(int_type) > sizeof(T))
|
(sizeof(int_type) > sizeof(T))
|
||||||
, int_type
|
, int_type
|
||||||
, T
|
, T
|
||||||
>::type n = n_param;
|
>::type m_value;
|
||||||
|
CharT* m_finish;
|
||||||
|
CharT const m_czero;
|
||||||
|
int_type const m_zero;
|
||||||
|
|
||||||
|
public:
|
||||||
|
lcast_put_unsigned(const T n_param, CharT* finish) BOOST_NOEXCEPT
|
||||||
|
: m_value(n_param), m_finish(finish)
|
||||||
|
, m_czero(lcast_char_constants<CharT>::zero), m_zero(Traits::to_int_type(m_czero))
|
||||||
|
{
|
||||||
|
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||||
|
BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CharT* convert() {
|
||||||
#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
|
#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
|
||||||
std::locale loc;
|
std::locale loc;
|
||||||
if (loc != std::locale::classic()) {
|
if (loc == std::locale::classic()) {
|
||||||
|
return main_convert_loop();
|
||||||
|
}
|
||||||
|
|
||||||
typedef std::numpunct<CharT> numpunct;
|
typedef std::numpunct<CharT> numpunct;
|
||||||
numpunct const& np = BOOST_USE_FACET(numpunct, loc);
|
numpunct const& np = BOOST_USE_FACET(numpunct, loc);
|
||||||
std::string const grouping = np.grouping();
|
std::string const grouping = np.grouping();
|
||||||
std::string::size_type const grouping_size = grouping.size();
|
std::string::size_type const grouping_size = grouping.size();
|
||||||
|
|
||||||
if ( grouping_size && grouping[0] > 0 )
|
if (!grouping_size || grouping[0] <= 0) {
|
||||||
{
|
return main_convert_loop();
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||||
// Check that ulimited group is unreachable:
|
// Check that ulimited group is unreachable:
|
||||||
BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
|
BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
|
||||||
#endif
|
#endif
|
||||||
CharT thousands_sep = np.thousands_sep();
|
CharT const thousands_sep = np.thousands_sep();
|
||||||
std::string::size_type group = 0; // current group number
|
std::string::size_type group = 0; // current group number
|
||||||
char last_grp_size = grouping[0];
|
char last_grp_size = grouping[0];
|
||||||
char left = last_grp_size;
|
char left = last_grp_size;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
if (left == 0) {
|
||||||
if(left == 0)
|
++group;
|
||||||
{
|
if (group < grouping_size) {
|
||||||
++group;
|
char const grp_size = grouping[group];
|
||||||
if(group < grouping_size)
|
last_grp_size = (grp_size <= 0 ? static_cast<char>(CHAR_MAX) : grp_size);
|
||||||
{
|
|
||||||
char const grp_size = grouping[group];
|
|
||||||
last_grp_size = grp_size <= 0 ? static_cast<char>(CHAR_MAX) : grp_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
left = last_grp_size;
|
|
||||||
--finish;
|
|
||||||
Traits::assign(*finish, thousands_sep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--left;
|
left = last_grp_size;
|
||||||
|
--m_finish;
|
||||||
|
Traits::assign(*m_finish, thousands_sep);
|
||||||
|
}
|
||||||
|
|
||||||
--finish;
|
--left;
|
||||||
int_type const digit = static_cast<int_type>(n % 10U);
|
} while (main_convert_itaration());
|
||||||
Traits::assign(*finish, Traits::to_char_type(zero + digit));
|
|
||||||
n /= 10;
|
return m_finish;
|
||||||
} while(n);
|
#else
|
||||||
return finish;
|
return main_convert_loop();
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
--finish;
|
|
||||||
int_type const digit = static_cast<int_type>(n % 10U);
|
|
||||||
Traits::assign(*finish, Traits::to_char_type(zero + digit));
|
|
||||||
n /= 10;
|
|
||||||
} while(n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return finish;
|
private:
|
||||||
}
|
inline bool main_convert_itaration() BOOST_NOEXCEPT {
|
||||||
|
--m_finish;
|
||||||
|
int_type const digit = static_cast<int_type>(m_value % 10U);
|
||||||
|
Traits::assign(*m_finish, Traits::to_char_type(m_zero + digit));
|
||||||
|
m_value /= 10;
|
||||||
|
return !!m_value; // supressing warnings
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CharT* main_convert_loop() BOOST_NOEXCEPT {
|
||||||
|
while (main_convert_itaration());
|
||||||
|
return m_finish;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail // lcast_ret_unsigned
|
namespace detail // lcast_ret_unsigned
|
||||||
@@ -1504,11 +1512,16 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline bool shl_signed(T n)
|
inline bool shl_unsigned(const T n) {
|
||||||
{
|
start = lcast_put_unsigned<Traits, T, CharT>(n, finish).convert();
|
||||||
start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
|
return true;
|
||||||
if(n < 0)
|
}
|
||||||
{
|
|
||||||
|
template <class T>
|
||||||
|
inline bool shl_signed(const T n) {
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type utype;
|
||||||
|
start = lcast_put_unsigned<Traits, utype, CharT>(lcast_to_unsigned(n), finish).convert();
|
||||||
|
if (n < 0) {
|
||||||
--start;
|
--start;
|
||||||
CharT const minus = lcast_char_constants<CharT>::minus;
|
CharT const minus = lcast_char_constants<CharT>::minus;
|
||||||
Traits::assign(*start, minus);
|
Traits::assign(*start, minus);
|
||||||
@@ -1697,20 +1710,20 @@ namespace boost {
|
|||||||
bool operator<<(short n) { return shl_signed(n); }
|
bool operator<<(short n) { return shl_signed(n); }
|
||||||
bool operator<<(int n) { return shl_signed(n); }
|
bool operator<<(int n) { return shl_signed(n); }
|
||||||
bool operator<<(long n) { return shl_signed(n); }
|
bool operator<<(long n) { return shl_signed(n); }
|
||||||
bool operator<<(unsigned short n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
|
bool operator<<(unsigned short n) { return shl_unsigned(n); }
|
||||||
bool operator<<(unsigned int n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
|
bool operator<<(unsigned int n) { return shl_unsigned(n); }
|
||||||
bool operator<<(unsigned long n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
|
bool operator<<(unsigned long n) { return shl_unsigned(n); }
|
||||||
|
|
||||||
#if defined(BOOST_HAS_LONG_LONG)
|
#if defined(BOOST_HAS_LONG_LONG)
|
||||||
bool operator<<(boost::ulong_long_type n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
|
bool operator<<(boost::ulong_long_type n) { return shl_unsigned(n); }
|
||||||
bool operator<<(boost::long_long_type n) { return shl_signed(n); }
|
bool operator<<(boost::long_long_type n) { return shl_signed(n); }
|
||||||
#elif defined(BOOST_HAS_MS_INT64)
|
#elif defined(BOOST_HAS_MS_INT64)
|
||||||
bool operator<<(unsigned __int64 n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
|
bool operator<<(unsigned __int64 n) { return shl_unsigned(n); }
|
||||||
bool operator<<( __int64 n) { return shl_signed(n); }
|
bool operator<<( __int64 n) { return shl_signed(n); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BOOST_HAS_INT128
|
#ifdef BOOST_HAS_INT128
|
||||||
bool operator<<(const boost::uint128_type& n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
|
bool operator<<(const boost::uint128_type& n) { return shl_unsigned(n); }
|
||||||
bool operator<<(const boost::int128_type& n) { return shl_signed(n); }
|
bool operator<<(const boost::int128_type& n) { return shl_signed(n); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user