duration_units.hpp 36 KB

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