Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62928 - in branches/date_time_io_rewrite: boost/date_time boost/date_time/local_time libs/date_time/build libs/date_time/src
From: andrey.semashev_at_[hidden]
Date: 2010-06-14 07:56:48


Author: andysem
Date: 2010-06-14 07:56:45 EDT (Mon, 14 Jun 2010)
New Revision: 62928
URL: http://svn.boost.org/trac/boost/changeset/62928

Log:
Added support for facet-based formatting. Implemented a locale-based character code conversion and deprecated the old one.
Added:
   branches/date_time_io_rewrite/libs/date_time/src/code_convert.cpp (contents, props changed)
Text files modified:
   branches/date_time_io_rewrite/boost/date_time/local_time/custom_time_zone.hpp | 6 +-
   branches/date_time_io_rewrite/boost/date_time/local_time/local_time_io.hpp | 18 +++++-----
   branches/date_time_io_rewrite/boost/date_time/local_time/posix_time_zone.hpp | 6 +-
   branches/date_time_io_rewrite/boost/date_time/period_parser.hpp | 49 +++++++++++++++--------------
   branches/date_time_io_rewrite/boost/date_time/string_convert.hpp | 2 +
   branches/date_time_io_rewrite/boost/date_time/time_facet.hpp | 4 +-
   branches/date_time_io_rewrite/libs/date_time/build/Jamfile.v2 | 3 +
   branches/date_time_io_rewrite/libs/date_time/src/formatter.cpp | 66 ++++++++++++++++++++++++++++++---------
   8 files changed, 97 insertions(+), 57 deletions(-)

Modified: branches/date_time_io_rewrite/boost/date_time/local_time/custom_time_zone.hpp
==============================================================================
--- branches/date_time_io_rewrite/boost/date_time/local_time/custom_time_zone.hpp (original)
+++ branches/date_time_io_rewrite/boost/date_time/local_time/custom_time_zone.hpp 2010-06-14 07:56:45 EDT (Mon, 14 Jun 2010)
@@ -14,7 +14,7 @@
 #include <boost/date_time/time_zone_names.hpp>
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/date_time/local_time/dst_transition_day_rules.hpp>
-#include <boost/date_time/string_convert.hpp>
+#include <boost/date_time/detail/code_convert.hpp>
 
 namespace boost {
 
@@ -148,7 +148,7 @@
                 }
             }
             // start/time
- ss << ',' << date_time::convert_string_type< char, char_type >(dst_calc_rules_->start_rule_as_string()) << '/'
+ ss << ',' << date_time::aux::code_convert< char_type >(dst_calc_rules_->start_rule_as_string()) << '/'
                 << std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':'
                 << std::setw(2) << dst_offsets_.dst_start_offset_.minutes();
             if (dst_offsets_.dst_start_offset_.seconds() != 0)
@@ -156,7 +156,7 @@
                 ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds();
             }
             // end/time
- ss << ',' << date_time::convert_string_type< char, char_type >(dst_calc_rules_->end_rule_as_string()) << '/'
+ ss << ',' << date_time::aux::code_convert< char_type >(dst_calc_rules_->end_rule_as_string()) << '/'
                 << std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':'
                 << std::setw(2) << dst_offsets_.dst_end_offset_.minutes();
             if (dst_offsets_.dst_end_offset_.seconds() != 0)

Modified: branches/date_time_io_rewrite/boost/date_time/local_time/local_time_io.hpp
==============================================================================
--- branches/date_time_io_rewrite/boost/date_time/local_time/local_time_io.hpp (original)
+++ branches/date_time_io_rewrite/boost/date_time/local_time/local_time_io.hpp 2010-06-14 07:56:45 EDT (Mon, 14 Jun 2010)
@@ -13,7 +13,7 @@
 #include <iterator> // i/ostreambuf_iterator
 #include <boost/io/ios_state.hpp>
 #include <boost/date_time/time_facet.hpp>
-#include <boost/date_time/string_convert.hpp>
+#include <boost/date_time/detail/code_convert.hpp>
 #include <boost/date_time/local_time/local_date_time.hpp>
 #include <boost/date_time/local_time/posix_time_zone.hpp>
 #include <boost/date_time/local_time/conversion.hpp> // to_tm will be needed in the facets
