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