Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85499 - trunk/boost
From: antoshkka_at_[hidden]
Date: 2013-08-28 08:55:10


Author: apolukhin
Date: 2013-08-28 08:55:09 EDT (Wed, 28 Aug 2013)
New Revision: 85499
URL: http://svn.boost.org/trac/boost/changeset/85499

Log:
lcast_put_unsigned in lexical_cast.hpp header is refactored, duplicate code removed (refs #9046)

Text files modified:
   trunk/boost/lexical_cast.hpp | 141 +++++++++++++++++++++------------------
   1 files changed, 77 insertions(+), 64 deletions(-)

Modified: trunk/boost/lexical_cast.hpp
==============================================================================
--- trunk/boost/lexical_cast.hpp Wed Aug 28 03:12:48 2013 (r85498)
+++ trunk/boost/lexical_cast.hpp 2013-08-28 08:55:09 EDT (Wed, 28 Aug 2013) (r85499)
@@ -635,7 +635,7 @@
     {
         template<class T>
         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;
             return static_cast<result_type>(
@@ -646,81 +646,89 @@
 
     namespace detail // lcast_put_unsigned
     {
- template<class Traits, class T, class CharT>
- CharT* lcast_put_unsigned(const T n_param, CharT* finish)
- {
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
-#endif
-
+ template <class Traits, class T, class CharT>
+ class lcast_put_unsigned {
             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<
                     (sizeof(int_type) > sizeof(T))
                     , int_type
                     , 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
- std::locale loc;
- if (loc != std::locale::classic()) {
+ std::locale loc;
+ if (loc == std::locale::classic()) {
+ return main_convert_loop();
+ }
+
                 typedef std::numpunct<CharT> numpunct;
                 numpunct const& np = BOOST_USE_FACET(numpunct, loc);
                 std::string const grouping = np.grouping();
                 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
                 // Check that ulimited group is unreachable:
                 BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
 #endif
- CharT thousands_sep = np.thousands_sep();
- std::string::size_type group = 0; // current group number
- char last_grp_size = grouping[0];
- char left = last_grp_size;
-
- do
- {
- if(left == 0)
- {
- ++group;
- if(group < grouping_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);
+ CharT const thousands_sep = np.thousands_sep();
+ std::string::size_type group = 0; // current group number
+ char last_grp_size = grouping[0];
+ char left = last_grp_size;
+
+ do {
+ if (left == 0) {
+ ++group;
+ if (group < grouping_size) {
+ char const grp_size = grouping[group];
+ last_grp_size = (grp_size <= 0 ? static_cast<char>(CHAR_MAX) : grp_size);
                         }
 
- --left;
+ left = last_grp_size;
+ --m_finish;
+ Traits::assign(*m_finish, thousands_sep);
+ }
 
- --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;
- }
- }
+ --left;
+ } while (main_convert_itaration());
+
+ return m_finish;
+#else
+ return main_convert_loop();
 #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
@@ -1504,11 +1512,16 @@
             }
 
             template <class T>
- inline bool shl_signed(T n)
- {
- start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
- if(n < 0)
- {
+ inline bool shl_unsigned(const T n) {
+ start = lcast_put_unsigned<Traits, T, CharT>(n, finish).convert();
+ return true;
+ }
+
+ 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;
                     CharT const minus = lcast_char_constants<CharT>::minus;
                     Traits::assign(*start, minus);
@@ -1697,20 +1710,20 @@
             bool operator<<(short n) { return shl_signed(n); }
             bool operator<<(int 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 int n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
- bool operator<<(unsigned long n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
+ bool operator<<(unsigned short n) { return shl_unsigned(n); }
+ bool operator<<(unsigned int n) { return shl_unsigned(n); }
+ bool operator<<(unsigned long n) { return shl_unsigned(n); }
 
 #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); }
 #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); }
 #endif
 
 #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); }
 #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