@@ -34,15 +34,15 @@
   operator<<(std::basic_ostream<CharT, TraitsT>& os, const local_date_time& ldt)
   {
     boost::io::ios_flags_saver iflags(os);
- typedef local_date_time time_type;//::utc_time_type typename
+ typedef local_date_time time_type;//::utc_time_type typename
     typedef date_time::time_facet<time_type, CharT> custom_time_facet;
     typedef std::time_put<CharT> std_time_facet;
     std::ostreambuf_iterator<CharT> oitr(os);
 
     if(std::has_facet<custom_time_facet>(os.getloc())) {
- std::use_facet<custom_time_facet>(os.getloc()).put(oitr,
- os,
- os.fill(),
+ std::use_facet<custom_time_facet>(os.getloc()).put(oitr,
+ os,
+ os.fill(),
                                                          ldt);
     }
     else {
@@ -71,7 +71,7 @@
 
         // intermediate objects
         std::basic_string<CharT> tz_str;
- utc_time_type pt(not_a_date_time);
+ utc_time_type pt(not_a_date_time);
 
         std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
         if(std::has_facet<time_input_facet>(is.getloc())) {
@@ -89,7 +89,7 @@
           ldt = local_date_time(pt, null_ptr);
         }
         else {
- time_zone_ptr tz_ptr(new posix_time_zone(date_time::convert_string_type<CharT,char>(tz_str)));
+ time_zone_ptr tz_ptr(new posix_time_zone(date_time::aux::code_convert<char>(tz_str)));
           // the "date & time" constructor expects the time label to *not* be utc.
           // a posix_tz_string also expects the time label to *not* be utc.
           ldt = local_date_time(pt.date(), pt.time_of_day(), tz_ptr, local_date_time::EXCEPTION_ON_ERROR);
@@ -98,7 +98,7 @@
       catch(...) {
         // mask tells us what exceptions are turned on
         std::ios_base::iostate exception_mask = is.exceptions();
- // if the user wants exceptions on failbit, we'll rethrow our
+ // if the user wants exceptions on failbit, we'll rethrow our
         // date_time exception & set the failbit
         if(std::ios_base::failbit & exception_mask) {
           try { is.setstate(std::ios_base::failbit); }
@@ -130,7 +130,7 @@
     }
     else {
       //instantiate a custom facet for dealing with periods since the user
- //has not put one in the stream so far. This is for efficiency
+ //has not put one in the stream so far. This is for efficiency
       //since we would always need to reconstruct for every time period
       //if the local did not already exist. Of course this will be overridden
       //if the user imbues as some later point.

Modified: branches/date_time_io_rewrite/boost/date_time/local_time/posix_time_zone.hpp
==============================================================================
--- branches/date_time_io_rewrite/boost/date_time/local_time/posix_time_zone.hpp (original)
+++ branches/date_time_io_rewrite/boost/date_time/local_time/posix_time_zone.hpp 2010-06-14 07:56:45 EDT (Mon, 14 Jun 2010)
@@ -18,7 +18,7 @@
 #include <boost/date_time/time_zone_base.hpp>
 #include <boost/date_time/local_time/dst_transition_day_rules.hpp>
 #include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/date_time/string_convert.hpp>
+#include <boost/date_time/detail/code_convert.hpp>
 #include <boost/date_time/time_parsing.hpp>
 
 namespace boost{
@@ -219,14 +219,14 @@
           }
         }
         // start/time
- ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->start_rule_as_string()) << '/'
+ ss << ',' << date_time::aux::code_convert<char_type>(dst_calc_rules_->start_rule_as_string()) << '/'
            << std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':'
            << std::setw(2) << dst_offsets_.dst_start_offset_.minutes();
         if(dst_offsets_.dst_start_offset_.seconds() != 0) {
           ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds();
         }
         // end/time
- ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->end_rule_as_string()) << '/'
+ ss << ',' << date_time::aux::code_convert<char_type>(dst_calc_rules_->end_rule_as_string()) << '/'
            << std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':'
            << std::setw(2) << dst_offsets_.dst_end_offset_.minutes();
         if(dst_offsets_.dst_end_offset_.seconds() != 0) {

Modified: branches/date_time_io_rewrite/boost/date_time/period_parser.hpp
==============================================================================
--- branches/date_time_io_rewrite/boost/date_time/period_parser.hpp (original)
+++ branches/date_time_io_rewrite/boost/date_time/period_parser.hpp 2010-06-14 07:56:45 EDT (Mon, 14 Jun 2010)
@@ -3,7 +3,7 @@
 #define DATETIME_PERIOD_PARSER_HPP___
 
 /* Copyright (c) 2002-2004 CrystalClear Software, Inc.
- * Use, modification and distribution is subject to the
+ * Use, modification and distribution is subject to the
  * Boost Software License, Version 1.0. (See accompanying
  * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  * Author: Jeff Garland, Bart Garst
@@ -12,18 +12,18 @@
 
 #include <boost/throw_exception.hpp>
 #include <boost/date_time/string_parse_tree.hpp>
-#include <boost/date_time/string_convert.hpp>
+#include <boost/date_time/detail/code_convert.hpp>
 
 
 namespace boost { namespace date_time {
 
 
- //! Not a facet, but a class used to specify and control period parsing
+ //! Not a facet, but a class used to specify and control period parsing
   /*! Provides settings for the following:
    * - period_separator -- default '/'
    * - period_open_start_delimeter -- default '['
- * - period_open_range_end_delimeter -- default ')'
- * - period_closed_range_end_delimeter -- default ']'
+ * - period_open_range_end_delimeter -- default ')'
+ * - period_closed_range_end_delimeter -- default ']'
    * - display_as_open_range, display_as_closed_range -- default closed_range
    *
    * For a typical date_period, the contents of the input stream would be
@@ -99,11 +99,11 @@
      * to get the 'elements'. For example, in the case of a date_period
      * the elements will be instances of a date which will be parsed
      * according the to setup in the passed facet parameter.
- *
+ *
      * The steps for parsing a period are always the same:
      * - consume the start delimiter
      * - get start element
- * - consume the separator
+ * - consume the separator
      * - get either last or end element depending on range settings
      * - consume the end delimeter depending on range settings
      *
@@ -117,15 +117,15 @@
      *@endcode
      */
     template<class period_type, class duration_type, class facet_type>
- period_type get_period(stream_itr_type& sitr,
+ period_type get_period(stream_itr_type& sitr,
                            stream_itr_type& stream_end,
- std::ios_base& a_ios,
+ std::ios_base& a_ios,
                            const period_type& /* p */,
                            const duration_type& dur_unit,
- const facet_type& facet) const
+ const facet_type& facet) const
     {
       // skip leading whitespace
- while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+ while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
 
       typedef typename period_type::point_type point_type;
       point_type p1(not_a_date_time), p2(not_a_date_time);
@@ -150,7 +150,7 @@
     }
 
   private:
- collection_type delimiters;
+ collection_type delimiters;
     period_range_option m_range_option;
 
     enum delim_ids { SEPARATOR, START, OPEN_END, CLOSED_END };
@@ -160,10 +160,10 @@
                        stream_itr_type& stream_end,
                        const string_type& delim) const
     {
- /* string_parse_tree will not parse a string of punctuation characters
+ /* string_parse_tree will not parse a string of punctuation characters
        * without knowing exactly how many characters to process
- * Ex [2000. Will not parse out the '[' string without knowing
- * to process only one character. By using length of the delimiter
+ * Ex [2000. Will not parse out the '[' string without knowing
+ * to process only one character. By using length of the delimiter
        * string we can safely iterate past it. */
       string_type s;
       for(unsigned int i = 0; i < delim.length() && sitr != stream_end; ++i) {
@@ -172,25 +172,26 @@
       }
       if(s != delim) {
         boost::throw_exception(std::ios_base::failure("Parse failed. Expected '"
- + convert_string_type<char_type,char>(delim) + "' but found '" + convert_string_type<char_type,char>(s) + "'"));
+ + date_time::aux::code_convert<char>(delim) + "' but found '"
+ + date_time::aux::code_convert<char>(s) + "'"));
       }
     }
   };
 
