duration_io.hpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. // (C) Copyright Howard Hinnant
  2. // (C) Copyright 2011 Vicente J. Botet Escriba
  3. // Use, modification and distribution are subject to the Boost Software License,
  4. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt).
  6. //
  7. // This code was adapted by Vicente from Howard Hinnant's experimental work
  8. // on chrono i/o to Boost
  9. #ifndef BOOST_CHRONO_IO_DURATION_IO_HPP
  10. #define BOOST_CHRONO_IO_DURATION_IO_HPP
  11. #include <boost/chrono/duration.hpp>
  12. #include <boost/ratio/ratio_io.hpp>
  13. #include <boost/chrono/io/duration_style.hpp>
  14. #include <boost/chrono/io/ios_base_state.hpp>
  15. #include <boost/chrono/io/duration_put.hpp>
  16. #include <boost/chrono/io/duration_get.hpp>
  17. #include <boost/chrono/io/utility/manip_base.hpp>
  18. #include <boost/detail/no_exceptions_support.hpp>
  19. #include <locale>
  20. #include <iostream>
  21. namespace boost
  22. {
  23. namespace chrono
  24. {
  25. /**
  26. * duration parameterized manipulator.
  27. */
  28. class duration_fmt: public manip<duration_fmt>
  29. {
  30. duration_style style_;
  31. public:
  32. /**
  33. * explicit manipulator constructor from a @c duration_style
  34. */
  35. explicit duration_fmt(duration_style style)BOOST_NOEXCEPT
  36. : style_(style)
  37. {}
  38. /**
  39. * Change the duration_style ios state;
  40. */
  41. void operator()(std::ios_base &ios) const
  42. {
  43. set_duration_style(ios, style_);
  44. }
  45. };
  46. /**
  47. * duration_style i/o saver.
  48. *
  49. * See Boost.IO i/o state savers for a motivating compression.
  50. */
  51. struct duration_style_io_saver
  52. {
  53. //! the type of the state to restore
  54. typedef std::ios_base state_type;
  55. //! the type of aspect to save
  56. typedef duration_style aspect_type;
  57. /**
  58. * Explicit construction from an i/o stream.
  59. *
  60. * Store a reference to the i/o stream and the value of the associated @c duration_style.
  61. */
  62. explicit duration_style_io_saver(state_type &s) :
  63. s_save_(s)
  64. {
  65. a_save_ = get_duration_style(s_save_);
  66. }
  67. /**
  68. * Construction from an i/o stream and a @c duration_style to restore.
  69. *
  70. * Stores a reference to the i/o stream and the value @c duration_style to restore given as parameter.
  71. */
  72. duration_style_io_saver(state_type &s, aspect_type new_value) :
  73. s_save_(s), a_save_(new_value)
  74. {
  75. }
  76. /**
  77. * Destructor.
  78. *
  79. * Restores the i/o stream with the duration_style to be restored.
  80. */
  81. ~duration_style_io_saver()
  82. {
  83. this->restore();
  84. }
  85. /**
  86. * Restores the i/o stream with the duration_style to be restored.
  87. */
  88. void restore()
  89. {
  90. set_duration_style(s_save_, a_save_);
  91. }
  92. private:
  93. duration_style_io_saver& operator=(duration_style_io_saver const& rhs) ;
  94. state_type& s_save_;
  95. aspect_type a_save_;
  96. };
  97. /**
  98. * duration stream inserter
  99. * @param os the output stream
  100. * @param d to value to insert
  101. * @return @c os
  102. */
  103. template <class CharT, class Traits, class Rep, class Period>
  104. std::basic_ostream<CharT, Traits>&
  105. operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d)
  106. {
  107. bool failed = false;
  108. BOOST_TRY
  109. {
  110. std::ios_base::iostate err = std::ios_base::goodbit;
  111. BOOST_TRY
  112. {
  113. typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
  114. if (bool(opfx))
  115. {
  116. if (!std::has_facet<duration_put<CharT> >(os.getloc()))
  117. {
  118. if (duration_put<CharT> ().put(os, os, os.fill(), d) .failed())
  119. {
  120. err = std::ios_base::badbit;
  121. }
  122. }
  123. else if (std::use_facet<duration_put<CharT> >(os.getloc()) .put(os, os, os.fill(), d) .failed())
  124. {
  125. err = std::ios_base::badbit;
  126. }
  127. os.width(0);
  128. }
  129. }
  130. BOOST_CATCH(...)
  131. {
  132. bool flag = false;
  133. BOOST_TRY
  134. {
  135. os.setstate(std::ios_base::failbit);
  136. }
  137. BOOST_CATCH (std::ios_base::failure )
  138. {
  139. flag = true;
  140. }
  141. BOOST_CATCH_END
  142. if (flag) throw;
  143. }
  144. BOOST_CATCH_END
  145. if (err) os.setstate(err);
  146. return os;
  147. }
  148. BOOST_CATCH(...)
  149. {
  150. failed = true;
  151. }
  152. BOOST_CATCH_END
  153. if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
  154. return os;
  155. }
  156. /**
  157. *
  158. * @param is the input stream
  159. * @param d the duration
  160. * @return @c is
  161. */
  162. template <class CharT, class Traits, class Rep, class Period>
  163. std::basic_istream<CharT, Traits>&
  164. operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)
  165. {
  166. std::ios_base::iostate err = std::ios_base::goodbit;
  167. BOOST_TRY
  168. {
  169. typename std::basic_istream<CharT, Traits>::sentry ipfx(is);
  170. if (bool(ipfx))
  171. {
  172. if (!std::has_facet<duration_get<CharT> >(is.getloc()))
  173. {
  174. duration_get<CharT> ().get(is, std::istreambuf_iterator<CharT, Traits>(), is, err, d);
  175. }
  176. else
  177. {
  178. std::use_facet<duration_get<CharT> >(is.getloc()) .get(is, std::istreambuf_iterator<CharT, Traits>(), is,
  179. err, d);
  180. }
  181. }
  182. }
  183. BOOST_CATCH (...)
  184. {
  185. bool flag = false;
  186. BOOST_TRY
  187. {
  188. is.setstate(std::ios_base::failbit);
  189. }
  190. BOOST_CATCH (std::ios_base::failure )
  191. {
  192. flag = true;
  193. }
  194. BOOST_CATCH_END
  195. if (flag) { BOOST_RETHROW }
  196. }
  197. BOOST_CATCH_END
  198. if (err) is.setstate(err);
  199. return is;
  200. }
  201. } // chrono
  202. }
  203. #endif // header