diff options
Diffstat (limited to 'boost/chrono/io/duration_io.hpp')
-rw-r--r-- | boost/chrono/io/duration_io.hpp | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/boost/chrono/io/duration_io.hpp b/boost/chrono/io/duration_io.hpp new file mode 100644 index 0000000000..438f7696db --- /dev/null +++ b/boost/chrono/io/duration_io.hpp @@ -0,0 +1,225 @@ +// (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 <boost/chrono/duration.hpp> +#include <boost/ratio/ratio_io.hpp> +#include <boost/chrono/io/duration_style.hpp> +#include <boost/chrono/io/ios_base_state.hpp> +#include <boost/chrono/io/duration_put.hpp> +#include <boost/chrono/io/duration_get.hpp> +#include <boost/chrono/io/utility/manip_base.hpp> +#include <boost/detail/no_exceptions_support.hpp> +#include <locale> +#include <iostream> + +namespace boost +{ + namespace chrono + { + + /** + * duration parameterized manipulator. + */ + + class duration_fmt: public manip<duration_fmt> + { + 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_save_); + } + + /** + * 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 duration_style to restore given as parameter. + */ + duration_style_io_saver(state_type &s, aspect_type new_value) : + s_save_(s), a_save_(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_; + }; + + /** + * duration stream inserter + * @param os the output stream + * @param d to value to insert + * @return @c os + */ + template <class CharT, class Traits, class Rep, class Period> + std::basic_ostream<CharT, Traits>& + operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d) + { + bool failed = false; + BOOST_TRY + { + std::ios_base::iostate err = std::ios_base::goodbit; + BOOST_TRY + { + typename std::basic_ostream<CharT, Traits>::sentry opfx(os); + if (bool(opfx)) + { + if (!std::has_facet<duration_put<CharT> >(os.getloc())) + { + if (duration_put<CharT> ().put(os, os, os.fill(), d) .failed()) + { + err = std::ios_base::badbit; + } + } + else if (std::use_facet<duration_put<CharT> >(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 (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 <class CharT, class Traits, class Rep, class Period> + 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; + + BOOST_TRY + { + typename std::basic_istream<CharT, Traits>::sentry ipfx(is); + if (bool(ipfx)) + { + if (!std::has_facet<duration_get<CharT> >(is.getloc())) + { + duration_get<CharT> ().get(is, std::istreambuf_iterator<CharT, Traits>(), is, err, d); + } + else + { + std::use_facet<duration_get<CharT> >(is.getloc()) .get(is, std::istreambuf_iterator<CharT, Traits>(), is, + err, d); + } + } + } + BOOST_CATCH (...) + { + bool flag = false; + BOOST_TRY + { + is.setstate(std::ios_base::failbit); + } + BOOST_CATCH (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 |