|
Boost-Commit : |
From: hinnant_at_[hidden]
Date: 2007-12-30 14:11:24
Author: hinnant
Date: 2007-12-30 14:11:24 EST (Sun, 30 Dec 2007)
New Revision: 42375
URL: http://svn.boost.org/trac/boost/changeset/42375
Log:
Introduced "common duration" to allow exact comparisons among arbitrary duration types.
Applied this logic to the binary + and - operators as well.
Text files modified:
sandbox/committee/LWG/ref_impl/hdate_time | 277 ++++++++++++++++++++++++++-------------
1 files changed, 183 insertions(+), 94 deletions(-)
Modified: sandbox/committee/LWG/ref_impl/hdate_time
==============================================================================
--- sandbox/committee/LWG/ref_impl/hdate_time (original)
+++ sandbox/committee/LWG/ref_impl/hdate_time 2007-12-30 14:11:24 EST (Sun, 30 Dec 2007)
@@ -286,6 +286,28 @@
namespace std {
+// __gcd
+
+template <long X, long Y>
+struct __gcd
+{
+ static const long value = __gcd<Y, X % Y>::value;
+};
+
+template <long X>
+struct __gcd<X, 0>
+{
+ static const long value = X;
+};
+
+// __lcm
+
+template <long X, long Y>
+struct __lcm
+{
+ static const long value = X / __gcd<X, Y>::value * Y;
+};
+
// __is_duration
template <class T>
@@ -455,33 +477,6 @@
__is_duration<ToDuration>::value>::value;
};
-// __choose_duration
-
-template <class LhsDuration, class RhsDuration,
- bool = __is_duration_exactly_convertible<RhsDuration, LhsDuration>::value,
- bool = __is_duration_exactly_convertible<LhsDuration, RhsDuration>::value>
-struct __choose_duration
-{
-};
-
-template <class LhsDuration, class RhsDuration>
-struct __choose_duration<LhsDuration, RhsDuration, true, true>
-{
- typedef LhsDuration type;
-};
-
-template <class LhsDuration, class RhsDuration>
-struct __choose_duration<LhsDuration, RhsDuration, true, false>
-{
- typedef LhsDuration type;
-};
-
-template <class LhsDuration, class RhsDuration>
-struct __choose_duration<LhsDuration, RhsDuration, false, true>
-{
- typedef RhsDuration type;
-};
-
// Durations
template <class TickType, TickType TicksPerSecond, TickType SecondsPerTick>
@@ -546,14 +541,98 @@
typedef __basic_duration<long, 0, 60> minutes;
typedef __basic_duration<long, 0, 3600> hours;
+// __make_duration
+
+template <class LhsDuration, class RhsDuration,
+ bool = LhsDuration::is_subsecond,
+ bool = RhsDuration::is_subsecond>
+struct __make_duration // false, false
+{
+private:
+ static const seconds::tick_type seconds_per_tick = __gcd<LhsDuration::seconds_per_tick,
+ RhsDuration::seconds_per_tick>::value;
+ typedef typename stb::conditional<seconds_per_tick < 5,
+ long long,
+ long>::type tick_type;
+public:
+ typedef __basic_duration<tick_type, seconds_per_tick == 1, seconds_per_tick> type;
+};
+
+template <class LhsDuration, class RhsDuration>
+struct __make_duration<LhsDuration, RhsDuration, false, true>
+{
+ typedef RhsDuration type;
+};
+
+template <class LhsDuration, class RhsDuration>
+struct __make_duration<LhsDuration, RhsDuration, true, false>
+{
+ typedef LhsDuration type;
+};
+
+template <class LhsDuration, class RhsDuration>
+struct __make_duration<LhsDuration, RhsDuration, true, true>
+{
+private:
+ static const seconds::tick_type ticks_per_second = __lcm<LhsDuration::ticks_per_second,
+ RhsDuration::ticks_per_second>::value;
+ typedef typename stb::conditional<!(RhsDuration::ticks_per_second < LhsDuration::ticks_per_second),
+ typename LhsDuration::tick_type,
+ typename RhsDuration::tick_type>::type tick_type;
+public:
+ typedef __basic_duration<tick_type, ticks_per_second, ticks_per_second == 1> type;
+};
+
+// __choose_duration
+
+template <class LhsDuration, class RhsDuration,
+ bool = __is_duration_exactly_convertible<RhsDuration, LhsDuration>::value,
+ bool = __is_duration_exactly_convertible<LhsDuration, RhsDuration>::value>
+struct __choose_duration
+{
+};
+
+template <class LhsDuration, class RhsDuration>
+struct __choose_duration<LhsDuration, RhsDuration, true, true>
+{
+ typedef LhsDuration type;
+};
+
+template <class LhsDuration, class RhsDuration>
+struct __choose_duration<LhsDuration, RhsDuration, true, false>
+{
+ typedef LhsDuration type;
+};
+
+template <class LhsDuration, class RhsDuration>
+struct __choose_duration<LhsDuration, RhsDuration, false, true>
+{
+ typedef RhsDuration type;
+};
+
+template <class LhsDuration, class RhsDuration>
+struct __choose_duration<LhsDuration, RhsDuration, false, false>
+{
+ typedef typename __make_duration<LhsDuration, RhsDuration>::type type;
+};
+
// Duration ==
template <class LhsDuration, class RhsDuration>
inline
bool
-__duration_eq(const LhsDuration& lhs, const RhsDuration& rhs, true_type)
+__duration_eq(const LhsDuration& lhs, const RhsDuration& rhs, false_type, false_type)
+{
+ typedef typename __make_duration<LhsDuration, RhsDuration>::type CommonDuration;
+ return CommonDuration(lhs).count() == CommonDuration(rhs).count();
+}
+
+template <class LhsDuration, class RhsDuration>
+inline
+bool
+__duration_eq(const LhsDuration& lhs, const RhsDuration& rhs, false_type, true_type)
{
- return lhs.count() == __duration_cast<LhsDuration>(rhs).count();
+ return RhsDuration(lhs).count() == rhs.count();
}
template <class LhsDuration, class RhsDuration>
@@ -561,15 +640,24 @@
bool
__duration_eq(const LhsDuration& lhs, const RhsDuration& rhs, false_type)
{
- return __duration_cast<RhsDuration>(lhs).count() == rhs.count();
+ return __duration_eq(lhs, rhs, false_type(),
+ integral_constant<bool, __is_duration_exactly_convertible<LhsDuration, RhsDuration>::value>());
+}
+
+template <class LhsDuration, class RhsDuration>
+inline
+bool
+__duration_eq(const LhsDuration& lhs, const RhsDuration& rhs, true_type)
+{
+ return lhs.count() == LhsDuration(rhs).count();
}
template <class LhsDuration, class RhsDuration>
inline
typename enable_if
<
- __is_duration_exactly_convertible<LhsDuration, RhsDuration>::value ||
- __is_duration_exactly_convertible<RhsDuration, LhsDuration>::value,
+ __is_duration<LhsDuration>::value &&
+ __is_duration<RhsDuration>::value,
bool
>::type
operator==(const LhsDuration& lhs, const RhsDuration& rhs)
@@ -583,8 +671,8 @@
inline
typename enable_if
<
- __is_duration_exactly_convertible<LhsDuration, RhsDuration>::value ||
- __is_duration_exactly_convertible<RhsDuration, LhsDuration>::value,
+ __is_duration<LhsDuration>::value &&
+ __is_duration<RhsDuration>::value,
bool
>::type
operator!=(const LhsDuration& lhs, const RhsDuration& rhs)
@@ -597,9 +685,18 @@
template <class LhsDuration, class RhsDuration>
inline
bool
-__duration_lt(const LhsDuration& lhs, const RhsDuration& rhs, true_type)
+__duration_lt(const LhsDuration& lhs, const RhsDuration& rhs, false_type, false_type)
{
- return lhs.count() < __duration_cast<LhsDuration>(rhs).count();
+ typedef typename __make_duration<LhsDuration, RhsDuration>::type CommonDuration;
+ return CommonDuration(lhs).count() < CommonDuration(rhs).count();
+}
+
+template <class LhsDuration, class RhsDuration>
+inline
+bool
+__duration_lt(const LhsDuration& lhs, const RhsDuration& rhs, false_type, true_type)
+{
+ return RhsDuration(lhs).count() < rhs.count();
}
template <class LhsDuration, class RhsDuration>
@@ -607,15 +704,23 @@
bool
__duration_lt(const LhsDuration& lhs, const RhsDuration& rhs, false_type)
{
- return __duration_cast<RhsDuration>(lhs).count() < rhs.count();
+ return __duration_lt(lhs, rhs, false_type(), integral_constant<bool, __is_duration_exactly_convertible<LhsDuration, RhsDuration>::value>());
+}
+
+template <class LhsDuration, class RhsDuration>
+inline
+bool
+__duration_lt(const LhsDuration& lhs, const RhsDuration& rhs, true_type)
+{
+ return lhs.count() < LhsDuration(rhs).count();
}
template <class LhsDuration, class RhsDuration>
inline
typename enable_if
<
- __is_duration_exactly_convertible<LhsDuration, RhsDuration>::value ||
- __is_duration_exactly_convertible<RhsDuration, LhsDuration>::value,
+ __is_duration<LhsDuration>::value &&
+ __is_duration<RhsDuration>::value,
bool
>::type
operator< (const LhsDuration& lhs, const RhsDuration& rhs)
@@ -629,8 +734,8 @@
inline
typename enable_if
<
- __is_duration_exactly_convertible<LhsDuration, RhsDuration>::value ||
- __is_duration_exactly_convertible<RhsDuration, LhsDuration>::value,
+ __is_duration<LhsDuration>::value &&
+ __is_duration<RhsDuration>::value,
bool
>::type
operator> (const LhsDuration& lhs, const RhsDuration& rhs)
@@ -644,8 +749,8 @@
inline
typename enable_if
<
- __is_duration_exactly_convertible<LhsDuration, RhsDuration>::value ||
- __is_duration_exactly_convertible<RhsDuration, LhsDuration>::value,
+ __is_duration<LhsDuration>::value &&
+ __is_duration<RhsDuration>::value,
bool
>::type
operator<=(const LhsDuration& lhs, const RhsDuration& rhs)
@@ -659,8 +764,8 @@
inline
typename enable_if
<
- __is_duration_exactly_convertible<LhsDuration, RhsDuration>::value ||
- __is_duration_exactly_convertible<RhsDuration, LhsDuration>::value,
+ __is_duration<LhsDuration>::value &&
+ __is_duration<RhsDuration>::value,
bool
>::type
operator>=(const LhsDuration& lhs, const RhsDuration& rhs)
@@ -673,29 +778,11 @@
template <class LhsDuration, class RhsDuration>
inline
typename __choose_duration<LhsDuration, RhsDuration>::type
-__duration_plus(const LhsDuration& lhs, const RhsDuration& rhs, true_type)
-{
- LhsDuration r(lhs);
- r += rhs;
- return r;
-}
-
-template <class LhsDuration, class RhsDuration>
-inline
-typename __choose_duration<LhsDuration, RhsDuration>::type
-__duration_plus(const LhsDuration& lhs, const RhsDuration& rhs, false_type)
-{
- RhsDuration r(rhs);
- r += lhs;
- return r;
-}
-
-template <class LhsDuration, class RhsDuration>
-inline
-typename __choose_duration<LhsDuration, RhsDuration>::type
operator+(const LhsDuration& lhs, const RhsDuration& rhs)
{
- return __duration_plus(lhs, rhs, integral_constant<bool, __is_duration_exactly_convertible<RhsDuration, LhsDuration>::value>());
+ typename __choose_duration<LhsDuration, RhsDuration>::type result = lhs;
+ result += rhs;
+ return result;
}
// Duration -
@@ -703,29 +790,11 @@
template <class LhsDuration, class RhsDuration>
inline
typename __choose_duration<LhsDuration, RhsDuration>::type
-__duration_subtract(const LhsDuration& lhs, const RhsDuration& rhs, true_type)
-{
- LhsDuration r(lhs);
- r -= rhs;
- return r;
-}
-
-template <class LhsDuration, class RhsDuration>
-inline
-typename __choose_duration<LhsDuration, RhsDuration>::type
-__duration_subtract(const LhsDuration& lhs, const RhsDuration& rhs, false_type)
-{
- RhsDuration r = __duration_cast<RhsDuration>(lhs);
- r -= rhs;
- return r;
-}
-
-template <class LhsDuration, class RhsDuration>
-inline
-typename __choose_duration<LhsDuration, RhsDuration>::type
operator-(const LhsDuration& lhs, const RhsDuration& rhs)
{
- return __duration_subtract(lhs, rhs, integral_constant<bool, __is_duration_exactly_convertible<RhsDuration, LhsDuration>::value>());
+ typename __choose_duration<LhsDuration, RhsDuration>::type result = lhs;
+ result -= rhs;
+ return result;
}
// Duration *
@@ -781,11 +850,11 @@
system_time() : ns_(0) {}
explicit system_time(time_t secs, nanoseconds ns = 0)
- : ns_(secs * 1000000000LL + ns.count()) {}
+ : ns_(secs * nanoseconds::ticks_per_second + ns.count()) {}
// ~system_time() = default;
- time_t seconds_since_epoch() const { return static_cast<time_t>(ns_ / 1000000000);}
+ time_t seconds_since_epoch() const { return static_cast<time_t>(ns_ / nanoseconds::ticks_per_second);}
nanoseconds nanoseconds_since_epoch() const {return static_cast<nanoseconds>(ns_);}
// traits
@@ -805,16 +874,36 @@
nanoseconds operator-(const system_time& rhs) const {return ns_ - rhs.ns_;}
template<typename Duration>
- system_time operator+(const Duration& td) const {system_time t(*this); t += td; return t;}
+ typename enable_if
+ <
+ __is_duration_exactly_convertible<Duration, nanoseconds>::value,
+ system_time
+ >::type
+ operator+(const Duration& td) const {system_time t(*this); t += td; return t;}
template<typename Duration>
- system_time& operator+=(const Duration& td) {ns_ += __duration_cast<nanoseconds>(td).count(); return *this;}
+ typename enable_if
+ <
+ __is_duration_exactly_convertible<Duration, nanoseconds>::value,
+ system_time&
+ >::type
+ operator+=(const Duration& td) {ns_ += nanoseconds(td).count(); return *this;}
template<typename Duration>
- system_time operator-(const Duration& td) const {system_time t(*this); t -= td; return t;}
+ typename enable_if
+ <
+ __is_duration_exactly_convertible<Duration, nanoseconds>::value,
+ system_time
+ >::type
+ operator-(const Duration& td) const {system_time t(*this); t -= td; return t;}
template<typename Duration>
- system_time& operator-=(const Duration& td) {ns_ -= __duration_cast<nanoseconds>(td).count(); return *this;}
+ typename enable_if
+ <
+ __is_duration_exactly_convertible<Duration, nanoseconds>::value,
+ system_time&
+ >::type
+ operator-=(const Duration& td) {ns_ -= nanoseconds(td).count(); return *this;}
};
@@ -822,7 +911,7 @@
inline
typename enable_if
<
- __is_duration<Duration>::value,
+ __is_duration_exactly_convertible<Duration, nanoseconds>::value,
system_time
>::type
operator+(const Duration& td, const system_time& rhs)
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