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$
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/compiler_config.hpp>
18 #include <boost/date_time/special_defs.hpp>
19 #include <boost/date_time/date_defs.hpp>
20 #include <boost/date_time/parse_format_base.hpp>
21 #include <boost/lexical_cast.hpp>
22 #include <locale>
23 
24 
25 namespace boost {
26 namespace date_time {
27 
28     //! Output facet base class for gregorian dates.
29     /*! This class is a base class for date facets used to localize the
30      *  names of months and the names of days in the week.
31      *
32      * Requirements of Config
33      *  - define an enumeration month_enum that enumerates the months.
34      *    The enumeration should be '1' based eg: Jan==1
35      *  - define as_short_string and as_long_string
36      *
37      * (see langer & kreft p334).
38      *
39      */
40     template<class Config,
41              class charT = char,
42              class OutputIterator = std::ostreambuf_iterator<charT> >
43     class BOOST_SYMBOL_VISIBLE date_names_put : public std::locale::facet
44     {
45     public:
date_names_put()46       date_names_put() {}
47       typedef OutputIterator iter_type;
48       typedef typename Config::month_type month_type;
49       typedef typename Config::month_enum month_enum;
50       typedef typename Config::weekday_enum weekday_enum;
51       typedef typename Config::special_value_enum special_value_enum;
52       //typedef typename Config::format_type format_type;
53       typedef std::basic_string<charT> string_type;
54       typedef charT char_type;
55       static const char_type default_special_value_names[3][17];
56       static const char_type separator[2];
57 
58       static std::locale::id id;
59 
60 #if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
__get_id(void) const61       std::locale::id& __get_id (void) const { return id; }
62 #endif
63 
put_special_value(iter_type & oitr,special_value_enum sv) const64       void put_special_value(iter_type& oitr, special_value_enum sv) const
65       {
66         do_put_special_value(oitr, sv);
67       }
put_month_short(iter_type & oitr,month_enum moy) const68       void put_month_short(iter_type& oitr, month_enum moy) const
69       {
70         do_put_month_short(oitr, moy);
71       }
put_month_long(iter_type & oitr,month_enum moy) const72       void put_month_long(iter_type& oitr, month_enum moy) const
73       {
74         do_put_month_long(oitr, moy);
75       }
put_weekday_short(iter_type & oitr,weekday_enum wd) const76       void put_weekday_short(iter_type& oitr, weekday_enum wd) const
77       {
78         do_put_weekday_short(oitr, wd);
79       }
put_weekday_long(iter_type & oitr,weekday_enum wd) const80       void put_weekday_long(iter_type& oitr, weekday_enum wd) const
81       {
82         do_put_weekday_long(oitr, wd);
83       }
has_date_sep_chars() const84       bool has_date_sep_chars() const
85       {
86         return do_has_date_sep_chars();
87       }
year_sep_char(iter_type & oitr) const88       void year_sep_char(iter_type& oitr) const
89       {
90         do_year_sep_char(oitr);
91       }
92       //! char between year-month
month_sep_char(iter_type & oitr) const93       void month_sep_char(iter_type& oitr) const
94       {
95         do_month_sep_char(oitr);
96       }
97       //! Char to separate month-day
day_sep_char(iter_type & oitr) const98       void day_sep_char(iter_type& oitr) const
99       {
100         do_day_sep_char(oitr);
101       }
102       //! Determines the order to put the date elements
date_order() const103       ymd_order_spec date_order() const
104       {
105         return do_date_order();
106       }
107       //! Determines if month is displayed as integer, short or long string
month_format() const108       month_format_spec month_format() const
109       {
110         return do_month_format();
111       }
112 
113     protected:
114       //! Default facet implementation uses month_type defaults
do_put_month_short(iter_type & oitr,month_enum moy) const115       virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
116       {
117         month_type gm(moy);
118         charT c = '\0';
119         put_string(oitr, gm.as_short_string(c));
120       }
121       //! Default facet implementation uses month_type defaults
do_put_month_long(iter_type & oitr,month_enum moy) const122       virtual void do_put_month_long(iter_type& oitr,
123                                      month_enum moy) const
124       {
125         month_type gm(moy);
126         charT c = '\0';
127         put_string(oitr, gm.as_long_string(c));
128       }
129       //! Default facet implementation for special value types
do_put_special_value(iter_type & oitr,special_value_enum sv) const130       virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
131       {
132         if(sv <= 2) { // only output not_a_date_time, neg_infin, or pos_infin
133           string_type s(default_special_value_names[sv]);
134           put_string(oitr, s);
135         }
136       }
do_put_weekday_short(iter_type &,weekday_enum) const137       virtual void do_put_weekday_short(iter_type&, weekday_enum) const
138       {
139       }
do_put_weekday_long(iter_type &,weekday_enum) const140       virtual void do_put_weekday_long(iter_type&, weekday_enum) const
141       {
142       }
do_has_date_sep_chars() const143       virtual bool do_has_date_sep_chars() const
144       {
145         return true;
146       }
do_year_sep_char(iter_type & oitr) const147       virtual void do_year_sep_char(iter_type& oitr) const
148       {
149         string_type s(separator);
150         put_string(oitr, s);
151       }
152       //! char between year-month
do_month_sep_char(iter_type & oitr) const153       virtual void do_month_sep_char(iter_type& oitr) const
154       {
155         string_type s(separator);
156         put_string(oitr, s);
157       }
158       //! Char to separate month-day
do_day_sep_char(iter_type & oitr) const159       virtual void do_day_sep_char(iter_type& oitr) const
160       {
161         string_type s(separator); //put in '-'
162         put_string(oitr, s);
163       }
164       //! Default for date order
do_date_order() const165       virtual ymd_order_spec do_date_order() const
166       {
167         return ymd_order_iso;
168       }
169       //! Default month format
do_month_format() const170       virtual month_format_spec do_month_format() const
171       {
172         return month_as_short_string;
173       }
put_string(iter_type & oi,const charT * const s) const174       void put_string(iter_type& oi, const charT* const s) const
175       {
176         string_type s1(boost::lexical_cast<string_type>(s));
177         typename string_type::iterator si,end;
178         for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
179           *oi = *si;
180         }
181       }
put_string(iter_type & oi,const string_type & s1) const182       void put_string(iter_type& oi, const string_type& s1) const
183       {
184         typename string_type::const_iterator si,end;
185         for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
186           *oi = *si;
187         }
188       }
189     };
190 
191     template<class Config, class charT, class OutputIterator>
192     const typename date_names_put<Config, charT, OutputIterator>::char_type
193     date_names_put<Config, charT, OutputIterator>::default_special_value_names[3][17] = {
194       {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'},
195       {'-','i','n','f','i','n','i','t','y'},
196       {'+','i','n','f','i','n','i','t','y'} };
197 
198     template<class Config, class charT, class OutputIterator>
199     const typename date_names_put<Config, charT, OutputIterator>::char_type
200     date_names_put<Config, charT, OutputIterator>::separator[2] =
201       {'-', '\0'} ;
202 
203 
204     //! Generate storage location for a std::locale::id
205     template<class Config, class charT, class OutputIterator>
206     std::locale::id date_names_put<Config, charT, OutputIterator>::id;
207 
208     //! A date name output facet that takes an array of char* to define strings
209     template<class Config,
210              class charT = char,
211              class OutputIterator = std::ostreambuf_iterator<charT> >
212     class BOOST_SYMBOL_VISIBLE all_date_names_put : public date_names_put<Config, charT, OutputIterator>
213     {
214     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)215       all_date_names_put(const charT* const month_short_names[],
216                          const charT* const month_long_names[],
217                          const charT* const special_value_names[],
218                          const charT* const weekday_short_names[],
219                          const charT* const weekday_long_names[],
220                          charT separator_char = '-',
221                          ymd_order_spec order_spec = ymd_order_iso,
222                          month_format_spec month_format = month_as_short_string) :
223         month_short_names_(month_short_names),
224         month_long_names_(month_long_names),
225         special_value_names_(special_value_names),
226         weekday_short_names_(weekday_short_names),
227         weekday_long_names_(weekday_long_names),
228         order_spec_(order_spec),
229         month_format_spec_(month_format)
230       {
231         separator_char_[0] = separator_char;
232         separator_char_[1] = '\0';
233 
234       }
235       typedef OutputIterator iter_type;
236       typedef typename Config::month_enum month_enum;
237       typedef typename Config::weekday_enum weekday_enum;
238       typedef typename Config::special_value_enum special_value_enum;
239 
get_short_month_names() const240       const charT* const* get_short_month_names() const
241       {
242         return month_short_names_;
243       }
get_long_month_names() const244       const charT* const* get_long_month_names() const
245       {
246         return month_long_names_;
247       }
get_special_value_names() const248       const charT* const* get_special_value_names() const
249       {
250         return special_value_names_;
251       }
get_short_weekday_names() const252       const charT* const* get_short_weekday_names()const
253       {
254         return weekday_short_names_;
255       }
get_long_weekday_names() const256       const charT* const* get_long_weekday_names()const
257       {
258         return weekday_long_names_;
259       }
260 
261     protected:
262       //! Generic facet that takes array of chars
do_put_month_short(iter_type & oitr,month_enum moy) const263       virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
264       {
265         this->put_string(oitr, month_short_names_[moy-1]);
266       }
267       //! Long month names
do_put_month_long(iter_type & oitr,month_enum moy) const268       virtual void do_put_month_long(iter_type& oitr, month_enum moy) const
269       {
270         this->put_string(oitr, month_long_names_[moy-1]);
271       }
272       //! Special values names
do_put_special_value(iter_type & oitr,special_value_enum sv) const273       virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
274       {
275         this->put_string(oitr, special_value_names_[sv]);
276       }
do_put_weekday_short(iter_type & oitr,weekday_enum wd) const277       virtual void do_put_weekday_short(iter_type& oitr, weekday_enum wd) const
278       {
279         this->put_string(oitr, weekday_short_names_[wd]);
280       }
do_put_weekday_long(iter_type & oitr,weekday_enum wd) const281       virtual void do_put_weekday_long(iter_type& oitr, weekday_enum wd) const
282       {
283         this->put_string(oitr, weekday_long_names_[wd]);
284       }
285       //! char between year-month
do_month_sep_char(iter_type & oitr) const286       virtual void do_month_sep_char(iter_type& oitr) const
287       {
288         this->put_string(oitr, separator_char_);
289       }
290       //! Char to separate month-day
do_day_sep_char(iter_type & oitr) const291       virtual void do_day_sep_char(iter_type& oitr) const
292       {
293         this->put_string(oitr, separator_char_);
294       }
295       //! Set the date ordering
do_date_order() const296       virtual ymd_order_spec do_date_order() const
297       {
298         return order_spec_;
299       }
300       //! Set the date ordering
do_month_format() const301       virtual month_format_spec do_month_format() const
302       {
303         return month_format_spec_;
304       }
305 
306     private:
307       const charT* const* month_short_names_;
308       const charT* const* month_long_names_;
309       const charT* const* special_value_names_;
310       const charT* const* weekday_short_names_;
311       const charT* const* weekday_long_names_;
312       charT separator_char_[2];
313       ymd_order_spec order_spec_;
314       month_format_spec month_format_spec_;
315     };
316 
317 } } //namespace boost::date_time
318 
319 #endif //BOOST_NO_STD_LOCALE
320 
321 #endif
322