date_names_put.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #ifndef DATE_TIME_DATE_NAMES_PUT_HPP___
  2. #define DATE_TIME_DATE_NAMES_PUT_HPP___
  3. /* Copyright (c) 2002-2005 CrystalClear Software, Inc.
  4. * Use, modification and distribution is subject to the
  5. * Boost Software License, Version 1.0. (See accompanying
  6. * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  7. * Author: Jeff Garland, Bart Garst
  8. * $Date$
  9. */
  10. #include <boost/date_time/locale_config.hpp> // set BOOST_DATE_TIME_NO_LOCALE
  11. #ifndef BOOST_DATE_TIME_NO_LOCALE
  12. #include <boost/date_time/compiler_config.hpp>
  13. #include <boost/date_time/special_defs.hpp>
  14. #include <boost/date_time/date_defs.hpp>
  15. #include <boost/date_time/parse_format_base.hpp>
  16. #include <boost/lexical_cast.hpp>
  17. #include <locale>
  18. namespace boost {
  19. namespace date_time {
  20. //! Output facet base class for gregorian dates.
  21. /*! This class is a base class for date facets used to localize the
  22. * names of months and the names of days in the week.
  23. *
  24. * Requirements of Config
  25. * - define an enumeration month_enum that enumerates the months.
  26. * The enumeration should be '1' based eg: Jan==1
  27. * - define as_short_string and as_long_string
  28. *
  29. * (see langer & kreft p334).
  30. *
  31. */
  32. template<class Config,
  33. class charT = char,
  34. class OutputIterator = std::ostreambuf_iterator<charT> >
  35. class BOOST_SYMBOL_VISIBLE date_names_put : public std::locale::facet
  36. {
  37. public:
  38. date_names_put() {}
  39. typedef OutputIterator iter_type;
  40. typedef typename Config::month_type month_type;
  41. typedef typename Config::month_enum month_enum;
  42. typedef typename Config::weekday_enum weekday_enum;
  43. typedef typename Config::special_value_enum special_value_enum;
  44. //typedef typename Config::format_type format_type;
  45. typedef std::basic_string<charT> string_type;
  46. typedef charT char_type;
  47. static const char_type default_special_value_names[3][17];
  48. static const char_type separator[2];
  49. static std::locale::id id;
  50. #if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
  51. std::locale::id& __get_id (void) const { return id; }
  52. #endif
  53. void put_special_value(iter_type& oitr, special_value_enum sv) const
  54. {
  55. do_put_special_value(oitr, sv);
  56. }
  57. void put_month_short(iter_type& oitr, month_enum moy) const
  58. {
  59. do_put_month_short(oitr, moy);
  60. }
  61. void put_month_long(iter_type& oitr, month_enum moy) const
  62. {
  63. do_put_month_long(oitr, moy);
  64. }
  65. void put_weekday_short(iter_type& oitr, weekday_enum wd) const
  66. {
  67. do_put_weekday_short(oitr, wd);
  68. }
  69. void put_weekday_long(iter_type& oitr, weekday_enum wd) const
  70. {
  71. do_put_weekday_long(oitr, wd);
  72. }
  73. bool has_date_sep_chars() const
  74. {
  75. return do_has_date_sep_chars();
  76. }
  77. void year_sep_char(iter_type& oitr) const
  78. {
  79. do_year_sep_char(oitr);
  80. }
  81. //! char between year-month
  82. void month_sep_char(iter_type& oitr) const
  83. {
  84. do_month_sep_char(oitr);
  85. }
  86. //! Char to separate month-day
  87. void day_sep_char(iter_type& oitr) const
  88. {
  89. do_day_sep_char(oitr);
  90. }
  91. //! Determines the order to put the date elements
  92. ymd_order_spec date_order() const
  93. {
  94. return do_date_order();
  95. }
  96. //! Determines if month is displayed as integer, short or long string
  97. month_format_spec month_format() const
  98. {
  99. return do_month_format();
  100. }
  101. protected:
  102. //! Default facet implementation uses month_type defaults
  103. virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
  104. {
  105. month_type gm(moy);
  106. charT c = '\0';
  107. put_string(oitr, gm.as_short_string(c));
  108. }
  109. //! Default facet implementation uses month_type defaults
  110. virtual void do_put_month_long(iter_type& oitr,
  111. month_enum moy) const
  112. {
  113. month_type gm(moy);
  114. charT c = '\0';
  115. put_string(oitr, gm.as_long_string(c));
  116. }
  117. //! Default facet implementation for special value types
  118. virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
  119. {
  120. if(sv <= 2) { // only output not_a_date_time, neg_infin, or pos_infin
  121. string_type s(default_special_value_names[sv]);
  122. put_string(oitr, s);
  123. }
  124. }
  125. virtual void do_put_weekday_short(iter_type&, weekday_enum) const
  126. {
  127. }
  128. virtual void do_put_weekday_long(iter_type&, weekday_enum) const
  129. {
  130. }
  131. virtual bool do_has_date_sep_chars() const
  132. {
  133. return true;
  134. }
  135. virtual void do_year_sep_char(iter_type& oitr) const
  136. {
  137. string_type s(separator);
  138. put_string(oitr, s);
  139. }
  140. //! char between year-month
  141. virtual void do_month_sep_char(iter_type& oitr) const
  142. {
  143. string_type s(separator);
  144. put_string(oitr, s);
  145. }
  146. //! Char to separate month-day
  147. virtual void do_day_sep_char(iter_type& oitr) const
  148. {
  149. string_type s(separator); //put in '-'
  150. put_string(oitr, s);
  151. }
  152. //! Default for date order
  153. virtual ymd_order_spec do_date_order() const
  154. {
  155. return ymd_order_iso;
  156. }
  157. //! Default month format
  158. virtual month_format_spec do_month_format() const
  159. {
  160. return month_as_short_string;
  161. }
  162. void put_string(iter_type& oi, const charT* const s) const
  163. {
  164. string_type s1(boost::lexical_cast<string_type>(s));
  165. typename string_type::iterator si,end;
  166. for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
  167. *oi = *si;
  168. }
  169. }
  170. void put_string(iter_type& oi, const string_type& s1) const
  171. {
  172. typename string_type::const_iterator si,end;
  173. for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
  174. *oi = *si;
  175. }
  176. }
  177. };
  178. template<class Config, class charT, class OutputIterator>
  179. const typename date_names_put<Config, charT, OutputIterator>::char_type
  180. date_names_put<Config, charT, OutputIterator>::default_special_value_names[3][17] = {
  181. {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'},
  182. {'-','i','n','f','i','n','i','t','y'},
  183. {'+','i','n','f','i','n','i','t','y'} };
  184. template<class Config, class charT, class OutputIterator>
  185. const typename date_names_put<Config, charT, OutputIterator>::char_type
  186. date_names_put<Config, charT, OutputIterator>::separator[2] =
  187. {'-', '\0'} ;
  188. //! Generate storage location for a std::locale::id
  189. template<class Config, class charT, class OutputIterator>
  190. std::locale::id date_names_put<Config, charT, OutputIterator>::id;
  191. //! A date name output facet that takes an array of char* to define strings
  192. template<class Config,
  193. class charT = char,
  194. class OutputIterator = std::ostreambuf_iterator<charT> >
  195. class BOOST_SYMBOL_VISIBLE all_date_names_put : public date_names_put<Config, charT, OutputIterator>
  196. {
  197. public:
  198. all_date_names_put(const charT* const month_short_names[],
  199. const charT* const month_long_names[],
  200. const charT* const special_value_names[],
  201. const charT* const weekday_short_names[],
  202. const charT* const weekday_long_names[],
  203. charT separator_char = '-',
  204. ymd_order_spec order_spec = ymd_order_iso,
  205. month_format_spec month_format = month_as_short_string) :
  206. month_short_names_(month_short_names),
  207. month_long_names_(month_long_names),
  208. special_value_names_(special_value_names),
  209. weekday_short_names_(weekday_short_names),
  210. weekday_long_names_(weekday_long_names),
  211. order_spec_(order_spec),
  212. month_format_spec_(month_format)
  213. {
  214. separator_char_[0] = separator_char;
  215. separator_char_[1] = '\0';
  216. }
  217. typedef OutputIterator iter_type;
  218. typedef typename Config::month_enum month_enum;
  219. typedef typename Config::weekday_enum weekday_enum;
  220. typedef typename Config::special_value_enum special_value_enum;
  221. const charT* const* get_short_month_names() const
  222. {
  223. return month_short_names_;
  224. }
  225. const charT* const* get_long_month_names() const
  226. {
  227. return month_long_names_;
  228. }
  229. const charT* const* get_special_value_names() const
  230. {
  231. return special_value_names_;
  232. }
  233. const charT* const* get_short_weekday_names()const
  234. {
  235. return weekday_short_names_;
  236. }
  237. const charT* const* get_long_weekday_names()const
  238. {
  239. return weekday_long_names_;
  240. }
  241. protected:
  242. //! Generic facet that takes array of chars
  243. virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
  244. {
  245. this->put_string(oitr, month_short_names_[moy-1]);
  246. }
  247. //! Long month names
  248. virtual void do_put_month_long(iter_type& oitr, month_enum moy) const
  249. {
  250. this->put_string(oitr, month_long_names_[moy-1]);
  251. }
  252. //! Special values names
  253. virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
  254. {
  255. this->put_string(oitr, special_value_names_[sv]);
  256. }
  257. virtual void do_put_weekday_short(iter_type& oitr, weekday_enum wd) const
  258. {
  259. this->put_string(oitr, weekday_short_names_[wd]);
  260. }
  261. virtual void do_put_weekday_long(iter_type& oitr, weekday_enum wd) const
  262. {
  263. this->put_string(oitr, weekday_long_names_[wd]);
  264. }
  265. //! char between year-month
  266. virtual void do_month_sep_char(iter_type& oitr) const
  267. {
  268. this->put_string(oitr, separator_char_);
  269. }
  270. //! Char to separate month-day
  271. virtual void do_day_sep_char(iter_type& oitr) const
  272. {
  273. this->put_string(oitr, separator_char_);
  274. }
  275. //! Set the date ordering
  276. virtual ymd_order_spec do_date_order() const
  277. {
  278. return order_spec_;
  279. }
  280. //! Set the date ordering
  281. virtual month_format_spec do_month_format() const
  282. {
  283. return month_format_spec_;
  284. }
  285. private:
  286. const charT* const* month_short_names_;
  287. const charT* const* month_long_names_;
  288. const charT* const* special_value_names_;
  289. const charT* const* weekday_short_names_;
  290. const charT* const* weekday_long_names_;
  291. charT separator_char_[2];
  292. ymd_order_spec order_spec_;
  293. month_format_spec month_format_spec_;
  294. };
  295. } } //namespace boost::date_time
  296. #endif //BOOST_NO_STD_LOCALE
  297. #endif