|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r62591 - in branches/date_time_io_rewrite: boost/date_time boost/date_time/detail boost/date_time/local_time libs/date_time/build libs/date_time/src
From: andrey.semashev_at_[hidden]
Date: 2010-06-08 14:48:56
Author: andysem
Date: 2010-06-08 14:48:55 EDT (Tue, 08 Jun 2010)
New Revision: 62591
URL: http://svn.boost.org/trac/boost/changeset/62591
Log:
Preliminary changes and the initial version of the spirit-based formatter.
Added:
branches/date_time_io_rewrite/boost/date_time/detail/
branches/date_time_io_rewrite/boost/date_time/detail/common_date_time.hpp (contents, props changed)
branches/date_time_io_rewrite/boost/date_time/detail/formatter.hpp (contents, props changed)
branches/date_time_io_rewrite/libs/date_time/src/formatter.cpp (contents, props changed)
Text files modified:
branches/date_time_io_rewrite/boost/date_time/c_time.hpp | 6 -
branches/date_time_io_rewrite/boost/date_time/compiler_config.hpp | 38 ++++--
branches/date_time_io_rewrite/boost/date_time/local_time/custom_time_zone.hpp | 228 +++++++++++++++++++++------------------
branches/date_time_io_rewrite/boost/date_time/local_time/posix_time_zone.hpp | 5
branches/date_time_io_rewrite/boost/date_time/string_convert.hpp | 6
branches/date_time_io_rewrite/boost/date_time/time_zone_base.hpp | 129 +++++++++++-----------
branches/date_time_io_rewrite/libs/date_time/build/Jamfile.v2 | 17 +-
7 files changed, 227 insertions(+), 202 deletions(-)
Modified: branches/date_time_io_rewrite/boost/date_time/c_time.hpp
==============================================================================
--- branches/date_time_io_rewrite/boost/date_time/c_time.hpp (original)
+++ branches/date_time_io_rewrite/boost/date_time/c_time.hpp 2010-06-08 14:48:55 EDT (Tue, 08 Jun 2010)
@@ -20,12 +20,6 @@
#include <boost/throw_exception.hpp>
#include <boost/date_time/compiler_config.hpp>
-//Work around libraries that don't put time_t and time in namespace std
-#ifdef BOOST_NO_STDC_NAMESPACE
-namespace std { using ::time_t; using ::time; using ::localtime;
- using ::tm; using ::gmtime; }
-#endif // BOOST_NO_STDC_NAMESPACE
-
//The following is used to support high precision time clocks
#ifdef BOOST_HAS_GETTIMEOFDAY
#include <sys/time.h>
Modified: branches/date_time_io_rewrite/boost/date_time/compiler_config.hpp
==============================================================================
--- branches/date_time_io_rewrite/boost/date_time/compiler_config.hpp (original)
+++ branches/date_time_io_rewrite/boost/date_time/compiler_config.hpp 2010-06-08 14:48:55 EDT (Tue, 08 Jun 2010)
@@ -8,6 +8,7 @@
* $Date$
*/
+#include <ctime>
#include <cstdlib>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
@@ -30,7 +31,7 @@
#include <boost/date_time/locale_config.hpp> //set up locale configurations
-//Set up a configuration parameter for platforms that have
+//Set up a configuration parameter for platforms that have
//GetTimeOfDay
#if defined(BOOST_HAS_GETTIMEOFDAY) || defined(BOOST_HAS_FTIME)
#define BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
@@ -69,17 +70,28 @@
#if defined(__BORLANDC__) && defined(BOOST_BCB_WITH_STLPORT)
#include <locale>
namespace std {
- using stlport::tolower;
- using stlport::ctype;
- using stlport::use_facet;
+ using stlport::tolower;
+ using stlport::ctype;
+ using stlport::use_facet;
}
#endif
-// workaround for errors associated with output for date classes
-// modifications and input streaming for time classes.
+//Work around libraries that don't put time_t and time in namespace std
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std {
+ using ::time_t;
+ using ::time;
+ using ::localtime;
+ using ::tm;
+ using ::gmtime;
+}
+#endif // BOOST_NO_STDC_NAMESPACE
+
+// workaround for errors associated with output for date classes
+// modifications and input streaming for time classes.
// Compilers affected are:
// gcc295, msvc (neither with STLPort), any borland
-//
+//
#if (((defined(__GNUC__) && (__GNUC__ < 3)) || \
(defined(_MSC_VER) && (_MSC_VER < 1300)) ) && \
!defined(_STLP_OWN_IOSTREAMS) ) || \
@@ -109,13 +121,13 @@
/* The following handles the definition of the necessary macros
* for dll building on Win32 platforms.
- *
- * For code that will be placed in the date_time .dll,
+ *
+ * For code that will be placed in the date_time .dll,
* it must be properly prefixed with BOOST_DATE_TIME_DECL.
* The corresponding .cpp file must have BOOST_DATE_TIME_SOURCE
* defined before including its header. For examples see:
* greg_month.hpp & greg_month.cpp
- *
+ *
*/
#ifdef BOOST_HAS_DECLSPEC // defined in config system
@@ -139,8 +151,8 @@
#endif
//
-// Automatically link to the correct build variant where possible.
-//
+// Automatically link to the correct build variant where possible.
+//
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_DATE_TIME_NO_LIB) && !defined(BOOST_DATE_TIME_SOURCE)
//
// Set the name of our library, this will get undef'ed by auto_link.hpp
@@ -159,7 +171,7 @@
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
-#if defined(BOOST_HAS_THREADS)
+#if defined(BOOST_HAS_THREADS)
# if defined(_MSC_VER) || defined(__MWERKS__) || defined(__MINGW32__) || defined(__BORLANDC__)
//no reentrant posix functions (eg: localtime_r)
# elif (!defined(__hpux) || (defined(__hpux) && defined(_REENTRANT)))
Added: branches/date_time_io_rewrite/boost/date_time/detail/common_date_time.hpp
==============================================================================
--- (empty file)
+++ branches/date_time_io_rewrite/boost/date_time/detail/common_date_time.hpp 2010-06-08 14:48:55 EDT (Tue, 08 Jun 2010)
@@ -0,0 +1,59 @@
+/*
+ * 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)
+ */
+/*!
+ * \file common_date_time.hpp
+ * \author Andrey Semashev
+ * \date 08.06.2010
+ *
+ * The header contains implementation of a common date/time type for ABI purposes.
+ */
+
+#if (defined(_MSC_VER) && _MSC_VER > 1000)
+#pragma once
+#endif // _MSC_VER > 1000
+
+#ifndef BOOST_DATE_TIME_DETAIL_COMMON_DATE_TIME_HPP_INCLUDED_
+#define BOOST_DATE_TIME_DETAIL_COMMON_DATE_TIME_HPP_INCLUDED_
+
+#include <ctime>
+#include <boost/cstdint.hpp>
+#include <boost/date_time/compiler_config.hpp>
+
+namespace boost {
+
+namespace date_time {
+
+namespace aux {
+
+class common_date_time
+{
+private:
+ bool negative_;
+ std::tm tm_;
+ uint32_t fractional_;
+
+public:
+ template< typename T >
+ explicit common_date_time(T const& t, uint32_t fractional, bool negative = false) :
+ negative_(negative),
+ tm_(to_tm(t)),
+ fractional_(fractional)
+ {
+ }
+
+ bool is_negative() const { return negative_; }
+ std::tm const& get_tm() const { return tm_; }
+ uint32_t fractional_seconds() const { return fractional_; }
+};
+
+} // namespace aux
+
+} // namespace date_time
+
+} // namespace boost
+
+#endif // BOOST_DATE_TIME_DETAIL_COMMON_DATE_TIME_HPP_INCLUDED_
Added: branches/date_time_io_rewrite/boost/date_time/detail/formatter.hpp
==============================================================================
--- (empty file)
+++ branches/date_time_io_rewrite/boost/date_time/detail/formatter.hpp 2010-06-08 14:48:55 EDT (Tue, 08 Jun 2010)
@@ -0,0 +1,71 @@
+/*
+ * 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)
+ */
+/*!
+ * \file common_date_time.hpp
+ * \author Andrey Semashev
+ * \date 08.06.2010
+ *
+ * The header contains implementation of a common date/time type for ABI purposes.
+ */
+
+#if (defined(_MSC_VER) && _MSC_VER > 1000)
+#pragma once
+#endif // _MSC_VER > 1000
+
+#ifndef BOOST_DATE_TIME_DETAIL_FORMATTER_HPP_INCLUDED_
+#define BOOST_DATE_TIME_DETAIL_FORMATTER_HPP_INCLUDED_
+
+#include <locale>
+#include <string>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/detail/common_date_time.hpp>
+
+namespace boost {
+
+namespace date_time {
+
+namespace aux {
+
+template< typename CharT >
+class BOOST_DATE_TIME_DECL formatter
+{
+public:
+ struct implementation;
+
+ typedef CharT char_type;
+ typedef std::basic_string< char_type > string_type;
+
+private:
+ implementation* m_pImpl;
+
+public:
+ //! Default constructor. Creates an empty formatter that does nothing.
+ formatter();
+ //! Copy constructor. Performs a deep copying.
+ formatter(formatter const& that);
+ //! Destructor
+ ~formatter();
+ //! Assignment
+ formatter& operator= (formatter const& that);
+
+ //! Formatting operator
+ void operator()(
+ common_date_time const& dt,
+ string_type& out,
+ std::locale const& loc = std::locale()) const;
+
+ //! Parses the format string and constructs the formatter
+ static formatter parse(const char_type* b, const char_type* e);
+};
+
+} // namespace aux
+
+} // namespace date_time
+
+} // namespace boost
+
+#endif // BOOST_DATE_TIME_DETAIL_FORMATTER_HPP_INCLUDED_
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-08 14:48:55 EDT (Tue, 08 Jun 2010)
@@ -2,168 +2,184 @@
#define LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__
/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
- * Subject to the Boost Software License, Version 1.0.
+ * 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
* $Date$
*/
-#include "boost/date_time/time_zone_base.hpp"
-#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/special_defs.hpp"
-#include "boost/shared_ptr.hpp"
+#include <sstream>
+#include <boost/shared_ptr.hpp>
+#include <boost/date_time/time_zone_base.hpp>
+#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>
namespace boost {
+
namespace local_time {
- //typedef boost::date_time::time_zone_names time_zone_names;
- typedef boost::date_time::dst_adjustment_offsets<boost::posix_time::time_duration> dst_adjustment_offsets;
- //typedef boost::date_time::time_zone_base<boost::posix_time::ptime> time_zone;
- typedef boost::shared_ptr<dst_calc_rule> dst_calc_rule_ptr;
-
- //! A real time zone
- template<class CharT>
- class custom_time_zone_base : public date_time::time_zone_base<posix_time::ptime,CharT> {
- public:
+//typedef boost::date_time::time_zone_names time_zone_names;
+typedef date_time::dst_adjustment_offsets< posix_time::time_duration > dst_adjustment_offsets;
+//typedef boost::date_time::time_zone_base<boost::posix_time::ptime> time_zone;
+typedef shared_ptr< dst_calc_rule > dst_calc_rule_ptr;
+
+//! A real time zone
+template< typename CharT >
+class custom_time_zone_base :
+ public date_time::time_zone_base< posix_time::ptime, CharT >
+{
+public:
typedef boost::posix_time::time_duration time_duration_type;
- typedef date_time::time_zone_base<posix_time::ptime,CharT> base_type;
+ typedef date_time::time_zone_base< posix_time::ptime, CharT > base_type;
typedef typename base_type::string_type string_type;
- typedef typename base_type::stringstream_type stringstream_type;
- typedef date_time::time_zone_names_base<CharT> time_zone_names;
+ typedef date_time::time_zone_names_base< CharT > time_zone_names;
typedef CharT char_type;
-
- custom_time_zone_base(const time_zone_names& zone_names,
- const time_duration_type& utc_offset,
- const dst_adjustment_offsets& dst_shift,
- boost::shared_ptr<dst_calc_rule> calc_rule) :
- zone_names_(zone_names),
- base_utc_offset_(utc_offset),
- dst_offsets_(dst_shift),
- dst_calc_rules_(calc_rule)
- {};
- virtual ~custom_time_zone_base() {};
+
+ custom_time_zone_base(const time_zone_names& zone_names,
+ const time_duration_type& utc_offset,
+ const dst_adjustment_offsets& dst_shift,
+ dst_calc_rule_ptr calc_rule
+ ) :
+ zone_names_(zone_names),
+ base_utc_offset_(utc_offset),
+ dst_offsets_(dst_shift),
+ dst_calc_rules_(calc_rule)
+ {}
+ virtual ~custom_time_zone_base() {}
virtual string_type dst_zone_abbrev() const
{
- return zone_names_.dst_zone_abbrev();
+ return zone_names_.dst_zone_abbrev();
}
virtual string_type std_zone_abbrev() const
{
- return zone_names_.std_zone_abbrev();
+ return zone_names_.std_zone_abbrev();
}
virtual string_type dst_zone_name() const
{
- return zone_names_.dst_zone_name();
+ return zone_names_.dst_zone_name();
}
virtual string_type std_zone_name() const
{
- return zone_names_.std_zone_name();
+ return zone_names_.std_zone_name();
}
//! True if zone uses daylight savings adjustments
virtual bool has_dst() const
{
- return (dst_calc_rules_); //if calc_rule is set the tz has dst
+ return (dst_calc_rules_); //if calc_rule is set the tz has dst
}
//! Local time that DST starts -- NADT if has_dst is false
virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y) const
{
- gregorian::date d(gregorian::not_a_date_time);
- if (dst_calc_rules_) {
- d = dst_calc_rules_->start_day(y);
- }
- return posix_time::ptime(d, dst_offsets_.dst_start_offset_);
+ gregorian::date d(gregorian::not_a_date_time);
+ if (dst_calc_rules_)
+ d = dst_calc_rules_->start_day(y);
+ return posix_time::ptime(d, dst_offsets_.dst_start_offset_);
}
//! Local time that DST ends -- NADT if has_dst is false
virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y) const
{
- gregorian::date d(gregorian::not_a_date_time);
- if (dst_calc_rules_) {
- d = dst_calc_rules_->end_day(y);
- }
- return posix_time::ptime(d, dst_offsets_.dst_end_offset_);
+ gregorian::date d(gregorian::not_a_date_time);
+ if (dst_calc_rules_)
+ d = dst_calc_rules_->end_day(y);
+ return posix_time::ptime(d, dst_offsets_.dst_end_offset_);
}
//! Base offset from UTC for zone (eg: -07:30:00)
virtual time_duration_type base_utc_offset() const
{
- return base_utc_offset_;
+ return base_utc_offset_;
}
//! Adjustment forward or back made while DST is in effect
virtual time_duration_type dst_offset() const
{
- return dst_offsets_.dst_adjust_;
+ return dst_offsets_.dst_adjust_;
}
//! Returns a POSIX time_zone string for this object
virtual string_type to_posix_string() const
{
- // std offset dst [offset],start[/time],end[/time] - w/o spaces
- stringstream_type ss;
- ss.fill('0');
- boost::shared_ptr<dst_calc_rule> no_rules;
- // std
- ss << std_zone_abbrev();
- // offset
- if(base_utc_offset().is_negative()) {
- // inverting the sign guarantees we get two digits
- ss << '-' << std::setw(2) << base_utc_offset().invert_sign().hours();
- }
- else {
- ss << '+' << std::setw(2) << base_utc_offset().hours();
- }
- if(base_utc_offset().minutes() != 0 || base_utc_offset().seconds() != 0) {
- ss << ':' << std::setw(2) << base_utc_offset().minutes();
- if(base_utc_offset().seconds() != 0) {
- ss << ':' << std::setw(2) << base_utc_offset().seconds();
- }
- }
- if(dst_calc_rules_ != no_rules) {
- // dst
- ss << dst_zone_abbrev();
- // dst offset
- if(dst_offset().is_negative()) {
- // inverting the sign guarantees we get two digits
- ss << '-' << std::setw(2) << dst_offset().invert_sign().hours();
- }
- else {
- ss << '+' << std::setw(2) << dst_offset().hours();
- }
- if(dst_offset().minutes() != 0 || dst_offset().seconds() != 0) {
- ss << ':' << std::setw(2) << dst_offset().minutes();
- if(dst_offset().seconds() != 0) {
- ss << ':' << std::setw(2) << dst_offset().seconds();
- }
+ // std offset dst [offset],start[/time],end[/time] - w/o spaces
+ typedef std::basic_ostringstream< CharT > stringstream_type;
+ stringstream_type ss;
+ ss.fill('0');
+
+ // std
+ ss << std_zone_abbrev();
+ // offset
+ if (base_utc_offset_.is_negative())
+ {
+ // inverting the sign guarantees we get two digits
+ ss << '-' << std::setw(2) << base_utc_offset_.invert_sign().hours();
+ }
+ else
+ {
+ ss << '+' << std::setw(2) << base_utc_offset_.hours();
+ }
+
+ if (base_utc_offset_.minutes() != 0 || base_utc_offset_.seconds() != 0)
+ {
+ ss << ':' << std::setw(2) << base_utc_offset_.minutes();
+ if (base_utc_offset_.seconds() != 0)
+ {
+ ss << ':' << std::setw(2) << base_utc_offset_.seconds();
+ }
+ }
+
+ if (!!dst_calc_rules_)
+ {
+ // dst
+ ss << dst_zone_abbrev();
+ // dst offset
+ if (dst_offsets_.dst_adjust_.is_negative())
+ {
+ // inverting the sign guarantees we get two digits
+ ss << '-' << std::setw(2) << dst_offsets_.dst_adjust_.invert_sign().hours();
+ }
+ else
+ {
+ ss << '+' << std::setw(2) << dst_offsets_.dst_adjust_.hours();
+ }
+ if (dst_offsets_.dst_adjust_.minutes() != 0 || dst_offsets_.dst_adjust_.seconds() != 0)
+ {
+ ss << ':' << std::setw(2) << dst_offsets_.dst_adjust_.minutes();
+ if (dst_offsets_.dst_adjust_.seconds() != 0)
+ {
+ ss << ':' << std::setw(2) << dst_offsets_.dst_adjust_.seconds();
+ }
+ }
+ // start/time
+ ss << ',' << date_time::convert_string_type< char, 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()) << '/'
+ << 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)
+ {
+ ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds();
+ }
}
- // start/time
- ss << ',' << date_time::convert_string_type<char, 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()) << '/'
- << 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) {
- ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds();
- }
- }
- return ss.str();
+ return ss.str();
}
- private:
+
+private:
time_zone_names zone_names_;
bool has_dst_;
time_duration_type base_utc_offset_;
dst_adjustment_offsets dst_offsets_;
- boost::shared_ptr<dst_calc_rule> dst_calc_rules_;
- };
-
- typedef custom_time_zone_base<char> custom_time_zone;
+ dst_calc_rule_ptr dst_calc_rules_;
+};
-} }//namespace
+typedef custom_time_zone_base< char > custom_time_zone;
+} // namespace local_time
+} // namespace boost
#endif
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-08 14:48:55 EDT (Tue, 08 Jun 2010)
@@ -74,7 +74,6 @@
typedef date_time::time_zone_base<posix_time::ptime,CharT> base_type;
typedef typename base_type::string_type string_type;
typedef CharT char_type;
- typedef typename base_type::stringstream_type stringstream_type;
typedef boost::char_separator<char_type, std::char_traits<char_type> > char_separator_type;
typedef boost::tokenizer<char_separator_type,
typename string_type::const_iterator,
@@ -175,6 +174,7 @@
virtual string_type to_posix_string() const
{
// std offset dst [offset],start[/time],end[/time] - w/o spaces
+ typedef std::basic_ostringstream< CharT > stringstream_type;
stringstream_type ss;
ss.fill('0');
boost::shared_ptr<dst_calc_rule> no_rules;
@@ -242,6 +242,7 @@
* NOT extracted so the abbreviations are used in their place */
void calc_zone(const string_type& obj){
const char_type empty_string[2] = {'\0'};
+ typedef std::basic_ostringstream< CharT > stringstream_type;
stringstream_type ss(empty_string);
typename string_type::const_pointer sit = obj.c_str(), obj_end = sit + obj.size();
string_type l_std_zone_abbrev, l_dst_zone_abbrev;
@@ -451,7 +452,7 @@
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
s = posix_time::to_simple_string(td);
#else
- std::stringstream ss;
+ std::ostringstream ss;
ss << td;
s = ss.str();
#endif
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-08 14:48:55 EDT (Tue, 08 Jun 2010)
@@ -8,14 +8,14 @@
* $Date$
*/
-#include "boost/date_time/compiler_config.hpp"
#include <string>
+#include <boost/date_time/compiler_config.hpp>
namespace boost {
namespace date_time {
//! Converts a string from one value_type to another
- /*! Converts a wstring to a string (or a string to wstring). If both template parameters
+ /*! Converts a wstring to a string (or a string to wstring). If both template parameters
* are of same type, a copy of the input string is returned. */
template<class InputT, class OutputT>
inline
@@ -27,7 +27,7 @@
result.insert(result.begin(), inp_str.begin(), inp_str.end());
return result;
}
-
+
}} // namespace boost::date_time
#endif // _STRING_CONVERT_HPP___
Modified: branches/date_time_io_rewrite/boost/date_time/time_zone_base.hpp
==============================================================================
--- branches/date_time_io_rewrite/boost/date_time/time_zone_base.hpp (original)
+++ branches/date_time_io_rewrite/boost/date_time/time_zone_base.hpp 2010-06-08 14:48:55 EDT (Tue, 08 Jun 2010)
@@ -2,98 +2,97 @@
#define _DATE_TIME_TIME_ZONE_BASE__
/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
- * Subject to the Boost Software License, Version 1.0.
+ * 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
* $Date$
*/
-
#include <string>
-#include <sstream>
namespace boost {
-namespace date_time {
-
+namespace date_time {
- //! Interface class for dynamic time zones.
- /*! This class represents the base interface for all timezone
- * representations. Subclasses may provide different systems
- * for identifying a particular zone. For example some may
- * provide a geographical based zone construction while others
- * may specify the offset from GMT. Another possible implementation
- * would be to convert from POSIX timezone strings. Regardless of
- * the construction technique, this is the interface that these
- * time zone types must provide.
- *
- * Note that this class is intended to be used as a shared
- * resource (hence the derivation from boost::counted_base.
- */
- template<typename time_type, typename CharT>
- class time_zone_base {
- public:
+//! Interface class for dynamic time zones.
+/*! This class represents the base interface for all timezone
+ * representations. Subclasses may provide different systems
+ * for identifying a particular zone. For example some may
+ * provide a geographical based zone construction while others
+ * may specify the offset from GMT. Another possible implementation
+ * would be to convert from POSIX timezone strings. Regardless of
+ * the construction technique, this is the interface that these
+ * time zone types must provide.
+ *
+ * Note that time zone is intended to be used a shared
+ * resource.
+ */
+template< typename TimeT, typename CharT >
+class time_zone_base
+{
+public:
typedef CharT char_type;
- typedef std::basic_string<CharT> string_type;
- typedef std::basic_ostringstream<CharT> stringstream_type;
+ typedef std::basic_string< CharT > string_type;
+ typedef TimeT time_type;
typedef typename time_type::date_type::year_type year_type;
typedef typename time_type::time_duration_type time_duration_type;
- time_zone_base() {};
- virtual ~time_zone_base() {};
- //!String for the timezone when in daylight savings (eg: EDT)
- virtual string_type dst_zone_abbrev() const=0;
- //!String for the zone when not in daylight savings (eg: EST)
- virtual string_type std_zone_abbrev() const=0;
- //!String for the timezone when in daylight savings (eg: Eastern Daylight Time)
- virtual string_type dst_zone_name() const=0;
- //!String for the zone when not in daylight savings (eg: Eastern Standard Time)
- virtual string_type std_zone_name() const=0;
+ time_zone_base() {}
+ virtual ~time_zone_base() {}
+ //! String for the timezone when in daylight savings (eg: EDT)
+ virtual string_type dst_zone_abbrev() const = 0;
+ //! String for the zone when not in daylight savings (eg: EST)
+ virtual string_type std_zone_abbrev() const = 0;
+ //! String for the timezone when in daylight savings (eg: Eastern Daylight Time)
+ virtual string_type dst_zone_name() const = 0;
+ //! String for the zone when not in daylight savings (eg: Eastern Standard Time)
+ virtual string_type std_zone_name() const = 0;
//! True if zone uses daylight savings adjustments otherwise false
- virtual bool has_dst() const=0;
+ virtual bool has_dst() const = 0;
//! Local time that DST starts -- undefined if has_dst is false
- virtual time_type dst_local_start_time(year_type y) const=0;
+ virtual time_type dst_local_start_time(year_type y) const = 0;
//! Local time that DST ends -- undefined if has_dst is false
- virtual time_type dst_local_end_time(year_type y) const=0;
+ virtual time_type dst_local_end_time(year_type y) const = 0;
//! Base offset from UTC for zone (eg: -07:30:00)
- virtual time_duration_type base_utc_offset() const=0;
+ virtual time_duration_type base_utc_offset() const = 0;
//! Adjustment forward or back made while DST is in effect
- virtual time_duration_type dst_offset() const=0;
+ virtual time_duration_type dst_offset() const = 0;
//! Returns a POSIX time_zone string for this object
- virtual string_type to_posix_string() const =0;
-
- private:
-
- };
-
-
- //! Structure which holds the time offsets associated with daylight savings time
- /*!
- *@param time_duration_type A type used to represent the offset
- */
- template<class time_duration_type>
- class dst_adjustment_offsets
- {
- public:
- dst_adjustment_offsets(const time_duration_type& dst_adjust,
- const time_duration_type& dst_start_offset,
- const time_duration_type& dst_end_offset) :
- dst_adjust_(dst_adjust),
- dst_start_offset_(dst_start_offset),
- dst_end_offset_(dst_end_offset)
- {}
-
+ virtual string_type to_posix_string() const = 0;
+};
+
+
+//! Structure which holds the time offsets associated with daylight savings time
+/*!
+*@param time_duration_type A type used to represent the offset
+*/
+template< typename TimeDurationT >
+class dst_adjustment_offsets
+{
+public:
+ typedef TimeDurationT time_duration_type;
+
+ dst_adjustment_offsets(
+ const time_duration_type& dst_adjust,
+ const time_duration_type& dst_start_offset,
+ const time_duration_type& dst_end_offset
+ ) :
+ dst_adjust_(dst_adjust),
+ dst_start_offset_(dst_start_offset),
+ dst_end_offset_(dst_end_offset)
+ {
+ }
+
//! Amount DST adjusts the clock eg: plus one hour
time_duration_type dst_adjust_;
//! Time past midnight on start transition day that dst starts
time_duration_type dst_start_offset_;
//! Time past midnight on end transition day that dst ends
time_duration_type dst_end_offset_;
- };
-
-
-} } //namespace date_time
+};
+} // namespace date_time
+} // namespace boost
#endif
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-08 14:48:55 EDT (Tue, 08 Jun 2010)
@@ -18,17 +18,20 @@
project boost/date_time
: requirements
<define>DATE_TIME_INLINE
- <link>shared:<define>BOOST_ALL_DYN_LINK=1
- <link>static:<define>BOOST_DATE_TIME_STATIC_LINK
- : usage-requirements
+ <link>shared:<define>BOOST_ALL_DYN_LINK=1
+ <link>static:<define>BOOST_DATE_TIME_STATIC_LINK
+ : usage-requirements
<define>DATE_TIME_INLINE
<link>shared:<define>BOOST_DATE_TIME_DYN_LINK=1
: source-location ../src
;
-# Base names of the source files for libboost_date_time
-CPP_SOURCES = greg_month greg_weekday date_generators ;
-
-lib boost_date_time : gregorian/$(CPP_SOURCES).cpp ;
+lib boost_date_time :
+ formatter.cpp
+ gregorian/greg_month.cpp
+ gregorian/greg_weekday.cpp
+ gregorian/date_generators.cpp
+ gregorian/greg_month.cpp
+ ;
boost-install boost_date_time ;
Added: branches/date_time_io_rewrite/libs/date_time/src/formatter.cpp
==============================================================================
--- (empty file)
+++ branches/date_time_io_rewrite/libs/date_time/src/formatter.cpp 2010-06-08 14:48:55 EDT (Tue, 08 Jun 2010)
@@ -0,0 +1,671 @@
+/*
+ * 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 <memory>
+#include <limits>
+#include <vector>
+#include <iterator>
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/checked_delete.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/slist_hook.hpp>
+#include <boost/intrusive/options.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/karma_uint.hpp>
+#include <boost/spirit/include/karma_generate.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_bind.hpp>
+#include <boost/spirit/include/phoenix_fusion.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#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>
+
+namespace boost {
+
+namespace date_time {
+
+namespace aux {
+
+namespace qi = boost::spirit::qi;
+namespace karma = boost::spirit::karma;
+
+namespace {
+
+ //! A simple trait that allows to use charset-specific Qi parsers in a generic way
+ template< typename CharT >
+ struct charset_parsers;
+
+#define BOOST_DATE_TIME_CHARSET_PARSERS\
+ ((char_type, char_))\
+ ((string_type, string))\
+ ((alnum_type, alnum))\
+ ((alpha_type, alpha))\
+ ((blank_type, blank))\
+ ((cntrl_type, cntrl))\
+ ((digit_type, digit))\
+ ((graph_type, graph))\
+ ((print_type, print))\
+ ((punct_type, punct))\
+ ((space_type, space))\
+ ((xdigit_type, xdigit))\
+ ((no_case_type, no_case))\
+ ((lower_type, lower))\
+ ((upper_type, upper))\
+ ((lowernum_type, lowernum))\
+ ((uppernum_type, uppernum))
+
+#define BOOST_DATE_TIME_DECLARE_CHARSET_PARSER(r, charset, parser)\
+ static spirit::charset::BOOST_PP_TUPLE_ELEM(2, 0, parser) const& BOOST_PP_TUPLE_ELEM(2, 1, parser);
+
+#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_PARSERS(char_type, charset)\
+ BOOST_PP_SEQ_FOR_EACH(BOOST_DATE_TIME_DEFINE_CHARSET_PARSER, (char_type, charset), BOOST_DATE_TIME_CHARSET_PARSERS)
+
+ template< >
+ struct charset_parsers< char >
+ {
+ BOOST_DATE_TIME_DECLARE_CHARSET_PARSERS(standard)
+ };
+ BOOST_DATE_TIME_DEFINE_CHARSET_PARSERS(char, standard)
+
+#ifndef BOOST_NO_STD_WSTRING
+ template< >
+ struct charset_parsers< wchar_t >
+ {
+ BOOST_DATE_TIME_DECLARE_CHARSET_PARSERS(standard_wide)
+ };
+ BOOST_DATE_TIME_DEFINE_CHARSET_PARSERS(wchar_t, standard_wide)
+#endif // BOOST_NO_STD_WSTRING
+
+#undef BOOST_DATE_TIME_DEFINE_CHARSET_PARSERS
+#undef BOOST_DATE_TIME_DEFINE_CHARSET_PARSER
+#undef BOOST_DATE_TIME_DECLARE_CHARSET_PARSERS
+#undef BOOST_DATE_TIME_DECLARE_CHARSET_PARSER
+#undef BOOST_DATE_TIME_CHARSET_PARSERS
+
+ //! The function appends a formatted integer to the end of the string
+ template< typename CharT >
+ inline void put(
+ uint32_t val,
+ unsigned int width,
+ CharT leading_char,
+ std::basic_string< CharT >& target)
+ {
+ CharT buf[std::numeric_limits< uint32_t >::digits10 + 2];
+ CharT* p = buf;
+
+ typedef karma::uint_generator< uint32_t, 10 > uint_gen;
+ karma::generate(p, uint_gen(), val);
+ const std::size_t len = p - buf;
+ if (len < width)
+ target.insert(target.end(), width - len, leading_char);
+ target.append(buf, p);
+ }
+
+} // namespace
+
+template< typename CharT >
+struct formatter< CharT >::implementation
+{
+public:
+ //! Base interface for formatter steps
+ struct step_base :
+ public intrusive::slist_base_hook< intrusive::tag< step_base > >
+ {
+ step_base() {}
+ virtual ~step_base() {}
+ virtual step_base* clone() const = 0;
+ virtual void operator()(
+ common_date_time const& dt,
+ std::locale const& loc,
+ string_type& target) = 0;
+
+ private:
+ step_base(step_base const&);
+ step_base& operator= (step_base const&);
+ };
+
+ //! Final class of formatting steps
+ template< typename T >
+ class step :
+ public step_base,
+ public T
+ {
+ public:
+ step() {}
+ step(step const& that) : step_base(), T(static_cast< T const& >(that)) {}
+ template< typename T1 >
+ explicit step(T1 const& arg1) : step_base(), T(arg1) {}
+ template< typename T1, typename T2 >
+ explicit step(T1 const& arg1, T2 const& arg2) : step_base(), T(arg1, arg2) {}
+
+ step_base* clone() const
+ {
+ return new step< T >(*this);
+ }
+ void operator()(common_date_time const& dt, std::locale const& loc, string_type& target)
+ {
+ T::operator() (dt, loc, target);
+ }
+ };
+
+ //! A composite step that sequentially executes 3 steps interleaving with a delimiter character
+ template< typename StepT1, typename StepT2, typename StepT3, char_type DelimiterV = 0 >
+ struct delimited3
+ {
+ void operator()(common_date_time const& dt, std::locale const& loc, string_type& target)
+ {
+ StepT1()(dt, loc, target);
+ if (DelimiterV)
+ target.push_back(DelimiterV);
+ StepT2()(dt, loc, target);
+ if (DelimiterV)
+ target.push_back(DelimiterV);
+ StepT3()(dt, loc, target);
+ }
+ };
+
+ //! The formatter appends a single character to the target string
+ struct constant_char
+ {
+ explicit constant_char(char_type c) : m_Char(c)
+ {
+ }
+ void operator()(common_date_time const&, std::locale const&, string_type& target)
+ {
+ target.push_back(m_Char);
+ }
+
+ char_type m_Char;
+ };
+
+ //! The formatter appends a fixed string to the target string
+ struct constant
+ {
+ explicit constant(std::vector< char_type > const& lit) : m_Str(lit.begin(), lit.end())
+ {
+ }
+ void operator()(common_date_time const&, std::locale const&, string_type& target)
+ {
+ target.append(m_Str);
+ }
+
+ string_type m_Str;
+ };
+
+ //! Formatter for year without the century
+ struct short_year
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ put(dt.get_tm().tm_year % 100, 2U, static_cast< char_type >('0'), target);
+ }
+ };
+
+ //! Formatter for year
+ struct long_year
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ typedef karma::uint_generator< uint32_t, 10 > uint_gen;
+ std::back_insert_iterator< string_type > it(target);
+ karma::generate(
+ it,
+ uint_gen(),
+ static_cast< uint32_t >(dt.get_tm().tm_year + 1900));
+ }
+ };
+
+ //! Formatter for numeric month
+ struct numeric_month
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ put(dt.get_tm().tm_mon + 1, 2U, static_cast< char_type >('0'), target);
+ }
+ };
+
+ //! Formatter for the day of month
+ struct day
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ put(dt.get_tm().tm_mday, 2U, static_cast< char_type >('0'), target);
+ }
+ };
+
+ //! Formatter for the day of month with leading space
+ struct day_leading_space
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ put(dt.get_tm().tm_mday, 2U, static_cast< char_type >(' '), target);
+ }
+ };
+
+ // Various types of american date formats
+ typedef delimited3< numeric_month, day, short_year, '/' > short_american_date;
+ typedef delimited3< numeric_month, day, long_year, '/' > long_american_date;
+ typedef delimited3< numeric_month, day, short_year, '.' > short_dotted_american_date;
+ typedef delimited3< numeric_month, day, long_year, '.' > long_dotted_american_date;
+
+ // Various types of european date formats
+ typedef delimited3< day, numeric_month, short_year, '.' > short_dotted_european_date;
+ typedef delimited3< day, numeric_month, long_year, '.' > long_dotted_european_date;
+
+ // Various types of ISO date formats
+ typedef delimited3< long_year, numeric_month, day > iso_date;
+ typedef delimited3< long_year, numeric_month, day, '-' > iso_extended_date;
+
+ //! Formatter for hours in 24-hour format
+ struct hours24
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ put(dt.get_tm().tm_hour % 24, 2U, static_cast< char_type >('0'), target);
+ }
+ };
+
+ //! Formatter for hours in 12-hour format
+ struct hours12
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ uint32_t h = (dt.get_tm().tm_hour % 12) + 1;
+ put(h, 2U, static_cast< char_type >('0'), target);
+ }
+ };
+
+ //! Formatter for hours for time durations
+ struct unrestricted_hours
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ put(dt.get_tm().tm_hour, 2U, static_cast< char_type >('0'), target);
+ }
+ };
+
+ //! Formatter for minutes
+ struct minutes
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ put(dt.get_tm().tm_min, 2U, static_cast< char_type >('0'), target);
+ }
+ };
+
+ //! Formatter for seconds
+ struct seconds
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ put(dt.get_tm().tm_sec, 2U, static_cast< char_type >('0'), target);
+ }
+ };
+
+ //! Formatter for fractional seconds
+ struct fractional_seconds
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ put(dt.fractional_seconds(), 6U, static_cast< char_type >('0'), target);
+ }
+ };
+
+ //! Formatter for the AM/PM sign
+ struct am_pm
+ {
+ void operator()(common_date_time const& dt, std::locale const&, string_type& target)
+ {
+ static const char_type am[3] = { 'A', 'M', 0 };
+ static const char_type pm[3] = { 'P', 'M', 0 };
+ target.append((dt.get_tm().tm_hour > 11) ? pm : am, 2U);
+ }
+ };
+
+ // Various time formats
+ typedef delimited3< hours24, minutes, seconds, ':' > h24ms_time;
+ typedef delimited3< hours12, minutes, seconds, ':' > h12ms_time;
+ typedef delimited3< unrestricted_hours, minutes, seconds, ':' > default_duration;
+
+ //! Sequence of elementary formatters
+ typedef intrusive::slist<
+ step_base,
+ intrusive::base_hook< intrusive::slist_base_hook< intrusive::tag< step_base > > >,
+ intrusive::constant_time_size< false >,
+ intrusive::cache_last< true >
+ > step_list;
+
+private:
+ step_list m_Steps;
+
+public:
+ implementation()
+ {
+ }
+ implementation(implementation const& that)
+ {
+ try
+ {
+ typename step_list::const_iterator it = that.m_Steps.begin(), end = that.m_Steps.end();
+ for (; it != end; ++it)
+ m_Steps.push_back(*it->clone());
+ }
+ catch (...)
+ {
+ m_Steps.clear_and_dispose(checked_deleter< step_base >());
+ throw;
+ }
+ }
+ ~implementation()
+ {
+ m_Steps.clear_and_dispose(checked_deleter< step_base >());
+ }
+
+ void format(common_date_time const& dt, string_type& str, std::locale const& loc)
+ {
+ typename step_list::iterator it = m_Steps.begin(), end = m_Steps.end();
+ for (; it != end; ++it)
+ (*it)(dt, loc, str);
+ }
+
+ void add_string_literal(std::vector< char_type > const& lit)
+ {
+ step_base* p;
+ if (lit.size() > 1)
+ p = new step< constant >(lit);
+ else
+ p = new step< constant_char >(lit[0]);
+ m_Steps.push_back(*p);
+ }
+
+ void add_percent()
+ {
+ m_Steps.push_back(*new step< constant_char >('%'));
+ }
+
+ template< typename T >
+ void add()
+ {
+ m_Steps.push_back(*new step< T >());
+ }
+
+private:
+ implementation& operator= (implementation const&);
+};
+
+namespace {
+
+ //! String constants with format placeholders
+ template< typename CharT >
+ struct format_placeholders;
+
+ template< >
+ struct format_placeholders< char >
+ {
+ typedef char char_type;
+
+ static const char_type* iso_date() { return "%Y%m%d"; }
+ static const char_type* iso_extended_date() { return "%Y-%m-%d"; }
+ static const char_type* explicit_short_american_date() { return "%m/%d/%y"; }
+ static const char_type* explicit_short_dotted_american_date() { return "%m.%d.%y"; }
+ static const char_type* explicit_long_american_date() { return "%m/%d/%Y"; }
+ static const char_type* explicit_long_dotted_american_date() { return "%m.%d.%Y"; }
+ static const char_type* explicit_short_dotted_european_date() { return "%d.%m.%y"; }
+ static const char_type* explicit_long_dotted_european_date() { return "%d.%m.%Y"; }
+ static const char_type* h24ms_time() { return "%H:%M:%S"; }
+ static const char_type* h12ms_time() { return "%I:%M:%S"; }
+ static const char_type* default_duration() { return "%O:%M:%S"; }
+
+ static const char_type* percent() { return "%%"; }
+ static const char_type* short_year() { return "%y"; }
+ static const char_type* long_year() { return "%Y"; }
+ static const char_type* numeric_month() { return "%m"; }
+ static const char_type* day() { return "%d"; }
+ static const char_type* day_leading_space() { return "%e"; }
+ static const char_type* american_date() { return "%D"; }
+ static const char_type* unrestricted_hours() { return "%O"; }
+ static const char_type* hours24() { return "%H"; }
+ static const char_type* hours12() { return "%I"; }
+ static const char_type* minutes() { return "%M"; }
+ static const char_type* seconds() { return "%S"; }
+ static const char_type* fractional_seconds() { return "%f"; }
+ static const char_type* am_pm() { return "%p"; }
+ };
+
+#ifndef BOOST_NO_STD_WSTRING
+ template< >
+ struct format_placeholders< wchar_t >
+ {
+ typedef wchar_t char_type;
+
+ static const char_type* iso_date() { return L"%Y%m%d"; }
+ static const char_type* iso_extended_date() { return L"%Y-%m-%d"; }
+ static const char_type* explicit_short_american_date() { return L"%m/%d/%y"; }
+ static const char_type* explicit_short_dotted_american_date() { return L"%m.%d.%y"; }
+ static const char_type* explicit_long_american_date() { return L"%m/%d/%Y"; }
+ static const char_type* explicit_long_dotted_american_date() { return L"%m.%d.%Y"; }
+ static const char_type* explicit_short_dotted_european_date() { return L"%d.%m.%y"; }
+ static const char_type* explicit_long_dotted_european_date() { return L"%d.%m.%Y"; }
+ static const char_type* h24ms_time() { return L"%H:%M:%S"; }
+ static const char_type* h12ms_time() { return L"%I:%M:%S"; }
+ static const char_type* default_duration() { return L"%O:%M:%S"; }
+
+ static const char_type* percent() { return L"%%"; }
+ static const char_type* short_year() { return L"%y"; }
+ static const char_type* long_year() { return L"%Y"; }
+ static const char_type* numeric_month() { return L"%m"; }
+ static const char_type* day() { return L"%d"; }
+ static const char_type* day_leading_space() { return L"%e"; }
+ static const char_type* american_date() { return L"%D"; }
+ static const char_type* unrestricted_hours() { return L"%O"; }
+ static const char_type* hours24() { return L"%H"; }
+ static const char_type* hours12() { return L"%I"; }
+ static const char_type* minutes() { return L"%M"; }
+ static const char_type* seconds() { return L"%S"; }
+ static const char_type* fractional_seconds() { return L"%f"; }
+ static const char_type* am_pm() { return L"%p"; }
+ };
+#endif // BOOST_NO_STD_WSTRING
+
+ //! Date and time format grammar
+ template< typename CharT >
+ struct date_time_grammar :
+ public qi::grammar< const CharT* >
+ {
+ typedef CharT char_type;
+ typedef typename formatter< char_type >::implementation collector;
+ typedef qi::rule< const char_type* > rule_type;
+ typedef void (collector::*callback_type)();
+ typedef qi::symbols< char_type, callback_type > symbols_type;
+
+ //! A simple mem_fun wrapper compatible with Boost.Phoenix
+ struct mem_fun
+ {
+ template< typename, typename >
+ struct result
+ {
+ typedef void type;
+ };
+
+ void operator() (callback_type fun, collector* p) const
+ {
+ (p->*fun)();
+ }
+ };
+
+#define BOOST_DATE_TIME_FORMAT_PLACEHOLDERS\
+ (short_year)\
+ (long_year)\
+ (numeric_month)\
+ (day)\
+ (day_leading_space)\
+ (unrestricted_hours)\
+ (hours24)\
+ (hours12)\
+ (minutes)\
+ (seconds)\
+ (fractional_seconds)\
+ (am_pm)
+
+#define BOOST_DATE_TIME_ADD_STEP(r, data, step)\
+ (constants::step (), &collector::BOOST_NESTED_TEMPLATE add< typename collector::step >)
+
+ explicit date_time_grammar(collector* p, bool& is_complete) :
+ date_time_grammar::base_type(m_Start)
+ {
+ typedef charset_parsers< char_type > charset;
+ typedef format_placeholders< char_type > constants;
+ namespace args = phoenix::arg_names;
+
+ // These templates are used often, so for sake of performance
+ // they are recognized and replaced with a single formatting step
+ m_PredefinedTemplates.add
+ (constants::explicit_short_american_date(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::short_american_date >)
+ (constants::explicit_long_american_date(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::long_american_date >)
+ (constants::explicit_short_dotted_american_date(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::short_dotted_american_date >)
+ (constants::explicit_long_dotted_american_date(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::long_dotted_american_date >)
+ (constants::explicit_short_dotted_european_date(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::short_dotted_european_date >)
+ (constants::explicit_long_dotted_european_date(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::long_dotted_european_date >)
+ (constants::iso_date(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::iso_date >)
+ (constants::iso_extended_date(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::iso_extended_date >)
+ (constants::h24ms_time(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::h24ms_time >)
+ (constants::h12ms_time(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::h12ms_time >)
+ (constants::default_duration(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::default_duration >)
+ ;
+
+ m_Placeholders.add
+ (constants::percent(), &collector::add_percent)
+ (constants::american_date(),
+ &collector::BOOST_NESTED_TEMPLATE add< typename collector::short_american_date >)
+ BOOST_PP_SEQ_FOR_EACH(BOOST_DATE_TIME_ADD_STEP, ~, BOOST_DATE_TIME_FORMAT_PLACEHOLDERS)
+ ;
+
+ m_Start =
+ *(
+ m_PredefinedTemplates[phoenix::bind(mem_fun(), phoenix::at_c< 0 >(args::_1), p)] |
+ m_Placeholders[phoenix::bind(mem_fun(), phoenix::at_c< 0 >(args::_1), p)] |
+ (+(charset::char_ - charset::char_(static_cast< char_type >('%'))))
+ [phoenix::bind(&collector::add_string_literal, p, phoenix::at_c< 0 >(args::_1))] |
+ // If it comes to this, then some placeholder is not recognized
+ charset::char_(static_cast< char_type >('%'))
+ [phoenix::ref(is_complete) = false, phoenix::bind(&collector::add_percent, p)]
+ );
+ }
+
+#undef BOOST_DATE_TIME_ADD_STEP
+#undef BOOST_DATE_TIME_FORMAT_PLACEHOLDERS
+
+ private:
+ //! Starting rule for the parser
+ rule_type m_Start;
+ //! Formatting placeholders
+ symbols_type m_Placeholders;
+ //! Predefined date/time formats
+ symbols_type m_PredefinedTemplates;
+ };
+
+} // namespace
+
+//! Default constructor. Creates an empty formatter that does nothing.
+template< typename CharT >
+formatter< CharT >::formatter() : m_pImpl(new implementation())
+{
+}
+
+//! Copy constructor. Performs a deep copying.
+template< typename CharT >
+formatter< CharT >::formatter(formatter const& that) :
+ m_pImpl(new implementation(*that.m_pImpl))
+{
+}
+
+//! Destructor
+template< typename CharT >
+formatter< CharT >::~formatter()
+{
+ delete m_pImpl;
+}
+
+//! Assignment
+template< typename CharT >
+formatter< CharT >& formatter< CharT >::operator= (formatter const& that)
+{
+ implementation* p = new implementation(*that.m_pImpl);
+ delete m_pImpl;
+ m_pImpl = p;
+ return *this;
+}
+
+//! Formatting operator
+template< typename CharT >
+void formatter< CharT >::operator()(
+ common_date_time const& dt, string_type& str, std::locale const& loc) const
+{
+ m_pImpl->format(dt, str, loc);
+}
+
+//! Parses the format string and constructs the formatter
+template< typename CharT >
+formatter< CharT > formatter< CharT >::parse(const char_type* b, const char_type* e)
+{
+ formatter< CharT > formatter;
+ bool is_complete = true;
+ date_time_grammar< CharT > grammar(formatter.m_pImpl, is_complete);
+
+ const char_type* p = b;
+ 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("\", stopped at position ");
+ std::back_insert_iterator< std::string > it(descr);
+ karma::generate(it, karma::uint_, static_cast< std::size_t >(p - b));
+ BOOST_THROW_EXCEPTION(std::runtime_error(descr));
+ }
+
+ if (!is_complete)
+ {
+ // The parser did not recognize all placeholders. We'll have to pass
+ // the formatter output to the standard facet to complete the formatting.
+ }
+
+ return formatter;
+}
+
+template class BOOST_DATE_TIME_DECL formatter< char >;
+
+#ifndef BOOST_NO_STD_WSTRING
+template class BOOST_DATE_TIME_DECL formatter< wchar_t >;
+#endif
+
+} // namespace aux
+
+} // namespace date_time
+
+} // namespace boost
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