|
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