Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:47

0001 //  (C) Copyright Howard Hinnant
0002 //  (C) Copyright 2011 Vicente J. Botet Escriba
0003 //  Use, modification and distribution are subject to the Boost Software License,
0004 //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 //  http://www.boost.org/LICENSE_1_0.txt).
0006 //
0007 
0008 #ifndef BOOST_CHRONO_IO_DURATION_UNITS_HPP
0009 #define BOOST_CHRONO_IO_DURATION_UNITS_HPP
0010 
0011 #include <boost/chrono/config.hpp>
0012 #include <boost/ratio/ratio_io.hpp>
0013 #include <boost/ratio/config.hpp>
0014 #include <boost/chrono/duration.hpp>
0015 #include <boost/chrono/io/duration_style.hpp>
0016 #include <boost/chrono/io/ios_base_state.hpp>
0017 #include <boost/assert.hpp>
0018 #include <string>
0019 #include <ios>
0020 #include <locale>
0021 #include <algorithm>
0022 
0023 namespace boost
0024 {
0025   namespace chrono
0026   {
0027     class rt_ratio
0028     {
0029     public:
0030       template <typename Period>
0031       rt_ratio(Period const&) :
0032         num(Period::type::num), den(Period::type::den)
0033       {
0034       }
0035 
0036       rt_ratio(intmax_t n = 0, intmax_t d = 0) :
0037         num(n), den(d)
0038       {
0039       }
0040 
0041       intmax_t num;
0042       intmax_t den;
0043     };
0044 
0045     /**
0046      * @c duration_units facet gives useful information about the duration units,
0047      * as the number of plural forms, the plural form associated to a duration,
0048      * the text associated to a plural form and a duration's period,
0049      */
0050     template <typename CharT = char>
0051     class duration_units: public std::locale::facet
0052     {
0053     public:
0054       /**
0055        * Type of character the facet is instantiated on.
0056        */
0057       typedef CharT char_type;
0058       /**
0059        * Type of character string passed to member functions.
0060        */
0061       typedef std::basic_string<CharT> string_type;
0062 
0063       /**
0064        * Unique identifier for this type of facet.
0065        */
0066       static std::locale::id id;
0067 
0068       /**
0069        * Construct a @c duration_units facet.
0070        * @param refs
0071        * @Effects Construct a @c duration_units facet.
0072        * If the @c refs argument is @c 0 then destruction of the object is
0073        * delegated to the @c locale, or locales, containing it. This allows
0074        * the user to ignore lifetime management issues. On the other had,
0075        * if @c refs is @c 1 then the object must be explicitly deleted;
0076        * the @c locale will not do so. In this case, the object can be
0077        * maintained across the lifetime of multiple locales.
0078        */
0079       explicit duration_units(size_t refs = 0) :
0080         std::locale::facet(refs)
0081       {
0082       }
0083 
0084       /**
0085        * @return pointer to the start of valid [N/D] units.
0086        */
0087       virtual const string_type* get_n_d_valid_units_start() const =0;
0088       /**
0089        * @effect calls the do_...
0090        * @return pointer to the end of valid [N/D] units.
0091        */
0092       virtual const string_type* get_n_d_valid_units_end() const=0;
0093 
0094       /**
0095        * @return pointer to the start of valid units, symbol or prefix with its different plural forms.
0096        */
0097       virtual const string_type* get_valid_units_start() const=0;
0098       /**
0099        * @return pointer to the end of valid units.
0100        */
0101       virtual const string_type* get_valid_units_end() const=0;
0102 
0103       /**
0104        * @param k the found pointer to the [N/D] unit.
0105        * @return true if @c k matches a valid unit.
0106        */
0107       virtual bool match_n_d_valid_unit(const string_type* k) const = 0;
0108       /**
0109        * @param k the found pointer to the unit.
0110        * @Effects @c rt is set to the valid Period when the @c k matches a valid unit.
0111        * @return true if @c k matches a valid unit.
0112        */
0113       virtual bool match_valid_unit(const string_type* k, rt_ratio& rt) const = 0;
0114 
0115       /**
0116        * @effect calls the do_...
0117        * @return the pattern to be used by default.
0118        */
0119       virtual string_type get_pattern() const=0;
0120 
0121       /**
0122        * @effect calls the do_...
0123        * @return the unit associated to this duration.
0124        */
0125       template <typename Rep, typename Period>
0126       string_type get_unit(duration_style style, duration<Rep, Period> const& d) const
0127       {
0128         return do_get_unit(style, rt_ratio(Period()), static_cast<intmax_t>(d.count()));
0129       }
0130       /**
0131        * @effect calls the do_...
0132        * @return the [N/D] suffix unit associated to this duration.
0133        */
0134       template <typename Rep, typename Period>
0135       string_type get_n_d_unit(duration_style style, duration<Rep, Period> const& d) const
0136       {
0137         return do_get_n_d_unit(style, rt_ratio(Period()), static_cast<intmax_t>(d.count()));
0138       }
0139 
0140       /**
0141        * @effect calls the do_...
0142        * @return true if the unit associated to the given Period is named, false otherwise.
0143        */
0144       template <typename Period>
0145       bool is_named_unit() const
0146       {
0147         return do_is_named_unit(rt_ratio(Period()));
0148       }
0149 
0150 
0151     protected:
0152 
0153       /**
0154        * @Effects Destroys the facet
0155        */
0156       virtual ~duration_units()
0157       {
0158       }
0159       /**
0160        * @return the [N/D] suffix unit associated to this duration.
0161        */
0162       virtual string_type do_get_n_d_unit(duration_style style, rt_ratio rt, intmax_t v) const = 0;
0163       /**
0164        * @return the unit associated to this duration.
0165        */
0166       virtual string_type do_get_unit(duration_style style,rt_ratio rt, intmax_t v) const = 0;
0167       /**
0168        * @return true if the unit associated to the given Period is named, false otherwise.
0169        */
0170       virtual bool do_is_named_unit(rt_ratio rt) const =0;
0171 
0172     };
0173 
0174     template <typename CharT>
0175     std::locale::id duration_units<CharT>::id;
0176 
0177     namespace detail
0178     {
0179       template<typename CharT>
0180       struct duration_units_default_holder
0181       {
0182         typedef std::basic_string<CharT> string_type;
0183         static string_type* n_d_valid_units_;
0184         static string_type* valid_units_;
0185         static bool initialized_;
0186       };
0187       template <typename CharT>
0188       typename duration_units_default_holder<CharT>::string_type* duration_units_default_holder<CharT>::n_d_valid_units_=0;
0189       template <typename CharT>
0190       typename duration_units_default_holder<CharT>::string_type* duration_units_default_holder<CharT>::valid_units_=0;
0191       template<typename CharT>
0192       bool duration_units_default_holder<CharT>::initialized_ = false;
0193     }
0194 
0195     /**
0196      * This class is used to define the strings for the default English
0197      */
0198     template <typename CharT = char>
0199     class duration_units_default: public duration_units<CharT>
0200     {
0201     protected:
0202       static const std::size_t pfs_ = 2;
0203 
0204     public:
0205       /**
0206        * Type of character the facet is instantiated on.
0207        */
0208       typedef CharT char_type;
0209       /**
0210        * Type of character string passed to member functions.
0211        */
0212       typedef std::basic_string<CharT> string_type;
0213 
0214       /**
0215        * Construct a @c duration_units_default facet.
0216        * @param refs
0217        * @Effects Construct a @c duration_units_default facet.
0218        * If the @c refs argument is @c 0 then destruction of the object is
0219        * delegated to the @c locale, or locales, containing it. This allows
0220        * the user to ignore lifetime management issues. On the other had,
0221        * if @c refs is @c 1 then the object must be explicitly deleted;
0222        * the @c locale will not do so. In this case, the object can be
0223        * maintained across the lifetime of multiple locales.
0224        */
0225       explicit duration_units_default(size_t refs = 0) :
0226         duration_units<CharT> (refs)
0227       {
0228       }
0229 
0230       /**
0231        * Destroys the facet.
0232        */
0233       ~duration_units_default()
0234       {
0235       }
0236 
0237     public:
0238 
0239       /**
0240        * @param k the found pointer to the [N/D] unit.
0241        * @return true if @c k matches a valid unit.
0242        */
0243       bool match_n_d_valid_unit(const string_type* k) const
0244       {
0245         std::size_t index = (k - get_n_d_valid_units_start()) / (pfs_ + 1);
0246         switch (index)
0247         {
0248         case 0:
0249           break;
0250         default:
0251           return false;
0252         }
0253         return true;
0254       }
0255       /**
0256        * @param k the found pointer to the unit.
0257        * @Effects @c rt is set to the valid Period when the @c k matches a valid unit.
0258        * @return true if @c k matches a valid unit.
0259        */
0260       bool match_valid_unit(const string_type* k, rt_ratio& rt) const
0261       {
0262         std::size_t index = (k - get_valid_units_start()) / (pfs_ + 1);
0263         switch (index)
0264         {
0265         case 0:
0266           rt = rt_ratio(atto());
0267           break;
0268         case 1:
0269           rt = rt_ratio(femto());
0270           break;
0271         case 2:
0272           rt = rt_ratio(pico());
0273           break;
0274         case 3:
0275           rt = rt_ratio(nano());
0276           break;
0277         case 4:
0278           rt = rt_ratio(micro());
0279           break;
0280         case 5:
0281           rt = rt_ratio(milli());
0282           break;
0283         case 6:
0284           rt = rt_ratio(centi());
0285           break;
0286         case 7:
0287           rt = rt_ratio(deci());
0288           break;
0289         case 8:
0290           rt = rt_ratio(deca());
0291           break;
0292         case 9:
0293           rt = rt_ratio(hecto());
0294           break;
0295         case 10:
0296           rt = rt_ratio(kilo());
0297           break;
0298         case 11:
0299           rt = rt_ratio(mega());
0300           break;
0301         case 12:
0302           rt = rt_ratio(giga());
0303           break;
0304         case 13:
0305           rt = rt_ratio(tera());
0306           break;
0307         case 14:
0308           rt = rt_ratio(peta());
0309           break;
0310         case 15:
0311           rt = rt_ratio(exa());
0312           break;
0313         case 16:
0314           rt = rt_ratio(ratio<1> ());
0315           break;
0316         case 17:
0317           rt = rt_ratio(ratio<60> ());
0318           break;
0319         case 18:
0320           rt = rt_ratio(ratio<3600> ());
0321           break;
0322         default:
0323           return false;
0324         }
0325         return true;
0326       }
0327 
0328       /**
0329        * @return pointer to the start of valid [N/D] units.
0330        */
0331       virtual const string_type* get_n_d_valid_units_start()const
0332       {
0333         return  detail::duration_units_default_holder<CharT>::n_d_valid_units_;
0334       }
0335       /**
0336        * @return pointer to the end of valid [N/D] units.
0337        */
0338       virtual const string_type* get_n_d_valid_units_end()const
0339       {
0340         return detail::duration_units_default_holder<CharT>::n_d_valid_units_ + (pfs_ + 1);
0341       }
0342 
0343       /**
0344        * @return pointer to the start of valid units.
0345        */
0346       virtual const string_type* get_valid_units_start() const
0347       {
0348         return detail::duration_units_default_holder<CharT>::valid_units_;
0349       }
0350       /**
0351        * @return pointer to the end of valid units.
0352        */
0353       virtual const string_type* get_valid_units_end() const
0354       {
0355         return detail::duration_units_default_holder<CharT>::valid_units_ + 19 * (pfs_ + 1);
0356       }
0357 
0358       string_type get_pattern() const
0359       {
0360         static const CharT t[] =
0361         { '%', 'v', ' ', '%', 'u' };
0362         static const string_type pattern(t, t + sizeof (t) / sizeof (t[0]));
0363 
0364         return pattern;
0365       }
0366 
0367     protected:
0368       /**
0369        *
0370        * This facet names the units associated to the following periods:
0371        * atto,femto,pico,nano,micro,milli,centi,deci,ratio<1>,deca,hecto,kilo,mega,giga,tera,peta,exa,ratio<60> and ratio<3600>.
0372        * @return true if the unit associated to the given Period is named, false otherwise.
0373        */
0374       bool do_is_named_unit(rt_ratio rt) const
0375       {
0376         if (rt.num==1) {
0377           switch (rt.den)
0378           {
0379           case BOOST_RATIO_INTMAX_C(1):
0380           case BOOST_RATIO_INTMAX_C(10):
0381           case BOOST_RATIO_INTMAX_C(100):
0382           case BOOST_RATIO_INTMAX_C(1000):
0383           case BOOST_RATIO_INTMAX_C(1000000):
0384           case BOOST_RATIO_INTMAX_C(1000000000):
0385           case BOOST_RATIO_INTMAX_C(1000000000000):
0386           case BOOST_RATIO_INTMAX_C(1000000000000000):
0387           case BOOST_RATIO_INTMAX_C(1000000000000000000):
0388             return true;
0389           default:
0390             return false;
0391           }
0392         } else if (rt.den==1) {
0393           switch (rt.num)
0394           {
0395           case BOOST_RATIO_INTMAX_C(10):
0396           case BOOST_RATIO_INTMAX_C(60):
0397           case BOOST_RATIO_INTMAX_C(100):
0398           case BOOST_RATIO_INTMAX_C(1000):
0399           case BOOST_RATIO_INTMAX_C(3600):
0400           case BOOST_RATIO_INTMAX_C(1000000):
0401           case BOOST_RATIO_INTMAX_C(1000000000):
0402           case BOOST_RATIO_INTMAX_C(1000000000000):
0403           case BOOST_RATIO_INTMAX_C(1000000000000000):
0404           case BOOST_RATIO_INTMAX_C(1000000000000000000):
0405             return true;
0406           default:
0407             return false;
0408           }
0409         }
0410         return false;
0411 
0412       }
0413 
0414       /**
0415        * In English the suffix used after [N/D] is the one associated to the period ratio<1>.
0416        * @return the [N/D] suffix unit associated to this duration.
0417        */
0418       string_type do_get_n_d_unit(duration_style style, rt_ratio, intmax_t v) const
0419       {
0420         return do_get_unit(style, ratio<1>(), do_get_plural_form(v));
0421       }
0422 
0423       /**
0424        * @return the unit associated to this duration if it is named, "" otherwise.
0425        */
0426       string_type do_get_unit(duration_style style, rt_ratio rt, intmax_t v) const
0427       {
0428         if (rt.num==1) {
0429           switch (rt.den)
0430           {
0431           case BOOST_RATIO_INTMAX_C(1):
0432             return do_get_unit(style, ratio<1>(), do_get_plural_form(v));
0433           case BOOST_RATIO_INTMAX_C(10):
0434             return do_get_unit(style, deci(), do_get_plural_form(v));
0435           case BOOST_RATIO_INTMAX_C(100):
0436             return do_get_unit(style, centi(), do_get_plural_form(v));
0437           case BOOST_RATIO_INTMAX_C(1000):
0438             return do_get_unit(style, milli(), do_get_plural_form(v));
0439           case BOOST_RATIO_INTMAX_C(1000000):
0440             return do_get_unit(style, micro(), do_get_plural_form(v));
0441           case BOOST_RATIO_INTMAX_C(1000000000):
0442             return do_get_unit(style, nano(), do_get_plural_form(v));
0443           case BOOST_RATIO_INTMAX_C(1000000000000):
0444             return do_get_unit(style, pico(), do_get_plural_form(v));
0445           case BOOST_RATIO_INTMAX_C(1000000000000000):
0446             return do_get_unit(style, femto(), do_get_plural_form(v));
0447           case BOOST_RATIO_INTMAX_C(1000000000000000000):
0448             return do_get_unit(style, atto(), do_get_plural_form(v));
0449           default:
0450             ;
0451           }
0452         } else if (rt.den==1) {
0453           switch (rt.num)
0454           {
0455           case BOOST_RATIO_INTMAX_C(10):
0456              return do_get_unit(style, deca(), do_get_plural_form(v));
0457           case BOOST_RATIO_INTMAX_C(60):
0458             return do_get_unit(style, ratio<60>(), do_get_plural_form(v));
0459           case BOOST_RATIO_INTMAX_C(100):
0460              return do_get_unit(style, hecto(), do_get_plural_form(v));
0461            case BOOST_RATIO_INTMAX_C(1000):
0462              return do_get_unit(style, kilo(), do_get_plural_form(v));
0463            case BOOST_RATIO_INTMAX_C(3600):
0464              return do_get_unit(style, ratio<3600>(), do_get_plural_form(v));
0465            case BOOST_RATIO_INTMAX_C(1000000):
0466              return do_get_unit(style, mega(), do_get_plural_form(v));
0467            case BOOST_RATIO_INTMAX_C(1000000000):
0468              return do_get_unit(style, giga(), do_get_plural_form(v));
0469            case BOOST_RATIO_INTMAX_C(1000000000000):
0470              return do_get_unit(style, tera(), do_get_plural_form(v));
0471            case BOOST_RATIO_INTMAX_C(1000000000000000):
0472              return do_get_unit(style, peta(), do_get_plural_form(v));
0473            case BOOST_RATIO_INTMAX_C(1000000000000000000):
0474              return do_get_unit(style, exa(), do_get_plural_form(v));
0475            default:
0476              ;
0477            }
0478         }
0479         BOOST_ASSERT(false&&"ratio parameter can not be translated");
0480         //throw "exception";
0481         return string_type();
0482       }
0483 
0484     protected:
0485       /**
0486        * @return the number of associated plural forms this facet manages.
0487        */
0488       virtual std::size_t do_get_plural_forms() const
0489       {
0490         return static_get_plural_forms();
0491       }
0492       static std::size_t static_get_plural_forms()
0493       {
0494         return pfs_;
0495       }
0496       /**
0497        * Gets the associated plural form.
0498        * @param value the duration representation
0499        * @return the plural form associated to the @c value parameter. In English there are 2 plural forms
0500        * 0 singular (-1 or 1)
0501        * 1 plural for all others
0502        */
0503       virtual std::size_t do_get_plural_form(int_least64_t value) const
0504       {
0505         return static_get_plural_form(value);
0506       }
0507       static std::size_t static_get_plural_form(int_least64_t value)
0508       {
0509         return (value == -1 || value == 1) ? 0 : 1;
0510       }
0511 
0512       /**
0513        * @param style the duration style.
0514        * @param period the period associated to the duration seconds.
0515        * @param pf the requested plural form.
0516        * @return if style is symbol returns "s", otherwise if pf is 0 return "second", if pf is 1 "seconds"
0517        */
0518       virtual string_type do_get_unit(duration_style style, ratio<1> u, std::size_t pf) const
0519       {
0520         return static_get_unit(style,u,pf);
0521       }
0522       static string_type static_get_unit(duration_style style, ratio<1> , std::size_t pf)
0523       {
0524         static const CharT t[] =
0525         { 's' };
0526         static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
0527         static const CharT u[] =
0528         { 's', 'e', 'c', 'o', 'n', 'd' };
0529         static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
0530         static const CharT v[] =
0531         { 's', 'e', 'c', 'o', 'n', 'd', 's' };
0532         static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
0533 
0534         if (style == duration_style::symbol)
0535         {
0536           return symbol;
0537         }
0538         if (pf == 0)
0539         {
0540           return singular;
0541         }
0542         if (pf == 1)
0543         {
0544           return plural;
0545         }
0546         BOOST_ASSERT(false&&"style/pf parameters not valid");
0547         //throw "exception";
0548         return string_type();
0549       }
0550 
0551       /**
0552        * @param style the duration style.
0553        * @param period the period associated to the duration minutes.
0554        * @param pf the requested plural form.
0555        * @return if style is symbol returns "min", otherwise if pf is 0 return "minute", if pf is 1 "minutes"
0556        */
0557       virtual string_type do_get_unit(duration_style style, ratio<60> u, std::size_t pf) const
0558       {
0559         return static_get_unit(style,u,pf);
0560       }
0561       static string_type static_get_unit(duration_style style, ratio<60> , std::size_t pf)
0562       {
0563         static const CharT t[] =
0564         { 'm', 'i', 'n' };
0565         static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
0566 
0567         static const CharT u[] =
0568         { 'm', 'i', 'n', 'u', 't', 'e' };
0569         static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
0570         static const CharT v[] =
0571         { 'm', 'i', 'n', 'u', 't', 'e', 's' };
0572         static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
0573 
0574         if (style == duration_style::symbol) return symbol;
0575         if (pf == 0) return singular;
0576         if (pf == 1) return plural;
0577         BOOST_ASSERT(false&&"style/pf parameters not valid");
0578         //throw "exception";
0579         return string_type();
0580 
0581       }
0582 
0583       /**
0584        * @param style the duration style.
0585        * @param period the period associated to the duration hours.
0586        * @param pf the requested plural form.
0587        * @return if style is symbol returns "h", otherwise if pf is 0 return "hour", if pf is 1 "hours"
0588        */
0589       virtual string_type do_get_unit(duration_style style, ratio<3600> u, std::size_t pf) const
0590       {
0591         return static_get_unit(style,u,pf);
0592       }
0593       static string_type static_get_unit(duration_style style, ratio<3600> , std::size_t pf)
0594       {
0595         static const CharT t[] =
0596         { 'h' };
0597         static const string_type symbol(t, t + sizeof (t) / sizeof (t[0]));
0598         static const CharT u[] =
0599         { 'h', 'o', 'u', 'r' };
0600         static const string_type singular(u, u + sizeof (u) / sizeof (u[0]));
0601         static const CharT v[] =
0602         { 'h', 'o', 'u', 'r', 's' };
0603         static const string_type plural(v, v + sizeof (v) / sizeof (v[0]));
0604 
0605         if (style == duration_style::symbol) return symbol;
0606         if (pf == 0) return singular;
0607         if (pf == 1) return plural;
0608         BOOST_ASSERT(false&&"style/pf parameters not valid");
0609         //throw "exception";
0610         return string_type();
0611 
0612       }
0613       /**
0614        * @param style the duration style.
0615        * @param u the period tag atto.
0616        * @param pf the requested plural form.
0617        * @return the concatenation of the prefix associated to @c period + the one associated to seconds.
0618        */
0619       virtual string_type do_get_unit(duration_style style, atto u, std::size_t pf) const
0620       {
0621         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0622       }
0623       static string_type static_get_unit(duration_style style, atto u, std::size_t pf)
0624       {
0625         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0626       }
0627       /**
0628        * @param style the duration style.
0629        * @param u the period tag femto.
0630        * @param pf the requested plural form.
0631        * @return the concatenation of the prefix associated to period @c u + the one associated to seconds.
0632        */
0633       virtual string_type do_get_unit(duration_style style, femto u, std::size_t pf) const
0634       {
0635         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0636       }
0637       static string_type static_get_unit(duration_style style, femto u, std::size_t pf)
0638       {
0639         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0640       }
0641       /**
0642        * @param style the duration style.
0643        * @param u the period tag femto.
0644        * @param pf the requested plural form.
0645        * @return the concatenation of the prefix associated to period @c u + the one associated to seconds.
0646        */
0647       virtual string_type do_get_unit(duration_style style, pico u, std::size_t pf) const
0648       {
0649         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0650       }
0651       static string_type static_get_unit(duration_style style, pico u, std::size_t pf)
0652       {
0653         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0654       }
0655       virtual string_type do_get_unit(duration_style style, nano u, std::size_t pf) const
0656       {
0657         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0658       }
0659       static string_type static_get_unit(duration_style style, nano u, std::size_t pf)
0660       {
0661         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0662       }
0663       virtual string_type do_get_unit(duration_style style, micro u, std::size_t pf) const
0664       {
0665         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0666       }
0667       static string_type static_get_unit(duration_style style, micro u, std::size_t pf)
0668       {
0669         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0670       }
0671       virtual string_type do_get_unit(duration_style style, milli u, std::size_t pf) const
0672       {
0673         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0674       }
0675       static string_type static_get_unit(duration_style style, milli u, std::size_t pf)
0676       {
0677         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0678       }
0679       virtual string_type do_get_unit(duration_style style, centi u, std::size_t pf) const
0680       {
0681         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0682       }
0683       static string_type static_get_unit(duration_style style, centi u, std::size_t pf)
0684       {
0685         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0686       }
0687       virtual string_type do_get_unit(duration_style style, deci u, std::size_t pf) const
0688       {
0689         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0690       }
0691       static string_type static_get_unit(duration_style style, deci u, std::size_t pf)
0692       {
0693         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0694       }
0695       virtual string_type do_get_unit(duration_style style, deca u, std::size_t pf) const
0696       {
0697         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0698       }
0699       static string_type static_get_unit(duration_style style, deca u, std::size_t pf)
0700       {
0701         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0702       }
0703       virtual string_type do_get_unit(duration_style style, hecto u, std::size_t pf) const
0704       {
0705         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0706       }
0707       static string_type static_get_unit(duration_style style, hecto u, std::size_t pf)
0708       {
0709         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0710       }
0711       virtual string_type do_get_unit(duration_style style, kilo u, std::size_t pf) const
0712       {
0713         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0714       }
0715       static string_type static_get_unit(duration_style style, kilo u, std::size_t pf)
0716       {
0717         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0718       }
0719       virtual string_type do_get_unit(duration_style style, mega u, std::size_t pf) const
0720       {
0721         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0722       }
0723       static string_type static_get_unit(duration_style style, mega u, std::size_t pf)
0724       {
0725         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0726       }
0727       virtual string_type do_get_unit(duration_style style, giga u, std::size_t pf) const
0728       {
0729         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0730       }
0731       static string_type static_get_unit(duration_style style, giga u, std::size_t pf)
0732       {
0733         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0734       }
0735       virtual string_type do_get_unit(duration_style style, tera u, std::size_t pf) const
0736       {
0737         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0738       }
0739       static string_type static_get_unit(duration_style style, tera u, std::size_t pf)
0740       {
0741         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0742       }
0743       virtual string_type do_get_unit(duration_style style, peta u, std::size_t pf) const
0744       {
0745         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0746       }
0747       static string_type static_get_unit(duration_style style, peta u, std::size_t pf)
0748       {
0749         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0750       }
0751       virtual string_type do_get_unit(duration_style style, exa u, std::size_t pf) const
0752       {
0753         return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf);
0754       }
0755       static string_type static_get_unit(duration_style style, exa u, std::size_t pf)
0756       {
0757         return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf);
0758       }
0759 
0760     protected:
0761 
0762       /**
0763        * @param style the duration style.
0764        * @param u the period tag atto.
0765        * @return depending on the value of @c style return the ratio_string symbol or prefix.
0766        */
0767       virtual string_type do_get_ratio_prefix(duration_style style, atto u) const
0768       {
0769         return static_get_ratio_prefix(style, u);
0770       }
0771       static string_type static_get_ratio_prefix(duration_style style, atto)
0772       {
0773         if (style == duration_style::symbol) return ratio_string<atto, CharT>::symbol();
0774         return ratio_string<atto, CharT>::prefix();
0775       }
0776       virtual string_type do_get_ratio_prefix(duration_style style, femto u) const
0777       {
0778         return static_get_ratio_prefix(style, u);
0779       }
0780       static string_type static_get_ratio_prefix(duration_style style, femto)
0781       {
0782         if (style == duration_style::symbol) return ratio_string<femto, CharT>::symbol();
0783         return ratio_string<femto, CharT>::prefix();
0784       }
0785       virtual string_type do_get_ratio_prefix(duration_style style, pico u) const
0786       {
0787         return static_get_ratio_prefix(style, u);
0788       }
0789       static string_type static_get_ratio_prefix(duration_style style, pico)
0790       {
0791         if (style == duration_style::symbol) return ratio_string<pico, CharT>::symbol();
0792         return ratio_string<pico, CharT>::prefix();
0793       }
0794       virtual string_type do_get_ratio_prefix(duration_style style, nano u) const
0795       {
0796         return static_get_ratio_prefix(style, u);
0797       }
0798       static string_type static_get_ratio_prefix(duration_style style, nano)
0799       {
0800         if (style == duration_style::symbol) return ratio_string<nano, CharT>::symbol();
0801         return ratio_string<nano, CharT>::prefix();
0802       }
0803       virtual string_type do_get_ratio_prefix(duration_style style, micro u) const
0804       {
0805         return static_get_ratio_prefix(style, u);
0806       }
0807       static string_type static_get_ratio_prefix(duration_style style, micro)
0808       {
0809         if (style == duration_style::symbol) return ratio_string<micro, CharT>::symbol();
0810         return ratio_string<micro, CharT>::prefix();
0811       }
0812       virtual string_type do_get_ratio_prefix(duration_style style, milli u) const
0813       {
0814         return static_get_ratio_prefix(style, u);
0815       }
0816       static string_type static_get_ratio_prefix(duration_style style, milli)
0817       {
0818         if (style == duration_style::symbol) return ratio_string<milli, CharT>::symbol();
0819         return ratio_string<milli, CharT>::prefix();
0820       }
0821       virtual string_type do_get_ratio_prefix(duration_style style, centi u) const
0822       {
0823         return static_get_ratio_prefix(style, u);
0824       }
0825       static string_type static_get_ratio_prefix(duration_style style, centi)
0826       {
0827         if (style == duration_style::symbol) return ratio_string<centi, CharT>::symbol();
0828         return ratio_string<centi, CharT>::prefix();
0829       }
0830       virtual string_type do_get_ratio_prefix(duration_style style, deci u) const
0831       {
0832         return static_get_ratio_prefix(style, u);
0833       }
0834       static string_type static_get_ratio_prefix(duration_style style, deci)
0835       {
0836         if (style == duration_style::symbol) return ratio_string<deci, CharT>::symbol();
0837         return ratio_string<deci, CharT>::prefix();
0838       }
0839       virtual string_type do_get_ratio_prefix(duration_style style, deca u) const
0840       {
0841         return static_get_ratio_prefix(style, u);
0842       }
0843       static string_type static_get_ratio_prefix(duration_style style, deca)
0844       {
0845         if (style == duration_style::symbol) return ratio_string<deca, CharT>::symbol();
0846         return ratio_string<deca, CharT>::prefix();
0847       }
0848       virtual string_type do_get_ratio_prefix(duration_style style, hecto u) const
0849       {
0850         return static_get_ratio_prefix(style, u);
0851       }
0852       static string_type static_get_ratio_prefix(duration_style style, hecto)
0853       {
0854         if (style == duration_style::symbol) return ratio_string<hecto, CharT>::symbol();
0855         return ratio_string<hecto, CharT>::prefix();
0856       }
0857       virtual string_type do_get_ratio_prefix(duration_style style, kilo u) const
0858       {
0859         return static_get_ratio_prefix(style, u);
0860       }
0861       static string_type static_get_ratio_prefix(duration_style style, kilo)
0862       {
0863         if (style == duration_style::symbol) return ratio_string<kilo, CharT>::symbol();
0864         return ratio_string<kilo, CharT>::prefix();
0865       }
0866       virtual string_type do_get_ratio_prefix(duration_style style, mega u) const
0867       {
0868         return static_get_ratio_prefix(style, u);
0869       }
0870       static string_type static_get_ratio_prefix(duration_style style, mega)
0871       {
0872         if (style == duration_style::symbol) return ratio_string<mega, CharT>::symbol();
0873         return ratio_string<mega, CharT>::prefix();
0874       }
0875       virtual string_type do_get_ratio_prefix(duration_style style, giga u) const
0876       {
0877         return static_get_ratio_prefix(style, u);
0878       }
0879       static string_type static_get_ratio_prefix(duration_style style, giga)
0880       {
0881         if (style == duration_style::symbol) return ratio_string<giga, CharT>::symbol();
0882         return ratio_string<giga, CharT>::prefix();
0883       }
0884       virtual string_type do_get_ratio_prefix(duration_style style, tera u) const
0885       {
0886         return static_get_ratio_prefix(style, u);
0887       }
0888       static string_type static_get_ratio_prefix(duration_style style, tera)
0889       {
0890         if (style == duration_style::symbol) return ratio_string<tera, CharT>::symbol();
0891         return ratio_string<tera, CharT>::prefix();
0892       }
0893       virtual string_type do_get_ratio_prefix(duration_style style, peta u) const
0894       {
0895         return static_get_ratio_prefix(style, u);
0896       }
0897       static string_type static_get_ratio_prefix(duration_style style, peta)
0898       {
0899         if (style == duration_style::symbol) return ratio_string<peta, CharT>::symbol();
0900         return ratio_string<peta, CharT>::prefix();
0901       }
0902       virtual string_type do_get_ratio_prefix(duration_style style, exa u) const
0903       {
0904         return static_get_ratio_prefix(style, u);
0905       }
0906       static string_type static_get_ratio_prefix(duration_style style, exa)
0907       {
0908         if (style == duration_style::symbol) return ratio_string<exa, CharT>::symbol();
0909         return ratio_string<exa, CharT>::prefix();
0910       }
0911 
0912     protected:
0913       template <typename Period>
0914       string_type* fill_units(string_type* it, Period) const
0915       {
0916         std::size_t pfs = do_get_plural_forms();
0917         for (std::size_t pf = 0; pf < pfs; ++pf)
0918         {
0919           *it++ = do_get_unit(duration_style::prefix, Period(), pf);
0920         }
0921         *it++ = do_get_unit(duration_style::symbol, Period(), 0);
0922         return it;
0923       }
0924     public:
0925       template <typename Period>
0926       static string_type* static_fill_units(string_type* it, Period)
0927       {
0928         std::size_t pfs = static_get_plural_forms();
0929         for (std::size_t pf = 0; pf < pfs; ++pf)
0930         {
0931           *it++ = static_get_unit(duration_style::prefix, Period(), pf);
0932         }
0933         *it++ = static_get_unit(duration_style::symbol, Period(), 0);
0934         return it;
0935       }
0936       static string_type* static_init_valid_units(string_type* it)
0937       {
0938         it = static_fill_units(it, atto());
0939         it = static_fill_units(it, femto());
0940         it = static_fill_units(it, pico());
0941         it = static_fill_units(it, nano());
0942         it = static_fill_units(it, micro());
0943         it = static_fill_units(it, milli());
0944         it = static_fill_units(it, centi());
0945         it = static_fill_units(it, deci());
0946         it = static_fill_units(it, deca());
0947         it = static_fill_units(it, hecto());
0948         it = static_fill_units(it, kilo());
0949         it = static_fill_units(it, mega());
0950         it = static_fill_units(it, giga());
0951         it = static_fill_units(it, tera());
0952         it = static_fill_units(it, peta());
0953         it = static_fill_units(it, exa());
0954         it = static_fill_units(it, ratio<1> ());
0955         it = static_fill_units(it, ratio<60> ());
0956         it = static_fill_units(it, ratio<3600> ());
0957         return it;
0958       }
0959     };
0960 
0961     namespace detail
0962     {
0963 
0964       template<typename CharT>
0965       struct duration_units_default_initializer_t
0966       {
0967         duration_units_default_initializer_t()
0968           {
0969               if (!duration_units_default_holder<CharT>::initialized_)
0970               {
0971                 typedef typename duration_units_default_holder<CharT>::string_type string_type;
0972                 duration_units_default_holder<CharT>::n_d_valid_units_ = new string_type[3];
0973                 duration_units_default_holder<CharT>::valid_units_ = new string_type[19 * 3];
0974 
0975                 string_type* it = duration_units_default_holder<CharT>::n_d_valid_units_;
0976                 it = duration_units_default<CharT>::static_fill_units(it, ratio<1> ());
0977                 it = duration_units_default<CharT>::static_init_valid_units(duration_units_default_holder<CharT>::valid_units_);
0978 
0979                 duration_units_default_holder<CharT>::initialized_ = true;
0980               }
0981           }
0982         ~duration_units_default_initializer_t()
0983           {
0984             if (duration_units_default_holder<CharT>::initialized_)
0985             {
0986               delete[] duration_units_default_holder<CharT>::n_d_valid_units_;
0987               duration_units_default_holder<CharT>::n_d_valid_units_ = BOOST_NULLPTR;
0988               delete[] duration_units_default_holder<CharT>::valid_units_;
0989               duration_units_default_holder<CharT>::valid_units_ = BOOST_NULLPTR;
0990               duration_units_default_holder<CharT>::initialized_ = false;
0991             }
0992         }
0993       };
0994       namespace /**/
0995       {
0996         duration_units_default_initializer_t<char> duration_units_default_initializer;
0997         duration_units_default_initializer_t<wchar_t> wduration_units_default_initializer;
0998       } // namespace
0999     }
1000   } // chrono
1001 
1002 } // boost
1003 
1004 #endif  // header