- template <class date_type, class char_type>
- const typename period_parser<date_type, char_type>::char_type
+ template <class date_type, class char_type>
+ const typename period_parser<date_type, char_type>::char_type
   period_parser<date_type, char_type>::default_period_separator[2] = {'/'};
 
- template <class date_type, class char_type>
- const typename period_parser<date_type, char_type>::char_type
+ template <class date_type, class char_type>
+ const typename period_parser<date_type, char_type>::char_type
   period_parser<date_type, char_type>::default_period_start_delimeter[2] = {'['};
 
- template <class date_type, class char_type>
- const typename period_parser<date_type, char_type>::char_type
+ template <class date_type, class char_type>
+ const typename period_parser<date_type, char_type>::char_type
   period_parser<date_type, char_type>::default_period_open_range_end_delimeter[2] = {')'};
 
- template <class date_type, class char_type>
- const typename period_parser<date_type, char_type>::char_type
+ template <class date_type, class char_type>
+ const typename period_parser<date_type, char_type>::char_type
   period_parser<date_type, char_type>::default_period_closed_range_end_delimeter[2] = {']'};
 
  } } //namespace boost::date_time

Modified: branches/date_time_io_rewrite/boost/date_time/string_convert.hpp
==============================================================================
--- branches/date_time_io_rewrite/boost/date_time/string_convert.hpp (original)
+++ branches/date_time_io_rewrite/boost/date_time/string_convert.hpp 2010-06-14 07:56:45 EDT (Mon, 14 Jun 2010)
@@ -11,6 +11,8 @@
 #include <string>
 #include <boost/date_time/compiler_config.hpp>
 
