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