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 /**
0009  * Duration formatting facet for output.
0010  */
0011 #ifndef BOOST_CHRONO_IO_DURATION_PUT_HPP
0012 #define BOOST_CHRONO_IO_DURATION_PUT_HPP
0013 
0014 #include <boost/chrono/config.hpp>
0015 #include <boost/chrono/io/duration_units.hpp>
0016 #include <boost/chrono/process_cpu_clocks.hpp>
0017 #include <boost/assert.hpp>
0018 #include <locale>
0019 
0020 namespace boost
0021 {
0022   namespace chrono
0023   {
0024 
0025     namespace detail
0026     {
0027       template <class T>
0028       struct propagate {
0029         typedef T type;
0030       };
0031       template <>
0032       struct propagate<boost::int_least32_t> {
0033         typedef boost::int_least64_t type;
0034       };
0035     }
0036     /**
0037      * @tparam ChatT a character type
0038      * @tparam OutputIterator a model of @c OutputIterator
0039      *
0040      * The @c duration_put facet provides facilities for formatted output of duration values.
0041      * The member function of @c duration_put take a duration and format it into character string representation.
0042      *
0043      */
0044     template <class CharT, class OutputIterator = std::ostreambuf_iterator<CharT> >
0045     class duration_put: public std::locale::facet
0046     {
0047     public:
0048       /**
0049        * Type of character the facet is instantiated on.
0050        */
0051       typedef CharT char_type;
0052       /**
0053        * Type of character string passed to member functions.
0054        */
0055       typedef std::basic_string<CharT> string_type;
0056       /**
0057        * Type of iterator used to write in the character buffer.
0058        */
0059       typedef OutputIterator iter_type;
0060 
0061       /**
0062        * Construct a duration_put facet.
0063        * @param refs
0064        * @Effects Construct a duration_put facet.
0065        * If the @c refs argument is @c 0 then destruction of the object is
0066        * delegated to the @c locale, or locales, containing it. This allows
0067        * the user to ignore lifetime management issues. On the other had,
0068        * if @c refs is @c 1 then the object must be explicitly deleted;
0069        * the @c locale will not do so. In this case, the object can be
0070        * maintained across the lifetime of multiple locales.
0071        */
0072       explicit duration_put(size_t refs = 0) :
0073         std::locale::facet(refs)
0074       {
0075       }
0076 
0077       /**
0078        *
0079        * @param s an output stream iterator
0080        * @param ios a reference to a ios_base
0081        * @param fill the character used as filler
0082        * @param d the duration
0083        * @param pattern begin of the formatting pattern
0084        * @param pat_end end of the formatting pattern
0085        *
0086        * @Effects Steps through the sequence from @c pattern to @c pat_end,
0087        * identifying characters that are part of a pattern sequence. Each character
0088        * that is not part of a pattern sequence is written to @c s immediately, and
0089        * each pattern sequence, as it is identified, results in a call to
0090        * @c put_value or @c put_unit;
0091        * thus, pattern elements and other characters are interleaved in the output
0092        * in the order in which they appear in the pattern. Pattern sequences are
0093        * identified by converting each character @c c to a @c char value as if by
0094        * @c ct.narrow(c,0), where @c ct is a reference to @c ctype<charT> obtained from
0095        * @c ios.getloc(). The first character of each sequence is equal to @c '%',
0096        * followed by a pattern specifier character @c spec, which can be @c 'v' for
0097        * the duration value or @c 'u' for the duration unit. .
0098        * For each valid pattern sequence identified, calls
0099        * <c>put_value(s, ios, fill, d)</c> or <c>put_unit(s, ios, fill, d)</c>.
0100        *
0101        * @Returns An iterator pointing immediately after the last character produced.
0102        */
0103       template <typename Rep, typename Period>
0104       iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d, const CharT* pattern,
0105           const CharT* pat_end, const char_type* val = BOOST_NULLPTR) const
0106       {
0107         if (std::has_facet<duration_units<CharT> >(ios.getloc()))
0108         {
0109           duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
0110               ios.getloc());
0111           return put(facet, s, ios, fill, d, pattern, pat_end, val);
0112         }
0113         else
0114         {
0115           duration_units_default<CharT> facet;
0116           return put(facet, s, ios, fill, d, pattern, pat_end, val);
0117         }
0118       }
0119 
0120       template <typename Rep, typename Period>
0121       iter_type put(duration_units<CharT> const& units_facet, iter_type s, std::ios_base& ios, char_type fill,
0122           duration<Rep, Period> const& d, const CharT* pattern, const CharT* pat_end, const char_type* val = BOOST_NULLPTR) const
0123       {
0124 
0125         const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
0126         for (; pattern != pat_end; ++pattern)
0127         {
0128           if (ct.narrow(*pattern, 0) == '%')
0129           {
0130             if (++pattern == pat_end)
0131             {
0132               *s++ = pattern[-1];
0133               break;
0134             }
0135             char fmt = ct.narrow(*pattern, 0);
0136             switch (fmt)
0137             {
0138             case 'v':
0139             {
0140               s = put_value(s, ios, fill, d, val);
0141               break;
0142             }
0143             case 'u':
0144             {
0145               s = put_unit(units_facet, s, ios, fill, d);
0146               break;
0147             }
0148             default:
0149               BOOST_ASSERT(false && "Boost::Chrono internal error.");
0150               break;
0151             }
0152           }
0153           else
0154             *s++ = *pattern;
0155         }
0156         return s;
0157       }
0158 
0159       /**
0160        *
0161        * @param s an output stream iterator
0162        * @param ios a reference to a ios_base
0163        * @param fill the character used as filler
0164        * @param d the duration
0165        * @Effects imbue in @c ios the @c duration_units_default facet if not already present.
0166        * Retrieves Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if
0167        * @code
0168        *   return put(s, ios, d, str.data(), str.data() + str.size());
0169        * @endcode
0170        * @Returns An iterator pointing immediately after the last character produced.
0171        */
0172       template <typename Rep, typename Period>
0173       iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d, const char_type* val = BOOST_NULLPTR) const
0174       {
0175         if (std::has_facet<duration_units<CharT> >(ios.getloc()))
0176         {
0177           duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
0178               ios.getloc());
0179           std::basic_string<CharT> str = facet.get_pattern();
0180           return put(facet, s, ios, fill, d, str.data(), str.data() + str.size(), val);
0181         }
0182         else
0183         {
0184           duration_units_default<CharT> facet;
0185           std::basic_string<CharT> str = facet.get_pattern();
0186 
0187           return put(facet, s, ios, fill, d, str.data(), str.data() + str.size(), val);
0188         }
0189       }
0190 
0191       /**
0192        *
0193        * @param s an output stream iterator
0194        * @param ios a reference to a ios_base
0195        * @param fill the character used as filler
0196        * @param d the duration
0197        * @Effects As if s=std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, static_cast<long int> (d.count())).
0198        * @Returns s, iterator pointing immediately after the last character produced.
0199        */
0200       template <typename Rep, typename Period>
0201       iter_type put_value(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d, const char_type* val = BOOST_NULLPTR) const
0202       {
0203         if (val)
0204         {
0205           while (*val) {
0206             *s = *val;
0207             s++; val++;
0208           }
0209           return s;
0210         }
0211         return std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill,
0212             static_cast<typename detail::propagate<Rep>::type> (d.count()));
0213       }
0214 
0215       template <typename Rep, typename Period>
0216       iter_type put_value(iter_type s, std::ios_base& ios, char_type fill, duration<process_times<Rep>, Period> const& d, const char_type* = BOOST_NULLPTR) const
0217       {
0218         *s++ = CharT('{');
0219         s = put_value(s, ios, fill, process_real_cpu_clock::duration(d.count().real));
0220         *s++ = CharT(';');
0221         s = put_value(s, ios, fill, process_user_cpu_clock::duration(d.count().user));
0222         *s++ = CharT(';');
0223         s = put_value(s, ios, fill, process_system_cpu_clock::duration(d.count().system));
0224         *s++ = CharT('}');
0225         return s;
0226       }
0227 
0228       /**
0229        *
0230        * @param s an output stream iterator
0231        * @param ios a reference to a ios_base
0232        * @param fill the character used as filler
0233        * @param d the duration
0234        * @Effects Let facet be the duration_units<CharT> facet associated to ios. If the associated unit is named,
0235        * as if
0236        * @code
0237           string_type str = facet.get_unit(get_duration_style(ios), d);
0238           s=std::copy(str.begin(), str.end(), s);
0239        * @endcode
0240        * Otherwise, format the unit as "[Period::num/Period::den]" followed by the unit associated to [N/D] obtained using facet.get_n_d_unit(get_duration_style(ios), d)
0241        * @Returns s, iterator pointing immediately after the last character produced.
0242        */
0243       template <typename Rep, typename Period>
0244       iter_type put_unit(iter_type s, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d) const
0245       {
0246         if (std::has_facet<duration_units<CharT> >(ios.getloc()))
0247         {
0248           duration_units<CharT> const&facet = std::use_facet<duration_units<CharT> >(
0249               ios.getloc());
0250           return put_unit(facet, s, ios, fill, d);
0251         }
0252         else
0253         {
0254           duration_units_default<CharT> facet;
0255           return put_unit(facet, s, ios, fill, d);
0256         }
0257       }
0258 
0259       template <typename Rep, typename Period>
0260       iter_type put_unit(duration_units<CharT> const& facet, iter_type s, std::ios_base& ios, char_type fill,
0261           duration<Rep, Period> const& d) const
0262       {
0263         if (facet.template is_named_unit<Period>()) {
0264           string_type str = facet.get_unit(get_duration_style(ios), d);
0265           s=std::copy(str.begin(), str.end(), s);
0266         } else {
0267           *s++ = CharT('[');
0268           std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::num);
0269           *s++ = CharT('/');
0270           std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::den);
0271           *s++ = CharT(']');
0272           string_type str = facet.get_n_d_unit(get_duration_style(ios), d);
0273           s=std::copy(str.begin(), str.end(), s);
0274         }
0275         return s;
0276       }
0277       template <typename Rep, typename Period>
0278       iter_type put_unit(duration_units<CharT> const& facet, iter_type s, std::ios_base& ios, char_type fill,
0279           duration<process_times<Rep>, Period> const& d) const
0280       {
0281         duration<Rep,Period> real(d.count().real);
0282         if (facet.template is_named_unit<Period>()) {
0283           string_type str = facet.get_unit(get_duration_style(ios), real);
0284           s=std::copy(str.begin(), str.end(), s);
0285         } else {
0286           *s++ = CharT('[');
0287           std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::num);
0288           *s++ = CharT('/');
0289           std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, Period::den);
0290           *s++ = CharT(']');
0291           string_type str = facet.get_n_d_unit(get_duration_style(ios), real);
0292           s=std::copy(str.begin(), str.end(), s);
0293         }
0294         return s;
0295       }
0296 
0297       /**
0298        * Unique identifier for this type of facet.
0299        */
0300       static std::locale::id id;
0301 
0302       /**
0303        * @Effects Destroy the facet
0304        */
0305       ~duration_put()
0306       {
0307       }
0308 
0309     };
0310 
0311     template <class CharT, class OutputIterator>
0312     std::locale::id duration_put<CharT, OutputIterator>::id;
0313 
0314   } // chrono
0315 } // boost
0316 
0317 #endif  // header