1 #ifndef DATE_TIME_DATE_NAMES_PUT_HPP___
2 #define DATE_TIME_DATE_NAMES_PUT_HPP___
3 
4 /* Copyright (c) 2002-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: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
10  */
11 
12 
13 #include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE
14 
15 #ifndef BOOST_DATE_TIME_NO_LOCALE
16 
17 #include "boost/date_time/special_defs.hpp"
18 #include "boost/date_time/date_defs.hpp"
19 #include "boost/date_time/parse_format_base.hpp"
20 #include "boost/lexical_cast.hpp"
21 #include <locale>
22 
23 
24 namespace boost {
25 namespace date_time {
26 
27     //! Output facet base class for gregorian dates.
28     /*! This class is a base class for date facets used to localize the
29      *  names of months and the names of days in the week.
30      *
31      * Requirements of Config
32      *  - define an enumeration month_enum that enumerates the months.
33      *    The enumeration should be '1' based eg: Jan==1
34      *  - define as_short_string and as_long_string
35      *
36      * (see langer & kreft p334).
37      *
38      */
39     template<class Config,
40              class charT = char,
41              class OutputIterator = std::ostreambuf_iterator<charT> >
42     class date_names_put : public std::locale::facet
43     {
44     public:
date_names_put()45       date_names_put() {};
46       typedef OutputIterator iter_type;
47       typedef typename Config::month_type month_type;
48       typedef typename Config::month_enum month_enum;
49       typedef typename Config::weekday_enum weekday_enum;
50       typedef typename Config::special_value_enum special_value_enum;
51       //typedef typename Config::format_type format_type;
52       typedef std::basic_string<charT> string_type;
53       typedef charT char_type;
54       static const char_type default_special_value_names[3][17];
55       static const char_type separator[2];
56 
57       static std::locale::id id;
58 
59 #if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
__get_id(void) const60       std::locale::id& __get_id (void) const { return id; }
61 #endif
62 
put_special_value(iter_type & oitr,special_value_enum sv) const63       void put_special_value(iter_type& oitr, special_value_enum sv) const
64       {
65         do_put_special_value(oitr, sv);
66       }
put_month_short(iter_type & oitr,month_enum moy) const67       void put_month_short(iter_type& oitr, month_enum moy) const
68       {
69         do_put_month_short(oitr, moy);
70       }
put_month_long(iter_type & oitr,month_enum moy) const71       void put_month_long(iter_type& oitr, month_enum moy) const
72       {
73         do_put_month_long(oitr, moy);
74       }
put_weekday_short(iter_type & oitr,weekday_enum wd) const75       void put_weekday_short(iter_type& oitr, weekday_enum wd) const
76       {
77         do_put_weekday_short(oitr, wd);
78       }
put_weekday_long(iter_type & oitr,weekday_enum wd) const79       void put_weekday_long(iter_type& oitr, weekday_enum wd) const
80       {
81         do_put_weekday_long(oitr, wd);
82       }
has_date_sep_chars() const83       bool has_date_sep_chars() const
84       {
85         return do_has_date_sep_chars();
86       }
year_sep_char(iter_type & oitr) const87       void year_sep_char(iter_type& oitr) const
88       {
89         do_year_sep_char(oitr);
90       }
91       //! char between year-month
month_sep_char(iter_type & oitr) const92       void month_sep_char(iter_type& oitr) const
93       {
94         do_month_sep_char(oitr);
95       }
96       //! Char to separate month-day
day_sep_char(iter_type & oitr) const97       void day_sep_char(iter_type& oitr) const
98       {
99         do_day_sep_char(oitr);
100       }
101       //! Determines the order to put the date elements
date_order() const102       ymd_order_spec date_order() const
103       {
104         return do_date_order();
105       }
106       //! Determines if month is displayed as integer, short or long string
month_format() const107       month_format_spec month_format() const
108       {
109         return do_month_format();
110       }
111 
112     protected:
113       //! Default facet implementation uses month_type defaults
do_put_month_short(iter_type & oitr,month_enum moy) const114       virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
115       {
116         month_type gm(moy);
117         charT c = '\0';
118         put_string(oitr, gm.as_short_string(c));
119       }
120       //! Default facet implementation uses month_type defaults
do_put_month_long(iter_type & oitr,month_enum moy) const121       virtual void do_put_month_long(iter_type& oitr,
122                                      month_enum moy) const
123       {
124         month_type gm(moy);
125         charT c = '\0';
126         put_string(oitr, gm.as_long_string(c));
127       }
128       //! Default facet implementation for special value types
do_put_special_value(iter_type & oitr,special_value_enum sv) const129       virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
130       {
131         if(sv <= 2) { // only output not_a_date_time, neg_infin, or pos_infin
132           string_type s(default_special_value_names[sv]);
133           put_string(oitr, s);
134         }
135       }
do_put_weekday_short(iter_type &,weekday_enum) const136       virtual void do_put_weekday_short(iter_type&, weekday_enum) const
137       {
138       }
do_put_weekday_long(iter_type &,weekday_enum) const139       virtual void do_put_weekday_long(iter_type&, weekday_enum) const
140       {
141       }
do_has_date_sep_chars() const142       virtual bool do_has_date_sep_chars() const
143       {
144         return true;
145       }
do_year_sep_char(iter_type & oitr) const146       virtual void do_year_sep_char(iter_type& oitr) const
147       {
148         string_type s(separator);
149         put_string(oitr, s);
150       }
151       //! char between year-month
do_month_sep_char(iter_type & oitr) const152       virtual void do_month_sep_char(iter_type& oitr) const
153       {
154         string_type s(separator);
155         put_string(oitr, s);
156       }
157       //! Char to separate month-day
do_day_sep_char(iter_type & oitr) const158       virtual void do_day_sep_char(iter_type& oitr) const
159       {
160         string_type s(separator); //put in '-'
161         put_string(oitr, s);
162       }
163       //! Default for date order
do_date_order() const164       virtual ymd_order_spec do_date_order() const
165       {
166         return ymd_order_iso;
167       }
168       //! Default month format
do_month_format() const169       virtual month_format_spec do_month_format() const
170       {
171         return month_as_short_string;
172       }
put_string(iter_type & oi,const charT * const s) const173       void put_string(iter_type& oi, const charT* const s) const
174       {
175         string_type s1(boost::lexical_cast<string_type>(s));
176         typename string_type::iterator si,end;
177         for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
178           *oi = *si;
179         }
180       }
put_string(iter_type & oi,const string_type & s1) const181       void put_string(iter_type& oi, const string_type& s1) const
182       {
183         typename string_type::const_iterator si,end;
184         for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
185           *oi = *si;
186         }
187       }
188     };
189 
190     template<class Config, class charT, class OutputIterator>
191     const typename date_names_put<Config, charT, OutputIterator>::char_type
192     date_names_put<Config, charT, OutputIterator>::default_special_value_names[3][17] = {
193       {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'},
194       {'-','i','n','f','i','n','i','t','y'},
195       {'+','i','n','f','i','n','i','t','y'} };
196 
197     template<class Config, class charT, class OutputIterator>
198     const typename date_names_put<Config, charT, OutputIterator>::char_type
199     date_names_put<Config, charT, OutputIterator>::separator[2] =
200       {'-', '\0'} ;
201 
202 
203     //! Generate storage location for a std::locale::id
204     template<class Config, class charT, class OutputIterator>
205     std::locale::id date_names_put<Config, charT, OutputIterator>::id;
206 
207     //! A date name output facet that takes an array of char* to define strings
208     template<class Config,
209              class charT = char,
210              class OutputIterator = std::ostreambuf_iterator<charT> >
211     class all_date_names_put : public date_names_put<Config, charT, OutputIterator>
212     {
213     public:
all_date_names_put(const charT * const month_short_names[],const charT * const month_long_names[],const charT * const special_value_names[],const charT * const weekday_short_names[],const charT * const weekday_long_names[],charT separator_char='-',ymd_order_spec order_spec=ymd_order_iso,month_format_spec month_format=month_as_short_string)214       all_date_names_put(const charT* const month_short_names[],
215                          const charT* const month_long_names[],
216                          const charT* const special_value_names[],
217                          const charT* const weekday_short_names[],
218                          const charT* const weekday_long_names[],
219                          charT separator_char = '-',
220                          ymd_order_spec order_spec = ymd_order_iso,
221                          month_format_spec month_format = month_as_short_string) :
222         month_short_names_(month_short_names),
223         month_long_names_(month_long_names),
224         special_value_names_(special_value_names),
225         weekday_short_names_(weekday_short_names),
226         weekday_long_names_(weekday_long_names),
227         order_spec_(order_spec),
228         month_format_spec_(month_format)
229       {
230         separator_char_[0] = separator_char;
231         separator_char_[1] = '\0';
232 
233       };
234       typedef OutputIterator iter_type;
235       typedef typename Config::month_enum month_enum;
236       typedef typename Config::weekday_enum weekday_enum;
237       typedef typename Config::special_value_enum special_value_enum;
238 
get_short_month_names() const239       const charT* const* get_short_month_names() const
240       {
241         return month_short_names_;
242       }
get_long_month_names() const243       const charT* const* get_long_month_names() const
244       {
245         return month_long_names_;
246       }
get_special_value_names() const247       const charT* const* get_special_value_names() const
248       {
249         return special_value_names_;
250       }
get_short_weekday_names() const251       const charT* const* get_short_weekday_names()const
252       {
253         return weekday_short_names_;
254       }
get_long_weekday_names() const255       const charT* const* get_long_weekday_names()const
256       {
257         return weekday_long_names_;
258       }
259 
260     protected:
261       //! Generic facet that takes array of chars
do_put_month_short(iter_type & oitr,month_enum moy) const262       virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
263       {
264         this->put_string(oitr, month_short_names_[moy-1]);
265       }
266       //! Long month names
do_put_month_long(iter_type & oitr,month_enum moy) const267       virtual void do_put_month_long(iter_type& oitr, month_enum moy) const
268       {
269         this->put_string(oitr, month_long_names_[moy-1]);
270       }
271       //! Special values names
do_put_special_value(iter_type & oitr,special_value_enum sv) const272       virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
273       {
274         this->put_string(oitr, special_value_names_[sv]);
275       }
do_put_weekday_short(iter_type & oitr,weekday_enum wd) const276       virtual void do_put_weekday_short(iter_type& oitr, weekday_enum wd) const
277       {
278         this->put_string(oitr, weekday_short_names_[wd]);
279       }
do_put_weekday_long(iter_type & oitr,weekday_enum wd) const280       virtual void do_put_weekday_long(iter_type& oitr, weekday_enum wd) const
281       {
282         this->put_string(oitr, weekday_long_names_[wd]);
283       }
284       //! char between year-month
do_month_sep_char(iter_type & oitr) const285       virtual void do_month_sep_char(iter_type& oitr) const
286       {
287         this->put_string(oitr, separator_char_);
288       }
289       //! Char to separate month-day
do_day_sep_char(iter_type & oitr) const290       virtual void do_day_sep_char(iter_type& oitr) const
291       {
292         this->put_string(oitr, separator_char_);
293       }
294       //! Set the date ordering
do_date_order() const295       virtual ymd_order_spec do_date_order() const
296       {
297         return order_spec_;
298       }
299       //! Set the date ordering
do_month_format() const300       virtual month_format_spec do_month_format() const
301       {
302         return month_format_spec_;
303       }
304 
305     private:
306       const charT* const* month_short_names_;
307       const charT* const* month_long_names_;
308       const charT* const* special_value_names_;
309       const charT* const* weekday_short_names_;
310       const charT* const* weekday_long_names_;
311       charT separator_char_[2];
312       ymd_order_spec order_spec_;
313       month_format_spec month_format_spec_;
314     };
315 
316 } } //namespace boost::date_time
317 
318 #endif //BOOST_NO_STD_LOCALE
319 
320 #endif
321