|
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 or http://www.boost.org/LICENSE-1.0) |
|
8 * Author: Jeff Garland, Bart Garst |
|
9 * $Date: 2005/04/16 18:59:51 $ |
|
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: |
|
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) |
|
60 std::locale::id& __get_id (void) const { return id; } |
|
61 #endif |
|
62 |
|
63 void put_special_value(iter_type& oitr, special_value_enum sv) const |
|
64 { |
|
65 do_put_special_value(oitr, sv); |
|
66 } |
|
67 void put_month_short(iter_type& oitr, month_enum moy) const |
|
68 { |
|
69 do_put_month_short(oitr, moy); |
|
70 } |
|
71 void put_month_long(iter_type& oitr, month_enum moy) const |
|
72 { |
|
73 do_put_month_long(oitr, moy); |
|
74 } |
|
75 void put_weekday_short(iter_type& oitr, weekday_enum wd) const |
|
76 { |
|
77 do_put_weekday_short(oitr, wd); |
|
78 } |
|
79 void put_weekday_long(iter_type& oitr, weekday_enum wd) const |
|
80 { |
|
81 do_put_weekday_long(oitr, wd); |
|
82 } |
|
83 bool has_date_sep_chars() const |
|
84 { |
|
85 return do_has_date_sep_chars(); |
|
86 } |
|
87 void year_sep_char(iter_type& oitr) const |
|
88 { |
|
89 do_year_sep_char(oitr); |
|
90 } |
|
91 //! char between year-month |
|
92 void month_sep_char(iter_type& oitr) const |
|
93 { |
|
94 do_month_sep_char(oitr); |
|
95 } |
|
96 //! Char to separate month-day |
|
97 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 |
|
102 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 |
|
107 month_format_spec month_format() const |
|
108 { |
|
109 return do_month_format(); |
|
110 } |
|
111 |
|
112 protected: |
|
113 //! Default facet implementation uses month_type defaults |
|
114 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 |
|
121 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 |
|
129 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 } |
|
136 virtual void do_put_weekday_short(iter_type&, weekday_enum) const |
|
137 { |
|
138 } |
|
139 virtual void do_put_weekday_long(iter_type&, weekday_enum) const |
|
140 { |
|
141 } |
|
142 virtual bool do_has_date_sep_chars() const |
|
143 { |
|
144 return true; |
|
145 } |
|
146 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 |
|
152 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 |
|
158 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 |
|
164 virtual ymd_order_spec do_date_order() const |
|
165 { |
|
166 return ymd_order_iso; |
|
167 } |
|
168 //! Default month format |
|
169 virtual month_format_spec do_month_format() const |
|
170 { |
|
171 return month_as_short_string; |
|
172 } |
|
173 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 } |
|
181 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: |
|
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 |
|
239 const charT* const* get_short_month_names() const |
|
240 { |
|
241 return month_short_names_; |
|
242 } |
|
243 const charT* const* get_long_month_names() const |
|
244 { |
|
245 return month_long_names_; |
|
246 } |
|
247 const charT* const* get_special_value_names() const |
|
248 { |
|
249 return special_value_names_; |
|
250 } |
|
251 const charT* const* get_short_weekday_names()const |
|
252 { |
|
253 return weekday_short_names_; |
|
254 } |
|
255 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 |
|
262 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 |
|
267 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 |
|
272 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 } |
|
276 virtual void do_put_weekday_short(iter_type& oitr, weekday_enum wd) const |
|
277 { |
|
278 this->put_string(oitr, weekday_short_names_[wd]); |
|
279 } |
|
280 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 |
|
285 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 |
|
290 virtual void do_day_sep_char(iter_type& oitr) const |
|
291 { |
|
292 this->put_string(oitr, separator_char_); |
|
293 } |
|
294 //! Set the date ordering |
|
295 virtual ymd_order_spec do_date_order() const |
|
296 { |
|
297 return order_spec_; |
|
298 } |
|
299 //! Set the date ordering |
|
300 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 |