summaryrefslogtreecommitdiff
path: root/boost/date_time/posix_time
diff options
context:
space:
mode:
Diffstat (limited to 'boost/date_time/posix_time')
-rw-r--r--boost/date_time/posix_time/posix_time_duration.hpp28
-rw-r--r--boost/date_time/posix_time/posix_time_io.hpp24
-rw-r--r--boost/date_time/posix_time/time_serialize.hpp85
3 files changed, 95 insertions, 42 deletions
diff --git a/boost/date_time/posix_time/posix_time_duration.hpp b/boost/date_time/posix_time/posix_time_duration.hpp
index 1143cedb57..c7ec57e8aa 100644
--- a/boost/date_time/posix_time/posix_time_duration.hpp
+++ b/boost/date_time/posix_time/posix_time_duration.hpp
@@ -9,42 +9,54 @@
* $Date$
*/
+#include <boost/core/enable_if.hpp>
#include <boost/date_time/compiler_config.hpp>
#include <boost/date_time/posix_time/posix_time_config.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/type_traits/is_integral.hpp>
namespace boost {
namespace posix_time {
//! Allows expression of durations as an hour count
+ //! The argument must be an integral type
/*! \ingroup time_basics
*/
class BOOST_SYMBOL_VISIBLE hours : public time_duration
{
public:
- explicit hours(long h) :
- time_duration(static_cast<hour_type>(h),0,0)
+ template <typename T>
+ explicit hours(T const& h,
+ typename boost::enable_if<boost::is_integral<T>, void>::type* = 0) :
+ time_duration(numeric_cast<hour_type>(h), 0, 0)
{}
};
//! Allows expression of durations as a minute count
+ //! The argument must be an integral type
/*! \ingroup time_basics
*/
class BOOST_SYMBOL_VISIBLE minutes : public time_duration
{
public:
- explicit minutes(long m) :
- time_duration(0,static_cast<min_type>(m),0)
+ template <typename T>
+ explicit minutes(T const& m,
+ typename boost::enable_if<boost::is_integral<T>, void>::type* = 0) :
+ time_duration(0, numeric_cast<min_type>(m),0)
{}
};
//! Allows expression of durations as a seconds count
+ //! The argument must be an integral type
/*! \ingroup time_basics
*/
class BOOST_SYMBOL_VISIBLE seconds : public time_duration
{
public:
- explicit seconds(long s) :
- time_duration(0,0,static_cast<sec_type>(s))
+ template <typename T>
+ explicit seconds(T const& s,
+ typename boost::enable_if<boost::is_integral<T>, void>::type* = 0) :
+ time_duration(0,0, numeric_cast<sec_type>(s))
{}
};
@@ -70,12 +82,8 @@ namespace posix_time {
typedef date_time::subsecond_duration<time_duration,1000000000> nanosec;
typedef date_time::subsecond_duration<time_duration,1000000000> nanoseconds;
-
#endif
-
-
-
} }//namespace posix_time
diff --git a/boost/date_time/posix_time/posix_time_io.hpp b/boost/date_time/posix_time/posix_time_io.hpp
index 45c338b220..90b02a6919 100644
--- a/boost/date_time/posix_time/posix_time_io.hpp
+++ b/boost/date_time/posix_time/posix_time_io.hpp
@@ -74,13 +74,13 @@ namespace posix_time {
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
- typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
+ typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
- if(std::has_facet<time_input_facet>(is.getloc())) {
- std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, pt);
+ if(std::has_facet<time_input_facet_local>(is.getloc())) {
+ std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, pt);
}
else {
- time_input_facet* f = new time_input_facet();
+ time_input_facet_local* f = new time_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, pt);
@@ -141,13 +141,13 @@ namespace posix_time {
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
- typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
+ typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
- if(std::has_facet<time_input_facet>(is.getloc())) {
- std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, tp);
+ if(std::has_facet<time_input_facet_local>(is.getloc())) {
+ std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, tp);
}
else {
- time_input_facet* f = new time_input_facet();
+ time_input_facet_local* f = new time_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, tp);
@@ -205,13 +205,13 @@ namespace posix_time {
typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
if (strm_sentry) {
try {
- typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
+ typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local;
std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
- if(std::has_facet<time_input_facet>(is.getloc())) {
- std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, td);
+ if(std::has_facet<time_input_facet_local>(is.getloc())) {
+ std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, td);
}
else {
- time_input_facet* f = new time_input_facet();
+ time_input_facet_local* f = new time_input_facet_local();
std::locale l = std::locale(is.getloc(), f);
is.imbue(l);
f->get(sit, str_end, is, td);
diff --git a/boost/date_time/posix_time/time_serialize.hpp b/boost/date_time/posix_time/time_serialize.hpp
index 8650ae1da9..71f60b3741 100644
--- a/boost/date_time/posix_time/time_serialize.hpp
+++ b/boost/date_time/posix_time/time_serialize.hpp
@@ -11,9 +11,10 @@
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/date_time/gregorian/greg_serialize.hpp"
+#include "boost/numeric/conversion/cast.hpp"
#include "boost/serialization/split_free.hpp"
#include "boost/serialization/nvp.hpp"
-
+#include "boost/serialization/version.hpp"
// macros to split serialize functions into save & load functions
// NOTE: these macros define template functions in the boost::serialization namespace.
@@ -22,6 +23,14 @@ BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::ptime)
BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_duration)
BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_period)
+// Define versions for serialization compatibility
+// alows the unit tests to make an older version to check compatibility
+#ifndef BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION
+#define BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION 1
+#endif
+
+BOOST_CLASS_VERSION(boost::posix_time::time_duration, BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION)
+
namespace boost {
namespace serialization {
@@ -33,10 +42,23 @@ namespace serialization {
* types are hour_type, min_type, sec_type, and fractional_seconds_type
* as defined in the time_duration class
*/
+template<class TimeResTraitsSize, class Archive>
+void save_td(Archive& ar, const posix_time::time_duration& td)
+{
+ TimeResTraitsSize h = boost::numeric_cast<TimeResTraitsSize>(td.hours());
+ TimeResTraitsSize m = boost::numeric_cast<TimeResTraitsSize>(td.minutes());
+ TimeResTraitsSize s = boost::numeric_cast<TimeResTraitsSize>(td.seconds());
+ posix_time::time_duration::fractional_seconds_type fs = td.fractional_seconds();
+ ar & make_nvp("time_duration_hours", h);
+ ar & make_nvp("time_duration_minutes", m);
+ ar & make_nvp("time_duration_seconds", s);
+ ar & make_nvp("time_duration_fractional_seconds", fs);
+}
+
template<class Archive>
void save(Archive & ar,
const posix_time::time_duration& td,
- unsigned int /*version*/)
+ unsigned int version)
{
// serialize a bool so we know how to read this back in later
bool is_special = td.is_special();
@@ -46,14 +68,13 @@ void save(Archive & ar,
ar & make_nvp("sv_time_duration", s);
}
else {
- posix_time::time_duration::hour_type h = td.hours();
- posix_time::time_duration::min_type m = td.minutes();
- posix_time::time_duration::sec_type s = td.seconds();
- posix_time::time_duration::fractional_seconds_type fs = td.fractional_seconds();
- ar & make_nvp("time_duration_hours", h);
- ar & make_nvp("time_duration_minutes", m);
- ar & make_nvp("time_duration_seconds", s);
- ar & make_nvp("time_duration_fractional_seconds", fs);
+ // Write support for earlier versions allows for upgrade compatibility testing
+ // See load comments for version information
+ if (version == 0) {
+ save_td<int32_t>(ar, td);
+ } else {
+ save_td<int64_t>(ar, td);
+ }
}
}
@@ -62,10 +83,24 @@ void save(Archive & ar,
* types are hour_type, min_type, sec_type, and fractional_seconds_type
* as defined in the time_duration class
*/
+template<class TimeResTraitsSize, class Archive>
+void load_td(Archive& ar, posix_time::time_duration& td)
+{
+ TimeResTraitsSize h(0);
+ TimeResTraitsSize m(0);
+ TimeResTraitsSize s(0);
+ posix_time::time_duration::fractional_seconds_type fs(0);
+ ar & make_nvp("time_duration_hours", h);
+ ar & make_nvp("time_duration_minutes", m);
+ ar & make_nvp("time_duration_seconds", s);
+ ar & make_nvp("time_duration_fractional_seconds", fs);
+ td = posix_time::time_duration(h, m, s, fs);
+}
+
template<class Archive>
void load(Archive & ar,
posix_time::time_duration & td,
- unsigned int /*version*/)
+ unsigned int version)
{
bool is_special = false;
ar & make_nvp("is_special", is_special);
@@ -76,15 +111,25 @@ void load(Archive & ar,
td = posix_time::time_duration(sv);
}
else {
- posix_time::time_duration::hour_type h(0);
- posix_time::time_duration::min_type m(0);
- posix_time::time_duration::sec_type s(0);
- posix_time::time_duration::fractional_seconds_type fs(0);
- ar & make_nvp("time_duration_hours", h);
- ar & make_nvp("time_duration_minutes", m);
- ar & make_nvp("time_duration_seconds", s);
- ar & make_nvp("time_duration_fractional_seconds", fs);
- td = posix_time::time_duration(h,m,s,fs);
+ // Version "0" (Boost 1.65.1 or earlier, which used int32_t for day/hour/minute/second and
+ // therefore suffered from the year 2038 issue.)
+ // Version "0.5" (Boost 1.66.0 changed to std::time_t but did not increase the version;
+ // it was missed in the original change, all code reviews, and there were no
+ // static assertions to protect the code; further std::time_t can be 32-bit
+ // or 64-bit so it reduced portability. This makes 1.66.0 hard to handle...)
+ // Version "1" (Boost 1.67.0 or later uses int64_t and is properly versioned)
+
+ // If the size of any of these items changes, a new version is needed.
+ BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::hour_type) == sizeof(boost::int64_t));
+ BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::min_type) == sizeof(boost::int64_t));
+ BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::sec_type) == sizeof(boost::int64_t));
+ BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::fractional_seconds_type) == sizeof(boost::int64_t));
+
+ if (version == 0) {
+ load_td<int32_t>(ar, td);
+ } else {
+ load_td<int64_t>(ar, td);
+ }
}
}