Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / date_time / date_facet.hpp
1 #ifndef _DATE_TIME_DATE_FACET__HPP___
2 #define _DATE_TIME_DATE_FACET__HPP___
3
4 /* Copyright (c) 2004-2005 CrystalClear Software, Inc.
5  * Use, modification and distribution is subject to the 
6  * Boost Software License, Version 1.0. (See accompanying
7  * file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
8  * Author:  Martin Andrian, Jeff Garland, Bart Garst
9  * $Date: 2005/05/25 11:52:24 $
10  */
11
12
13 #include "boost/algorithm/string/replace.hpp"
14 #include "boost/date_time/period.hpp"
15 #include "boost/date_time/special_values_formatter.hpp"
16 #include "boost/date_time/period_formatter.hpp"
17 #include "boost/date_time/period_parser.hpp"
18 #include "boost/date_time/date_generator_formatter.hpp"
19 #include "boost/date_time/date_generator_parser.hpp"
20 #include "boost/date_time/format_date_parser.hpp"
21 #include <string>
22 #include <vector>
23
24 namespace boost { namespace date_time {
25
26   
27   /*! Class that provides format based I/O facet for date types.
28    *
29    * This class allows the formatting of dates by using format string.
30    * Format strings are:
31    *
32    *  - %A => long_weekday_format - Full name Ex: Tuesday
33    *  - %a => short_weekday_format - Three letter abbreviation Ex: Tue
34    *  - %B => long_month_format - Full name Ex: October
35    *  - %b => short_month_format - Three letter abbreviation Ex: Oct
36    *  - %x => standard_format_specifier - defined by the locale
37    *  - %Y-%b-%d => default_date_format - YYYY-Mon-dd
38    *
39    * Default month format == %b
40    * Default weekday format == %a
41    */
42   template <class date_type,
43             class CharT, 
44             class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
45   class date_facet : public std::locale::facet {
46   public:
47     typedef typename date_type::duration_type duration_type;
48     // greg_weekday is gregorian_calendar::day_of_week_type
49     typedef typename date_type::day_of_week_type day_of_week_type;
50     typedef typename date_type::day_type day_type;
51     typedef typename date_type::month_type month_type;
52     typedef boost::date_time::period<date_type,duration_type> period_type;
53     typedef std::basic_string<CharT> string_type;
54     typedef CharT                    char_type;
55     typedef boost::date_time::period_formatter<CharT>  period_formatter_type;
56     typedef boost::date_time::special_values_formatter<CharT>  special_values_formatter_type;
57     typedef std::vector<std::basic_string<CharT> > input_collection_type;
58     // used for the output of the date_generators
59     typedef date_generator_formatter<date_type, CharT> date_gen_formatter_type;
60     typedef partial_date<date_type>          partial_date_type;
61     typedef nth_kday_of_month<date_type>     nth_kday_type;
62     typedef first_kday_of_month<date_type>   first_kday_type;
63     typedef last_kday_of_month<date_type>    last_kday_type;
64     typedef first_kday_after<date_type>      kday_after_type;
65     typedef first_kday_before<date_type>     kday_before_type;
66     static const char_type long_weekday_format[3];
67     static const char_type short_weekday_format[3];
68     static const char_type long_month_format[3];
69     static const char_type short_month_format[3];
70     static const char_type default_period_separator[4];
71     static const char_type standard_format_specifier[3];
72     static const char_type iso_format_specifier[7];
73     static const char_type iso_format_extended_specifier[9];
74     static const char_type default_date_format[9]; // YYYY-Mon-DD
75     static std::locale::id id;
76
77 #if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
78       std::locale::id& __get_id (void) const { return id; }
79 #endif
80     
81     explicit date_facet(::size_t a_ref = 0) 
82       : std::locale::facet(a_ref), 
83         //m_format(standard_format_specifier)
84         m_format(default_date_format),
85         m_month_format(short_month_format),
86         m_weekday_format(short_weekday_format)
87     {}
88
89     explicit date_facet(const char_type* format,
90                         const input_collection_type& short_month_names,
91                         ::size_t ref_count = 0) 
92       : std::locale::facet(ref_count), 
93         m_format(format),
94         m_month_format(short_month_format),
95         m_weekday_format(short_weekday_format),
96         m_month_short_names(short_month_names) 
97     {}
98
99      
100     explicit date_facet(const char_type* format, 
101                         period_formatter_type period_formatter = period_formatter_type(), 
102                         special_values_formatter_type special_values_formatter = special_values_formatter_type(),
103                         date_gen_formatter_type dg_formatter = date_gen_formatter_type(),
104                         ::size_t ref_count = 0)
105       : std::locale::facet(ref_count), 
106         m_format(format), 
107         m_month_format(short_month_format),
108         m_weekday_format(short_weekday_format),
109         m_period_formatter(period_formatter),
110         m_date_gen_formatter(dg_formatter),
111         m_special_values_formatter(special_values_formatter)
112      {}
113     void format(const char_type* const format) {
114       m_format = format;
115     }
116     virtual void set_iso_format()
117     {
118       m_format = iso_format_specifier;
119     }
120     virtual void set_iso_extended_format()
121     {
122       m_format = iso_format_extended_specifier;
123     }
124     void month_format(const char_type* const format) {
125       m_month_format = format;
126     }
127     void weekday_format(const char_type* const format) {
128       m_weekday_format = format;
129     }
130     
131     void period_formatter(period_formatter_type period_formatter) {
132       m_period_formatter= period_formatter;
133     }
134     void special_values_formatter(const special_values_formatter_type& svf) 
135     {
136       m_special_values_formatter = svf;
137     }
138     void short_weekday_names(const input_collection_type& short_weekday_names)
139     {
140       m_weekday_short_names = short_weekday_names;
141     }
142     void long_weekday_names(const input_collection_type& long_weekday_names)
143     {
144       m_weekday_long_names = long_weekday_names;
145     }
146
147     void short_month_names(const input_collection_type& short_month_names)
148     {
149       m_month_short_names = short_month_names;
150     }
151
152     void long_month_names(const input_collection_type& long_month_names)
153     {
154       m_month_long_names = long_month_names;
155     }
156
157     void date_gen_phrase_strings(const input_collection_type& new_strings,
158                            typename date_gen_formatter_type::phrase_elements beg_pos=date_gen_formatter_type::first)
159     {
160       m_date_gen_formatter.elements(new_strings, beg_pos);
161     }
162
163     OutItrT put(OutItrT next, 
164                 std::ios_base& a_ios, 
165                 char_type fill_char, 
166                 const date_type& d) const 
167     {
168       if (d.is_special()) { 
169         return do_put_special(next, a_ios, fill_char, d.as_special());
170       }
171       //The following line of code required the date to support a to_tm function
172       return do_put_tm(next, a_ios, fill_char, to_tm(d), m_format);
173     }
174
175     OutItrT put(OutItrT next, 
176                 std::ios_base& a_ios, 
177                 char_type fill_char, 
178                 const duration_type& dd) const 
179     {
180       if (dd.is_special()) { 
181         return do_put_special(next, a_ios, fill_char, dd.get_rep().as_special());
182       }
183
184       typedef std::num_put<CharT, OutItrT> num_put;
185       if (std::has_facet<num_put>(a_ios.getloc())) {
186         return std::use_facet<num_put>(a_ios.getloc()).put(next, a_ios, fill_char, dd.get_rep().as_number());
187       }
188       else {
189         num_put* f = new num_put();
190         std::locale l = std::locale(a_ios.getloc(), f);
191         a_ios.imbue(l);
192         return f->put(next, a_ios, fill_char, dd.get_rep().as_number());
193       }
194
195     }
196
197
198     OutItrT put(OutItrT next, 
199                 std::ios_base& a_ios, 
200                 char_type fill_char, 
201                 const month_type& m) const 
202     {
203       //if (d.is_special()) { 
204       //  return do_put_special(next, a_ios, fill_char, d.as_special());
205       //}
206       //The following line of code required the date to support a to_tm function
207       tm dtm;
208       init_tm(dtm);
209       dtm.tm_mon = m -1;
210       return do_put_tm(next, a_ios, fill_char, dtm, m_month_format);
211     }
212
213     //! puts the day of month
214     OutItrT put(OutItrT next, 
215                 std::ios_base& a_ios, 
216                 char_type fill_char, 
217                 const day_type& day) const 
218     {
219       tm dtm;
220       init_tm(dtm);
221       dtm.tm_mday = day.as_number();
222       char_type tmp[3] = {'%','d'};
223       string_type temp_format(tmp);
224       return do_put_tm(next, a_ios, fill_char, dtm, temp_format);
225     }
226
227     OutItrT put(OutItrT next, 
228                 std::ios_base& a_ios, 
229                 char_type fill_char, 
230                 const day_of_week_type& dow) const 
231     {
232       //if (d.is_special()) { 
233       //  return do_put_special(next, a_ios, fill_char, d.as_special());
234       //}
235       //The following line of code required the date to support a to_tm function
236       tm dtm;
237       init_tm(dtm);
238       dtm.tm_wday = dow;
239       return do_put_tm(next, a_ios, fill_char, dtm, m_weekday_format);
240     }
241
242
243     OutItrT put(OutItrT next, 
244                 std::ios_base& a_ios, 
245                 char_type fill_char, 
246                 const period_type& p) const 
247     {
248       return m_period_formatter.put_period(next, a_ios, fill_char, p, *this);
249     }
250
251     OutItrT put(OutItrT next, 
252                 std::ios_base& a_ios, 
253                 char_type fill_char, 
254                 const partial_date_type& pd) const 
255     {
256       return m_date_gen_formatter.put_partial_date(next, a_ios, fill_char, pd, *this);
257     }
258
259     OutItrT put(OutItrT next, 
260                 std::ios_base& a_ios, 
261                 char_type fill_char, 
262                 const nth_kday_type& nkd) const 
263     {
264       return m_date_gen_formatter.put_nth_kday(next, a_ios, fill_char, nkd, *this);
265     }
266
267     OutItrT put(OutItrT next, 
268                 std::ios_base& a_ios, 
269                 char_type fill_char, 
270                 const first_kday_type& fkd) const 
271     {
272       return m_date_gen_formatter.put_first_kday(next, a_ios, fill_char, fkd, *this);
273     }
274
275     OutItrT put(OutItrT next, 
276                 std::ios_base& a_ios, 
277                 char_type fill_char, 
278                 const last_kday_type& lkd) const 
279     {
280       return m_date_gen_formatter.put_last_kday(next, a_ios, fill_char, lkd, *this);
281     }
282
283     OutItrT put(OutItrT next, 
284                 std::ios_base& a_ios, 
285                 char_type fill_char, 
286                 const kday_before_type& fkb) const 
287     {
288       return m_date_gen_formatter.put_kday_before(next, a_ios, fill_char, fkb, *this);
289     }
290
291     OutItrT put(OutItrT next, 
292                 std::ios_base& a_ios, 
293                 char_type fill_char, 
294                 const kday_after_type& fka) const 
295     {
296       return m_date_gen_formatter.put_kday_after(next, a_ios, fill_char, fka, *this);
297     }
298     
299   protected:
300     //! Helper function to initialize all fields in a tm struct
301     tm init_tm(tm& tm_value) const
302     {
303       tm_value.tm_sec = 0;         /* seconds */
304       tm_value.tm_min = 0;         /* minutes */
305       tm_value.tm_hour = 0;        /* hours */
306       tm_value.tm_mday = 0;        /* day of the month */
307       tm_value.tm_mon = 0;         /* month */
308       tm_value.tm_year = 0;        /* year */
309       tm_value.tm_wday = 0;        /* day of the week */
310       tm_value.tm_yday = 0;        /* day in the year */
311       tm_value.tm_isdst = 0;       /* daylight saving time */
312       return tm_value;
313     }
314     virtual OutItrT do_put_special(OutItrT next, 
315                                    std::ios_base& /*a_ios*/, 
316                                    char_type /*fill_char*/, 
317                                    const boost::date_time::special_values sv) const 
318     {
319       m_special_values_formatter.put_special(next, sv);
320       return next;
321     }
322     virtual OutItrT do_put_tm(OutItrT next, 
323                               std::ios_base& a_ios, 
324                               char_type fill_char, 
325                               const tm& tm_value,
326                               string_type a_format) const 
327     {
328       // update format string with custom names
329       if (m_weekday_long_names.size()) {
330         boost::algorithm::replace_all(a_format, 
331                                       long_weekday_format, 
332                                       m_weekday_long_names[tm_value.tm_wday]);
333       }
334       if (m_weekday_short_names.size()) {
335         boost::algorithm::replace_all(a_format, 
336                                       short_weekday_format, 
337                                       m_weekday_short_names[tm_value.tm_wday]);
338
339       }
340       if (m_month_long_names.size()) {
341         boost::algorithm::replace_all(a_format, 
342                                       long_month_format, 
343                                       m_month_long_names[tm_value.tm_mon]);
344       }
345       if (m_month_short_names.size()) {
346         boost::algorithm::replace_all(a_format, 
347                                       short_month_format, 
348                                       m_month_short_names[tm_value.tm_mon]);
349       }
350       // use time_put facet to create final string
351       return std::use_facet<std::time_put<CharT> >(a_ios.getloc()).put(next, a_ios, 
352                                                                        fill_char, 
353                                                                        &tm_value,
354                                                                        &*a_format.begin(), 
355                                                                        &*a_format.begin()+a_format.size());
356     }
357   protected:
358     string_type                   m_format;
359     string_type                   m_month_format;
360     string_type                   m_weekday_format;
361     period_formatter_type         m_period_formatter;
362     date_gen_formatter_type       m_date_gen_formatter;
363     special_values_formatter_type m_special_values_formatter;
364     input_collection_type         m_month_short_names;
365     input_collection_type         m_month_long_names;
366     input_collection_type         m_weekday_short_names;
367     input_collection_type         m_weekday_long_names;
368   private:
369   };
370
371   template <class date_type, class CharT, class OutItrT>
372   std::locale::id date_facet<date_type, CharT, OutItrT>::id;
373
374   template <class date_type, class CharT, class OutItrT>  
375   const typename date_facet<date_type, CharT, OutItrT>::char_type 
376   date_facet<date_type, CharT, OutItrT>::long_weekday_format[3] = {'%','A'};
377
378   template <class date_type, class CharT, class OutItrT>  
379   const typename date_facet<date_type, CharT, OutItrT>::char_type 
380   date_facet<date_type, CharT, OutItrT>::short_weekday_format[3] = {'%','a'};
381
382   template <class date_type, class CharT, class OutItrT>  
383   const typename date_facet<date_type, CharT, OutItrT>::char_type 
384   date_facet<date_type, CharT, OutItrT>::long_month_format[3] = {'%','B'};
385
386   template <class date_type, class CharT, class OutItrT>  
387   const typename date_facet<date_type, CharT, OutItrT>::char_type 
388   date_facet<date_type, CharT, OutItrT>::short_month_format[3] = {'%','b'};
389
390   template <class date_type, class CharT, class OutItrT>  
391   const typename date_facet<date_type, CharT, OutItrT>::char_type 
392   date_facet<date_type, CharT, OutItrT>::default_period_separator[4] = { ' ', '/', ' '};
393
394   template <class date_type, class CharT, class OutItrT>  
395   const typename date_facet<date_type, CharT, OutItrT>::char_type 
396   date_facet<date_type, CharT, OutItrT>::standard_format_specifier[3] = 
397     {'%', 'x' };
398
399   template <class date_type, class CharT, class OutItrT>  
400   const typename date_facet<date_type, CharT, OutItrT>::char_type 
401   date_facet<date_type, CharT, OutItrT>::iso_format_specifier[7] = 
402     {'%', 'Y', '%', 'm', '%', 'd' };
403
404   template <class date_type, class CharT, class OutItrT>  
405   const typename date_facet<date_type, CharT, OutItrT>::char_type 
406   date_facet<date_type, CharT, OutItrT>::iso_format_extended_specifier[9] = 
407     {'%', 'Y', '-', '%', 'm', '-', '%', 'd' };
408
409   template <class date_type, class CharT, class OutItrT>  
410   const typename date_facet<date_type, CharT, OutItrT>::char_type 
411   date_facet<date_type, CharT, OutItrT>::default_date_format[9] = 
412     {'%','Y','-','%','b','-','%','d'};
413
414
415
416   //! Input facet
417   template <class date_type,
418             class CharT, 
419             class InItrT = std::istreambuf_iterator<CharT, std::char_traits<CharT> > >
420   class date_input_facet : public std::locale::facet {
421   public:
422     typedef typename date_type::duration_type duration_type;
423     // greg_weekday is gregorian_calendar::day_of_week_type
424     typedef typename date_type::day_of_week_type day_of_week_type;
425     typedef typename date_type::day_type day_type;
426     typedef typename date_type::month_type month_type;
427     typedef typename date_type::year_type year_type;
428     typedef boost::date_time::period<date_type,duration_type> period_type;
429     typedef std::basic_string<CharT> string_type;
430     typedef CharT                    char_type;
431     typedef boost::date_time::period_parser<date_type, CharT>  period_parser_type;
432     typedef special_values_parser<date_type,CharT> special_values_parser_type; 
433     typedef std::vector<std::basic_string<CharT> > input_collection_type;
434     typedef format_date_parser<date_type, CharT> format_date_parser_type;
435     // date_generators stuff goes here
436     typedef date_generator_parser<date_type, CharT> date_gen_parser_type;
437     typedef partial_date<date_type>          partial_date_type;
438     typedef nth_kday_of_month<date_type>     nth_kday_type;
439     typedef first_kday_of_month<date_type>   first_kday_type;
440     typedef last_kday_of_month<date_type>    last_kday_type;
441     typedef first_kday_after<date_type>      kday_after_type;
442     typedef first_kday_before<date_type>     kday_before_type;
443
444     static const char_type long_weekday_format[3];
445     static const char_type short_weekday_format[3];
446     static const char_type long_month_format[3];
447     static const char_type short_month_format[3];
448     static const char_type four_digit_year_format[3];
449     static const char_type two_digit_year_format[3];
450     static const char_type default_period_separator[4];
451     static const char_type standard_format_specifier[3];
452     static const char_type iso_format_specifier[7];
453     static const char_type iso_format_extended_specifier[9];
454     static const char_type default_date_format[9]; // YYYY-Mon-DD
455     static std::locale::id id;
456     
457     explicit date_input_facet(::size_t a_ref = 0) 
458       : std::locale::facet(a_ref), 
459         m_format(default_date_format),
460         m_month_format(short_month_format),
461         m_weekday_format(short_weekday_format),
462         m_year_format(four_digit_year_format),
463         m_parser(m_format, std::locale::classic())
464         // default period_parser & special_values_parser used
465     {}
466
467     explicit date_input_facet(const string_type& format,
468                               ::size_t a_ref = 0) 
469       : std::locale::facet(a_ref), 
470         m_format(format),
471         m_month_format(short_month_format),
472         m_weekday_format(short_weekday_format),
473         m_year_format(four_digit_year_format),
474         m_parser(m_format, std::locale::classic())
475         // default period_parser & special_values_parser used
476     {}
477
478     explicit date_input_facet(const string_type& format,
479                               const format_date_parser_type& date_parser,
480                               const special_values_parser_type& sv_parser,
481                               const period_parser_type& per_parser,
482                               const date_gen_parser_type& date_gen_parser,
483                               ::size_t ref_count = 0)
484       : std::locale::facet(ref_count),
485         m_format(format),
486         m_month_format(short_month_format),
487         m_weekday_format(short_weekday_format),
488         m_year_format(four_digit_year_format),
489         m_parser(date_parser),
490         m_date_gen_parser(date_gen_parser),
491         m_period_parser(per_parser),
492         m_sv_parser(sv_parser)
493     {}
494
495
496     void format(const char_type* const format) {
497       m_format = format;
498     }
499     virtual void set_iso_format()
500     {
501       m_format = iso_format_specifier;
502     }
503     virtual void set_iso_extended_format()
504     {
505       m_format = iso_format_extended_specifier;
506     }
507     void month_format(const char_type* const format) {
508       m_month_format = format;
509     }
510     void weekday_format(const char_type* const format) {
511       m_weekday_format = format;
512     }
513     void year_format(const char_type* const format) {
514       m_year_format = format;
515     }
516     
517     void period_parser(period_parser_type period_parser) {
518       m_period_parser= period_parser;
519     }
520     void short_weekday_names(const input_collection_type& weekday_names)
521     {
522       m_parser.short_weekday_names(weekday_names);
523     }
524     void long_weekday_names(const input_collection_type& weekday_names)
525     {
526       m_parser.long_weekday_names(weekday_names);
527     }
528
529     void short_month_names(const input_collection_type& month_names)
530     {
531       m_parser.short_month_names(month_names);
532     }
533
534     void long_month_names(const input_collection_type& month_names)
535     {
536       m_parser.long_month_names(month_names);
537     }
538
539     void date_gen_element_strings(const input_collection_type& col)
540     {
541       m_date_gen_parser.element_strings(col);
542     }
543     void date_gen_element_strings(const string_type& first,
544                                   const string_type& second,
545                                   const string_type& third,
546                                   const string_type& fourth,
547                                   const string_type& fifth,
548                                   const string_type& last,
549                                   const string_type& before,
550                                   const string_type& after,
551                                   const string_type& of)
552                            
553     {
554       m_date_gen_parser.element_strings(first,second,third,fourth,fifth,last,before,after,of);
555     }
556
557     void special_values_parser(special_values_parser_type sv_parser)
558     {
559       m_sv_parser = sv_parser;
560     }
561
562     InItrT get(InItrT& from, 
563                InItrT& to, 
564                std::ios_base& /*a_ios*/, 
565                date_type& d) const
566     {
567       d = m_parser.parse_date(from, to, m_format, m_sv_parser);
568       return from;
569     }
570     InItrT get(InItrT& from, 
571                InItrT& to, 
572                std::ios_base& /*a_ios*/, 
573                month_type& m) const
574     {
575       m = m_parser.parse_month(from, to, m_month_format);
576       return from;
577     }
578     InItrT get(InItrT& from, 
579                InItrT& to, 
580                std::ios_base& /*a_ios*/, 
581                day_of_week_type& wd) const
582     {
583       wd = m_parser.parse_weekday(from, to, m_weekday_format);
584       return from;
585     }
586     InItrT get(InItrT& from, 
587                InItrT& to, 
588                std::ios_base& /*a_ios*/, 
589                day_type& d) const
590     {
591       d = m_parser.parse_day_of_month(from, to);
592       return from;
593     }
594     InItrT get(InItrT& from, 
595                InItrT& to, 
596                std::ios_base& /*a_ios*/, 
597                year_type& y) const
598     {
599       y = m_parser.parse_year(from, to, m_year_format);
600       return from;
601     }
602     InItrT get(InItrT& from, 
603                InItrT& to, 
604                std::ios_base& a_ios, 
605                duration_type& dd) const
606     {
607       // skip leading whitespace
608       while(std::isspace(*from) && from != to) { ++from; } 
609      
610       /* num_get.get() will always consume the first character if it 
611        * is a sign indicator (+/-). Special value strings may begin 
612        * with one of these signs so we'll need a copy of it
613        * in case num_get.get() fails. */
614       char_type c = '\0'; 
615       // TODO Are these characters somewhere in the locale?
616       if(*from == '-' || *from == '+') { 
617         c = *from;
618       }
619       typedef std::num_get<CharT, InItrT> num_get;
620       typename duration_type::duration_rep_type val = 0;
621       std::ios_base::iostate err = std::ios_base::goodbit;
622       
623       if (std::has_facet<num_get>(a_ios.getloc())) {
624         from = std::use_facet<num_get>(a_ios.getloc()).get(from, to, a_ios, err, val);
625       }
626       else {
627         num_get* ng = new num_get();
628         std::locale l = std::locale(a_ios.getloc(), ng);
629         a_ios.imbue(l);
630         from = ng->get(from, to, a_ios, err, val);
631       }
632       if(err & std::ios_base::failbit){
633         typedef typename special_values_parser_type::match_results match_results;
634         match_results mr;
635         if(c == '-' || c == '+') { // was the first character consumed?
636           mr.cache += c;
637         }
638         m_sv_parser.match(from, to, mr);
639         if(mr.current_match == match_results::PARSE_ERROR) {
640           throw std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'");
641         }
642         dd = duration_type(static_cast<special_values>(mr.current_match)); 
643       }
644       else {
645         dd = duration_type(val);
646       }
647       return from;
648     }
649     InItrT get(InItrT& from, 
650                InItrT& to, 
651                std::ios_base& a_ios, 
652                period_type& p) const
653     {
654       p = m_period_parser.get_period(from, to, a_ios, p, duration_type::unit(), *this);     
655       return from;
656     }
657     InItrT get(InItrT& from, 
658                InItrT& to, 
659                std::ios_base& a_ios, 
660                nth_kday_type& nkd) const
661     {
662       nkd = m_date_gen_parser.get_nth_kday_type(from, to, a_ios, *this);
663       return from;
664     }
665     InItrT get(InItrT& from, 
666                InItrT& to, 
667                std::ios_base& a_ios, 
668                partial_date_type& pd) const
669     {
670
671       pd = m_date_gen_parser.get_partial_date_type(from, to, a_ios, *this);
672       return from;
673     }
674     InItrT get(InItrT& from, 
675                InItrT& to, 
676                std::ios_base& a_ios, 
677                first_kday_type& fkd) const
678     {
679       fkd = m_date_gen_parser.get_first_kday_type(from, to, a_ios, *this);
680       return from;
681     }
682     InItrT get(InItrT& from, 
683                InItrT& to, 
684                std::ios_base& a_ios, 
685                last_kday_type& lkd) const
686     {
687       lkd = m_date_gen_parser.get_last_kday_type(from, to, a_ios, *this);
688       return from;
689     }
690     InItrT get(InItrT& from, 
691                InItrT& to, 
692                std::ios_base& a_ios, 
693                kday_before_type& fkb) const
694     {
695       fkb = m_date_gen_parser.get_kday_before_type(from, to, a_ios, *this);
696       return from;
697     }
698     InItrT get(InItrT& from, 
699                InItrT& to, 
700                std::ios_base& a_ios, 
701                kday_after_type& fka) const
702     {
703       fka = m_date_gen_parser.get_kday_after_type(from, to, a_ios, *this);
704       return from;
705     }
706
707   protected:
708     string_type                   m_format;
709     string_type                   m_month_format;
710     string_type                   m_weekday_format;
711     string_type                   m_year_format;
712     format_date_parser_type       m_parser;
713     date_gen_parser_type          m_date_gen_parser;
714     period_parser_type            m_period_parser;
715     special_values_parser_type    m_sv_parser;
716   private:
717   };
718
719
720   template <class date_type, class CharT, class OutItrT>
721   std::locale::id date_input_facet<date_type, CharT, OutItrT>::id;
722
723   template <class date_type, class CharT, class OutItrT>  
724   const typename date_input_facet<date_type, CharT, OutItrT>::char_type 
725   date_input_facet<date_type, CharT, OutItrT>::long_weekday_format[3] = {'%','A'};
726
727   template <class date_type, class CharT, class OutItrT>  
728   const typename date_input_facet<date_type, CharT, OutItrT>::char_type 
729   date_input_facet<date_type, CharT, OutItrT>::short_weekday_format[3] = {'%','a'};
730
731   template <class date_type, class CharT, class OutItrT>  
732   const typename date_input_facet<date_type, CharT, OutItrT>::char_type 
733   date_input_facet<date_type, CharT, OutItrT>::long_month_format[3] = {'%','B'};
734
735   template <class date_type, class CharT, class OutItrT>  
736   const typename date_input_facet<date_type, CharT, OutItrT>::char_type 
737   date_input_facet<date_type, CharT, OutItrT>::short_month_format[3] = {'%','b'};
738
739   template <class date_type, class CharT, class OutItrT>  
740   const typename date_input_facet<date_type, CharT, OutItrT>::char_type 
741   date_input_facet<date_type, CharT, OutItrT>::four_digit_year_format[3] = {'%','Y'};
742
743   template <class date_type, class CharT, class OutItrT>  
744   const typename date_input_facet<date_type, CharT, OutItrT>::char_type 
745   date_input_facet<date_type, CharT, OutItrT>::two_digit_year_format[3] = {'%','y'};
746
747   template <class date_type, class CharT, class OutItrT>  
748   const typename date_input_facet<date_type, CharT, OutItrT>::char_type 
749   date_input_facet<date_type, CharT, OutItrT>::default_period_separator[4] = { ' ', '/', ' '};
750
751   template <class date_type, class CharT, class OutItrT>  
752   const typename date_input_facet<date_type, CharT, OutItrT>::char_type 
753   date_input_facet<date_type, CharT, OutItrT>::standard_format_specifier[3] = 
754     {'%', 'x' };
755
756   template <class date_type, class CharT, class OutItrT>  
757   const typename date_input_facet<date_type, CharT, OutItrT>::char_type 
758   date_input_facet<date_type, CharT, OutItrT>::iso_format_specifier[7] = 
759     {'%', 'Y', '%', 'm', '%', 'd' };
760
761   template <class date_type, class CharT, class OutItrT>  
762   const typename date_input_facet<date_type, CharT, OutItrT>::char_type 
763   date_input_facet<date_type, CharT, OutItrT>::iso_format_extended_specifier[9] = 
764     {'%', 'Y', '-', '%', 'm', '-', '%', 'd' };
765
766   template <class date_type, class CharT, class OutItrT>  
767   const typename date_input_facet<date_type, CharT, OutItrT>::char_type 
768   date_input_facet<date_type, CharT, OutItrT>::default_date_format[9] = 
769     {'%','Y','-','%','b','-','%','d'};
770
771 } } // namespaces
772
773
774 #endif