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