Back to home page

EIC code displayed by LXR

 
 

    


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

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_TIME_POINT_PUT_HPP
0012 #define BOOST_CHRONO_IO_TIME_POINT_PUT_HPP
0013 
0014 #include <boost/chrono/config.hpp>
0015 #include <boost/chrono/io/time_point_units.hpp>
0016 #include <boost/chrono/io/duration_put.hpp>
0017 #include <boost/assert.hpp>
0018 #include <locale>
0019 
0020 namespace boost
0021 {
0022   namespace chrono
0023   {
0024 
0025     /**
0026      * @tparam ChatT a character type
0027      * @tparam OutputIterator a model of @c OutputIterator
0028      *
0029      * The @c time_point_put facet provides facilities for formatted output of @c time_point values.
0030      * The member function of @c time_point_put take a @c time_point and format it into character string representation.
0031      *
0032      */
0033     template <class CharT, class OutputIterator = std::ostreambuf_iterator<CharT> >
0034     class time_point_put: public std::locale::facet
0035     {
0036     public:
0037       /**
0038        * Type of character the facet is instantiated on.
0039        */
0040       typedef CharT char_type;
0041       /**
0042        * Type of character string passed to member functions.
0043        */
0044       typedef std::basic_string<CharT> string_type;
0045       /**
0046        * Type of iterator used to write in the character buffer.
0047        */
0048       typedef OutputIterator iter_type;
0049 
0050       /**
0051        * Construct a time_point_put facet.
0052        * @param refs
0053        * @Effects Construct a time_point_put facet.
0054        * If the @c refs argument is @c 0 then destruction of the object is
0055        * delegated to the @c locale, or locales, containing it. This allows
0056        * the user to ignore lifetime management issues. On the other had,
0057        * if @c refs is @c 1 then the object must be explicitly deleted;
0058        * the @c locale will not do so. In this case, the object can be
0059        * maintained across the lifetime of multiple locales.
0060        */
0061       explicit time_point_put(size_t refs = 0) :
0062         std::locale::facet(refs)
0063       {
0064       }
0065 
0066       /**
0067        * @param i an output stream iterator
0068        * @param ios a reference to a ios_base
0069        * @param fill the character used as filler
0070        * @param tp the @c time_point
0071        * @param pattern begin of the formatting pattern
0072        * @param pat_end end of the formatting pattern
0073        *
0074        * @Effects Steps through the sequence from @c pattern to @c pat_end,
0075        * identifying characters that are part of a pattern sequence. Each character
0076        * that is not part of a pattern sequence is written to @c s immediately, and
0077        * each pattern sequence, as it is identified, results in a call to
0078        * @c put_duration or @c put_epoch;
0079        * thus, pattern elements and other characters are interleaved in the output
0080        * in the order in which they appear in the pattern. Pattern sequences are
0081        * identified by converting each character @c c to a @c char value as if by
0082        * @c ct.narrow(c,0), where @c ct is a reference to @c ctype<charT> obtained from
0083        * @c ios.getloc(). The first character of each sequence is equal to @c '%',
0084        * followed by a pattern specifier character @c spec, which can be @c 'd' for
0085        * the duration value or @c 'e' for the epoch.
0086        * For each valid pattern sequence identified, calls
0087        * <c>put_duration(s, ios, fill, tp.time_since_epoch())</c> or <c>put_epoch(s, ios)</c>.
0088        *
0089        * @Returns An iterator pointing immediately after the last character produced.
0090        */
0091 
0092       template <class Clock, class Duration>
0093       iter_type put(iter_type i, std::ios_base& ios, char_type fill, time_point<Clock, Duration> const& tp, const CharT* pattern,
0094           const CharT* pat_end) const
0095       {
0096         if (std::has_facet<time_point_units<CharT> >(ios.getloc()))
0097         {
0098           time_point_units<CharT> const &facet =
0099               std::use_facet<time_point_units<CharT> >(ios.getloc());
0100           return put(facet, i, ios, fill, tp, pattern, pat_end);
0101         }
0102         else
0103         {
0104           time_point_units_default<CharT> facet;
0105           return put(facet, i, ios, fill, tp, pattern, pat_end);
0106         }
0107       }
0108 
0109       template <class Clock, class Duration>
0110       iter_type put(time_point_units<CharT> const& units_facet, iter_type s, std::ios_base& ios, char_type fill,
0111           time_point<Clock, Duration> const& tp, const CharT* pattern, const CharT* pat_end) const
0112       {
0113 
0114         const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(ios.getloc());
0115         for (; pattern != pat_end; ++pattern)
0116         {
0117           if (ct.narrow(*pattern, 0) == '%')
0118           {
0119             if (++pattern == pat_end)
0120             {
0121               *s++ = pattern[-1];
0122               break;
0123             }
0124             char fmt = ct.narrow(*pattern, 0);
0125             switch (fmt)
0126             {
0127             case 'd':
0128             {
0129               s = put_duration(s, ios, fill, tp.time_since_epoch());
0130               break;
0131             }
0132             case 'e':
0133             {
0134               s = put_epoch<Clock> (units_facet, s, ios);
0135               break;
0136             }
0137             default:
0138               BOOST_ASSERT(false && "Boost::Chrono internal error.");
0139               break;
0140             }
0141           }
0142           else
0143             *s++ = *pattern;
0144         }
0145         return s;
0146       }
0147 
0148       /**
0149        * @param i an output stream iterator
0150        * @param ios a reference to a ios_base
0151        * @param fill the character used as filler
0152        * @param tp the @c time_point
0153        * @param pattern begin of the formatting pattern
0154        * @param pat_end end of the formatting pattern
0155        *
0156        * @Effects Stores the time_point pattern from the @c time_point_unit facet in let say @c str. Last as if
0157        * @code
0158        *   return put(s, ios, dill, tp, str.data(), str.data() + str.size());
0159        * @endcode
0160        * @Returns An iterator pointing immediately after the last character produced.
0161        */
0162       template <class Clock, class Duration>
0163       iter_type put(iter_type i, std::ios_base& ios, char_type fill, time_point<Clock, Duration> const& tp) const
0164       {
0165         if (std::has_facet<time_point_units<CharT> >(ios.getloc()))
0166         {
0167           time_point_units<CharT> const &facet =
0168               std::use_facet<time_point_units<CharT> >(ios.getloc());
0169           std::basic_string<CharT> str = facet.get_pattern();
0170           return put(facet, i, ios, fill, tp, str.data(), str.data() + str.size());
0171         }
0172         else
0173         {
0174           time_point_units_default<CharT> facet;
0175           std::basic_string<CharT> str = facet.get_pattern();
0176           return put(facet, i, ios, fill, tp, str.data(), str.data() + str.size());
0177         }
0178       }
0179 
0180       /**
0181        * @param i an output stream iterator
0182        * @param ios a reference to a ios_base
0183        * @param fill the character used as filler
0184        * @param d the @c duration
0185        * @Effects As if <c>facet.put(s, ios, fill, d)</c> where facet is the @c duration_put<CharT> facet associated
0186        * to the @c ios or a new instance of @c duration_put<CharT>.
0187        * @Returns An iterator pointing immediately after the last character produced.
0188        */
0189       template <typename Rep, typename Period>
0190       iter_type put_duration(iter_type i, std::ios_base& ios, char_type fill, duration<Rep, Period> const& d) const
0191       {
0192         if (std::has_facet<duration_put<CharT> >(ios.getloc()))
0193         {
0194           duration_put<CharT> const &facet = std::use_facet<duration_put<CharT> >(ios.getloc());
0195           return facet.put(i, ios, fill, d);
0196         }
0197         else
0198         {
0199           duration_put<CharT> facet;
0200           return facet.put(i, ios, fill, d);
0201         }
0202       }
0203 
0204       /**
0205        *
0206        * @param i an output stream iterator
0207        * @param ios a reference to a ios_base
0208        * @Effects As if
0209        * @code
0210        * string_type str = facet.template get_epoch<Clock>();
0211        * s=std::copy(str.begin(), str.end(), s);
0212        * @endcode
0213        * where facet is the @c time_point_units<CharT> facet associated
0214        * to the @c ios or a new instance of @c time_point_units_default<CharT>.
0215        * @Returns s, iterator pointing immediately after the last character produced.
0216        */
0217 
0218       template <typename Clock>
0219       iter_type put_epoch(iter_type i, std::ios_base& os) const
0220       {
0221         if (std::has_facet<time_point_units<CharT> >(os.getloc()))
0222         {
0223           time_point_units<CharT> const &facet = std::use_facet<time_point_units<CharT> >(os.getloc());
0224           return put_epoch<Clock> (facet, i, os);
0225         }
0226         else
0227         {
0228           time_point_units_default<CharT> facet;
0229           return put_epoch<Clock> (facet, i, os);
0230         }
0231       }
0232 
0233       template <typename Clock>
0234       iter_type put_epoch(time_point_units<CharT> const& facet, iter_type s, std::ios_base&) const
0235       {
0236         string_type str = facet.template get_epoch<Clock>();
0237         s= std::copy(str.begin(), str.end(), s);
0238         return s;
0239       }
0240 
0241       /**
0242        * Unique identifier for this type of facet.
0243        */
0244       static std::locale::id id;
0245 
0246       /**
0247        * @Effects Destroy the facet
0248        */
0249       ~time_point_put()
0250       {
0251       }
0252 
0253     };
0254 
0255     template <class CharT, class OutputIterator>
0256     std::locale::id time_point_put<CharT, OutputIterator>::id;
0257 
0258   } // chrono
0259 } // boost
0260 
0261 #endif  // header