Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r75237 - in trunk: boost/chrono/io libs/chrono/test/io
From: vicente.botet_at_[hidden]
Date: 2011-11-01 16:23:04


Author: viboes
Date: 2011-11-01 16:23:03 EDT (Tue, 01 Nov 2011)
New Revision: 75237
URL: http://svn.boost.org/trac/boost/changeset/75237

Log:
Chrono: fix 2 new tests [N/D]second and duration input from float or double
Text files modified:
   trunk/boost/chrono/io/duration_get.hpp | 86 +++++++++++++++++++++++++++++----------
   trunk/boost/chrono/io/duration_io.hpp | 32 ++++++--------
   trunk/libs/chrono/test/io/duration_input.cpp | 74 ++++++++++++++++++++++++++++++---
   3 files changed, 142 insertions(+), 50 deletions(-)

Modified: trunk/boost/chrono/io/duration_get.hpp
==============================================================================
--- trunk/boost/chrono/io/duration_get.hpp (original)
+++ trunk/boost/chrono/io/duration_get.hpp 2011-11-01 16:23:03 EDT (Tue, 01 Nov 2011)
@@ -42,6 +42,31 @@
             is_signed<Rep>::value, long long, unsigned long long>::type>::type type;
       };
 
+ template <typename intermediate_type>
+ typename enable_if<is_integral<intermediate_type>, bool>::type
+ reduce(intermediate_type& r, unsigned long long& den, std::ios_base::iostate& err)
+ {
+ typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t;
+
+ // Reduce r * num / den
+ common_type_t t = math::gcd<common_type_t>(common_type_t(r), common_type_t(den));
+ r /= t;
+ den /= t;
+ if (den != 1)
+ {
+ // Conversion to Period is integral and not exact
+ err |= std::ios_base::failbit;
+ return false;
+ }
+ return true;
+ }
+ template <typename intermediate_type>
+ typename disable_if<is_integral<intermediate_type>, bool>::type
+ reduce(intermediate_type& , unsigned long long& , std::ios_base::iostate& )
+ {
+ return true;
+ }
+
     }
 
     /**
@@ -142,6 +167,7 @@
         typedef typename detail::duration_io_intermediate<Rep>::type intermediate_type;
         intermediate_type r;
         detail::rt_ratio rt;
+ bool value_found=false, unit_found=false, loc_found=false;
 
         const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
         err = std::ios_base::goodbit;
@@ -164,6 +190,15 @@
                 {
                 case 'v':
                 {
+ if (value_found) {
+ err |= std::ios_base::failbit;
+ break;
+ }
+ if (value_found) {
+ err |= std::ios_base::failbit;
+ break;
+ }
+ value_found=true;
                   s=get_value(s, end, ios, err, r);
                   if ((err & std::ios_base::failbit) != 0)
                   {
@@ -173,12 +208,27 @@
                 }
                 case 'u':
                 {
+ if (unit_found) {
+ err |= std::ios_base::failbit;
+ break;
+ }
+ unit_found=true;
                   s = get_unit<Rep>(s, end, ios, err, rt);
- break;
+ if ((err & std::ios_base::failbit) != 0)
+ {
+ return s;
+ } break;
                 }
                 case 'x':
                 {
+ if (unit_found || value_found || loc_found) {
+ err |= std::ios_base::failbit;
+ break;
+ }
+ loc_found=true;
                   std::basic_string<CharT> pat = std::use_facet<duration_units<CharT> >(ios.getloc()).get_pattern();
+ if (pattern+1 != pat_end)
+ pat.append(pattern+1, pat_end);
                   pattern = pat.data();
                   pat_end = pattern + pat.size();
                   break;
@@ -207,8 +257,6 @@
             }
 
         }
- if (s == end)
- err |= std::ios_base::eofbit;
 
         unsigned long long num = rt.num;
         unsigned long long den = rt.den;
@@ -231,21 +279,12 @@
         num *= d2;
         den *= n2;
 
- // num / den is now factor to multiply by r
         typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t;
- if (is_integral<intermediate_type>::value)
- {
- // Reduce r * num / den
- common_type_t t = math::gcd<common_type_t>(r, den);
- r /= t;
- den /= t;
- if (den != 1)
- {
- // Conversion to Period is integral and not exact
- err |= std::ios_base::failbit;
- return s;
- }
- }
+
+ // num / den is now factor to multiply by r
+ if (!detail::reduce(r, den, err))
+ return s;
+
         if (r > ( (duration_values<common_type_t>::max)() / num))
         {
           // Conversion to Period overflowed
@@ -268,6 +307,7 @@
         r = Rep(t);
         d = duration<Rep, Period> (r);
 
+
         return s;
       }
 
@@ -320,9 +360,8 @@
       iter_type get_unit(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err,
           detail::rt_ratio &rt) const
       {
- if (!std::has_facet<duration_units<CharT> >(is.getloc())) is.imbue(
- std::locale(is.getloc(), new duration_units_default<CharT> ()));
-
+ if (!std::has_facet<duration_units<CharT> >(is.getloc()))
+ is.imbue(std::locale(is.getloc(), new duration_units_default<CharT> ()));
         duration_units<CharT> const &facet = std::use_facet<duration_units<CharT> >(is.getloc());
 
         if (*i == '[')
@@ -370,7 +409,8 @@
           const std::basic_string<CharT> units[] =
           {
               facet.template get_plural_form<ratio<1> >(duration_style::prefix, 1),
- facet.template get_plural_form<ratio<1> >(duration_style::symbol, 1)
+ facet.template get_plural_form<ratio<1> >(duration_style::prefix, 0),
+ facet.template get_plural_form<ratio<1> >(duration_style::symbol, 0)
           };
           // FIXME is this necessary?????
           err = std::ios_base::goodbit;
@@ -378,7 +418,7 @@
               units + sizeof (units) / sizeof (units[0]),
               //~ std::use_facet<std::ctype<CharT> >(loc),
               err);
- switch ( (k - units) / 2)
+ switch ( (k - units) / 3)
           {
           case 0:
             break;
@@ -451,7 +491,7 @@
               facet.template get_plural_form<ratio<3600> >(duration_style::prefix, 0),
               facet.template get_plural_form<ratio<3600> >(duration_style::symbol, 0)
               };
- std::ios_base::iostate err = std::ios_base::goodbit;
+ err = std::ios_base::goodbit;
           const std::basic_string<CharT>* k = chrono_detail::scan_keyword(i, e, units,
               units + sizeof (units) / sizeof (units[0]),
               //~ std::use_facet<std::ctype<CharT> >(loc),

Modified: trunk/boost/chrono/io/duration_io.hpp
==============================================================================
--- trunk/boost/chrono/io/duration_io.hpp (original)
+++ trunk/boost/chrono/io/duration_io.hpp 2011-11-01 16:23:03 EDT (Tue, 01 Nov 2011)
@@ -570,6 +570,8 @@
     std::basic_istream<CharT, Traits>&
     operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)
     {
+ std::ios_base::iostate err = std::ios_base::goodbit;
+
 #if !defined BOOST_CHRONO_IO_V1_DONT_PROVIDE_DEPRECATED
       typedef duration_punct<CharT> Facet;
       std::locale loc = is.getloc();
@@ -580,7 +582,6 @@
 #endif
 #if defined BOOST_CHRONO_USES_DURATION_GET
 
- std::ios_base::iostate err = std::ios_base::goodbit;
       try
       {
         typename std::basic_istream<CharT, Traits>::sentry ipfx(is);
@@ -658,8 +659,9 @@
                   f.template long_name<ratio<1> >(),
                   f.template short_name<ratio<1> >()
 #else
- duration_unit<CharT> (is.getloc(), true, seconds(2)), duration_unit<CharT> (is.getloc(), false,
- seconds(1))
+ duration_unit<CharT> (is.getloc(), true, seconds(2)),
+ duration_unit<CharT> (is.getloc(), true, seconds(1)),
+ duration_unit<CharT> (is.getloc(), false, seconds(1))
 #endif
                   };
               std::ios_base::iostate err = std::ios_base::goodbit;
@@ -667,7 +669,7 @@
                   units + sizeof (units) / sizeof (units[0]),
                   //~ std::use_facet<std::ctype<CharT> >(loc),
                   err);
- switch ( (k - units) / 2)
+ switch ( (k - units) / 3)
               {
               case 0:
                 break;
@@ -761,9 +763,9 @@
                   duration_unit<CharT> (is.getloc(), true, duration<Rep, giga> (2)),
                   duration_unit<CharT> (is.getloc(), true, duration<Rep, giga> (1)),
                   duration_unit<CharT> (is.getloc(), false, duration<Rep, giga> (1)),
- duration_unit<CharT> (is.getloc(), true, duration<Rep, giga> (2)),
+ duration_unit<CharT> (is.getloc(), true, duration<Rep, tera> (2)),
                   duration_unit<CharT> (is.getloc(), true, duration<Rep, tera> (1)),
- duration_unit<CharT> (is.getloc(), false, duration<Rep, giga> (1)),
+ duration_unit<CharT> (is.getloc(), false, duration<Rep, tera> (1)),
                   duration_unit<CharT> (is.getloc(), true, duration<Rep, peta> (2)),
                   duration_unit<CharT> (is.getloc(), true, duration<Rep, peta> (1)),
                   duration_unit<CharT> (is.getloc(), false, duration<Rep, peta> (1)),
@@ -781,7 +783,6 @@
                   duration_unit<CharT> (is.getloc(), false, duration<Rep, ratio<3600> > (1)),
 #endif
                   };
- std::ios_base::iostate err = std::ios_base::goodbit;
               const std::basic_string<CharT>* k = chrono_detail::scan_keyword(i, e, units,
                   units + sizeof (units) / sizeof (units[0]),
                   //~ std::use_facet<std::ctype<CharT> >(loc),
@@ -893,19 +894,11 @@
             den *= n2;
             // num / den is now factor to multiply by r
             typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t;
- if (is_integral<intermediate_type>::value)
- {
- // Reduce r * num / den
- common_type_t t = math::gcd<common_type_t>(r, den);
- r /= t;
- den /= t;
- if (den != 1)
- {
- // Conversion to Period is integral and not exact
- is.setstate(is.failbit);
- return is;
- }
+ if (!detail::reduce(r, den, err)) {
+ is.setstate(is.failbit);
+ return is;
             }
+
             if (r > ( (duration_values<common_type_t>::max)() / num))
             {
               // Conversion to Period overflowed
@@ -927,6 +920,7 @@
             // Success! Store it.
             r = Rep(t);
             d = duration<Rep, Period> (r);
+ if (i == e) is.setstate(is.eofbit);
           }
           else
             is.setstate(is.failbit | is.eofbit);

Modified: trunk/libs/chrono/test/io/duration_input.cpp
==============================================================================
--- trunk/libs/chrono/test/io/duration_input.cpp (original)
+++ trunk/libs/chrono/test/io/duration_input.cpp 2011-11-01 16:23:03 EDT (Tue, 01 Nov 2011)
@@ -3,54 +3,102 @@
 // See http://www.boost.org/LICENSE_1_0.txt
 
 #include <boost/chrono/chrono_io.hpp>
+#include <boost/chrono/io/duration_units.hpp>
 #include <sstream>
 #include <boost/detail/lightweight_test.hpp>
 
 template<typename D>
+void test_good2(const char* str, D res)
+{
+ std::istringstream in(str);
+ D d(0);
+ in >> d;
+ std::cerr << d << " * " << str << " * " << res << " st " << in.rdstate() << std::endl;
+ BOOST_TEST(in.eof());
+ BOOST_TEST(!in.fail());
+ BOOST_TEST(d == res);
+}
+template<typename D>
 void test_good(const char* str, D res)
 {
   std::istringstream in(str);
   D d(0);
   in >> d;
+ std::cerr << d << " * " << str << " * " << res << " st " << in.rdstate() << std::endl;
+ BOOST_TEST(in.eof());
   BOOST_TEST(!in.fail());
   BOOST_TEST(d == res);
 }
 
-template<typename DFail, typename DGood>
-void test_fail(const char* str, DFail, DGood res)
+template<typename DFail>
+void test_fail(const char* str, DFail res)
 {
   {
     std::istringstream in(str);
     DFail d = DFail::zero();
     in >> d;
+ std::cerr << d << " * " << str << " * " << res << " st " << in.rdstate() << std::endl;
     BOOST_TEST(in.fail());
     BOOST_TEST(d == DFail::zero());
   }
+}
+
+template<typename D>
+void test_not_eof(const char* str, D res)
+{
   {
     std::istringstream in(str);
- DGood d = DGood::zero();
+ D d = D::zero();
     in >> d;
- BOOST_TEST(!in.fail());
+ //std::cerr << d << " " << str << " " << res << std::endl;
+ BOOST_TEST(!in.eof());
     BOOST_TEST(d == res);
   }
 }
-
 int main()
 {
   using namespace boost::chrono;
   using namespace boost;
 
+ test_good2("5000", 5000);
+
   test_good("5000 hours", hours(5000));
   test_good("5000 minutes", minutes(5000));
   test_good("5000 seconds", seconds(5000));
+ test_fail("1.0 second", seconds(1));
+
+ test_good("1.0 second", duration<float,ratio<1> >(1));
+ /* BUG with DURATION_GET
+../../../boost/math/common_factor_rt.hpp: In function ÔRingType boost::math::detail::gcd_euclidean(RingType, RingType) [with RingType = long double]Õ:
+../../../boost/math/common_factor_rt.hpp:122: instantiated from ÔIntegerType boost::math::detail::gcd_integer(const IntegerType&, const IntegerType&) [with IntegerType = long double]Õ
+../../../boost/math/common_factor_rt.hpp:240: instantiated from ÔT boost::math::detail::gcd_optimal_evaluator_helper_t<T, true, true>::operator()(const T&, const T&) [with T = long double]Õ
+../../../boost/math/common_factor_rt.hpp:290: instantiated from ÔT boost::math::detail::gcd_optimal_evaluator<T>::operator()(const T&, const T&) [with T = long double]Õ
+../../../boost/math/common_factor_rt.hpp:442: instantiated from ÔT boost::math::detail::gcd_optimal(const T&, const T&) [with T = long double]Õ
+../../../boost/math/common_factor_rt.hpp:473: instantiated from Ôtypename boost::math::gcd_evaluator<IntegerType>::result_type boost::math::gcd_evaluator<IntegerType>::operator()(const IntegerType&, const IntegerType&) const [with IntegerType = long double]Õ
+../../../boost/math/common_factor_rt.hpp:505: instantiated from ÔIntegerType boost::math::gcd(const IntegerType&, const IntegerType&) [with IntegerType = long double]Õ
+../../../boost/chrono/io/duration_get.hpp:239: instantiated from ÔInputIterator boost::chrono::duration_get<CharT, InputIterator>::get(InputIterator, InputIterator, std::ios_base&, std::_Ios_Iostate&, boost::chrono::duration<Rep2, Period2>&, const CharT*, const CharT*) const [with Rep = double, Period = boost::ratio<1l, 1l>, CharT = char, InputIterator = std::istreambuf_iterator<char, std::char_traits<char> >]Õ
+../../../boost/chrono/io/duration_get.hpp:294: instantiated from ÔInputIterator boost::chrono::duration_get<CharT, InputIterator>::get(InputIterator, InputIterator, std::ios_base&, std::_Ios_Iostate&, boost::chrono::duration<Rep2, Period2>&) const [with Rep = double, Period = boost::ratio<1l, 1l>, CharT = char, InputIterator = std::istreambuf_iterator<char, std::char_traits<char> >]Õ
+../../../boost/chrono/io/duration_io.hpp:593: instantiated from Ôstd::basic_istream<_CharT, _Traits>& boost::chrono::operator>>(std::basic_istream<_CharT, _Traits>&, boost::chrono::duration<Rep2, Period2>&) [with CharT = char, Traits = std::char_traits<char>, Rep = double, Period = boost::ratio<1l, 1l>]Õ
+io/duration_input.cpp:15: instantiated from Ôvoid test_good(const char*, D) [with D = boost::chrono::duration<double, boost::ratio<1l, 1l> >]Õ
+io/duration_input.cpp:52: instantiated from here
+../../../boost/math/common_factor_rt.hpp:102: error: invalid operands of types Ôlong doubleÕ and Ôlong doubleÕ to binary Ôoperator%Õ
+../../../boost/math/common_factor_rt.hpp:102: error: in evaluation of Ôoperator%=(long double, long double)Õ
+../../../boost/math/common_factor_rt.hpp:106: error: invalid operands of types Ôlong doubleÕ and Ôlong doubleÕ to binary Ôoperator%Õ
+../../../boost/math/common_factor_rt.hpp:106: error: in evaluation of Ôoperator%=(long double, long double)Õ
+ *
+ */
+ test_good("1 second", seconds(1));
+ test_not_eof("1 second ", seconds(1));
+ test_not_eof("1 seconde", seconds(1));
   test_good("1 seconds", seconds(1));
