duration_units.hpp 36 KB

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