// (C) Copyright Howard Hinnant // (C) Copyright 2011 Vicente J. Botet Escriba // Use, modification and distribution are subject to 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). // // This code was adapted by Vicente from Howard Hinnant's experimental work // on chrono i/o to Boost #ifndef BOOST_CHRONO_IO_DURATION_IO_HPP #define BOOST_CHRONO_IO_DURATION_IO_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace chrono { /** * duration parameterized manipulator. */ class duration_fmt: public manip { duration_style style_; public: /** * explicit manipulator constructor from a @c duration_style */ explicit duration_fmt(duration_style style)BOOST_NOEXCEPT : style_(style) {} /** * Change the duration_style ios state; */ void operator()(std::ios_base &ios) const { set_duration_style(ios, style_); } }; /** * duration_style i/o saver. * * See Boost.IO i/o state savers for a motivating compression. */ struct duration_style_io_saver { //! the type of the state to restore typedef std::ios_base state_type; //! the type of aspect to save typedef duration_style aspect_type; /** * Explicit construction from an i/o stream. * * Store a reference to the i/o stream and the value of the associated @c duration_style. */ explicit duration_style_io_saver(state_type &s) : s_save_(s), a_save_(get_duration_style(s)) { } /** * Construction from an i/o stream and a @c duration_style to restore. * * Stores a reference to the i/o stream and the value @c new_value @c duration_style to set. */ duration_style_io_saver(state_type &s, aspect_type new_value) : s_save_(s), a_save_(get_duration_style(s)) { set_duration_style(s, new_value); } /** * Destructor. * * Restores the i/o stream with the duration_style to be restored. */ ~duration_style_io_saver() { this->restore(); } /** * Restores the i/o stream with the duration_style to be restored. */ void restore() { set_duration_style(s_save_, a_save_); } private: duration_style_io_saver& operator=(duration_style_io_saver const& rhs) ; state_type& s_save_; aspect_type a_save_; }; template struct duration_put_enabled : integral_constant::value || is_floating_point::value > {}; /** * duration stream inserter * @param os the output stream * @param d to value to insert * @return @c os */ template typename boost::enable_if_c< ! duration_put_enabled::value, std::basic_ostream& >::type operator<<(std::basic_ostream& os, const duration& d) { std::basic_ostringstream ostr; ostr << d.count(); duration dd(0); bool failed = false; BOOST_TRY { std::ios_base::iostate err = std::ios_base::goodbit; BOOST_TRY { typename std::basic_ostream::sentry opfx(os); if (bool(opfx)) { if (!std::has_facet >(os.getloc())) { if (duration_put ().put(os, os, os.fill(), dd, ostr.str().c_str()) .failed()) { err = std::ios_base::badbit; } } else if (std::use_facet >(os.getloc()) .put(os, os, os.fill(), dd, ostr.str().c_str()) .failed()) { err = std::ios_base::badbit; } os.width(0); } } BOOST_CATCH(...) { bool flag = false; BOOST_TRY { os.setstate(std::ios_base::failbit); } BOOST_CATCH (const std::ios_base::failure& ) { flag = true; } BOOST_CATCH_END if (flag) throw; } BOOST_CATCH_END if (err) os.setstate(err); return os; } BOOST_CATCH(...) { failed = true; } BOOST_CATCH_END if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit); return os; } template typename boost::enable_if_c< duration_put_enabled::value, std::basic_ostream& >::type operator<<(std::basic_ostream& os, const duration& d) { bool failed = false; BOOST_TRY { std::ios_base::iostate err = std::ios_base::goodbit; BOOST_TRY { typename std::basic_ostream::sentry opfx(os); if (bool(opfx)) { if (!std::has_facet >(os.getloc())) { if (duration_put ().put(os, os, os.fill(), d) .failed()) { err = std::ios_base::badbit; } } else if (std::use_facet >(os.getloc()) .put(os, os, os.fill(), d) .failed()) { err = std::ios_base::badbit; } os.width(0); } } BOOST_CATCH(...) { bool flag = false; BOOST_TRY { os.setstate(std::ios_base::failbit); } BOOST_CATCH (const std::ios_base::failure& ) { flag = true; } BOOST_CATCH_END if (flag) throw; } BOOST_CATCH_END if (err) os.setstate(err); return os; } BOOST_CATCH(...) { failed = true; } BOOST_CATCH_END if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit); return os; } /** * * @param is the input stream * @param d the duration * @return @c is */ template std::basic_istream& operator>>(std::basic_istream& is, duration& d) { std::ios_base::iostate err = std::ios_base::goodbit; BOOST_TRY { typename std::basic_istream::sentry ipfx(is); if (bool(ipfx)) { if (!std::has_facet >(is.getloc())) { duration_get ().get(is, std::istreambuf_iterator(), is, err, d); } else { std::use_facet >(is.getloc()) .get(is, std::istreambuf_iterator(), is, err, d); } } } BOOST_CATCH (...) { bool flag = false; BOOST_TRY { is.setstate(std::ios_base::failbit); } BOOST_CATCH (const std::ios_base::failure& ) { flag = true; } BOOST_CATCH_END if (flag) { BOOST_RETHROW } } BOOST_CATCH_END if (err) is.setstate(err); return is; } } // chrono } #endif // header