Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:37

0001 #ifndef _DATE_TIME_DATE_FACET__HPP___
0002 #define _DATE_TIME_DATE_FACET__HPP___
0003 
0004 /* Copyright (c) 2004-2005 CrystalClear Software, Inc.
0005  * Use, modification and distribution is subject to the
0006  * Boost Software License, Version 1.0. (See accompanying
0007  * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
0008  * Author:  Martin Andrian, Jeff Garland, Bart Garst
0009  * $Date$
0010  */
0011 
0012 #include <iterator> // ostreambuf_iterator
0013 #include <locale>
0014 #include <string>
0015 #include <vector>
0016 #include <boost/throw_exception.hpp>
0017 #include <boost/algorithm/string/replace.hpp>
0018 #include <boost/date_time/compiler_config.hpp>
0019 #include <boost/date_time/period.hpp>
0020 #include <boost/date_time/special_defs.hpp>
0021 #include <boost/date_time/special_values_formatter.hpp>
0022 #include <boost/date_time/period_formatter.hpp>
0023 #include <boost/date_time/period_parser.hpp>
0024 #include <boost/date_time/date_generator_formatter.hpp>
0025 #include <boost/date_time/date_generator_parser.hpp>
0026 #include <boost/date_time/format_date_parser.hpp>
0027 
0028 namespace boost { namespace date_time {
0029 
0030 
0031   /*! Class that provides format based I/O facet for date types.
0032    *
0033    * This class allows the formatting of dates by using format string.
0034    * Format strings are:
0035    *
0036    *  - %A => long_weekday_format - Full name Ex: Tuesday
0037    *  - %a => short_weekday_format - Three letter abbreviation Ex: Tue
0038    *  - %B => long_month_format - Full name Ex: October
0039    *  - %b => short_month_format - Three letter abbreviation Ex: Oct
0040    *  - %x => standard_format_specifier - defined by the locale
0041    *  - %Y-%b-%d => default_date_format - YYYY-Mon-dd
0042    *
0043    * Default month format == %b
0044    * Default weekday format == %a
0045    */
0046   template <class date_type,
0047             class CharT,
0048             class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
0049   class BOOST_SYMBOL_VISIBLE date_facet : public std::locale::facet {
0050   public:
0051     typedef typename date_type::duration_type duration_type;
0052     // greg_weekday is gregorian_calendar::day_of_week_type
0053     typedef typename date_type::day_of_week_type day_of_week_type;
0054     typedef typename date_type::day_type day_type;
0055     typedef typename date_type::month_type month_type;
0056     typedef boost::date_time::period<date_type,duration_type> period_type;
0057     typedef std::basic_string<CharT> string_type;
0058     typedef CharT                    char_type;
0059     typedef boost::date_time::period_formatter<CharT>  period_formatter_type;
0060     typedef boost::date_time::special_values_formatter<CharT>  special_values_formatter_type;
0061     typedef std::vector<std::basic_string<CharT> > input_collection_type;
0062     // used for the output of the date_generators
0063     typedef date_generator_formatter<date_type, CharT> date_gen_formatter_type;
0064     typedef partial_date<date_type>          partial_date_type;
0065     typedef nth_kday_of_month<date_type>     nth_kday_type;
0066     typedef first_kday_of_month<date_type>   first_kday_type;
0067     typedef last_kday_of_month<date_type>    last_kday_type;
0068     typedef first_kday_after<date_type>      kday_after_type;
0069     typedef first_kday_before<date_type>     kday_before_type;
0070     static const char_type long_weekday_format[3];
0071     static const char_type short_weekday_format[3];
0072     static const char_type long_month_format[3];
0073     static const char_type short_month_format[3];
0074     static const char_type default_period_separator[4];
0075     static const char_type standard_format_specifier[3];
0076     static const char_type iso_format_specifier[7];
0077     static const char_type iso_format_extended_specifier[9];
0078     static const char_type default_date_format[9]; // YYYY-Mon-DD
0079     static std::locale::id id;
0080 
0081 #if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
0082       std::locale::id& __get_id (void) const { return id; }
0083 #endif
0084 
0085     explicit date_facet(::size_t a_ref = 0)
0086       : std::locale::facet(a_ref),
0087         //m_format(standard_format_specifier)
0088         m_format(default_date_format),
0089         m_month_format(short_month_format),
0090         m_weekday_format(short_weekday_format)
0091     {}
0092 
0093     explicit date_facet(const char_type* format_str,
0094                         const input_collection_type& short_names,
0095                         ::size_t ref_count = 0)
0096       : std::locale::facet(ref_count),
0097         m_format(format_str),
0098         m_month_format(short_month_format),
0099         m_weekday_format(short_weekday_format),
0100         m_month_short_names(short_names)
0101     {}
0102 
0103 
0104     explicit date_facet(const char_type* format_str,
0105                         period_formatter_type per_formatter = period_formatter_type(),
0106                         special_values_formatter_type sv_formatter = special_values_formatter_type(),
0107                         date_gen_formatter_type dg_formatter = date_gen_formatter_type(),
0108                         ::size_t ref_count = 0)
0109       : std::locale::facet(ref_count),
0110         m_format(format_str),
0111         m_month_format(short_month_format),
0112         m_weekday_format(short_weekday_format),
0113         m_period_formatter(per_formatter),
0114         m_date_gen_formatter(dg_formatter),
0115         m_special_values_formatter(sv_formatter)
0116      {}
0117     void format(const char_type* const format_str) {
0118       m_format = format_str;
0119     }
0120     virtual void set_iso_format()
0121     {
0122       m_format = iso_format_specifier;
0123     }
0124     virtual void set_iso_extended_format()
0125     {
0126       m_format = iso_format_extended_specifier;
0127     }
0128     void month_format(const char_type* const format_str) {
0129       m_month_format = format_str;
0130     }
0131     void weekday_format(const char_type* const format_str) {
0132       m_weekday_format = format_str;
0133     }
0134 
0135     void period_formatter(period_formatter_type per_formatter) {
0136       m_period_formatter= per_formatter;
0137     }
0138     void special_values_formatter(const special_values_formatter_type& svf)
0139     {
0140       m_special_values_formatter = svf;
0141     }
0142     void short_weekday_names(const input_collection_type& short_names)
0143     {
0144       m_weekday_short_names = short_names;
0145     }
0146     void long_weekday_names(const input_collection_type& long_names)
0147     {
0148       m_weekday_long_names = long_names;
0149     }
0150 
0151     void short_month_names(const input_collection_type& short_names)
0152     {
0153       m_month_short_names = short_names;
0154     }
0155 
0156     void long_month_names(const input_collection_type& long_names)
0157     {
0158       m_month_long_names = long_names;
0159     }
0160 
0161     void date_gen_phrase_strings(const input_collection_type& new_strings,
0162                            typename date_gen_formatter_type::phrase_elements beg_pos=date_gen_formatter_type::first)
0163     {
0164       m_date_gen_formatter.elements(new_strings, beg_pos);
0165     }
0166 
0167     OutItrT put(OutItrT next,
0168                 std::ios_base& a_ios,
0169                 char_type fill_char,
0170                 const date_type& d) const
0171     {
0172       if (d.is_special()) {
0173         return do_put_special(next, a_ios, fill_char, d.as_special());
0174       }
0175       //The following line of code required the date to support a to_tm function
0176       return do_put_tm(next, a_ios, fill_char, to_tm(d), m_format);
0177     }
0178 
0179     OutItrT put(OutItrT next,
0180                 std::ios_base& a_ios,
0181                 char_type fill_char,
0182                 const duration_type& dd) const
0183     {
0184       if (dd.is_special()) {
0185         return do_put_special(next, a_ios, fill_char, dd.get_rep().as_special());
0186       }
0187 
0188       typedef std::num_put<CharT, OutItrT> num_put;
0189       if (std::has_facet<num_put>(a_ios.getloc())) {
0190         return std::use_facet<num_put>(a_ios.getloc()).put(next, a_ios, fill_char, dd.get_rep().as_number());
0191       }
0192       else {
0193         num_put* f = new num_put();
0194         std::locale l = std::locale(a_ios.getloc(), f);
0195         a_ios.imbue(l);
0196         return f->put(next, a_ios, fill_char, dd.get_rep().as_number());
0197       }
0198 
0199     }
0200 
0201 
0202     OutItrT put(OutItrT next,
0203                 std::ios_base& a_ios,
0204                 char_type fill_char,
0205                 const month_type& m) const
0206     {
0207       //if (d.is_special()) {
0208       //  return do_put_special(next, a_ios, fill_char, d.as_special());
0209       //}
0210       //The following line of code required the date to support a to_tm function
0211       std::tm dtm;
0212       std::memset(&dtm, 0, sizeof(dtm));
0213       dtm.tm_mon = m - 1;
0214       return do_put_tm(next, a_ios, fill_char, dtm, m_month_format);
0215     }
0216 
0217     //! puts the day of month
0218     OutItrT put(OutItrT next,
0219                 std::ios_base& a_ios,
0220                 char_type fill_char,
0221                 const day_type& day) const
0222     {
0223       std::tm dtm;
0224       std::memset(&dtm, 0, sizeof(dtm));
0225       dtm.tm_mday = day.as_number();
0226       char_type tmp[3] = {'%','d'};
0227       string_type temp_format(tmp);
0228       return do_put_tm(next, a_ios, fill_char, dtm, temp_format);
0229     }
0230 
0231     OutItrT put(OutItrT next,
0232                 std::ios_base& a_ios,
0233                 char_type fill_char,
0234                 const day_of_week_type& dow) const
0235     {
0236       //if (d.is_special()) {
0237       //  return do_put_special(next, a_ios, fill_char, d.as_special());
0238       //}
0239       //The following line of code required the date to support a to_tm function
0240       std::tm dtm;
0241       std::memset(&dtm, 0, sizeof(dtm));
0242       dtm.tm_wday = dow;
0243       return do_put_tm(next, a_ios, fill_char, dtm, m_weekday_format);
0244     }
0245 
0246 
0247     OutItrT put(OutItrT next,
0248                 std::ios_base& a_ios,
0249                 char_type fill_char,
0250                 const period_type& p) const
0251     {
0252       return m_period_formatter.put_period(next, a_ios, fill_char, p, *this);
0253     }
0254 
0255     OutItrT put(OutItrT next,
0256                 std::ios_base& a_ios,
0257                 char_type fill_char,
0258                 const partial_date_type& pd) const
0259     {
0260       return m_date_gen_formatter.put_partial_date(next, a_ios, fill_char, pd, *this);
0261     }
0262 
0263     OutItrT put(OutItrT next,
0264                 std::ios_base& a_ios,
0265                 char_type fill_char,
0266                 const nth_kday_type& nkd) const
0267     {
0268       return m_date_gen_formatter.put_nth_kday(next, a_ios, fill_char, nkd, *this);
0269     }
0270 
0271     OutItrT put(OutItrT next,
0272                 std::ios_base& a_ios,
0273                 char_type fill_char,
0274                 const first_kday_type& fkd) const
0275     {
0276       return m_date_gen_formatter.put_first_kday(next, a_ios, fill_char, fkd, *this);
0277     }
0278 
0279     OutItrT put(OutItrT next,
0280                 std::ios_base& a_ios,
0281                 char_type fill_char,
0282                 const last_kday_type& lkd) const
0283     {
0284       return m_date_gen_formatter.put_last_kday(next, a_ios, fill_char, lkd, *this);
0285     }
0286 
0287     OutItrT put(OutItrT next,
0288                 std::ios_base& a_ios,
0289                 char_type fill_char,
0290                 const kday_before_type& fkb) const
0291     {
0292       return m_date_gen_formatter.put_kday_before(next, a_ios, fill_char, fkb, *this);
0293     }
0294 
0295     OutItrT put(OutItrT next,
0296                 std::ios_base& a_ios,
0297                 char_type fill_char,
0298                 const kday_after_type& fka) const
0299     {
0300       return m_date_gen_formatter.put_kday_after(next, a_ios, fill_char, fka, *this);
0301     }
0302 
0303   protected:
0304     virtual OutItrT do_put_special(OutItrT next,
0305                                    std::ios_base& /*a_ios*/,
0306                                    char_type /*fill_char*/,
0307                                    const boost::date_time::special_values sv) const
0308     {
0309       m_special_values_formatter.put_special(next, sv);
0310       return next;
0311     }
0312     virtual OutItrT do_put_tm(OutItrT next,
0313                               std::ios_base& a_ios,
0314                               char_type fill_char,
0315                               const tm& tm_value,
0316                               string_type a_format) const
0317     {
0318       // update format string with custom names
0319       if (!m_weekday_long_names.empty()) {
0320         boost::algorithm::replace_all(a_format,
0321                                       long_weekday_format,
0322                                       m_weekday_long_names[tm_value.tm_wday]);
0323       }
0324       if (!m_weekday_short_names.empty()) {
0325         boost::algorithm::replace_all(a_format,
0326                                       short_weekday_format,
0327                                       m_weekday_short_names[tm_value.tm_wday]);
0328 
0329       }
0330       if (!m_month_long_names.empty()) {
0331         boost::algorithm::replace_all(a_format,
0332                                       long_month_format,
0333                                       m_month_long_names[tm_value.tm_mon]);
0334       }
0335       if (!m_month_short_names.empty()) {
0336         boost::algorithm::replace_all(a_format,
0337                                       short_month_format,
0338                                       m_month_short_names[tm_value.tm_mon]);
0339       }
0340       // use time_put facet to create final string
0341       const char_type* p_format = a_format.c_str();
0342       return std::use_facet<std::time_put<CharT> >(a_ios.getloc()).put(next, a_ios,
0343                                                                        fill_char,
0344                                                                        &tm_value,
0345                                                                        p_format,
0346                                                                        p_format + a_format.size());
0347     }
0348   protected:
0349     string_type                   m_format;
0350     string_type                   m_month_format;
0351     string_type                   m_weekday_format;
0352     period_formatter_type         m_period_formatter;
0353     date_gen_formatter_type       m_date_gen_formatter;
0354     special_values_formatter_type m_special_values_formatter;
0355     input_collection_type         m_month_short_names;
0356     input_collection_type         m_month_long_names;
0357     input_collection_type         m_weekday_short_names;
0358     input_collection_type         m_weekday_long_names;
0359   private:
0360   };
0361 
0362   template <class date_type, class CharT, class OutItrT>
0363   std::locale::id date_facet<date_type, CharT, OutItrT>::id;
0364 
0365   template <class date_type, class CharT, class OutItrT>
0366   const typename date_facet<date_type, CharT, OutItrT>::char_type
0367   date_facet<date_type, CharT, OutItrT>::long_weekday_format[3] = {'%','A'};
0368 
0369   template <class date_type, class CharT, class OutItrT>
0370   const typename date_facet<date_type, CharT, OutItrT>::char_type
0371   date_facet<date_type, CharT, OutItrT>::short_weekday_format[3] = {'%','a'};
0372 
0373   template <class date_type, class CharT, class OutItrT>
0374   const typename date_facet<date_type, CharT, OutItrT>::char_type
0375   date_facet<date_type, CharT, OutItrT>::long_month_format[3] = {'%','B'};
0376 
0377   template <class date_type, class CharT, class OutItrT>
0378   const typename date_facet<date_type, CharT, OutItrT>::char_type
0379   date_facet<date_type, CharT, OutItrT>::short_month_format[3] = {'%','b'};
0380 
0381   template <class date_type, class CharT, class OutItrT>
0382   const typename date_facet<date_type, CharT, OutItrT>::char_type
0383   date_facet<date_type, CharT, OutItrT>::default_period_separator[4] = { ' ', '/', ' '};
0384 
0385   template <class date_type, class CharT, class OutItrT>
0386   const typename date_facet<date_type, CharT, OutItrT>::char_type
0387   date_facet<date_type, CharT, OutItrT>::standard_format_specifier[3] =
0388     {'%', 'x' };
0389 
0390   template <class date_type, class CharT, class OutItrT>
0391   const typename date_facet<date_type, CharT, OutItrT>::char_type
0392   date_facet<date_type, CharT, OutItrT>::iso_format_specifier[7] =
0393     {'%', 'Y', '%', 'm', '%', 'd' };
0394 
0395   template <class date_type, class CharT, class OutItrT>
0396   const typename date_facet<date_type, CharT, OutItrT>::char_type
0397   date_facet<date_type, CharT, OutItrT>::iso_format_extended_specifier[9] =
0398     {'%', 'Y', '-', '%', 'm', '-', '%', 'd' };
0399 
0400   template <class date_type, class CharT, class OutItrT>
0401   const typename date_facet<date_type, CharT, OutItrT>::char_type
0402   date_facet<date_type, CharT, OutItrT>::default_date_format[9] =
0403     {'%','Y','-','%','b','-','%','d'};
0404 
0405 
0406 
0407   //! Input facet
0408   template <class date_type,
0409             class CharT,
0410             class InItrT = std::istreambuf_iterator<CharT, std::char_traits<CharT> > >
0411   class BOOST_SYMBOL_VISIBLE date_input_facet : public std::locale::facet {
0412   public:
0413     typedef typename date_type::duration_type duration_type;
0414     // greg_weekday is gregorian_calendar::day_of_week_type
0415     typedef typename date_type::day_of_week_type day_of_week_type;
0416     typedef typename date_type::day_type day_type;
0417     typedef typename date_type::month_type month_type;
0418     typedef typename date_type::year_type year_type;
0419     typedef boost::date_time::period<date_type,duration_type> period_type;
0420     typedef std::basic_string<CharT> string_type;
0421     typedef CharT                    char_type;
0422     typedef boost::date_time::period_parser<date_type, CharT>  period_parser_type;
0423     typedef boost::date_time::special_values_parser<date_type,CharT> special_values_parser_type;
0424     typedef std::vector<std::basic_string<CharT> > input_collection_type;
0425     typedef format_date_parser<date_type, CharT> format_date_parser_type;
0426     // date_generators stuff goes here
0427     typedef date_generator_parser<date_type, CharT> date_gen_parser_type;
0428     typedef partial_date<date_type>          partial_date_type;
0429     typedef nth_kday_of_month<date_type>     nth_kday_type;
0430     typedef first_kday_of_month<date_type>   first_kday_type;
0431     typedef last_kday_of_month<date_type>    last_kday_type;
0432     typedef first_kday_after<date_type>      kday_after_type;
0433     typedef first_kday_before<date_type>     kday_before_type;
0434 
0435     static const char_type long_weekday_format[3];
0436     static const char_type short_weekday_format[3];
0437     static const char_type long_month_format[3];
0438     static const char_type short_month_format[3];
0439     static const char_type four_digit_year_format[3];
0440     static const char_type two_digit_year_format[3];
0441     static const char_type default_period_separator[4];
0442     static const char_type standard_format_specifier[3];
0443     static const char_type iso_format_specifier[7];
0444     static const char_type iso_format_extended_specifier[9];
0445     static const char_type default_date_format[9]; // YYYY-Mon-DD
0446     static std::locale::id id;
0447 
0448     explicit date_input_facet(::size_t a_ref = 0)
0449       : std::locale::facet(a_ref),
0450         m_format(default_date_format),
0451         m_month_format(short_month_format),
0452         m_weekday_format(short_weekday_format),
0453         m_year_format(four_digit_year_format),
0454         m_parser(m_format, std::locale::classic())
0455         // default period_parser & special_values_parser used
0456     {}
0457 
0458     explicit date_input_facet(const string_type& format_str,
0459                               ::size_t a_ref = 0)
0460       : std::locale::facet(a_ref),
0461         m_format(format_str),
0462         m_month_format(short_month_format),
0463         m_weekday_format(short_weekday_format),
0464         m_year_format(four_digit_year_format),
0465         m_parser(m_format, std::locale::classic())
0466         // default period_parser & special_values_parser used
0467     {}
0468 
0469     explicit date_input_facet(const string_type& format_str,
0470                               const format_date_parser_type& date_parser,
0471                               const special_values_parser_type& sv_parser,
0472                               const period_parser_type& per_parser,
0473                               const date_gen_parser_type& date_gen_parser,
0474                               ::size_t ref_count = 0)
0475       : std::locale::facet(ref_count),
0476         m_format(format_str),
0477         m_month_format(short_month_format),
0478         m_weekday_format(short_weekday_format),
0479         m_year_format(four_digit_year_format),
0480         m_parser(date_parser),
0481         m_date_gen_parser(date_gen_parser),
0482         m_period_parser(per_parser),
0483         m_sv_parser(sv_parser)
0484     {}
0485 
0486 
0487     void format(const char_type* const format_str) {
0488       m_format = format_str;
0489     }
0490     virtual void set_iso_format()
0491     {
0492       m_format = iso_format_specifier;
0493     }
0494     virtual void set_iso_extended_format()
0495     {
0496       m_format = iso_format_extended_specifier;
0497     }
0498     void month_format(const char_type* const format_str) {
0499       m_month_format = format_str;
0500     }
0501     void weekday_format(const char_type* const format_str) {
0502       m_weekday_format = format_str;
0503     }
0504     void year_format(const char_type* const format_str) {
0505       m_year_format = format_str;
0506     }
0507 
0508     void period_parser(period_parser_type per_parser) {
0509       m_period_parser = per_parser;
0510     }
0511     void short_weekday_names(const input_collection_type& weekday_names)
0512     {
0513       m_parser.short_weekday_names(weekday_names);
0514     }
0515     void long_weekday_names(const input_collection_type& weekday_names)
0516     {
0517       m_parser.long_weekday_names(weekday_names);
0518     }
0519 
0520     void short_month_names(const input_collection_type& month_names)
0521     {
0522       m_parser.short_month_names(month_names);
0523     }
0524 
0525     void long_month_names(const input_collection_type& month_names)
0526     {
0527       m_parser.long_month_names(month_names);
0528     }
0529 
0530     void date_gen_element_strings(const input_collection_type& col)
0531     {
0532       m_date_gen_parser.element_strings(col);
0533     }
0534     void date_gen_element_strings(const string_type& first,
0535                                   const string_type& second,
0536                                   const string_type& third,
0537                                   const string_type& fourth,
0538                                   const string_type& fifth,
0539                                   const string_type& last,
0540                                   const string_type& before,
0541                                   const string_type& after,
0542                                   const string_type& of)
0543 
0544     {
0545       m_date_gen_parser.element_strings(first,second,third,fourth,fifth,last,before,after,of);
0546     }
0547 
0548     void special_values_parser(special_values_parser_type sv_parser)
0549     {
0550       m_sv_parser = sv_parser;
0551     }
0552 
0553     InItrT get(InItrT& from,
0554                InItrT& to,
0555                std::ios_base& /*a_ios*/,
0556                date_type& d) const
0557     {
0558       d = m_parser.parse_date(from, to, m_format, m_sv_parser);
0559       return from;
0560     }
0561     InItrT get(InItrT& from,
0562                InItrT& to,
0563                std::ios_base& /*a_ios*/,
0564                month_type& m) const
0565     {
0566       m = m_parser.parse_month(from, to, m_month_format);
0567       return from;
0568     }
0569     InItrT get(InItrT& from,
0570                InItrT& to,
0571                std::ios_base& /*a_ios*/,
0572                day_of_week_type& wd) const
0573     {
0574       wd = m_parser.parse_weekday(from, to, m_weekday_format);
0575       return from;
0576     }
0577     //! Expects 1 or 2 digit day range: 1-31
0578     InItrT get(InItrT& from,
0579                InItrT& to,
0580                std::ios_base& /*a_ios*/,
0581                day_type& d) const
0582     {
0583       d = m_parser.parse_var_day_of_month(from, to);
0584       return from;
0585     }
0586     InItrT get(InItrT& from,
0587                InItrT& to,
0588                std::ios_base& /*a_ios*/,
0589                year_type& y) const
0590     {
0591       y = m_parser.parse_year(from, to, m_year_format);
0592       return from;
0593     }
0594     InItrT get(InItrT& from,
0595                InItrT& to,
0596                std::ios_base& a_ios,
0597                duration_type& dd) const
0598     {
0599       // skip leading whitespace
0600       while(std::isspace(*from) && from != to) { ++from; }
0601 
0602       /* num_get.get() will always consume the first character if it
0603        * is a sign indicator (+/-). Special value strings may begin
0604        * with one of these signs so we'll need a copy of it
0605        * in case num_get.get() fails. */
0606       char_type c = '\0';
0607       // TODO Are these characters somewhere in the locale?
0608       if(*from == '-' || *from == '+') {
0609         c = *from;
0610       }
0611       typedef std::num_get<CharT, InItrT> num_get;
0612       typename duration_type::duration_rep_type val = 0;
0613       std::ios_base::iostate err = std::ios_base::goodbit;
0614 
0615       if (std::has_facet<num_get>(a_ios.getloc())) {
0616         from = std::use_facet<num_get>(a_ios.getloc()).get(from, to, a_ios, err, val);
0617       }
0618       else {
0619         num_get* ng = new num_get();
0620         std::locale l = std::locale(a_ios.getloc(), ng);
0621         a_ios.imbue(l);
0622         from = ng->get(from, to, a_ios, err, val);
0623       }
0624       if(err & std::ios_base::failbit){
0625         typedef typename special_values_parser_type::match_results match_results;
0626         match_results mr;
0627         if(c == '-' || c == '+') { // was the first character consumed?
0628           mr.cache += c;
0629         }
0630         m_sv_parser.match(from, to, mr);
0631         if(mr.current_match == match_results::PARSE_ERROR) {
0632           boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"));
0633           BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return from); // should never reach
0634         }
0635         dd = duration_type(static_cast<special_values>(mr.current_match));
0636       }
0637       else {
0638         dd = duration_type(val);
0639       }
0640       return from;
0641     }
0642     InItrT get(InItrT& from,
0643                InItrT& to,
0644                std::ios_base& a_ios,
0645                period_type& p) const
0646     {
0647       p = m_period_parser.get_period(from, to, a_ios, p, duration_type::unit(), *this);
0648       return from;
0649     }
0650     InItrT get(InItrT& from,
0651                InItrT& to,
0652                std::ios_base& a_ios,
0653                nth_kday_type& nkd) const
0654     {
0655       nkd = m_date_gen_parser.get_nth_kday_type(from, to, a_ios, *this);
0656       return from;
0657     }
0658     InItrT get(InItrT& from,
0659                InItrT& to,
0660                std::ios_base& a_ios,
0661                partial_date_type& pd) const
0662     {
0663 
0664       pd = m_date_gen_parser.get_partial_date_type(from, to, a_ios, *this);
0665       return from;
0666     }
0667     InItrT get(InItrT& from,
0668                InItrT& to,
0669                std::ios_base& a_ios,
0670                first_kday_type& fkd) const
0671     {
0672       fkd = m_date_gen_parser.get_first_kday_type(from, to, a_ios, *this);
0673       return from;
0674     }
0675     InItrT get(InItrT& from,
0676                InItrT& to,
0677                std::ios_base& a_ios,
0678                last_kday_type& lkd) const
0679     {
0680       lkd = m_date_gen_parser.get_last_kday_type(from, to, a_ios, *this);
0681       return from;
0682     }
0683     InItrT get(InItrT& from,
0684                InItrT& to,
0685                std::ios_base& a_ios,
0686                kday_before_type& fkb) const
0687     {
0688       fkb = m_date_gen_parser.get_kday_before_type(from, to, a_ios, *this);
0689       return from;
0690     }
0691     InItrT get(InItrT& from,
0692                InItrT& to,
0693                std::ios_base& a_ios,
0694                kday_after_type& fka) const
0695     {
0696       fka = m_date_gen_parser.get_kday_after_type(from, to, a_ios, *this);
0697       return from;
0698     }
0699 
0700   protected:
0701     string_type                   m_format;
0702     string_type                   m_month_format;
0703     string_type                   m_weekday_format;
0704     string_type                   m_year_format;
0705     format_date_parser_type       m_parser;
0706     date_gen_parser_type          m_date_gen_parser;
0707     period_parser_type            m_period_parser;
0708     special_values_parser_type    m_sv_parser;
0709   private:
0710   };
0711 
0712 
0713   template <class date_type, class CharT, class OutItrT>
0714   std::locale::id date_input_facet<date_type, CharT, OutItrT>::id;
0715 
0716   template <class date_type, class CharT, class OutItrT>
0717   const typename date_input_facet<date_type, CharT, OutItrT>::char_type
0718   date_input_facet<date_type, CharT, OutItrT>::long_weekday_format[3] = {'%','A'};
0719 
0720   template <class date_type, class CharT, class OutItrT>
0721   const typename date_input_facet<date_type, CharT, OutItrT>::char_type
0722   date_input_facet<date_type, CharT, OutItrT>::short_weekday_format[3] = {'%','a'};
0723 
0724   template <class date_type, class CharT, class OutItrT>
0725   const typename date_input_facet<date_type, CharT, OutItrT>::char_type
0726   date_input_facet<date_type, CharT, OutItrT>::long_month_format[3] = {'%','B'};
0727 
0728   template <class date_type, class CharT, class OutItrT>
0729   const typename date_input_facet<date_type, CharT, OutItrT>::char_type
0730   date_input_facet<date_type, CharT, OutItrT>::short_month_format[3] = {'%','b'};
0731 
0732   template <class date_type, class CharT, class OutItrT>
0733   const typename date_input_facet<date_type, CharT, OutItrT>::char_type
0734   date_input_facet<date_type, CharT, OutItrT>::four_digit_year_format[3] = {'%','Y'};
0735 
0736   template <class date_type, class CharT, class OutItrT>
0737   const typename date_input_facet<date_type, CharT, OutItrT>::char_type
0738   date_input_facet<date_type, CharT, OutItrT>::two_digit_year_format[3] = {'%','y'};
0739 
0740   template <class date_type, class CharT, class OutItrT>
0741   const typename date_input_facet<date_type, CharT, OutItrT>::char_type
0742   date_input_facet<date_type, CharT, OutItrT>::default_period_separator[4] = { ' ', '/', ' '};
0743 
0744   template <class date_type, class CharT, class OutItrT>
0745   const typename date_input_facet<date_type, CharT, OutItrT>::char_type
0746   date_input_facet<date_type, CharT, OutItrT>::standard_format_specifier[3] =
0747     {'%', 'x' };
0748 
0749   template <class date_type, class CharT, class OutItrT>
0750   const typename date_input_facet<date_type, CharT, OutItrT>::char_type
0751   date_input_facet<date_type, CharT, OutItrT>::iso_format_specifier[7] =
0752     {'%', 'Y', '%', 'm', '%', 'd' };
0753 
0754   template <class date_type, class CharT, class OutItrT>
0755   const typename date_input_facet<date_type, CharT, OutItrT>::char_type
0756   date_input_facet<date_type, CharT, OutItrT>::iso_format_extended_specifier[9] =
0757     {'%', 'Y', '-', '%', 'm', '-', '%', 'd' };
0758 
0759   template <class date_type, class CharT, class OutItrT>
0760   const typename date_input_facet<date_type, CharT, OutItrT>::char_type
0761   date_input_facet<date_type, CharT, OutItrT>::default_date_format[9] =
0762     {'%','Y','-','%','b','-','%','d'};
0763 
0764 } } // namespaces
0765 
0766 #endif