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@101
|
21 #include <boost/type_traits/is_integral.hpp>
|
Chris@101
|
22 #include <boost/type_traits/is_floating_point.hpp>
|
Chris@16
|
23 #include <locale>
|
Chris@16
|
24 #include <iostream>
|
Chris@101
|
25 #include <sstream>
|
Chris@16
|
26
|
Chris@16
|
27 namespace boost
|
Chris@16
|
28 {
|
Chris@16
|
29 namespace chrono
|
Chris@16
|
30 {
|
Chris@16
|
31
|
Chris@16
|
32 /**
|
Chris@16
|
33 * duration parameterized manipulator.
|
Chris@16
|
34 */
|
Chris@16
|
35
|
Chris@16
|
36 class duration_fmt: public manip<duration_fmt>
|
Chris@16
|
37 {
|
Chris@16
|
38 duration_style style_;
|
Chris@16
|
39 public:
|
Chris@16
|
40
|
Chris@16
|
41 /**
|
Chris@16
|
42 * explicit manipulator constructor from a @c duration_style
|
Chris@16
|
43 */
|
Chris@16
|
44 explicit duration_fmt(duration_style style)BOOST_NOEXCEPT
|
Chris@16
|
45 : style_(style)
|
Chris@16
|
46 {}
|
Chris@16
|
47
|
Chris@16
|
48 /**
|
Chris@16
|
49 * Change the duration_style ios state;
|
Chris@16
|
50 */
|
Chris@16
|
51 void operator()(std::ios_base &ios) const
|
Chris@16
|
52
|
Chris@16
|
53 {
|
Chris@16
|
54 set_duration_style(ios, style_);
|
Chris@16
|
55 }
|
Chris@16
|
56 };
|
Chris@16
|
57
|
Chris@16
|
58 /**
|
Chris@16
|
59 * duration_style i/o saver.
|
Chris@16
|
60 *
|
Chris@16
|
61 * See Boost.IO i/o state savers for a motivating compression.
|
Chris@16
|
62 */
|
Chris@16
|
63 struct duration_style_io_saver
|
Chris@16
|
64 {
|
Chris@16
|
65
|
Chris@16
|
66 //! the type of the state to restore
|
Chris@16
|
67 typedef std::ios_base state_type;
|
Chris@16
|
68 //! the type of aspect to save
|
Chris@16
|
69 typedef duration_style aspect_type;
|
Chris@16
|
70
|
Chris@16
|
71 /**
|
Chris@16
|
72 * Explicit construction from an i/o stream.
|
Chris@16
|
73 *
|
Chris@16
|
74 * Store a reference to the i/o stream and the value of the associated @c duration_style.
|
Chris@16
|
75 */
|
Chris@16
|
76 explicit duration_style_io_saver(state_type &s) :
|
Chris@101
|
77 s_save_(s), a_save_(get_duration_style(s))
|
Chris@16
|
78 {
|
Chris@16
|
79 }
|
Chris@16
|
80
|
Chris@16
|
81 /**
|
Chris@16
|
82 * Construction from an i/o stream and a @c duration_style to restore.
|
Chris@16
|
83 *
|
Chris@101
|
84 * Stores a reference to the i/o stream and the value @c new_value @c duration_style to set.
|
Chris@16
|
85 */
|
Chris@16
|
86 duration_style_io_saver(state_type &s, aspect_type new_value) :
|
Chris@101
|
87 s_save_(s), a_save_(get_duration_style(s))
|
Chris@16
|
88 {
|
Chris@101
|
89 set_duration_style(s, new_value);
|
Chris@16
|
90 }
|
Chris@16
|
91
|
Chris@16
|
92 /**
|
Chris@16
|
93 * Destructor.
|
Chris@16
|
94 *
|
Chris@16
|
95 * Restores the i/o stream with the duration_style to be restored.
|
Chris@16
|
96 */
|
Chris@16
|
97 ~duration_style_io_saver()
|
Chris@16
|
98 {
|
Chris@16
|
99 this->restore();
|
Chris@16
|
100 }
|
Chris@16
|
101
|
Chris@16
|
102 /**
|
Chris@16
|
103 * Restores the i/o stream with the duration_style to be restored.
|
Chris@16
|
104 */
|
Chris@16
|
105 void restore()
|
Chris@16
|
106 {
|
Chris@16
|
107 set_duration_style(s_save_, a_save_);
|
Chris@16
|
108 }
|
Chris@16
|
109
|
Chris@16
|
110 private:
|
Chris@16
|
111 duration_style_io_saver& operator=(duration_style_io_saver const& rhs) ;
|
Chris@16
|
112
|
Chris@16
|
113 state_type& s_save_;
|
Chris@16
|
114 aspect_type a_save_;
|
Chris@16
|
115 };
|
Chris@16
|
116
|
Chris@101
|
117 template <class Rep>
|
Chris@101
|
118 struct duration_put_enabled
|
Chris@101
|
119 : integral_constant<bool,
|
Chris@101
|
120 is_integral<Rep>::value || is_floating_point<Rep>::value
|
Chris@101
|
121 >
|
Chris@101
|
122 {};
|
Chris@101
|
123
|
Chris@101
|
124
|
Chris@16
|
125 /**
|
Chris@16
|
126 * duration stream inserter
|
Chris@16
|
127 * @param os the output stream
|
Chris@16
|
128 * @param d to value to insert
|
Chris@16
|
129 * @return @c os
|
Chris@16
|
130 */
|
Chris@101
|
131
|
Chris@16
|
132 template <class CharT, class Traits, class Rep, class Period>
|
Chris@101
|
133 typename boost::enable_if_c< ! duration_put_enabled<Rep>::value, std::basic_ostream<CharT, Traits>& >::type
|
Chris@101
|
134 operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d)
|
Chris@101
|
135 {
|
Chris@101
|
136 std::basic_ostringstream<CharT, Traits> ostr;
|
Chris@101
|
137 ostr << d.count();
|
Chris@101
|
138 duration<int, Period> dd(0);
|
Chris@101
|
139 bool failed = false;
|
Chris@101
|
140 BOOST_TRY
|
Chris@101
|
141 {
|
Chris@101
|
142 std::ios_base::iostate err = std::ios_base::goodbit;
|
Chris@101
|
143 BOOST_TRY
|
Chris@101
|
144 {
|
Chris@101
|
145 typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
|
Chris@101
|
146 if (bool(opfx))
|
Chris@101
|
147 {
|
Chris@101
|
148 if (!std::has_facet<duration_put<CharT> >(os.getloc()))
|
Chris@101
|
149 {
|
Chris@101
|
150 if (duration_put<CharT> ().put(os, os, os.fill(), dd, ostr.str().c_str()) .failed())
|
Chris@101
|
151 {
|
Chris@101
|
152 err = std::ios_base::badbit;
|
Chris@101
|
153 }
|
Chris@101
|
154 }
|
Chris@101
|
155 else if (std::use_facet<duration_put<CharT> >(os.getloc()) .put(os, os, os.fill(), dd, ostr.str().c_str()) .failed())
|
Chris@101
|
156 {
|
Chris@101
|
157 err = std::ios_base::badbit;
|
Chris@101
|
158 }
|
Chris@101
|
159 os.width(0);
|
Chris@101
|
160 }
|
Chris@101
|
161 }
|
Chris@101
|
162 BOOST_CATCH(...)
|
Chris@101
|
163 {
|
Chris@101
|
164 bool flag = false;
|
Chris@101
|
165 BOOST_TRY
|
Chris@101
|
166 {
|
Chris@101
|
167 os.setstate(std::ios_base::failbit);
|
Chris@101
|
168 }
|
Chris@101
|
169 BOOST_CATCH (std::ios_base::failure )
|
Chris@101
|
170 {
|
Chris@101
|
171 flag = true;
|
Chris@101
|
172 }
|
Chris@101
|
173 BOOST_CATCH_END
|
Chris@101
|
174 if (flag) throw;
|
Chris@101
|
175 }
|
Chris@101
|
176 BOOST_CATCH_END
|
Chris@101
|
177 if (err) os.setstate(err);
|
Chris@101
|
178 return os;
|
Chris@101
|
179 }
|
Chris@101
|
180 BOOST_CATCH(...)
|
Chris@101
|
181 {
|
Chris@101
|
182 failed = true;
|
Chris@101
|
183 }
|
Chris@101
|
184 BOOST_CATCH_END
|
Chris@101
|
185 if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
|
Chris@101
|
186 return os;
|
Chris@101
|
187
|
Chris@101
|
188 }
|
Chris@101
|
189
|
Chris@101
|
190 template <class CharT, class Traits, class Rep, class Period>
|
Chris@101
|
191 typename boost::enable_if_c< duration_put_enabled<Rep>::value, std::basic_ostream<CharT, Traits>& >::type
|
Chris@16
|
192 operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d)
|
Chris@16
|
193 {
|
Chris@16
|
194 bool failed = false;
|
Chris@16
|
195 BOOST_TRY
|
Chris@16
|
196 {
|
Chris@16
|
197 std::ios_base::iostate err = std::ios_base::goodbit;
|
Chris@16
|
198 BOOST_TRY
|
Chris@16
|
199 {
|
Chris@16
|
200 typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
|
Chris@16
|
201 if (bool(opfx))
|
Chris@16
|
202 {
|
Chris@16
|
203 if (!std::has_facet<duration_put<CharT> >(os.getloc()))
|
Chris@16
|
204 {
|
Chris@16
|
205 if (duration_put<CharT> ().put(os, os, os.fill(), d) .failed())
|
Chris@16
|
206 {
|
Chris@16
|
207 err = std::ios_base::badbit;
|
Chris@16
|
208 }
|
Chris@16
|
209 }
|
Chris@16
|
210 else if (std::use_facet<duration_put<CharT> >(os.getloc()) .put(os, os, os.fill(), d) .failed())
|
Chris@16
|
211 {
|
Chris@16
|
212 err = std::ios_base::badbit;
|
Chris@16
|
213 }
|
Chris@16
|
214 os.width(0);
|
Chris@16
|
215 }
|
Chris@16
|
216 }
|
Chris@16
|
217 BOOST_CATCH(...)
|
Chris@16
|
218 {
|
Chris@16
|
219 bool flag = false;
|
Chris@16
|
220 BOOST_TRY
|
Chris@16
|
221 {
|
Chris@16
|
222 os.setstate(std::ios_base::failbit);
|
Chris@16
|
223 }
|
Chris@16
|
224 BOOST_CATCH (std::ios_base::failure )
|
Chris@16
|
225 {
|
Chris@16
|
226 flag = true;
|
Chris@16
|
227 }
|
Chris@16
|
228 BOOST_CATCH_END
|
Chris@16
|
229 if (flag) throw;
|
Chris@16
|
230 }
|
Chris@16
|
231 BOOST_CATCH_END
|
Chris@16
|
232 if (err) os.setstate(err);
|
Chris@16
|
233 return os;
|
Chris@16
|
234 }
|
Chris@16
|
235 BOOST_CATCH(...)
|
Chris@16
|
236 {
|
Chris@16
|
237 failed = true;
|
Chris@16
|
238 }
|
Chris@16
|
239 BOOST_CATCH_END
|
Chris@16
|
240 if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
|
Chris@16
|
241 return os;
|
Chris@16
|
242 }
|
Chris@16
|
243
|
Chris@16
|
244 /**
|
Chris@16
|
245 *
|
Chris@16
|
246 * @param is the input stream
|
Chris@16
|
247 * @param d the duration
|
Chris@16
|
248 * @return @c is
|
Chris@16
|
249 */
|
Chris@16
|
250 template <class CharT, class Traits, class Rep, class Period>
|
Chris@16
|
251 std::basic_istream<CharT, Traits>&
|
Chris@16
|
252 operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)
|
Chris@16
|
253 {
|
Chris@16
|
254 std::ios_base::iostate err = std::ios_base::goodbit;
|
Chris@16
|
255
|
Chris@16
|
256 BOOST_TRY
|
Chris@16
|
257 {
|
Chris@16
|
258 typename std::basic_istream<CharT, Traits>::sentry ipfx(is);
|
Chris@16
|
259 if (bool(ipfx))
|
Chris@16
|
260 {
|
Chris@16
|
261 if (!std::has_facet<duration_get<CharT> >(is.getloc()))
|
Chris@16
|
262 {
|
Chris@16
|
263 duration_get<CharT> ().get(is, std::istreambuf_iterator<CharT, Traits>(), is, err, d);
|
Chris@16
|
264 }
|
Chris@16
|
265 else
|
Chris@16
|
266 {
|
Chris@16
|
267 std::use_facet<duration_get<CharT> >(is.getloc()) .get(is, std::istreambuf_iterator<CharT, Traits>(), is,
|
Chris@16
|
268 err, d);
|
Chris@16
|
269 }
|
Chris@16
|
270 }
|
Chris@16
|
271 }
|
Chris@16
|
272 BOOST_CATCH (...)
|
Chris@16
|
273 {
|
Chris@16
|
274 bool flag = false;
|
Chris@16
|
275 BOOST_TRY
|
Chris@16
|
276 {
|
Chris@16
|
277 is.setstate(std::ios_base::failbit);
|
Chris@16
|
278 }
|
Chris@16
|
279 BOOST_CATCH (std::ios_base::failure )
|
Chris@16
|
280 {
|
Chris@16
|
281 flag = true;
|
Chris@16
|
282 }
|
Chris@16
|
283 BOOST_CATCH_END
|
Chris@16
|
284 if (flag) { BOOST_RETHROW }
|
Chris@16
|
285 }
|
Chris@16
|
286 BOOST_CATCH_END
|
Chris@16
|
287 if (err) is.setstate(err);
|
Chris@16
|
288 return is;
|
Chris@16
|
289 }
|
Chris@16
|
290
|
Chris@16
|
291 } // chrono
|
Chris@16
|
292
|
Chris@16
|
293 }
|
Chris@16
|
294
|
Chris@16
|
295 #endif // header
|