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