+ test_good("0 seconds", seconds(0));
   test_good("-1 seconds", seconds(-1));
   test_good("5000 milliseconds", milliseconds(5000));
   test_good("5000 microseconds", microseconds(5000));
   test_good("5000 nanoseconds", nanoseconds(5000));
   test_good("5000 deciseconds", duration<boost::int_least64_t, deci> (5000));
   test_good("5000 [1/30]seconds", duration<boost::int_least64_t, ratio<1, 30> > (5000));
-
+ test_good("5000 [1/30]second", duration<boost::int_least64_t, ratio<1, 30> > (5000));
   test_good("5000 h", hours(5000));
   test_good("5000 min", minutes(5000));
   test_good("5000 s", seconds(5000));
@@ -58,11 +106,21 @@
   test_good("5000 ns", nanoseconds(5000));
   test_good("5000 ds", duration<boost::int_least64_t, deci> (5000));
   test_good("5000 [1/30]s", duration<boost::int_least64_t, ratio<1, 30> > (5000));
-
+ test_not_eof("5000 [1/30]ss", duration<boost::int_least64_t, ratio<1, 30> > (5000));
+ std::cout << __LINE__<< "*****" << std::endl;
   test_good("5000 milliseconds", seconds(5));
+ test_good("5000 millisecond", seconds(5));
   test_good("5 milliseconds", nanoseconds(5000000));
+ std::cout << __LINE__<< "*****" << std::endl;
   test_good("4000 ms", seconds(4));
- test_fail("3001 ms", seconds(3), milliseconds(3001));
+ std::cout << __LINE__<< "*****" << std::endl;
+ test_fail("3001 ms", seconds(3));
+ std::cout << __LINE__<< "*****" << std::endl;
+ test_fail("3001 ", milliseconds(3001));
+ std::cout << __LINE__<< "*****" << std::endl;
+ test_fail("one ms", milliseconds(1));
+ test_fail("5000 millisecon", seconds(5));
+ test_not_eof("3001 ms ", milliseconds(3001));
 
   return boost::report_errors();
 


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