+#warning Boost.DateTime: this header is deprecated and will be removed in future releases
+
 namespace boost {
 namespace date_time {
 

Modified: branches/date_time_io_rewrite/boost/date_time/time_facet.hpp
==============================================================================
--- branches/date_time_io_rewrite/boost/date_time/time_facet.hpp (original)
+++ branches/date_time_io_rewrite/boost/date_time/time_facet.hpp 2010-06-14 07:56:45 EDT (Mon, 14 Jun 2010)
@@ -26,7 +26,7 @@
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/date_time/compiler_config.hpp>
 #include <boost/date_time/date_facet.hpp>
-#include <boost/date_time/string_convert.hpp>
+#include <boost/date_time/detail/code_convert.hpp>
 #include <boost/date_time/special_defs.hpp>
 #include <boost/date_time/time_resolution_traits.hpp> // absolute_value
 
@@ -1251,7 +1251,7 @@
         }
         this->m_sv_parser.match(sitr, stream_end, mr);
         if(mr.current_match == match_results::PARSE_ERROR) {
- std::string tmp = convert_string_type<char_type, char>(mr.cache);
+ std::string tmp = date_time::aux::code_convert<char>(mr.cache);
           boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + tmp + "'"));
           BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return sitr); // should never reach
         }

Modified: branches/date_time_io_rewrite/libs/date_time/build/Jamfile.v2
==============================================================================
--- branches/date_time_io_rewrite/libs/date_time/build/Jamfile.v2 (original)
+++ branches/date_time_io_rewrite/libs/date_time/build/Jamfile.v2 2010-06-14 07:56:45 EDT (Mon, 14 Jun 2010)
@@ -1,5 +1,5 @@
 # Copyright (c) 2002-2005 CrystalClear Software, Inc.
-# Use, modification and distribution is subject to the
+# Use, modification and distribution is subject to the
 # Boost Software License, Version 1.0. (See accompanying
 # file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 #
@@ -27,6 +27,7 @@
     ;
 
 lib boost_date_time :
+ code_convert.cpp
     formatter.cpp
     gregorian/greg_month.cpp
     gregorian/greg_weekday.cpp

