]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/chrono/include/boost/chrono/io/duration_put.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / chrono / include / boost / chrono / io / duration_put.hpp
CommitLineData
7c673cae
FG
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
8/**
9 * Duration formatting facet for output.
10 */
11#ifndef BOOST_CHRONO_IO_DURATION_PUT_HPP
12#define BOOST_CHRONO_IO_DURATION_PUT_HPP
13
14#include <boost/chrono/config.hpp>
15#include <boost/chrono/io/duration_units.hpp>
16#include <boost/chrono/process_cpu_clocks.hpp>
17#include <boost/assert.hpp>
18#include <locale>
19
20namespace boost
21{
22 namespace chrono
23 {
24
25 namespace detail
26 {
27 template <class T>
28 struct propagate {
29 typedef T type;
30 };
31 template <>
32 struct propagate<boost::int_least32_t> {
33 typedef boost::int_least64_t type;
34 };
35 }
36 /**
37 * @tparam ChatT a character type
38 * @tparam OutputIterator a model of @c OutputIterator
39 *
40 * The @c duration_put facet provides facilities for formatted output of duration values.
41 * The member function of @c duration_put take a duration and format it into character string representation.
42 *
43 */
44 template <class CharT, class OutputIterator = std::ostreambuf_iterator<CharT> >
45 class duration_put: public std::locale::facet
46 {
47 public:
48 /**
49 * Type of character the facet is instantiated on.
50 */
51 typedef CharT char_type;
52 /**
53 * Type of character string passed to member functions.
54 */
55 typedef std::basic_string<CharT> string_type;
56 /**
57 * Type of iterator used to write in the character buffer.
58 */
59 typedef OutputIterator iter_type;
60
61 /**
62 * Construct a duration_put facet.
63 * @param refs
64 * @Effects Construct a duration_put facet.
65 * If the @c refs argument is @c 0 then destruction of the object is
66 * delegated to the @c locale, or locales, containing it. This allows
67 * the user to ignore lifetime management issues. On the other had,
68 * if @c refs is @c 1 then the object must be explicitly deleted;
69 * the @c locale will not do so. In this case, the object can be
70 * maintained across the lifetime of multiple locales.
71 */
72 explicit duration_put(size_t refs = 0) :
73 std::locale::facet(refs)
74 {
75 }
76
77 /**
78 *
79 * @param s an output stream iterator
80 * @param ios a reference to a ios_base
81 * @param fill the character used as filler
82 * @param d the duration
83 * @param pattern begin of the formatting pattern
84 * @param pat_end end of the formatting pattern
85 *
86 * @Effects Steps through the sequence from @c pattern to @c pat_end,
87 * identifying characters that are part of a pattern sequence. Each character
88 * that is not part of a pattern sequence is written to @c s immediately, and
89 * each pattern sequence, as it is identified, results in a call to
90 * @c put_value or @c put_unit;
91 * thus, pattern elements and other characters are interleaved in the output
92 * in the order in which they appear in the pattern. Pattern sequences are
93 * identified by converting each character @c c to a @c char value as if by
94 * @c ct.narrow(c,0), where @c ct is a reference to @c ctype<charT> obtained from
95 * @c ios.getloc(). The first character of each sequence is equal to @c '%',
96 * followed by a pattern specifier character @c spec, which can be @c 'v' for
97 * the duration value or @c 'u' for the duration unit. .
98 * For each valid pattern sequence identified, calls
99 * <c>put_value(s, ios, fill, d)</c> or <c>put_unit(s, ios, fill, d)</c>.
100 *
101 * @Returns An iterator pointing immediately after the last character produced.
102 */
103 template <typename Rep, typename Period>
104 iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d, const CharT* pattern,
105 const CharT* pat_end, const char_type* val = 0) const
106 {
107 if (std::has_facet<duration_units<CharT> >(ios.getloc()))
108 {
109 duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
110 ios.getloc());
111 return put(facet, s, ios, fill, d, pattern, pat_end, val);
112 }
113 else
114 {
115 duration_units_default<CharT> facet;
116 return put(facet, s, ios, fill, d, pattern, pat_end, val);
117 }
118 }
119
120 template <typename Rep, typename Period>
121 iter_type put(duration_units<CharT> const& units_facet, iter_type s, std::ios_base& ios, char_type fill,
122 duration<Rep, Period> const& d, const CharT* pattern, const CharT* pat_end, const char_type* val = 0) const
123 {
124
125 const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
126 for (; pattern != pat_end; ++pattern)
127 {
128 if (ct.narrow(*pattern, 0) == '%')
129 {
130 if (++pattern == pat_end)
131 {
132 *s++ = pattern[-1];
133 break;
134 }
135 char fmt = ct.narrow(*pattern, 0);
136 switch (fmt)
137 {
138 case 'v':
139 {
140 s = put_value(s, ios, fill, d, val);
141 break;
142 }
143 case 'u':
144 {
145 s = put_unit(units_facet, s, ios, fill, d);
146 break;
147 }
148 default:
149 BOOST_ASSERT(false && "Boost::Chrono internal error.");
150 break;
151 }
152 }
153 else
154 *s++ = *pattern;
155 }
156 return s;
157 }
158
159 /**
160 *
161 * @param s an output stream iterator
162 * @param ios a reference to a ios_base
163 * @param fill the character used as filler
164 * @param d the duration
165 * @Effects imbue in @c ios the @c duration_units_default facet if not already present.
166 * Retrieves Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
167 * @code
168 * return put(s, ios, d, str.data(), str.data() + str.size());
169 * @endcode
170 * @Returns An iterator pointing immediately after the last character produced.
171 */
172 template <typename Rep, typename Period>
173 iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d, const char_type* val = 0) const
174 {
175 if (std::has_facet<duration_units<CharT> >(ios.getloc()))
176 {
177 duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
178 ios.getloc());
179 std::basic_string<CharT> str = facet.get_pattern();
180 return put(facet, s, ios, fill, d, str.data(), str.data() + str.size(), val);
181 }
182 else
183 {
184 duration_units_default<CharT> facet;
185 std::basic_string<CharT> str = facet.get_pattern();
186
187 return put(facet, s, ios, fill, d, str.data(), str.data() + str.size(), val);
188 }
189 }
190
191 /**
192 *
193 * @param s an output stream iterator
194 * @param ios a reference to a ios_base
195 * @param fill the character used as filler
196 * @param d the duration
197 * @Effects As if s=std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, static_cast<long int> (d.count())).
198 * @Returns s, iterator pointing immediately after the last character produced.
199 */
200 template <typename Rep, typename Period>
201 iter_type put_value(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d, const char_type* val = 0) const
202 {
203 if (val)
204 {
205 while (*val) {
206 *s = *val;
207 s++; val++;
208 }
209 return s;
210 }
211 return std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill,
212 static_cast<typename detail::propagate<Rep>::type> (d.count()));
213 }
214
215 template <typename Rep, typename Period>
216 iter_type put_value(iter_type s, std::ios_base& ios, char_type fill, duration<process_times<Rep>, Period> const& d, const char_type* = 0) const
217 {
218 *s++ = CharT('{');
219 s = put_value(s, ios, fill, process_real_cpu_clock::duration(d.count().real));
220 *s++ = CharT(';');
221 s = put_value(s, ios, fill, process_user_cpu_clock::duration(d.count().user));
222 *s++ = CharT(';');
223 s = put_value(s, ios, fill, process_system_cpu_clock::duration(d.count().system));
224 *s++ = CharT('}');
225 return s;
226 }
227
228 /**
229 *
230 * @param s an output stream iterator
231 * @param ios a reference to a ios_base
232 * @param fill the character used as filler
233 * @param d the duration
234 * @Effects Let facet be the duration_units<CharT> facet associated to ios. If the associated unit is named,
235 * as if
236 * @code
237 string_type str = facet.get_unit(get_duration_style(ios), d);
238 s=std::copy(str.begin(), str.end(), s);
239 * @endcode
240 * Otherwise, format the unit as "[Period::num/Period::den]" followed by the unit associated to [N/D] obtained using facet.get_n_d_unit(get_duration_style(ios), d)
241 * @Returns s, iterator pointing immediately after the last character produced.
242 */
243 template <typename Rep, typename Period>
244 iter_type put_unit(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d) const
245 {
246 if (std::has_facet<duration_units<CharT> >(ios.getloc()))
247 {
248 duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
249 ios.getloc());
250 return put_unit(facet, s, ios, fill, d);
251 }
252 else
253 {
254 duration_units_default<CharT> facet;
255 return put_unit(facet, s, ios, fill, d);
256 }
257 }
258
259 template <typename Rep, typename Period>
260 iter_type put_unit(duration_units<CharT> const& facet, iter_type s, std::ios_base& ios, char_type fill,
261 duration<Rep, Period> const& d) const
262 {
263 if (facet.template is_named_unit<Period>()) {
264 string_type str = facet.get_unit(get_duration_style(ios), d);
265 s=std::copy(str.begin(), str.end(), s);
266 } else {
267 *s++ = CharT('[');
268 std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::num);
269 *s++ = CharT('/');
270 std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::den);
271 *s++ = CharT(']');
272 string_type str = facet.get_n_d_unit(get_duration_style(ios), d);
273 s=std::copy(str.begin(), str.end(), s);
274 }
275 return s;
276 }
277 template <typename Rep, typename Period>
278 iter_type put_unit(duration_units<CharT> const& facet, iter_type s, std::ios_base& ios, char_type fill,
279 duration<process_times<Rep>, Period> const& d) const
280 {
281 duration<Rep,Period> real(d.count().real);
282 if (facet.template is_named_unit<Period>()) {
283 string_type str = facet.get_unit(get_duration_style(ios), real);
284 s=std::copy(str.begin(), str.end(), s);
285 } else {
286 *s++ = CharT('[');
287 std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::num);
288 *s++ = CharT('/');
289 std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::den);
290 *s++ = CharT(']');
291 string_type str = facet.get_n_d_unit(get_duration_style(ios), real);
292 s=std::copy(str.begin(), str.end(), s);
293 }
294 return s;
295 }
296
297 /**
298 * Unique identifier for this type of facet.
299 */
300 static std::locale::id id;
301
302 /**
303 * @Effects Destroy the facet
304 */
305 ~duration_put()
306 {
307 }
308
309 };
310
311 template <class CharT, class OutputIterator>
312 std::locale::id duration_put<CharT, OutputIterator>::id;
313
314 } // chrono
315} // boost
316
317#endif // header