|
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