Added: branches/date_time_io_rewrite/libs/date_time/src/code_convert.cpp
==============================================================================
--- (empty file)
+++ branches/date_time_io_rewrite/libs/date_time/src/code_convert.cpp 2010-06-14 07:56:45 EDT (Mon, 14 Jun 2010)
@@ -0,0 +1,115 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2010.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include <cstddef>
+#include <locale>
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/detail/code_convert.hpp>
+
+#if !defined(BOOST_NO_STD_WSTRING)
+
+namespace boost {
+
+namespace date_time {
+
+namespace aux {
+
+namespace {
+
+ //! The function performs character conversion with the specified facet
+ inline std::codecvt_base::result convert(
+ std::codecvt< wchar_t, char, std::mbstate_t > const& fac,
+ std::mbstate_t& state,
+ const char*& pSrcBegin,
+ const char* pSrcEnd,
+ wchar_t*& pDstBegin,
+ wchar_t* pDstEnd)
+ {
+ return fac.in(state, pSrcBegin, pSrcEnd, pSrcBegin, pDstBegin, pDstEnd, pDstBegin);
+ }
+
+ //! The function performs character conversion with the specified facet
+ inline std::codecvt_base::result convert(
+ std::codecvt< wchar_t, char, std::mbstate_t > const& fac,
+ std::mbstate_t& state,
+ const wchar_t*& pSrcBegin,
+ const wchar_t* pSrcEnd,
+ char*& pDstBegin,
+ char* pDstEnd)
+ {
+ return fac.out(state, pSrcBegin, pSrcEnd, pSrcBegin, pDstBegin, pDstEnd, pDstBegin);
+ }
+
+ //! The function actually converts encodings
+ template< typename ToCharT, typename FromCharT >
+ inline void do_code_convert(
+ std::basic_string< FromCharT > const& from,
+ std::basic_string< ToCharT >& to,
+ std::locale const& loc)
+ {
+ typedef std::codecvt< wchar_t, char, std::mbstate_t > facet_t;
+ facet_t const& fac = std::use_facet< facet_t >(loc);
+ std::mbstate_t state = {};
+
+ to.resize(from.size());
+ const FromCharT* from_p = from.data(), *from_e = from_p + from.size();
+ ToCharT* to_p = const_cast< ToCharT* >(to.data()), *to_e = to_p + to.size();
+
+ std::codecvt_base::result res = std::codecvt_base::error;
+ do
+ {
+ res = convert(fac, state, from_p, from_e, to_p, to_e);
+ switch (res)
+ {
+ case std::codecvt_base::partial:
+ {
+ // The converted data does not fit in the resulting buffer.
+ std::size_t index = to_p - to.data();
+ to.resize(to.size() + to.size() / 2);
+ to_p = const_cast< ToCharT* >(to.data()) + index;
+ to_e = to_p + to.size();
+ }
+ break;
+
+ case std::codecvt_base::error:
+ BOOST_THROW_EXCEPTION(std::runtime_error("Could not perform character encoding conversion"));
+ break;
+
+ default:
+ break;
+ }
+ }
+ while (res != std::codecvt_base::ok && res != std::codecvt_base::noconv);
+
+ // Correct the target buffer size
+ to.resize(to_p - to.data());
+ }
+
+} // namespace
+
+//! Widens the string, according to the specified locale
+BOOST_DATE_TIME_DECL void code_convert(
+ std::string const& from, std::wstring& to, std::locale const& loc)
+{
+ do_code_convert(from, to, loc);
+}
+
+//! Narrows the string, according to the specified locale
+BOOST_DATE_TIME_DECL void code_convert(
+ std::wstring const& from, std::string& to, std::locale const& loc)
+{
+ do_code_convert(from, to, loc);
+}
+
+} // namespace aux
+
+} // namespace date_time
+
+} // namespace boost
+
+#endif // !defined(BOOST_NO_STD_WSTRING)

Modified: branches/date_time_io_rewrite/libs/date_time/src/formatter.cpp
==============================================================================
--- branches/date_time_io_rewrite/libs/date_time/src/formatter.cpp (original)
+++ branches/date_time_io_rewrite/libs/date_time/src/formatter.cpp 2010-06-14 07:56:45 EDT (Mon, 14 Jun 2010)
@@ -8,6 +8,8 @@
 #include <memory>
 #include <limits>
 #include <vector>
+#include <locale>
+#include <sstream>
 #include <iterator>
 #include <stdexcept>
 #include <boost/throw_exception.hpp>
@@ -25,7 +27,7 @@
 #include <boost/preprocessor/tuple/elem.hpp>
 #include <boost/preprocessor/seq/for_each.hpp>
 #include <boost/date_time/detail/formatter.hpp>
