Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:24

0001 
0002 #ifndef DATETIME_PERIOD_FORMATTER_HPP___
0003 #define DATETIME_PERIOD_FORMATTER_HPP___
0004 
0005 /* Copyright (c) 2002-2004 CrystalClear Software, Inc.
0006  * Use, modification and distribution is subject to the
0007  * Boost Software License, Version 1.0. (See accompanying
0008  * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
0009  * Author: Jeff Garland, Bart Garst
0010  * $Date$
0011  */
0012 
0013 #include <iosfwd>
0014 #include <string>
0015 #include <vector>
0016 #include <iterator>
0017 
0018 namespace boost { namespace date_time {
0019 
0020 
0021   //! Not a facet, but a class used to specify and control period formats
0022   /*! Provides settings for the following:
0023    *   - period_separator -- default '/'
0024    *   - period_open_start_delimeter -- default '['
0025    *   - period_open_range_end_delimeter -- default ')'
0026    *   - period_closed_range_end_delimeter -- default ']'
0027    *   - display_as_open_range, display_as_closed_range -- default closed_range
0028    *
0029    *  Thus the default formatting for a period is as follows:
0030    *@code
0031    *  [period.start()/period.last()]
0032    *@endcode
0033    *  So for a typical date_period this would be
0034    *@code
0035    *  [2004-Jan-04/2004-Feb-01]
0036    *@endcode
0037    * where the date formatting is controlled by the date facet
0038    */
0039   template <class CharT, class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
0040   class period_formatter {
0041   public:
0042     typedef std::basic_string<CharT> string_type;
0043     typedef CharT                    char_type;
0044     typedef typename std::basic_string<char_type>::const_iterator const_itr_type;
0045     typedef std::vector<std::basic_string<CharT> > collection_type;
0046 
0047     static const char_type default_period_separator[2];
0048     static const char_type default_period_start_delimeter[2];
0049     static const char_type default_period_open_range_end_delimeter[2];
0050     static const char_type default_period_closed_range_end_delimeter[2];
0051 
0052     enum range_display_options { AS_OPEN_RANGE, AS_CLOSED_RANGE };
0053 
0054     //! Constructor that sets up period formatter options -- default should suffice most cases.
0055     period_formatter(range_display_options range_option_in = AS_CLOSED_RANGE,
0056                      const char_type* const period_separator = default_period_separator,
0057                      const char_type* const period_start_delimeter = default_period_start_delimeter,
0058                      const char_type* const period_open_range_end_delimeter = default_period_open_range_end_delimeter,
0059                      const char_type* const period_closed_range_end_delimeter = default_period_closed_range_end_delimeter) :
0060       m_range_option(range_option_in),
0061       m_period_separator(period_separator),
0062       m_period_start_delimeter(period_start_delimeter),
0063       m_open_range_end_delimeter(period_open_range_end_delimeter),
0064       m_closed_range_end_delimeter(period_closed_range_end_delimeter)
0065     {}
0066 
0067     //! Puts the characters between period elements into stream -- default is /
0068     OutItrT put_period_separator(OutItrT& oitr) const
0069     {
0070       const_itr_type ci = m_period_separator.begin();
0071       while (ci != m_period_separator.end()) {
0072         *oitr = *ci;
0073         ci++;
0074       }
0075       return oitr;
0076     }
0077 
0078     //! Puts the period start characters into stream -- default is [
0079     OutItrT put_period_start_delimeter(OutItrT& oitr) const
0080     {
0081       const_itr_type ci = m_period_start_delimeter.begin();
0082       while (ci != m_period_start_delimeter.end()) {
0083         *oitr = *ci;
0084         ci++;
0085       }
0086       return oitr;
0087     }
0088 
0089     //! Puts the period end characters into stream as controled by open/closed range setting.
0090     OutItrT put_period_end_delimeter(OutItrT& oitr) const
0091     {
0092 
0093       const_itr_type ci, end;
0094       if (m_range_option == AS_OPEN_RANGE) {
0095         ci = m_open_range_end_delimeter.begin();
0096         end = m_open_range_end_delimeter.end();
0097       }
0098       else {
0099         ci = m_closed_range_end_delimeter.begin();
0100         end = m_closed_range_end_delimeter.end();
0101       }
0102       while (ci != end) {
0103         *oitr = *ci;
0104         ci++;
0105       }
0106       return oitr;
0107     }
0108 
0109     range_display_options range_option() const
0110     {
0111       return m_range_option;
0112     }
0113 
0114     //! Reset the range_option control
0115     void
0116     range_option(range_display_options option) const
0117     {
0118       m_range_option = option;
0119     }
0120 
0121     //! Change the delimiter strings
0122     void delimiter_strings(const string_type& separator,
0123                            const string_type& start_delim,
0124                            const string_type& open_end_delim,
0125                            const string_type& closed_end_delim)
0126     {
0127         m_period_separator = separator;
0128         m_period_start_delimeter = start_delim;
0129         m_open_range_end_delimeter = open_end_delim;
0130         m_closed_range_end_delimeter = closed_end_delim;
0131     }
0132 
0133     //! Generic code to output a period -- no matter the period type.
0134     /*! This generic code will output any period using a facet to
0135      *  to output the 'elements'.  For example, in the case of a date_period
0136      *  the elements will be instances of a date which will be formatted
0137      *  according the to setup in the passed facet parameter.
0138      *
0139      *  The steps for formatting a period are always the same:
0140      *  - put the start delimiter
0141      *  - put start element
0142      *  - put the separator
0143      *  - put either last or end element depending on range settings
0144      *  - put end delimeter depending on range settings
0145      *
0146      *  Thus for a typical date period the result might look like this:
0147      *@code
0148      *
0149      *    [March 01, 2004/June 07, 2004]   <-- closed range
0150      *    [March 01, 2004/June 08, 2004)   <-- open range
0151      *
0152      *@endcode
0153      */
0154     template<class period_type, class facet_type>
0155     OutItrT put_period(OutItrT next,
0156                        std::ios_base& a_ios,
0157                        char_type a_fill,
0158                        const period_type& p,
0159                        const facet_type& facet) const {
0160       put_period_start_delimeter(next);
0161       next = facet.put(next, a_ios, a_fill, p.begin());
0162       put_period_separator(next);
0163       if (m_range_option == AS_CLOSED_RANGE) {
0164         facet.put(next, a_ios, a_fill, p.last());
0165       }
0166       else {
0167         facet.put(next, a_ios, a_fill, p.end());
0168       }
0169       put_period_end_delimeter(next);
0170       return next;
0171     }
0172 
0173 
0174   private:
0175     range_display_options m_range_option;
0176     string_type m_period_separator;
0177     string_type m_period_start_delimeter;
0178     string_type m_open_range_end_delimeter;
0179     string_type m_closed_range_end_delimeter;
0180   };
0181 
0182   template <class CharT, class OutItrT>
0183   const typename period_formatter<CharT, OutItrT>::char_type
0184   period_formatter<CharT, OutItrT>::default_period_separator[2] = {'/'};
0185 
0186   template <class CharT, class OutItrT>
0187   const typename period_formatter<CharT, OutItrT>::char_type
0188   period_formatter<CharT, OutItrT>::default_period_start_delimeter[2] = {'['};
0189 
0190   template <class CharT, class OutItrT>
0191   const typename period_formatter<CharT, OutItrT>::char_type
0192   period_formatter<CharT, OutItrT>::default_period_open_range_end_delimeter[2] = {')'};
0193 
0194   template <class CharT, class OutItrT>
0195   const typename period_formatter<CharT, OutItrT>::char_type
0196   period_formatter<CharT, OutItrT>::default_period_closed_range_end_delimeter[2] = {']'};
0197 
0198  } } //namespace boost::date_time
0199 
0200 #endif