Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / date_time / gregorian / gregorian_io.hpp
1 #ifndef DATE_TIME_GREGORIAN_IO_HPP__
2 #define DATE_TIME_GREGORIAN_IO_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.txt or http://www.boost.org/LICENSE_1_0.txt)
8  * Author: Jeff Garland, Bart Garst
9  * $Date$
10  */
11
12 #include <locale>
13 #include <iostream>
14 #include <iterator> // i/ostreambuf_iterator
15 #include <boost/io/ios_state.hpp>
16 #include <boost/date_time/date_facet.hpp>
17 #include <boost/date_time/period_parser.hpp>
18 #include <boost/date_time/period_formatter.hpp>
19 #include <boost/date_time/special_values_parser.hpp>
20 #include <boost/date_time/special_values_formatter.hpp>
21 #include <boost/date_time/gregorian/gregorian_types.hpp>
22 #include <boost/date_time/gregorian/conversion.hpp> // to_tm will be needed in the facets
23
24 namespace boost {
25 namespace gregorian {
26
27
28   typedef boost::date_time::period_formatter<wchar_t> wperiod_formatter;
29   typedef boost::date_time::period_formatter<char>    period_formatter;
30   
31   typedef boost::date_time::date_facet<date,wchar_t> wdate_facet;
32   typedef boost::date_time::date_facet<date,char>    date_facet;
33
34   typedef boost::date_time::period_parser<date,char>       period_parser;
35   typedef boost::date_time::period_parser<date,wchar_t>    wperiod_parser;
36     
37   typedef boost::date_time::special_values_formatter<char> special_values_formatter; 
38   typedef boost::date_time::special_values_formatter<wchar_t> wspecial_values_formatter; 
39   
40   typedef boost::date_time::special_values_parser<date,char> special_values_parser; 
41   typedef boost::date_time::special_values_parser<date,wchar_t> wspecial_values_parser; 
42   
43   typedef boost::date_time::date_input_facet<date,char>    date_input_facet;
44   typedef boost::date_time::date_input_facet<date,wchar_t> wdate_input_facet;
45
46   template <class CharT, class TraitsT>
47   inline std::basic_ostream<CharT, TraitsT>&
48   operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date& d) {
49     boost::io::ios_flags_saver iflags(os);
50     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
51     std::ostreambuf_iterator<CharT> output_itr(os);
52     if (std::has_facet<custom_date_facet>(os.getloc()))
53       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), d);
54     else {
55       //instantiate a custom facet for dealing with dates since the user
56       //has not put one in the stream so far.  This is for efficiency 
57       //since we would always need to reconstruct for every date
58       //if the locale did not already exist.  Of course this will be overridden
59       //if the user imbues at some later point.  With the default settings
60       //for the facet the resulting format will be the same as the
61       //std::time_facet settings.
62       custom_date_facet* f = new custom_date_facet();
63       std::locale l = std::locale(os.getloc(), f);
64       os.imbue(l);
65       f->put(output_itr, os, os.fill(), d);
66     }
67     return os;
68   }
69
70   //! input operator for date
71   template <class CharT, class Traits>
72   inline
73   std::basic_istream<CharT, Traits>&
74   operator>>(std::basic_istream<CharT, Traits>& is, date& d)
75   {
76     boost::io::ios_flags_saver iflags(is);
77     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
78     if (strm_sentry) {
79       try {
80         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
81         
82         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
83         if(std::has_facet<date_input_facet>(is.getloc())) {
84           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, d);
85         }
86         else {
87           date_input_facet* f = new date_input_facet();
88           std::locale l = std::locale(is.getloc(), f);
89           is.imbue(l);
90           f->get(sit, str_end, is, d);
91         }
92       }
93       catch(...) { 
94         // mask tells us what exceptions are turned on
95         std::ios_base::iostate exception_mask = is.exceptions();
96         // if the user wants exceptions on failbit, we'll rethrow our 
97         // date_time exception & set the failbit
98         if(std::ios_base::failbit & exception_mask) {
99           try { is.setstate(std::ios_base::failbit); } 
100           catch(std::ios_base::failure&) {} // ignore this one
101           throw; // rethrow original exception
102         }
103         else {
104           // if the user want's to fail quietly, we simply set the failbit
105           is.setstate(std::ios_base::failbit); 
106         } 
107             
108       }
109     }    
110     return is;
111   }
112
113   template <class CharT, class TraitsT>
114   inline std::basic_ostream<CharT, TraitsT>&
115   operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date_duration& dd) {
116     boost::io::ios_flags_saver iflags(os);
117     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
118     std::ostreambuf_iterator<CharT> output_itr(os);
119     if (std::has_facet<custom_date_facet>(os.getloc()))
120       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), dd);
121     else {
122       custom_date_facet* f = new custom_date_facet();
123       std::locale l = std::locale(os.getloc(), f);
124       os.imbue(l);
125       f->put(output_itr, os, os.fill(), dd);
126
127     }
128     return os;
129   }
130
131   //! input operator for date_duration
132   template <class CharT, class Traits>
133   inline
134   std::basic_istream<CharT, Traits>&
135   operator>>(std::basic_istream<CharT, Traits>& is, date_duration& dd)
136   {
137     boost::io::ios_flags_saver iflags(is);
138     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
139     if (strm_sentry) {
140       try {
141         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
142         
143         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
144         if(std::has_facet<date_input_facet>(is.getloc())) {
145           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, dd);
146         }
147         else {
148           date_input_facet* f = new date_input_facet();
149           std::locale l = std::locale(is.getloc(), f);
150           is.imbue(l);
151           f->get(sit, str_end, is, dd);
152         }
153       }
154       catch(...) { 
155         std::ios_base::iostate exception_mask = is.exceptions();
156         if(std::ios_base::failbit & exception_mask) {
157           try { is.setstate(std::ios_base::failbit); } 
158           catch(std::ios_base::failure&) {}
159           throw; // rethrow original exception
160         }
161         else {
162           is.setstate(std::ios_base::failbit); 
163         } 
164             
165       }
166     }
167     return is;
168   }
169
170   template <class CharT, class TraitsT>
171   inline std::basic_ostream<CharT, TraitsT>&
172   operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date_period& dp) {
173     boost::io::ios_flags_saver iflags(os);
174     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
175     std::ostreambuf_iterator<CharT> output_itr(os);
176     if (std::has_facet<custom_date_facet>(os.getloc()))
177       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), dp);
178     else {
179       //instantiate a custom facet for dealing with date periods since the user
180       //has not put one in the stream so far.  This is for efficiency 
181       //since we would always need to reconstruct for every time period
182       //if the local did not already exist.  Of course this will be overridden
183       //if the user imbues at some later point.  With the default settings
184       //for the facet the resulting format will be the same as the
185       //std::time_facet settings.
186       custom_date_facet* f = new custom_date_facet();
187       std::locale l = std::locale(os.getloc(), f);
188       os.imbue(l);
189       f->put(output_itr, os, os.fill(), dp);
190
191     }
192     return os;
193   }
194
195   //! input operator for date_period 
196   template <class CharT, class Traits>
197   inline
198   std::basic_istream<CharT, Traits>&
199   operator>>(std::basic_istream<CharT, Traits>& is, date_period& dp)
200   {
201     boost::io::ios_flags_saver iflags(is);
202     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
203     if (strm_sentry) {
204       try {
205         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
206
207         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
208         if(std::has_facet<date_input_facet>(is.getloc())) {
209           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, dp);
210         }
211         else {
212           date_input_facet* f = new date_input_facet();
213           std::locale l = std::locale(is.getloc(), f);
214           is.imbue(l);
215           f->get(sit, str_end, is, dp);
216         }
217       }
218       catch(...) { 
219         std::ios_base::iostate exception_mask = is.exceptions();
220         if(std::ios_base::failbit & exception_mask) {
221           try { is.setstate(std::ios_base::failbit); } 
222           catch(std::ios_base::failure&) {}
223           throw; // rethrow original exception
224         }
225         else {
226           is.setstate(std::ios_base::failbit); 
227         } 
228             
229       }
230     }
231     return is;
232   }
233
234   /********** small gregorian types **********/
235   
236   template <class CharT, class TraitsT>
237   inline std::basic_ostream<CharT, TraitsT>&
238   operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::greg_month& gm) {
239     boost::io::ios_flags_saver iflags(os);
240     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
241     std::ostreambuf_iterator<CharT> output_itr(os);
242     if (std::has_facet<custom_date_facet>(os.getloc()))
243       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), gm);
244     else {
245       custom_date_facet* f = new custom_date_facet();//-> 10/1074199752/32 because year & day not initialized in put(...)
246       //custom_date_facet* f = new custom_date_facet("%B");
247       std::locale l = std::locale(os.getloc(), f);
248       os.imbue(l);
249       f->put(output_itr, os, os.fill(), gm);
250     }
251     return os;
252   }
253
254   //! input operator for greg_month
255   template <class CharT, class Traits>
256   inline
257   std::basic_istream<CharT, Traits>&
258   operator>>(std::basic_istream<CharT, Traits>& is, greg_month& m)
259   {
260     boost::io::ios_flags_saver iflags(is);
261     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
262     if (strm_sentry) {
263       try {
264         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
265
266         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
267         if(std::has_facet<date_input_facet>(is.getloc())) {
268           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, m);
269         }
270         else {
271           date_input_facet* f = new date_input_facet();
272           std::locale l = std::locale(is.getloc(), f);
273           is.imbue(l);
274           f->get(sit, str_end, is, m);
275         }
276       }
277       catch(...) { 
278         std::ios_base::iostate exception_mask = is.exceptions();
279         if(std::ios_base::failbit & exception_mask) {
280           try { is.setstate(std::ios_base::failbit); } 
281           catch(std::ios_base::failure&) {}
282           throw; // rethrow original exception
283         }
284         else {
285           is.setstate(std::ios_base::failbit); 
286         } 
287             
288       }
289     }
290     return is;
291   }
292
293
294   template <class CharT, class TraitsT>
295   inline std::basic_ostream<CharT, TraitsT>&
296   operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::greg_weekday& gw) {
297     boost::io::ios_flags_saver iflags(os);
298     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
299     std::ostreambuf_iterator<CharT> output_itr(os);
300     if (std::has_facet<custom_date_facet>(os.getloc()))
301       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), gw);
302     else {
303       custom_date_facet* f = new custom_date_facet();
304       std::locale l = std::locale(os.getloc(), f);
305       os.imbue(l);
306       f->put(output_itr, os, os.fill(), gw);
307     }
308     return os;
309   }
310  
311   //! input operator for greg_weekday
312   template <class CharT, class Traits>
313   inline
314   std::basic_istream<CharT, Traits>&
315   operator>>(std::basic_istream<CharT, Traits>& is, greg_weekday& wd)
316   {
317     boost::io::ios_flags_saver iflags(is);
318     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
319     if (strm_sentry) {
320       try {
321         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
322
323         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
324         if(std::has_facet<date_input_facet>(is.getloc())) {
325           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, wd);
326         }
327         else {
328           date_input_facet* f = new date_input_facet();
329           std::locale l = std::locale(is.getloc(), f);
330           is.imbue(l);
331           f->get(sit, str_end, is, wd);
332         }
333       }
334       catch(...) { 
335         std::ios_base::iostate exception_mask = is.exceptions();
336         if(std::ios_base::failbit & exception_mask) {
337           try { is.setstate(std::ios_base::failbit); } 
338           catch(std::ios_base::failure&) {}
339           throw; // rethrow original exception
340         }
341         else {
342           is.setstate(std::ios_base::failbit); 
343         } 
344             
345       }
346     }
347     return is;
348   }
349
350   //NOTE: output operator for greg_day was not necessary
351
352   //! input operator for greg_day
353   template <class CharT, class Traits>
354   inline
355   std::basic_istream<CharT, Traits>&
356   operator>>(std::basic_istream<CharT, Traits>& is, greg_day& gd)
357   {
358     boost::io::ios_flags_saver iflags(is);
359     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
360     if (strm_sentry) {
361       try {
362         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
363
364         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
365         if(std::has_facet<date_input_facet>(is.getloc())) {
366           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, gd);
367         }
368         else {
369           date_input_facet* f = new date_input_facet();
370           std::locale l = std::locale(is.getloc(), f);
371           is.imbue(l);
372           f->get(sit, str_end, is, gd);
373         }
374       }
375       catch(...) { 
376         std::ios_base::iostate exception_mask = is.exceptions();
377         if(std::ios_base::failbit & exception_mask) {
378           try { is.setstate(std::ios_base::failbit); } 
379           catch(std::ios_base::failure&) {}
380           throw; // rethrow original exception
381         }
382         else {
383           is.setstate(std::ios_base::failbit); 
384         } 
385             
386       }
387     }
388     return is;
389   }
390
391   //NOTE: output operator for greg_year was not necessary
392
393   //! input operator for greg_year
394   template <class CharT, class Traits>
395   inline
396   std::basic_istream<CharT, Traits>&
397   operator>>(std::basic_istream<CharT, Traits>& is, greg_year& gy)
398   {
399     boost::io::ios_flags_saver iflags(is);
400     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
401     if (strm_sentry) {
402       try {
403         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
404
405         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
406         if(std::has_facet<date_input_facet>(is.getloc())) {
407           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, gy);
408         }
409         else {
410           date_input_facet* f = new date_input_facet();
411           std::locale l = std::locale(is.getloc(), f);
412           is.imbue(l);
413           f->get(sit, str_end, is, gy);
414         }
415       }
416       catch(...) { 
417         std::ios_base::iostate exception_mask = is.exceptions();
418         if(std::ios_base::failbit & exception_mask) {
419           try { is.setstate(std::ios_base::failbit); } 
420           catch(std::ios_base::failure&) {}
421           throw; // rethrow original exception
422         }
423         else {
424           is.setstate(std::ios_base::failbit); 
425         } 
426             
427       }
428     }
429     return is;
430   }
431
432   /********** date generator types **********/
433   
434   template <class CharT, class TraitsT>
435   inline std::basic_ostream<CharT, TraitsT>&
436   operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::partial_date& pd) {
437     boost::io::ios_flags_saver iflags(os);
438     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
439     std::ostreambuf_iterator<CharT> output_itr(os);
440     if (std::has_facet<custom_date_facet>(os.getloc()))
441       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), pd);
442     else {
443       custom_date_facet* f = new custom_date_facet();
444       std::locale l = std::locale(os.getloc(), f);
445       os.imbue(l);
446       f->put(output_itr, os, os.fill(), pd);
447     }
448     return os;
449   }
450
451   //! input operator for partial_date
452   template <class CharT, class Traits>
453   inline
454   std::basic_istream<CharT, Traits>&
455   operator>>(std::basic_istream<CharT, Traits>& is, partial_date& pd)
456   {
457     boost::io::ios_flags_saver iflags(is);
458     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
459     if (strm_sentry) {
460       try {
461         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
462
463         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
464         if(std::has_facet<date_input_facet>(is.getloc())) {
465           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, pd);
466         }
467         else {
468           date_input_facet* f = new date_input_facet();
469           std::locale l = std::locale(is.getloc(), f);
470           is.imbue(l);
471           f->get(sit, str_end, is, pd);
472         }
473       }
474       catch(...) { 
475         std::ios_base::iostate exception_mask = is.exceptions();
476         if(std::ios_base::failbit & exception_mask) {
477           try { is.setstate(std::ios_base::failbit); } 
478           catch(std::ios_base::failure&) {}
479           throw; // rethrow original exception
480         }
481         else {
482           is.setstate(std::ios_base::failbit); 
483         } 
484             
485       }
486     }
487     return is;
488   }
489
490   template <class CharT, class TraitsT>
491   inline std::basic_ostream<CharT, TraitsT>&
492   operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::nth_day_of_the_week_in_month& nkd) {
493     boost::io::ios_flags_saver iflags(os);
494     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
495     std::ostreambuf_iterator<CharT> output_itr(os);
496     if (std::has_facet<custom_date_facet>(os.getloc()))
497       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), nkd);
498     else {
499       custom_date_facet* f = new custom_date_facet();
500       std::locale l = std::locale(os.getloc(), f);
501       os.imbue(l);
502       f->put(output_itr, os, os.fill(), nkd);
503     }
504     return os;
505   }
506
507   //! input operator for nth_day_of_the_week_in_month
508   template <class CharT, class Traits>
509   inline
510   std::basic_istream<CharT, Traits>&
511   operator>>(std::basic_istream<CharT, Traits>& is, 
512              nth_day_of_the_week_in_month& nday)
513   {
514     boost::io::ios_flags_saver iflags(is);
515     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
516     if (strm_sentry) {
517       try {
518         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
519
520         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
521         if(std::has_facet<date_input_facet>(is.getloc())) {
522           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, nday);
523         }
524         else {
525           date_input_facet* f = new date_input_facet();
526           std::locale l = std::locale(is.getloc(), f);
527           is.imbue(l);
528           f->get(sit, str_end, is, nday);
529         }
530       }
531       catch(...) { 
532         std::ios_base::iostate exception_mask = is.exceptions();
533         if(std::ios_base::failbit & exception_mask) {
534           try { is.setstate(std::ios_base::failbit); } 
535           catch(std::ios_base::failure&) {}
536           throw; // rethrow original exception
537         }
538         else {
539           is.setstate(std::ios_base::failbit); 
540         } 
541             
542       }
543     }
544     return is;
545   }
546
547
548   template <class CharT, class TraitsT>
549   inline std::basic_ostream<CharT, TraitsT>&
550   operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_in_month& fkd) {
551     boost::io::ios_flags_saver iflags(os);
552     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
553     std::ostreambuf_iterator<CharT> output_itr(os);
554     if (std::has_facet<custom_date_facet>(os.getloc()))
555       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fkd);
556     else {
557       custom_date_facet* f = new custom_date_facet();
558       std::locale l = std::locale(os.getloc(), f);
559       os.imbue(l);
560       f->put(output_itr, os, os.fill(), fkd);
561     }
562     return os;
563   }
564
565   //! input operator for first_day_of_the_week_in_month
566   template <class CharT, class Traits>
567   inline
568   std::basic_istream<CharT, Traits>&
569   operator>>(std::basic_istream<CharT, Traits>& is, 
570              first_day_of_the_week_in_month& fkd)
571   {
572     boost::io::ios_flags_saver iflags(is);
573     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
574     if (strm_sentry) {
575       try {
576         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
577
578         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
579         if(std::has_facet<date_input_facet>(is.getloc())) {
580           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fkd);
581         }
582         else {
583           date_input_facet* f = new date_input_facet();
584           std::locale l = std::locale(is.getloc(), f);
585           is.imbue(l);
586           f->get(sit, str_end, is, fkd);
587         }
588       }
589       catch(...) { 
590         std::ios_base::iostate exception_mask = is.exceptions();
591         if(std::ios_base::failbit & exception_mask) {
592           try { is.setstate(std::ios_base::failbit); } 
593           catch(std::ios_base::failure&) {}
594           throw; // rethrow original exception
595         }
596         else {
597           is.setstate(std::ios_base::failbit); 
598         } 
599             
600       }
601     }
602     return is;
603   }
604
605
606   template <class CharT, class TraitsT>
607   inline std::basic_ostream<CharT, TraitsT>&
608   operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::last_day_of_the_week_in_month& lkd) {
609     boost::io::ios_flags_saver iflags(os);
610     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
611     std::ostreambuf_iterator<CharT> output_itr(os);
612     if (std::has_facet<custom_date_facet>(os.getloc()))
613       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), lkd);
614     else {
615       custom_date_facet* f = new custom_date_facet();
616       std::locale l = std::locale(os.getloc(), f);
617       os.imbue(l);
618       f->put(output_itr, os, os.fill(), lkd);
619     }
620     return os;
621   }
622
623   //! input operator for last_day_of_the_week_in_month
624   template <class CharT, class Traits>
625   inline
626   std::basic_istream<CharT, Traits>&
627   operator>>(std::basic_istream<CharT, Traits>& is, 
628              last_day_of_the_week_in_month& lkd)
629   {
630     boost::io::ios_flags_saver iflags(is);
631     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
632     if (strm_sentry) {
633       try {
634         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
635
636         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
637         if(std::has_facet<date_input_facet>(is.getloc())) {
638           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, lkd);
639         }
640         else {
641           date_input_facet* f = new date_input_facet();
642           std::locale l = std::locale(is.getloc(), f);
643           is.imbue(l);
644           f->get(sit, str_end, is, lkd);
645         }
646       }
647       catch(...) { 
648         std::ios_base::iostate exception_mask = is.exceptions();
649         if(std::ios_base::failbit & exception_mask) {
650           try { is.setstate(std::ios_base::failbit); } 
651           catch(std::ios_base::failure&) {}
652           throw; // rethrow original exception
653         }
654         else {
655           is.setstate(std::ios_base::failbit); 
656         } 
657             
658       }
659     }
660     return is;
661   }
662
663
664   template <class CharT, class TraitsT>
665   inline std::basic_ostream<CharT, TraitsT>&
666   operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_after& fda) {
667     boost::io::ios_flags_saver iflags(os);
668     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
669     std::ostreambuf_iterator<CharT> output_itr(os);
670     if (std::has_facet<custom_date_facet>(os.getloc())) {
671       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fda);
672     } 
673     else {
674       custom_date_facet* f = new custom_date_facet();
675       std::locale l = std::locale(os.getloc(), f);
676       os.imbue(l);
677       f->put(output_itr, os, os.fill(), fda);
678     }
679     return os;
680   }
681
682   //! input operator for first_day_of_the_week_after
683   template <class CharT, class Traits>
684   inline
685   std::basic_istream<CharT, Traits>&
686   operator>>(std::basic_istream<CharT, Traits>& is, 
687              first_day_of_the_week_after& fka)
688   {
689     boost::io::ios_flags_saver iflags(is);
690     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
691     if (strm_sentry) {
692       try {
693         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
694
695         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
696         if(std::has_facet<date_input_facet>(is.getloc())) {
697           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fka);
698         }
699         else {
700           date_input_facet* f = new date_input_facet();
701           std::locale l = std::locale(is.getloc(), f);
702           is.imbue(l);
703           f->get(sit, str_end, is, fka);
704         }
705       }
706       catch(...) { 
707         std::ios_base::iostate exception_mask = is.exceptions();
708         if(std::ios_base::failbit & exception_mask) {
709           try { is.setstate(std::ios_base::failbit); } 
710           catch(std::ios_base::failure&) {}
711           throw; // rethrow original exception
712         }
713         else {
714           is.setstate(std::ios_base::failbit); 
715         } 
716             
717       }
718     }
719     return is;
720   }
721
722
723   template <class CharT, class TraitsT>
724   inline std::basic_ostream<CharT, TraitsT>&
725   operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_before& fdb) {
726     boost::io::ios_flags_saver iflags(os);
727     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
728     std::ostreambuf_iterator<CharT> output_itr(os);
729     if (std::has_facet<custom_date_facet>(os.getloc())) {
730       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fdb);
731     }
732     else {
733       custom_date_facet* f = new custom_date_facet();
734       std::locale l = std::locale(os.getloc(), f);
735       os.imbue(l);
736       f->put(output_itr, os, os.fill(), fdb);
737     }
738     return os;
739   }
740
741   //! input operator for first_day_of_the_week_before
742   template <class CharT, class Traits>
743   inline
744   std::basic_istream<CharT, Traits>&
745   operator>>(std::basic_istream<CharT, Traits>& is, 
746              first_day_of_the_week_before& fkb)
747   {
748     boost::io::ios_flags_saver iflags(is);
749     typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
750     if (strm_sentry) {
751       try {
752         typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
753
754         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
755         if(std::has_facet<date_input_facet>(is.getloc())) {
756           std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fkb);
757         }
758         else {
759           date_input_facet* f = new date_input_facet();
760           std::locale l = std::locale(is.getloc(), f);
761           is.imbue(l);
762           f->get(sit, str_end, is, fkb);
763         }
764       }
765       catch(...) { 
766         std::ios_base::iostate exception_mask = is.exceptions();
767         if(std::ios_base::failbit & exception_mask) {
768           try { is.setstate(std::ios_base::failbit); } 
769           catch(std::ios_base::failure&) {}
770           throw; // rethrow original exception
771         }
772         else {
773           is.setstate(std::ios_base::failbit); 
774         } 
775             
776       }
777     }
778     return is;
779   }
780
781   
782 } } // namespaces
783
784 #endif // DATE_TIME_GREGORIAN_IO_HPP__