-#include <boost/date_time/string_convert.hpp>
+#include <boost/date_time/detail/code_convert.hpp>
 
 namespace boost {
 
@@ -38,9 +40,23 @@
 
 namespace {
 
+ template< typename >
+ struct encoding;
+
+ template< >
+ struct encoding< char >
+ {
+ typedef spirit::char_encoding::standard type;
+ };
+ template< >
+ struct encoding< wchar_t >
+ {
+ typedef spirit::char_encoding::standard_wide type;
+ };
+
     //! A simple trait that allows to use charset-specific Qi parsers in a generic way
- template< typename CharT >
- struct charset_parsers;
+ template< typename EncodingT >
+ struct encoding_specific;
 
 #define BOOST_DATE_TIME_CHARSET_PARSERS\
     ((char_type, char_))\
@@ -67,28 +83,28 @@
 #define BOOST_DATE_TIME_DECLARE_CHARSET_PARSERS(charset)\
     BOOST_PP_SEQ_FOR_EACH(BOOST_DATE_TIME_DECLARE_CHARSET_PARSER, charset, BOOST_DATE_TIME_CHARSET_PARSERS)
 
-#define BOOST_DATE_TIME_DEFINE_CHARSET_PARSER(r, params, parser)\
- spirit::BOOST_PP_TUPLE_ELEM(2, 1, params)::BOOST_PP_TUPLE_ELEM(2, 0, parser) const&\
- charset_parsers< BOOST_PP_TUPLE_ELEM(2, 0, params) >::BOOST_PP_TUPLE_ELEM(2, 1, parser) =\
- spirit::BOOST_PP_TUPLE_ELEM(2, 1, params)::BOOST_PP_TUPLE_ELEM(2, 1, parser);
+#define BOOST_DATE_TIME_DEFINE_CHARSET_PARSER(r, charset, parser)\
+ spirit::charset::BOOST_PP_TUPLE_ELEM(2, 0, parser) const&\
+ encoding_specific< spirit::char_encoding::charset >::BOOST_PP_TUPLE_ELEM(2, 1, parser) =\
+ spirit::charset::BOOST_PP_TUPLE_ELEM(2, 1, parser);
 
-#define BOOST_DATE_TIME_DEFINE_CHARSET_PARSERS(char_type, charset)\
- BOOST_PP_SEQ_FOR_EACH(BOOST_DATE_TIME_DEFINE_CHARSET_PARSER, (char_type, charset), BOOST_DATE_TIME_CHARSET_PARSERS)
+#define BOOST_DATE_TIME_DEFINE_CHARSET_PARSERS(charset)\
+ BOOST_PP_SEQ_FOR_EACH(BOOST_DATE_TIME_DEFINE_CHARSET_PARSER, charset, BOOST_DATE_TIME_CHARSET_PARSERS)
 
     template< >
- struct charset_parsers< char >
+ struct encoding_specific< spirit::char_encoding::standard >
     {
         BOOST_DATE_TIME_DECLARE_CHARSET_PARSERS(standard)
     };
- BOOST_DATE_TIME_DEFINE_CHARSET_PARSERS(char, standard)
+ BOOST_DATE_TIME_DEFINE_CHARSET_PARSERS(standard)
 
 #ifndef BOOST_NO_STD_WSTRING
     template< >
- struct charset_parsers< wchar_t >
+ struct encoding_specific< spirit::char_encoding::standard_wide >
     {
         BOOST_DATE_TIME_DECLARE_CHARSET_PARSERS(standard_wide)
     };
- BOOST_DATE_TIME_DEFINE_CHARSET_PARSERS(wchar_t, standard_wide)
+ BOOST_DATE_TIME_DEFINE_CHARSET_PARSERS(standard_wide)
 #endif // BOOST_NO_STD_WSTRING
 
 #undef BOOST_DATE_TIME_DEFINE_CHARSET_PARSERS
@@ -342,6 +358,25 @@
     typedef delimited3< hours12, minutes, seconds, ':' > h12ms_time;
     typedef delimited3< unrestricted_hours, minutes, seconds, ':' > default_duration;
 
+ //! Formatter based on the standard locale facet
+ struct facet_based
+ {
+ void operator()(common_date_time const& dt, std::locale const& loc, string_type& target)
+ {
+ std::basic_ostringstream< char_type > strm;
+ strm.imbue(loc);
+ std::ostreambuf_iterator< char_type > it(strm);
+ std::use_facet< std::time_put< char_type > >(loc).put(
+ it,
+ strm,
+ static_cast< char_type >(' '), // TODO: pass it from the date_facet and time_facet
+ &dt.get_tm(),
+ target.data(),
+ target.data() + target.size());
+ strm.str().swap(target);
+ }
+ };
+
     //! Sequence of elementary formatters
     typedef intrusive::slist<
         step_base,
@@ -528,7 +563,7 @@
         explicit date_time_grammar(collector* p, bool& is_complete) :
             date_time_grammar::base_type(m_Start)
         {
- typedef charset_parsers< char_type > charset;
+ typedef aux::encoding_specific< typename encoding< char_type >::type > charset;
             typedef format_placeholders< char_type > constants;
             namespace args = phoenix::arg_names;
 
@@ -642,7 +677,7 @@
     if (!qi::parse(p, e, grammar) || p != e)
     {
         std::string descr = "Could not parse date/time format specification \"";
- descr.append(date_time::convert_string_type< char_type, char >(string_type(b, e)));
+ descr.append(date_time::aux::code_convert< char >(string_type(b, e)));
         descr.append("\", stopped at position ");
         std::back_insert_iterator< std::string > it(descr);
         karma::generate(it, karma::uint_, static_cast< std::size_t >(p - b));
@@ -653,6 +688,7 @@
     {
         // The parser did not recognize all placeholders. We'll have to pass
         // the formatter output to the standard facet to complete the formatting.
+ formatter.m_pImpl->BOOST_NESTED_TEMPLATE add< typename implementation::facet_based >();
     }
 
     return formatter;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk