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#ifndef BOOST_CHRONO_IO_DURATION_UNITS_HPP
9#define BOOST_CHRONO_IO_DURATION_UNITS_HPP
10
11#include <boost/chrono/config.hpp>
12#include <boost/ratio/ratio_io.hpp>
13#include <boost/ratio/config.hpp>
14#include <boost/chrono/duration.hpp>
15#include <boost/chrono/io/duration_style.hpp>
16#include <boost/chrono/io/ios_base_state.hpp>
17#include <boost/assert.hpp>
18#include <string>
19#include <ios>
20#include <locale>
21#include <algorithm>
22
23namespace boost
24{
25 namespace chrono
26 {
27 class rt_ratio
28 {
29 public:
30 template <typename Period>
31 rt_ratio(Period const&) :
32 num(Period::type::num), den(Period::type::den)
33 {
34 }
35
36 rt_ratio(intmax_t n = 0, intmax_t d = 0) :
37 num(n), den(d)
38 {
39 }
40
41 intmax_t num;
42 intmax_t den;
43 };
44
45 /**
46 * @c duration_units facet gives useful information about the duration units,
47 * as the number of plural forms, the plural form associated to a duration,
48 * the text associated to a plural form and a duration's period,
49 */
50 template <typename CharT = char>
51 class duration_units: public std::locale::facet
52 {
53 public:
54 /**
55 * Type of character the facet is instantiated on.
56 */
57 typedef CharT char_type;
58 /**
59 * Type of character string passed to member functions.
60 */
61 typedef std::basic_string<CharT> string_type;
62
63 /**
64 * Unique identifier for this type of facet.
65 */
66 static std::locale::id id;
67
68 /**
69 * Construct a @c duration_units facet.
70 * @param refs
71 * @Effects Construct a @c duration_units facet.
72 * If the @c refs argument is @c 0 then destruction of the object is
73 * delegated to the @c locale, or locales, containing it. This allows
74 * the user to ignore lifetime management issues. On the other had,
75 * if @c refs is @c 1 then the object must be explicitly deleted;
76 * the @c locale will not do so. In this case, the object can be
77 * maintained across the lifetime of multiple locales.
78 */
79 explicit duration_units(size_t refs = 0) :
80 std::locale::facet(refs)
81 {
82 }
83
84 /**
85 * @return pointer to the start of valid [N/D] units.
86 */
87 virtual const string_type* get_n_d_valid_units_start() const =0;
88 /**
89 * @effect calls the do_...
90 * @return pointer to the end of valid [N/D] units.
91 */
92 virtual const string_type* get_n_d_valid_units_end() const=0;
93
94 /**
95 * @return pointer to the start of valid units, symbol or prefix with its different plural forms.
96 */
97 virtual const string_type* get_valid_units_start() const=0;
98 /**
99 * @return pointer to the end of valid units.
100 */
101 virtual const string_type* get_valid_units_end() const=0;
102
103 /**
104 * @param k the found pointer to the [N/D] unit.
105 * @return true if @c k matches a valid unit.
106 */
107 virtual bool match_n_d_valid_unit(const string_type* k) const = 0;
108 /**
109 * @param k the found pointer to the unit.
110 * @Effects @c rt is set to the valid Period when the @c k matches a valid unit.
111 * @return true if @c k matches a valid unit.
112 */
113 virtual bool match_valid_unit(const string_type* k, rt_ratio& rt) const = 0;
114
115 /**
116 * @effect calls the do_...
117 * @return the pattern to be used by default.
118 */
119 virtual string_type get_pattern() const=0;
120
121 /**
122 * @effect calls the do_...
123 * @return the unit associated to this duration.
124 */
125 template <typename Rep, typename Period>
126 string_type get_unit(duration_style style, duration<Rep, Period> const& d) const
127 {
128 return do_get_unit(style, rt: rt_ratio(Period()), v: static_cast<intmax_t>(d.count()));
129 }
130 /**
131 * @effect calls the do_...
132 * @return the [N/D] suffix unit associated to this duration.
133 */
134 template <typename Rep, typename Period>
135 string_type get_n_d_unit(duration_style style, duration<Rep, Period> const& d) const
136 {
137 return do_get_n_d_unit(style, rt: rt_ratio(Period()), v: static_cast<intmax_t>(d.count()));
138 }
139
140 /**
141 * @effect calls the do_...
142 * @return true if the unit associated to the given Period is named, false otherwise.
143 */
144 template <typename Period>
145 bool is_named_unit() const
146 {
147 return do_is_named_unit(rt: rt_ratio(Period()));
148 }
149
150
151 protected:
152
153 /**
154 * @Effects Destroys the facet
155 */
156 virtual ~duration_units()
157 {
158 }
159 /**
160 * @return the [N/D] suffix unit associated to this duration.
161 */
162 virtual string_type do_get_n_d_unit(duration_style style, rt_ratio rt, intmax_t v) const = 0;
163 /**
164 * @return the unit associated to this duration.
165 */
166 virtual string_type do_get_unit(duration_style style,rt_ratio rt, intmax_t v) const = 0;
167 /**
168 * @return true if the unit associated to the given Period is named, false otherwise.
169 */
170 virtual bool do_is_named_unit(rt_ratio rt) const =0;
171
172 };
173
174 template <typename CharT>
175 std::locale::id duration_units<CharT>::id;
176
177 namespace detail
178 {
179 template<typename CharT>
180 struct duration_units_default_holder
181 {
182 typedef std::basic_string<CharT> string_type;
183 static string_type* n_d_valid_units_;
184 static string_type* valid_units_;
185 static bool initialized_;
186 };
187 template <typename CharT>
188 typename duration_units_default_holder<CharT>::string_type* duration_units_default_holder<CharT>::n_d_valid_units_=0;
189 template <typename CharT>
190 typename duration_units_default_holder<CharT>::string_type* duration_units_default_holder<CharT>::valid_units_=0;
191 template<typename CharT>
192 bool duration_units_default_holder<CharT>::initialized_ = false;
193 }
194
195 /**
196 * This class is used to define the strings for the default English
197 */
198 template <typename CharT = char>
199 class duration_units_default: public duration_units<CharT>
200 {
201 protected:
202 static const std::size_t pfs_ = 2;
203
204 public:
205 /**
206 * Type of character the facet is instantiated on.
207 */
208 typedef CharT char_type;
209 /**
210 * Type of character string passed to member functions.
211 */
212 typedef std::basic_string<CharT> string_type;
213
214 /**
215 * Construct a @c duration_units_default facet.
216 * @param refs
217 * @Effects Construct a @c duration_units_default facet.
218 * If the @c refs argument is @c 0 then destruction of the object is
219 * delegated to the @c locale, or locales, containing it. This allows
220 * the user to ignore lifetime management issues. On the other had,
221 * if @c refs is @c 1 then the object must be explicitly deleted;
222 * the @c locale will not do so. In this case, the object can be
223 * maintained across the lifetime of multiple locales.
224 */
225 explicit duration_units_default(size_t refs = 0) :
226 duration_units<CharT> (refs)
227 {
228 }
229
230 /**
231 * Destroys the facet.
232 */
233 ~duration_units_default()
234 {
235 }
236
237 public:
238
239 /**
240 * @param k the found pointer to the [N/D] unit.
241 * @return true if @c k matches a valid unit.
242 */
243 bool match_n_d_valid_unit(const string_type* k) const
244 {
245 std::size_t index = (k - get_n_d_valid_units_start()) / (pfs_ + 1);
246 switch (index)
247 {
248 case 0:
249 break;
250 default:
251 return false;
252 }
253 return true;
254 }
255 /**
256 * @param k the found pointer to the unit.
257 * @Effects @c rt is set to the valid Period when the @c k matches a valid unit.
258 * @return true if @c k matches a valid unit.
259 */
260 bool match_valid_unit(const string_type* k, rt_ratio& rt) const
261 {
262 std::size_t index = (k - get_valid_units_start()) / (pfs_ + 1);
263 switch (index)
264 {
265 case 0:
266 rt = rt_ratio(atto());
267 break;
268 case 1:
269 rt = rt_ratio(femto());
270 break;
271 case 2:
272 rt = rt_ratio(pico());
273 break;
274 case 3:
275 rt = rt_ratio(nano());
276 break;
277 case 4:
278 rt = rt_ratio(micro());
279 break;
280 case 5:
281 rt = rt_ratio(milli());
282 break;
283 case 6:
284 rt = rt_ratio(centi());
285 break;
286 case 7:
287 rt = rt_ratio(deci());
288 break;
289 case 8:
290 rt = rt_ratio(deca());
291 break;
292 case 9:
293 rt = rt_ratio(hecto());
294 break;
295 case 10:
296 rt = rt_ratio(kilo());
297 break;
298 case 11:
299 rt = rt_ratio(mega());
300 break;
301 case 12:
302 rt = rt_ratio(giga());
303 break;
304 case 13:
305 rt = rt_ratio(tera());
306 break;
307 case 14:
308 rt = rt_ratio(peta());
309 break;
310 case 15:
311 rt = rt_ratio(exa());
312 break;
313 case 16:
314 rt = rt_ratio(ratio<1> ());
315 break;
316 case 17:
317 rt = rt_ratio(ratio<60> ());
318 break;
319 case 18:
320 rt = rt_ratio(ratio<3600> ());
321 break;
322 default:
323 return false;
324 }
325 return true;
326 }
327
328 /**
329 * @return pointer to the start of valid [N/D] units.
330 */
331 virtual const string_type* get_n_d_valid_units_start()const
332 {
333 return detail::duration_units_default_holder<CharT>::n_d_valid_units_;
334 }
335 /**
336 * @return pointer to the end of valid [N/D] units.
337 */
338 virtual const string_type* get_n_d_valid_units_end()const
339 {
340 return detail::duration_units_default_holder<CharT>::n_d_valid_units_ + (pfs_ + 1);
341 }
342
343 /**
344 * @return pointer to the start of valid units.
345 */
346 virtual const string_type* get_valid_units_start() const
347 {
348 return detail::duration_units_default_holder<CharT>::valid_units_;
349 }
350 /**
351 * @return pointer to the end of valid units.
352 */
353 virtual const string_type* get_valid_units_end() const
354 {
355 return detail::duration_units_default_holder<CharT>::valid_units_ + 19 * (pfs_ + 1);
356 }
357
358 string_type get_pattern() const
359 {
360 static const CharT t[] =
361 { '%', 'v', ' ', '%', 'u' };
362 static const string_type pattern(t, t + sizeof (t) / sizeof (t[0]));
363
364 return pattern;
365 }
366
367 protected:
368 /**
369 *
370 * This facet names the units associated to the following periods:
371 * atto,femto,pico,nano,micro,milli,centi,deci,ratio<1>,deca,hecto,kilo,mega,giga,tera,peta,exa,ratio<60> and ratio<3600>.
372 * @return true if the unit associated to the given Period is named, false otherwise.
373 */
374 bool do_is_named_unit(rt_ratio rt) const
375 {
376 if (rt.num==1) {
377 switch (rt.den)
378 {
379 case BOOST_RATIO_INTMAX_C(1):
380 case BOOST_RATIO_INTMAX_C(10):
381 case BOOST_RATIO_INTMAX_C(100):
382 case BOOST_RATIO_INTMAX_C(1000):
383 case BOOST_RATIO_INTMAX_C(1000000):
384 case BOOST_RATIO_INTMAX_C(1000000000):
385 case BOOST_RATIO_INTMAX_C(1000000000000):
386 case BOOST_RATIO_INTMAX_C(1000000000000000):
387 case BOOST_RATIO_INTMAX_C(1000000000000000000):
388 return true;
389 default:
390 return false;
391 }
392 } else if (rt.den==1) {
393 switch (rt.num)
394 {
395 case BOOST_RATIO_INTMAX_C(10):
396 case BOOST_RATIO_INTMAX_C(60):
397 case BOOST_RATIO_INTMAX_C(100):
398 case BOOST_RATIO_INTMAX_C(1000):
399 case BOOST_RATIO_INTMAX_C(3600):
400 case BOOST_RATIO_INTMAX_C(1000000):
401 case BOOST_RATIO_INTMAX_C(1000000000):
402 case BOOST_RATIO_INTMAX_C(1000000000000):
403 case BOOST_RATIO_INTMAX_C(1000000000000000):
404 case BOOST_RATIO_INTMAX_C(1000000000000000000):
405 return true;
406 default:
407 return false;
408 }
409 }
410 return false;
411
412 }
413
414 /**
415 * In English the suffix used after [N/D] is the one associated to the period ratio<1>.
416 * @return the [N/D] suffix unit associated to this duration.
417 */
418 string_type do_get_n_d_unit(duration_style style, rt_ratio, intmax_t v) const
419 {
420 return do_get_unit(style, ratio<1>(), do_get_plural_form(value: v));
421 }
422
423 /**
424 * @return the unit associated to this duration if it is named, "" otherwise.
425 */
426 string_type do_get_unit(duration_style style, rt_ratio rt, intmax_t v) const
427 {
428 if (rt.num==1) {
429 switch (rt.den)
430 {
431 case BOOST_RATIO_INTMAX_C(1):
432 return do_get_unit(style, ratio<1>(), do_get_plural_form(value: v));
433 case BOOST_RATIO_INTMAX_C(10):
434 return do_get_unit(style, deci(), do_get_plural_form(value: v));
435 case BOOST_RATIO_INTMAX_C(100):
436 return do_get_unit(style, centi(), do_get_plural_form(value: v));
437 case BOOST_RATIO_INTMAX_C(1000):
438 return do_get_unit(style, milli(), do_get_plural_form(value: v));
439 case BOOST_RATIO_INTMAX_C(1000000):
440 return do_get_unit(style, micro(), do_get_plural_form(value: v));
441 case BOOST_RATIO_INTMAX_C(1000000000):
442 return do_get_unit(style, nano(), do_get_plural_form(value: v));
443 case BOOST_RATIO_INTMAX_C(1000000000000):
444 return do_get_unit(style, pico(), do_get_plural_form(value: v));
445 case BOOST_RATIO_INTMAX_C(1000000000000000):
446 return do_get_unit(style, femto(), do_get_plural_form(value: v));
447 case BOOST_RATIO_INTMAX_C(1000000000000000000):
448 return do_get_unit(style, atto(), do_get_plural_form(value: v));
449 default:
450 ;
451 }
452 } else if (rt.den==1) {
453 switch (rt.num)
454 {
455 case BOOST_RATIO_INTMAX_C(10):
456 return do_get_unit(style, deca(), do_get_plural_form(value: v));
457 case BOOST_RATIO_INTMAX_C(60):
458 return do_get_unit(style, ratio<60>(), do_get_plural_form(value: v));
459 case BOOST_RATIO_INTMAX_C(100):
460 return do_get_unit(style, hecto(), do_get_plural_form(value: v));
461 case BOOST_RATIO_INTMAX_C(1000):
462 return do_get_unit(style, kilo(), do_get_plural_form(value: v));
463 case BOOST_RATIO_INTMAX_C(3600):
464 return do_get_unit(style, ratio<3600>(), do_get_plural_form(value: v));
465 case BOOST_RATIO_INTMAX_C(1000000):
466 return do_get_unit(style, mega(), do_get_plural_form(value: v));
467 case BOOST_RATIO_INTMAX_C(1000000000):
468 return do_get_unit(style, giga(), do_get_plural_form(value: v));
469 case BOOST_RATIO_INTMAX_C(1000000000000):
470 return do_get_unit(style, tera(), do_get_plural_form(value: v));
471 case BOOST_RATIO_INTMAX_C(1000000000000000):
472 return do_get_unit(style, peta(), do_get_plural_form(value: v));
473 case BOOST_RATIO_INTMAX_C(1000000000000000000):
474 return do_get_unit(style, exa(), do_get_plural_form(value: v));
475 default:
476 ;
477 }
478 }
479 BOOST_ASSERT(false&&"ratio parameter can not be translated");
480 //throw "exception";
481 return string_type();
482 }
483
484 protected:
485 /**
486 * @return the number of associated plural forms this facet manages.
487 */
488 virtual std::size_t do_get_plural_forms() const
489 {
490 return static_get_plural_forms();
491 }
492 static std::size_t static_get_plural_forms()
493 {
494 return pfs_;
495 }
496 /**
497 * Gets the associated plural form.
498 * @param value the duration representation
499 * @return the plural form associated to the @c value parameter. In English there are 2 plural forms
500 * 0 singular (-1 or 1)
501 * 1 plural for all others
502 */
503 virtual std::size_t do_get_plural_form(int_least64_t value) const
504 {
505 return static_get_plural_form(value);
506 }
507 static std::size_t static_get_plural_form(int_least64_t value)
508 {
509 return (value == -1 || value == 1) ? 0 : 1;
510 }
511
512 /**
513 * @param style the duration style.
514 * @param period the period associated to the duration seconds.
515 * @param pf the requested plural form.
516 * @return if style is symbol returns "s", otherwise if pf is 0 return "second", if pf is 1 "seconds"
517 */
518 virtual string_type do_get_unit(duration_style style, ratio<1> u, std::size_t pf) const
519 {
520 return static_get_unit(style,u,pf);
521 }
522 static string_type static_get_unit(duration_style style, ratio<1> , std::size_t pf)
523 {
524 static const CharT t[] =
525 { 's' };
526 static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
527 static const CharT u[] =
528 { 's', 'e', 'c', 'o', 'n', 'd' };
529 static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
530 static const CharT v[] =
531 { 's', 'e', 'c', 'o', 'n', 'd', 's' };
532 static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
533
534 if (style == duration_style::symbol)
535 {
536 return symbol;
537 }
538 if (pf == 0)
539 {
540 return singular;
541 }
542 if (pf == 1)
543 {
544 return plural;
545 }
546 BOOST_ASSERT(false&&"style/pf parameters not valid");
547 //throw "exception";
548 return string_type();
549 }
550
551 /**
552 * @param style the duration style.
553 * @param period the period associated to the duration minutes.
554 * @param pf the requested plural form.
555 * @return if style is symbol returns "min", otherwise if pf is 0 return "minute", if pf is 1 "minutes"
556 */
557 virtual string_type do_get_unit(duration_style style, ratio<60> u, std::size_t pf) const
558 {
559 return static_get_unit(style,u,pf);
560 }
561 static string_type static_get_unit(duration_style style, ratio<60> , std::size_t pf)
562 {
563 static const CharT t[] =
564 { 'm', 'i', 'n' };
565 static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
566
567 static const CharT u[] =
568 { 'm', 'i', 'n', 'u', 't', 'e' };
569 static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
570 static const CharT v[] =
571 { 'm', 'i', 'n', 'u', 't', 'e', 's' };
572 static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
573
574 if (style == duration_style::symbol) return symbol;
575 if (pf == 0) return singular;
576 if (pf == 1) return plural;
577 BOOST_ASSERT(false&&"style/pf parameters not valid");
578 //throw "exception";
579 return string_type();
580
581 }
582
583 /**
584 * @param style the duration style.
585 * @param period the period associated to the duration hours.
586 * @param pf the requested plural form.
587 * @return if style is symbol returns "h", otherwise if pf is 0 return "hour", if pf is 1 "hours"
588 */
589 virtual string_type do_get_unit(duration_style style, ratio<3600> u, std::size_t pf) const
590 {
591 return static_get_unit(style,u,pf);
592 }
593 static string_type static_get_unit(duration_style style, ratio<3600> , std::size_t pf)
594 {
595 static const CharT t[] =
596 { 'h' };
597 static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
598 static const CharT u[] =
599 { 'h', 'o', 'u', 'r' };
600 static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
601 static const CharT v[] =
602 { 'h', 'o', 'u', 'r', 's' };
603 static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
604
605 if (style == duration_style::symbol) return symbol;
606 if (pf == 0) return singular;
607 if (pf == 1) return plural;
608 BOOST_ASSERT(false&&"style/pf parameters not valid");
609 //throw "exception";
610 return string_type();
611
612 }
613 /**
614 * @param style the duration style.
615 * @param u the period tag atto.
616 * @param pf the requested plural form.
617 * @return the concatenation of the prefix associated to @c period + the one associated to seconds.
618 */
619 virtual string_type do_get_unit(duration_style style, atto u, std::size_t pf) const
620 {
621 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
622 }
623 static string_type static_get_unit(duration_style style, atto u, std::size_t pf)
624 {
625 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
626 }
627 /**
628 * @param style the duration style.
629 * @param u the period tag femto.
630 * @param pf the requested plural form.
631 * @return the concatenation of the prefix associated to period @c u + the one associated to seconds.
632 */
633 virtual string_type do_get_unit(duration_style style, femto u, std::size_t pf) const
634 {
635 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
636 }
637 static string_type static_get_unit(duration_style style, femto u, std::size_t pf)
638 {
639 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
640 }
641 /**
642 * @param style the duration style.
643 * @param u the period tag femto.
644 * @param pf the requested plural form.
645 * @return the concatenation of the prefix associated to period @c u + the one associated to seconds.
646 */
647 virtual string_type do_get_unit(duration_style style, pico u, std::size_t pf) const
648 {
649 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
650 }
651 static string_type static_get_unit(duration_style style, pico u, std::size_t pf)
652 {
653 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
654 }
655 virtual string_type do_get_unit(duration_style style, nano u, std::size_t pf) const
656 {
657 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
658 }
659 static string_type static_get_unit(duration_style style, nano u, std::size_t pf)
660 {
661 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
662 }
663 virtual string_type do_get_unit(duration_style style, micro u, std::size_t pf) const
664 {
665 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
666 }
667 static string_type static_get_unit(duration_style style, micro u, std::size_t pf)
668 {
669 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
670 }
671 virtual string_type do_get_unit(duration_style style, milli u, std::size_t pf) const
672 {
673 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
674 }
675 static string_type static_get_unit(duration_style style, milli u, std::size_t pf)
676 {
677 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
678 }
679 virtual string_type do_get_unit(duration_style style, centi u, std::size_t pf) const
680 {
681 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
682 }
683 static string_type static_get_unit(duration_style style, centi u, std::size_t pf)
684 {
685 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
686 }
687 virtual string_type do_get_unit(duration_style style, deci u, std::size_t pf) const
688 {
689 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
690 }
691 static string_type static_get_unit(duration_style style, deci u, std::size_t pf)
692 {
693 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
694 }
695 virtual string_type do_get_unit(duration_style style, deca u, std::size_t pf) const
696 {
697 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
698 }
699 static string_type static_get_unit(duration_style style, deca u, std::size_t pf)
700 {
701 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
702 }
703 virtual string_type do_get_unit(duration_style style, hecto u, std::size_t pf) const
704 {
705 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
706 }
707 static string_type static_get_unit(duration_style style, hecto u, std::size_t pf)
708 {
709 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
710 }
711 virtual string_type do_get_unit(duration_style style, kilo u, std::size_t pf) const
712 {
713 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
714 }
715 static string_type static_get_unit(duration_style style, kilo u, std::size_t pf)
716 {
717 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
718 }
719 virtual string_type do_get_unit(duration_style style, mega u, std::size_t pf) const
720 {
721 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
722 }
723 static string_type static_get_unit(duration_style style, mega u, std::size_t pf)
724 {
725 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
726 }
727 virtual string_type do_get_unit(duration_style style, giga u, std::size_t pf) const
728 {
729 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
730 }
731 static string_type static_get_unit(duration_style style, giga u, std::size_t pf)
732 {
733 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
734 }
735 virtual string_type do_get_unit(duration_style style, tera u, std::size_t pf) const
736 {
737 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
738 }
739 static string_type static_get_unit(duration_style style, tera u, std::size_t pf)
740 {
741 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
742 }
743 virtual string_type do_get_unit(duration_style style, peta u, std::size_t pf) const
744 {
745 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
746 }
747 static string_type static_get_unit(duration_style style, peta u, std::size_t pf)
748 {
749 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
750 }
751 virtual string_type do_get_unit(duration_style style, exa u, std::size_t pf) const
752 {
753 return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
754 }
755 static string_type static_get_unit(duration_style style, exa u, std::size_t pf)
756 {
757 return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
758 }
759
760 protected:
761
762 /**
763 * @param style the duration style.
764 * @param u the period tag atto.
765 * @return depending on the value of @c style return the ratio_string symbol or prefix.
766 */
767 virtual string_type do_get_ratio_prefix(duration_style style, atto u) const
768 {
769 return static_get_ratio_prefix(style, u);
770 }
771 static string_type static_get_ratio_prefix(duration_style style, atto)
772 {
773 if (style == duration_style::symbol) return ratio_string<atto, CharT>::symbol();
774 return ratio_string<atto, CharT>::prefix();
775 }
776 virtual string_type do_get_ratio_prefix(duration_style style, femto u) const
777 {
778 return static_get_ratio_prefix(style, u);
779 }
780 static string_type static_get_ratio_prefix(duration_style style, femto)
781 {
782 if (style == duration_style::symbol) return ratio_string<femto, CharT>::symbol();
783 return ratio_string<femto, CharT>::prefix();
784 }
785 virtual string_type do_get_ratio_prefix(duration_style style, pico u) const
786 {
787 return static_get_ratio_prefix(style, u);
788 }
789 static string_type static_get_ratio_prefix(duration_style style, pico)
790 {
791 if (style == duration_style::symbol) return ratio_string<pico, CharT>::symbol();
792 return ratio_string<pico, CharT>::prefix();
793 }
794 virtual string_type do_get_ratio_prefix(duration_style style, nano u) const
795 {
796 return static_get_ratio_prefix(style, u);
797 }
798 static string_type static_get_ratio_prefix(duration_style style, nano)
799 {
800 if (style == duration_style::symbol) return ratio_string<nano, CharT>::symbol();
801 return ratio_string<nano, CharT>::prefix();
802 }
803 virtual string_type do_get_ratio_prefix(duration_style style, micro u) const
804 {
805 return static_get_ratio_prefix(style, u);
806 }
807 static string_type static_get_ratio_prefix(duration_style style, micro)
808 {
809 if (style == duration_style::symbol) return ratio_string<micro, CharT>::symbol();
810 return ratio_string<micro, CharT>::prefix();
811 }
812 virtual string_type do_get_ratio_prefix(duration_style style, milli u) const
813 {
814 return static_get_ratio_prefix(style, u);
815 }
816 static string_type static_get_ratio_prefix(duration_style style, milli)
817 {
818 if (style == duration_style::symbol) return ratio_string<milli, CharT>::symbol();
819 return ratio_string<milli, CharT>::prefix();
820 }
821 virtual string_type do_get_ratio_prefix(duration_style style, centi u) const
822 {
823 return static_get_ratio_prefix(style, u);
824 }
825 static string_type static_get_ratio_prefix(duration_style style, centi)
826 {
827 if (style == duration_style::symbol) return ratio_string<centi, CharT>::symbol();
828 return ratio_string<centi, CharT>::prefix();
829 }
830 virtual string_type do_get_ratio_prefix(duration_style style, deci u) const
831 {
832 return static_get_ratio_prefix(style, u);
833 }
834 static string_type static_get_ratio_prefix(duration_style style, deci)
835 {
836 if (style == duration_style::symbol) return ratio_string<deci, CharT>::symbol();
837 return ratio_string<deci, CharT>::prefix();
838 }
839 virtual string_type do_get_ratio_prefix(duration_style style, deca u) const
840 {
841 return static_get_ratio_prefix(style, u);
842 }
843 static string_type static_get_ratio_prefix(duration_style style, deca)
844 {
845 if (style == duration_style::symbol) return ratio_string<deca, CharT>::symbol();
846 return ratio_string<deca, CharT>::prefix();
847 }
848 virtual string_type do_get_ratio_prefix(duration_style style, hecto u) const
849 {
850 return static_get_ratio_prefix(style, u);
851 }
852 static string_type static_get_ratio_prefix(duration_style style, hecto)
853 {
854 if (style == duration_style::symbol) return ratio_string<hecto, CharT>::symbol();
855 return ratio_string<hecto, CharT>::prefix();
856 }
857 virtual string_type do_get_ratio_prefix(duration_style style, kilo u) const
858 {
859 return static_get_ratio_prefix(style, u);
860 }
861 static string_type static_get_ratio_prefix(duration_style style, kilo)
862 {
863 if (style == duration_style::symbol) return ratio_string<kilo, CharT>::symbol();
864 return ratio_string<kilo, CharT>::prefix();
865 }
866 virtual string_type do_get_ratio_prefix(duration_style style, mega u) const
867 {
868 return static_get_ratio_prefix(style, u);
869 }
870 static string_type static_get_ratio_prefix(duration_style style, mega)
871 {
872 if (style == duration_style::symbol) return ratio_string<mega, CharT>::symbol();
873 return ratio_string<mega, CharT>::prefix();
874 }
875 virtual string_type do_get_ratio_prefix(duration_style style, giga u) const
876 {
877 return static_get_ratio_prefix(style, u);
878 }
879 static string_type static_get_ratio_prefix(duration_style style, giga)
880 {
881 if (style == duration_style::symbol) return ratio_string<giga, CharT>::symbol();
882 return ratio_string<giga, CharT>::prefix();
883 }
884 virtual string_type do_get_ratio_prefix(duration_style style, tera u) const
885 {
886 return static_get_ratio_prefix(style, u);
887 }
888 static string_type static_get_ratio_prefix(duration_style style, tera)
889 {
890 if (style == duration_style::symbol) return ratio_string<tera, CharT>::symbol();
891 return ratio_string<tera, CharT>::prefix();
892 }
893 virtual string_type do_get_ratio_prefix(duration_style style, peta u) const
894 {
895 return static_get_ratio_prefix(style, u);
896 }
897 static string_type static_get_ratio_prefix(duration_style style, peta)
898 {
899 if (style == duration_style::symbol) return ratio_string<peta, CharT>::symbol();
900 return ratio_string<peta, CharT>::prefix();
901 }
902 virtual string_type do_get_ratio_prefix(duration_style style, exa u) const
903 {
904 return static_get_ratio_prefix(style, u);
905 }
906 static string_type static_get_ratio_prefix(duration_style style, exa)
907 {
908 if (style == duration_style::symbol) return ratio_string<exa, CharT>::symbol();
909 return ratio_string<exa, CharT>::prefix();
910 }
911
912 protected:
913 template <typename Period>
914 string_type* fill_units(string_type* it, Period) const
915 {
916 std::size_t pfs = do_get_plural_forms();
917 for (std::size_t pf = 0; pf < pfs; ++pf)
918 {
919 *it++ = do_get_unit(duration_style::prefix, Period(), pf);
920 }
921 *it++ = do_get_unit(duration_style::symbol, Period(), 0);
922 return it;
923 }
924 public:
925 template <typename Period>
926 static string_type* static_fill_units(string_type* it, Period)
927 {
928 std::size_t pfs = static_get_plural_forms();
929 for (std::size_t pf = 0; pf < pfs; ++pf)
930 {
931 *it++ = static_get_unit(duration_style::prefix, Period(), pf);
932 }
933 *it++ = static_get_unit(duration_style::symbol, Period(), 0);
934 return it;
935 }
936 static string_type* static_init_valid_units(string_type* it)
937 {
938 it = static_fill_units(it, atto());
939 it = static_fill_units(it, femto());
940 it = static_fill_units(it, pico());
941 it = static_fill_units(it, nano());
942 it = static_fill_units(it, micro());
943 it = static_fill_units(it, milli());
944 it = static_fill_units(it, centi());
945 it = static_fill_units(it, deci());
946 it = static_fill_units(it, deca());
947 it = static_fill_units(it, hecto());
948 it = static_fill_units(it, kilo());
949 it = static_fill_units(it, mega());
950 it = static_fill_units(it, giga());
951 it = static_fill_units(it, tera());
952 it = static_fill_units(it, peta());
953 it = static_fill_units(it, exa());
954 it = static_fill_units(it, ratio<1> ());
955 it = static_fill_units(it, ratio<60> ());
956 it = static_fill_units(it, ratio<3600> ());
957 return it;
958 }
959 };
960
961 namespace detail
962 {
963
964 template<typename CharT>
965 struct duration_units_default_initializer_t
966 {
967 duration_units_default_initializer_t()
968 {
969 if (!duration_units_default_holder<CharT>::initialized_)
970 {
971 typedef typename duration_units_default_holder<CharT>::string_type string_type;
972 duration_units_default_holder<CharT>::n_d_valid_units_ = new string_type[3];
973 duration_units_default_holder<CharT>::valid_units_ = new string_type[19 * 3];
974
975 string_type* it = duration_units_default_holder<CharT>::n_d_valid_units_;
976 it = duration_units_default<CharT>::static_fill_units(it, ratio<1> ());
977 it = duration_units_default<CharT>::static_init_valid_units(duration_units_default_holder<CharT>::valid_units_);
978
979 duration_units_default_holder<CharT>::initialized_ = true;
980 }
981 }
982 ~duration_units_default_initializer_t()
983 {
984 if (duration_units_default_holder<CharT>::initialized_)
985 {
986 delete[] duration_units_default_holder<CharT>::n_d_valid_units_;
987 duration_units_default_holder<CharT>::n_d_valid_units_ = BOOST_NULLPTR;
988 delete[] duration_units_default_holder<CharT>::valid_units_;
989 duration_units_default_holder<CharT>::valid_units_ = BOOST_NULLPTR;
990 duration_units_default_holder<CharT>::initialized_ = false;
991 }
992 }
993 };
994 namespace /**/
995 {
996 duration_units_default_initializer_t<char> duration_units_default_initializer;
997 duration_units_default_initializer_t<wchar_t> wduration_units_default_initializer;
998 } // namespace
999 }
1000 } // chrono
1001
1002} // boost
1003
1004#endif // header
1005

source code of boost/libs/chrono/include/boost/chrono/io/duration_units.hpp