annotate DEPENDENCIES/generic/include/boost/chrono/duration.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
rev   line source
Chris@16 1 // duration.hpp --------------------------------------------------------------//
Chris@16 2
Chris@16 3 // Copyright 2008 Howard Hinnant
Chris@16 4 // Copyright 2008 Beman Dawes
Chris@16 5 // Copyright 2009-2011 Vicente J. Botet Escriba
Chris@16 6
Chris@16 7 // Distributed under the Boost Software License, Version 1.0.
Chris@16 8 // See http://www.boost.org/LICENSE_1_0.txt
Chris@16 9
Chris@16 10 /*
Chris@16 11
Chris@16 12 This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
Chris@16 13 Many thanks to Howard for making his code available under the Boost license.
Chris@16 14 The original code was modified to conform to Boost conventions and to section
Chris@16 15 20.9 Time utilities [time] of the C++ committee's working paper N2798.
Chris@16 16 See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
Chris@16 17
Chris@16 18 time2_demo contained this comment:
Chris@16 19
Chris@16 20 Much thanks to Andrei Alexandrescu,
Chris@16 21 Walter Brown,
Chris@16 22 Peter Dimov,
Chris@16 23 Jeff Garland,
Chris@16 24 Terry Golubiewski,
Chris@16 25 Daniel Krugler,
Chris@16 26 Anthony Williams.
Chris@16 27 */
Chris@16 28
Chris@16 29
Chris@16 30 #ifndef BOOST_CHRONO_DURATION_HPP
Chris@16 31 #define BOOST_CHRONO_DURATION_HPP
Chris@16 32
Chris@16 33 #include <boost/chrono/config.hpp>
Chris@16 34 #include <boost/chrono/detail/static_assert.hpp>
Chris@16 35
Chris@16 36 #include <climits>
Chris@16 37 #include <limits>
Chris@16 38
Chris@16 39
Chris@16 40 #include <boost/mpl/logical.hpp>
Chris@16 41 #include <boost/ratio/ratio.hpp>
Chris@16 42 #include <boost/type_traits/common_type.hpp>
Chris@16 43 #include <boost/type_traits/is_arithmetic.hpp>
Chris@16 44 #include <boost/type_traits/is_convertible.hpp>
Chris@16 45 #include <boost/type_traits/is_floating_point.hpp>
Chris@16 46 #include <boost/type_traits/is_unsigned.hpp>
Chris@16 47 #include <boost/chrono/detail/is_evenly_divisible_by.hpp>
Chris@16 48
Chris@16 49 #include <boost/cstdint.hpp>
Chris@16 50 #include <boost/utility/enable_if.hpp>
Chris@16 51 #include <boost/detail/workaround.hpp>
Chris@16 52 #include <boost/integer_traits.hpp>
Chris@16 53
Chris@16 54 #if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || !defined(BOOST_CHRONO_USES_MPL_ASSERT)
Chris@16 55 #define BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION "A duration representation can not be a duration"
Chris@16 56 #define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO "Second template parameter of duration must be a boost::ratio"
Chris@16 57 #define BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE "duration period must be positive"
Chris@16 58 #define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_CHRONO_DURATION "Second template parameter of time_point must be a boost::chrono::duration"
Chris@16 59 #endif
Chris@16 60
Chris@16 61 #ifndef BOOST_CHRONO_HEADER_ONLY
Chris@16 62 // this must occur after all of the includes and before any code appears:
Chris@16 63 #include <boost/config/abi_prefix.hpp> // must be the last #include
Chris@16 64 #endif
Chris@16 65
Chris@16 66 //----------------------------------------------------------------------------//
Chris@16 67 // //
Chris@16 68 // 20.9 Time utilities [time] //
Chris@16 69 // synopsis //
Chris@16 70 // //
Chris@16 71 //----------------------------------------------------------------------------//
Chris@16 72
Chris@16 73 namespace boost {
Chris@16 74 namespace chrono {
Chris@16 75
Chris@16 76 template <class Rep, class Period = ratio<1> >
Chris@16 77 class duration;
Chris@16 78
Chris@16 79 namespace detail
Chris@16 80 {
Chris@16 81 template <class T>
Chris@16 82 struct is_duration
Chris@16 83 : boost::false_type {};
Chris@16 84
Chris@16 85 template <class Rep, class Period>
Chris@16 86 struct is_duration<duration<Rep, Period> >
Chris@16 87 : boost::true_type {};
Chris@16 88
Chris@16 89 template <class Duration, class Rep, bool = is_duration<Rep>::value>
Chris@16 90 struct duration_divide_result
Chris@16 91 {
Chris@16 92 };
Chris@16 93
Chris@16 94 template <class Duration, class Rep2,
Chris@16 95 bool = (
Chris@16 96 ((boost::is_convertible<typename Duration::rep,
Chris@16 97 typename common_type<typename Duration::rep, Rep2>::type>::value))
Chris@16 98 && ((boost::is_convertible<Rep2,
Chris@16 99 typename common_type<typename Duration::rep, Rep2>::type>::value))
Chris@16 100 )
Chris@16 101 >
Chris@16 102 struct duration_divide_imp
Chris@16 103 {
Chris@16 104 };
Chris@16 105
Chris@16 106 template <class Rep1, class Period, class Rep2>
Chris@16 107 struct duration_divide_imp<duration<Rep1, Period>, Rep2, true>
Chris@16 108 {
Chris@16 109 typedef duration<typename common_type<Rep1, Rep2>::type, Period> type;
Chris@16 110 };
Chris@16 111
Chris@16 112 template <class Rep1, class Period, class Rep2>
Chris@16 113 struct duration_divide_result<duration<Rep1, Period>, Rep2, false>
Chris@16 114 : duration_divide_imp<duration<Rep1, Period>, Rep2>
Chris@16 115 {
Chris@16 116 };
Chris@16 117
Chris@16 118 ///
Chris@16 119 template <class Rep, class Duration, bool = is_duration<Rep>::value>
Chris@16 120 struct duration_divide_result2
Chris@16 121 {
Chris@16 122 };
Chris@16 123
Chris@16 124 template <class Rep, class Duration,
Chris@16 125 bool = (
Chris@16 126 ((boost::is_convertible<typename Duration::rep,
Chris@16 127 typename common_type<typename Duration::rep, Rep>::type>::value))
Chris@16 128 && ((boost::is_convertible<Rep,
Chris@16 129 typename common_type<typename Duration::rep, Rep>::type>::value))
Chris@16 130 )
Chris@16 131 >
Chris@16 132 struct duration_divide_imp2
Chris@16 133 {
Chris@16 134 };
Chris@16 135
Chris@16 136 template <class Rep1, class Rep2, class Period >
Chris@16 137 struct duration_divide_imp2<Rep1, duration<Rep2, Period>, true>
Chris@16 138 {
Chris@16 139 //typedef typename common_type<Rep1, Rep2>::type type;
Chris@16 140 typedef double type;
Chris@16 141 };
Chris@16 142
Chris@16 143 template <class Rep1, class Rep2, class Period >
Chris@16 144 struct duration_divide_result2<Rep1, duration<Rep2, Period>, false>
Chris@16 145 : duration_divide_imp2<Rep1, duration<Rep2, Period> >
Chris@16 146 {
Chris@16 147 };
Chris@16 148
Chris@16 149 ///
Chris@16 150 template <class Duration, class Rep, bool = is_duration<Rep>::value>
Chris@16 151 struct duration_modulo_result
Chris@16 152 {
Chris@16 153 };
Chris@16 154
Chris@16 155 template <class Duration, class Rep2,
Chris@16 156 bool = (
Chris@16 157 //boost::is_convertible<typename Duration::rep,
Chris@16 158 //typename common_type<typename Duration::rep, Rep2>::type>::value
Chris@16 159 //&&
Chris@16 160 boost::is_convertible<Rep2,
Chris@16 161 typename common_type<typename Duration::rep, Rep2>::type>::value
Chris@16 162 )
Chris@16 163 >
Chris@16 164 struct duration_modulo_imp
Chris@16 165 {
Chris@16 166 };
Chris@16 167
Chris@16 168 template <class Rep1, class Period, class Rep2>
Chris@16 169 struct duration_modulo_imp<duration<Rep1, Period>, Rep2, true>
Chris@16 170 {
Chris@16 171 typedef duration<typename common_type<Rep1, Rep2>::type, Period> type;
Chris@16 172 };
Chris@16 173
Chris@16 174 template <class Rep1, class Period, class Rep2>
Chris@16 175 struct duration_modulo_result<duration<Rep1, Period>, Rep2, false>
Chris@16 176 : duration_modulo_imp<duration<Rep1, Period>, Rep2>
Chris@16 177 {
Chris@16 178 };
Chris@16 179
Chris@16 180 } // namespace detail
Chris@16 181 } // namespace chrono
Chris@16 182
Chris@16 183
Chris@16 184 // common_type trait specializations
Chris@16 185
Chris@16 186 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 187 struct common_type<chrono::duration<Rep1, Period1>,
Chris@16 188 chrono::duration<Rep2, Period2> >;
Chris@16 189
Chris@16 190
Chris@16 191 namespace chrono {
Chris@16 192
Chris@16 193 // customization traits
Chris@16 194 template <class Rep> struct treat_as_floating_point;
Chris@16 195 template <class Rep> struct duration_values;
Chris@16 196
Chris@16 197 // convenience typedefs
Chris@16 198 typedef duration<boost::int_least64_t, nano> nanoseconds; // at least 64 bits needed
Chris@16 199 typedef duration<boost::int_least64_t, micro> microseconds; // at least 55 bits needed
Chris@16 200 typedef duration<boost::int_least64_t, milli> milliseconds; // at least 45 bits needed
Chris@16 201 typedef duration<boost::int_least64_t> seconds; // at least 35 bits needed
Chris@16 202 typedef duration<boost::int_least32_t, ratio< 60> > minutes; // at least 29 bits needed
Chris@16 203 typedef duration<boost::int_least32_t, ratio<3600> > hours; // at least 23 bits needed
Chris@16 204
Chris@16 205 //----------------------------------------------------------------------------//
Chris@16 206 // duration helpers //
Chris@16 207 //----------------------------------------------------------------------------//
Chris@16 208
Chris@16 209 namespace detail
Chris@16 210 {
Chris@16 211
Chris@16 212 // duration_cast
Chris@16 213
Chris@16 214 // duration_cast is the heart of this whole prototype. It can convert any
Chris@16 215 // duration to any other. It is also (implicitly) used in converting
Chris@16 216 // time_points. The conversion is always exact if possible. And it is
Chris@16 217 // always as efficient as hand written code. If different representations
Chris@16 218 // are involved, care is taken to never require implicit conversions.
Chris@16 219 // Instead static_cast is used explicitly for every required conversion.
Chris@16 220 // If there are a mixture of integral and floating point representations,
Chris@16 221 // the use of common_type ensures that the most logical "intermediate"
Chris@16 222 // representation is used.
Chris@16 223 template <class FromDuration, class ToDuration,
Chris@16 224 class Period,
Chris@16 225 bool PeriodNumEq1,
Chris@16 226 bool PeriodDenEq1>
Chris@16 227 struct duration_cast_aux;
Chris@16 228
Chris@16 229 // When the two periods are the same, all that is left to do is static_cast from
Chris@16 230 // the source representation to the target representation (which may be a no-op).
Chris@16 231 // This conversion is always exact as long as the static_cast from the source
Chris@16 232 // representation to the destination representation is exact.
Chris@16 233 template <class FromDuration, class ToDuration, class Period>
Chris@16 234 struct duration_cast_aux<FromDuration, ToDuration, Period, true, true>
Chris@16 235 {
Chris@16 236 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const
Chris@16 237 {
Chris@16 238 return ToDuration(static_cast<typename ToDuration::rep>(fd.count()));
Chris@16 239 }
Chris@16 240 };
Chris@16 241
Chris@16 242 // When the numerator of FromPeriod / ToPeriod is 1, then all we need to do is
Chris@16 243 // divide by the denominator of FromPeriod / ToPeriod. The common_type of
Chris@16 244 // the two representations is used for the intermediate computation before
Chris@16 245 // static_cast'ing to the destination.
Chris@16 246 // This conversion is generally not exact because of the division (but could be
Chris@16 247 // if you get lucky on the run time value of fd.count()).
Chris@16 248 template <class FromDuration, class ToDuration, class Period>
Chris@16 249 struct duration_cast_aux<FromDuration, ToDuration, Period, true, false>
Chris@16 250 {
Chris@16 251 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const
Chris@16 252 {
Chris@16 253 typedef typename common_type<
Chris@16 254 typename ToDuration::rep,
Chris@16 255 typename FromDuration::rep,
Chris@16 256 boost::intmax_t>::type C;
Chris@16 257 return ToDuration(static_cast<typename ToDuration::rep>(
Chris@16 258 static_cast<C>(fd.count()) / static_cast<C>(Period::den)));
Chris@16 259 }
Chris@16 260 };
Chris@16 261
Chris@16 262 // When the denominator of FromPeriod / ToPeriod is 1, then all we need to do is
Chris@16 263 // multiply by the numerator of FromPeriod / ToPeriod. The common_type of
Chris@16 264 // the two representations is used for the intermediate computation before
Chris@16 265 // static_cast'ing to the destination.
Chris@16 266 // This conversion is always exact as long as the static_cast's involved are exact.
Chris@16 267 template <class FromDuration, class ToDuration, class Period>
Chris@16 268 struct duration_cast_aux<FromDuration, ToDuration, Period, false, true>
Chris@16 269 {
Chris@16 270 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const
Chris@16 271 {
Chris@16 272 typedef typename common_type<
Chris@16 273 typename ToDuration::rep,
Chris@16 274 typename FromDuration::rep,
Chris@16 275 boost::intmax_t>::type C;
Chris@16 276 return ToDuration(static_cast<typename ToDuration::rep>(
Chris@16 277 static_cast<C>(fd.count()) * static_cast<C>(Period::num)));
Chris@16 278 }
Chris@16 279 };
Chris@16 280
Chris@16 281 // When neither the numerator or denominator of FromPeriod / ToPeriod is 1, then we need to
Chris@16 282 // multiply by the numerator and divide by the denominator of FromPeriod / ToPeriod. The
Chris@16 283 // common_type of the two representations is used for the intermediate computation before
Chris@16 284 // static_cast'ing to the destination.
Chris@16 285 // This conversion is generally not exact because of the division (but could be
Chris@16 286 // if you get lucky on the run time value of fd.count()).
Chris@16 287 template <class FromDuration, class ToDuration, class Period>
Chris@16 288 struct duration_cast_aux<FromDuration, ToDuration, Period, false, false>
Chris@16 289 {
Chris@16 290 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const
Chris@16 291 {
Chris@16 292 typedef typename common_type<
Chris@16 293 typename ToDuration::rep,
Chris@16 294 typename FromDuration::rep,
Chris@16 295 boost::intmax_t>::type C;
Chris@16 296 return ToDuration(static_cast<typename ToDuration::rep>(
Chris@16 297 static_cast<C>(fd.count()) * static_cast<C>(Period::num)
Chris@16 298 / static_cast<C>(Period::den)));
Chris@16 299 }
Chris@16 300 };
Chris@16 301
Chris@16 302 template <class FromDuration, class ToDuration>
Chris@16 303 struct duration_cast {
Chris@16 304 typedef typename ratio_divide<typename FromDuration::period,
Chris@16 305 typename ToDuration::period>::type Period;
Chris@16 306 typedef duration_cast_aux<
Chris@16 307 FromDuration,
Chris@16 308 ToDuration,
Chris@16 309 Period,
Chris@16 310 Period::num == 1,
Chris@16 311 Period::den == 1
Chris@16 312 > Aux;
Chris@16 313 BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const
Chris@16 314 {
Chris@16 315 return Aux()(fd);
Chris@16 316 }
Chris@16 317 };
Chris@16 318
Chris@16 319 } // namespace detail
Chris@16 320
Chris@16 321 //----------------------------------------------------------------------------//
Chris@16 322 // //
Chris@16 323 // 20.9.2 Time-related traits [time.traits] //
Chris@16 324 // //
Chris@16 325 //----------------------------------------------------------------------------//
Chris@16 326 //----------------------------------------------------------------------------//
Chris@16 327 // 20.9.2.1 treat_as_floating_point [time.traits.is_fp] //
Chris@16 328 // Probably should have been treat_as_floating_point. Editor notifed. //
Chris@16 329 //----------------------------------------------------------------------------//
Chris@16 330
Chris@16 331 // Support bidirectional (non-exact) conversions for floating point rep types
Chris@16 332 // (or user defined rep types which specialize treat_as_floating_point).
Chris@16 333 template <class Rep>
Chris@16 334 struct treat_as_floating_point : boost::is_floating_point<Rep> {};
Chris@16 335
Chris@16 336 //----------------------------------------------------------------------------//
Chris@16 337 // 20.9.2.2 duration_values [time.traits.duration_values] //
Chris@16 338 //----------------------------------------------------------------------------//
Chris@16 339
Chris@16 340 namespace detail {
Chris@16 341 template <class T, bool = is_arithmetic<T>::value>
Chris@16 342 struct chrono_numeric_limits {
Chris@16 343 static BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits<T>::min) ();}
Chris@16 344 };
Chris@16 345
Chris@16 346 template <class T>
Chris@16 347 struct chrono_numeric_limits<T,true> {
Chris@16 348 static BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits<T>::min) ();}
Chris@16 349 };
Chris@16 350
Chris@16 351 template <>
Chris@16 352 struct chrono_numeric_limits<float,true> {
Chris@16 353 static BOOST_CHRONO_LIB_CONSTEXPR float lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
Chris@16 354 {
Chris@16 355 return -(std::numeric_limits<float>::max) ();
Chris@16 356 }
Chris@16 357 };
Chris@16 358
Chris@16 359 template <>
Chris@16 360 struct chrono_numeric_limits<double,true> {
Chris@16 361 static BOOST_CHRONO_LIB_CONSTEXPR double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
Chris@16 362 {
Chris@16 363 return -(std::numeric_limits<double>::max) ();
Chris@16 364 }
Chris@16 365 };
Chris@16 366
Chris@16 367 template <>
Chris@16 368 struct chrono_numeric_limits<long double,true> {
Chris@16 369 static BOOST_CHRONO_LIB_CONSTEXPR long double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW
Chris@16 370 {
Chris@16 371 return -(std::numeric_limits<long double>::max)();
Chris@16 372 }
Chris@16 373 };
Chris@16 374
Chris@16 375 template <class T>
Chris@16 376 struct numeric_limits : chrono_numeric_limits<typename remove_cv<T>::type>
Chris@16 377 {};
Chris@16 378
Chris@16 379 }
Chris@16 380 template <class Rep>
Chris@16 381 struct duration_values
Chris@16 382 {
Chris@16 383 static BOOST_CONSTEXPR Rep zero() {return Rep(0);}
Chris@16 384 static BOOST_CHRONO_LIB_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION ()
Chris@16 385 {
Chris@16 386 return (std::numeric_limits<Rep>::max)();
Chris@16 387 }
Chris@16 388
Chris@16 389 static BOOST_CHRONO_LIB_CONSTEXPR Rep min BOOST_PREVENT_MACRO_SUBSTITUTION ()
Chris@16 390 {
Chris@16 391 return detail::numeric_limits<Rep>::lowest();
Chris@16 392 }
Chris@16 393 };
Chris@16 394
Chris@16 395 } // namespace chrono
Chris@16 396
Chris@16 397 //----------------------------------------------------------------------------//
Chris@16 398 // 20.9.2.3 Specializations of common_type [time.traits.specializations] //
Chris@16 399 //----------------------------------------------------------------------------//
Chris@16 400
Chris@16 401 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 402 struct common_type<chrono::duration<Rep1, Period1>,
Chris@16 403 chrono::duration<Rep2, Period2> >
Chris@16 404 {
Chris@16 405 typedef chrono::duration<typename common_type<Rep1, Rep2>::type,
Chris@16 406 typename boost::ratio_gcd<Period1, Period2>::type> type;
Chris@16 407 };
Chris@16 408
Chris@16 409
Chris@16 410 //----------------------------------------------------------------------------//
Chris@16 411 // //
Chris@16 412 // 20.9.3 Class template duration [time.duration] //
Chris@16 413 // //
Chris@16 414 //----------------------------------------------------------------------------//
Chris@16 415
Chris@16 416
Chris@16 417 namespace chrono {
Chris@16 418
Chris@16 419 template <class Rep, class Period>
Chris@16 420 class BOOST_SYMBOL_VISIBLE duration
Chris@16 421 {
Chris@16 422 //BOOST_CHRONO_STATIC_ASSERT(boost::is_integral<Rep>::value, BOOST_CHRONO_A_DURATION_REPRESENTATION_MUST_BE_INTEGRAL, ());
Chris@16 423 BOOST_CHRONO_STATIC_ASSERT(!boost::chrono::detail::is_duration<Rep>::value,
Chris@16 424 BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION, ());
Chris@16 425 BOOST_CHRONO_STATIC_ASSERT(boost::ratio_detail::is_ratio<typename Period::type>::value,
Chris@16 426 BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO, ());
Chris@16 427 BOOST_CHRONO_STATIC_ASSERT(Period::num>0,
Chris@16 428 BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE, ());
Chris@16 429 public:
Chris@16 430 typedef Rep rep;
Chris@16 431 typedef Period period;
Chris@16 432 private:
Chris@16 433 rep rep_;
Chris@16 434 public:
Chris@16 435
Chris@16 436 BOOST_FORCEINLINE BOOST_CONSTEXPR
Chris@16 437 duration() : rep_(duration_values<rep>::zero()) { }
Chris@16 438 template <class Rep2>
Chris@16 439 BOOST_SYMBOL_VISIBLE BOOST_FORCEINLINE BOOST_CONSTEXPR
Chris@16 440 explicit duration(const Rep2& r
Chris@16 441 , typename boost::enable_if <
Chris@16 442 mpl::and_ <
Chris@16 443 boost::is_convertible<Rep2, rep>,
Chris@16 444 mpl::or_ <
Chris@16 445 treat_as_floating_point<rep>,
Chris@16 446 mpl::and_ <
Chris@16 447 mpl::not_ < treat_as_floating_point<rep> >,
Chris@16 448 mpl::not_ < treat_as_floating_point<Rep2> >
Chris@16 449 >
Chris@16 450 >
Chris@16 451 >
Chris@16 452 >::type* = 0
Chris@16 453 ) : rep_(r) { }
Chris@16 454 //~duration() {} //= default;
Chris@16 455 // BOOST_CONSTEXPR duration(const duration& rhs) : rep_(rhs.rep_) {} // = default;
Chris@16 456 duration& operator=(const duration& rhs) // = default;
Chris@16 457 {
Chris@16 458 if (&rhs != this) rep_= rhs.rep_;
Chris@16 459 return *this;
Chris@16 460 }
Chris@16 461
Chris@16 462 // conversions
Chris@16 463 template <class Rep2, class Period2>
Chris@16 464 BOOST_FORCEINLINE BOOST_CONSTEXPR
Chris@16 465 duration(const duration<Rep2, Period2>& d
Chris@16 466 , typename boost::enable_if <
Chris@16 467 mpl::or_ <
Chris@16 468 treat_as_floating_point<rep>,
Chris@16 469 mpl::and_ <
Chris@16 470 chrono_detail::is_evenly_divisible_by<Period2, period>,
Chris@16 471 mpl::not_ < treat_as_floating_point<Rep2> >
Chris@16 472 >
Chris@16 473 >
Chris@16 474 >::type* = 0
Chris@16 475 )
Chris@16 476 : rep_(chrono::detail::duration_cast<duration<Rep2, Period2>, duration>()(d).count()) {}
Chris@16 477
Chris@16 478 // observer
Chris@16 479
Chris@16 480 BOOST_CONSTEXPR
Chris@16 481 rep count() const {return rep_;}
Chris@16 482
Chris@16 483 // arithmetic
Chris@16 484
Chris@16 485 BOOST_CONSTEXPR
Chris@16 486 duration operator+() const {return duration(rep_);;}
Chris@16 487 BOOST_CONSTEXPR
Chris@16 488 duration operator-() const {return duration(-rep_);}
Chris@16 489 duration& operator++() {++rep_; return *this;}
Chris@16 490 duration operator++(int) {return duration(rep_++);}
Chris@16 491 duration& operator--() {--rep_; return *this;}
Chris@16 492 duration operator--(int) {return duration(rep_--);}
Chris@16 493
Chris@16 494 duration& operator+=(const duration& d)
Chris@16 495 {
Chris@16 496 rep_ += d.count(); return *this;
Chris@16 497 }
Chris@16 498 duration& operator-=(const duration& d)
Chris@16 499 {
Chris@16 500 rep_ -= d.count(); return *this;
Chris@16 501 }
Chris@16 502
Chris@16 503 duration& operator*=(const rep& rhs) {rep_ *= rhs; return *this;}
Chris@16 504 duration& operator/=(const rep& rhs) {rep_ /= rhs; return *this;}
Chris@16 505 duration& operator%=(const rep& rhs) {rep_ %= rhs; return *this;}
Chris@16 506 duration& operator%=(const duration& rhs)
Chris@16 507 {
Chris@16 508 rep_ %= rhs.count(); return *this;
Chris@16 509 }
Chris@16 510 // 20.9.3.4 duration special values [time.duration.special]
Chris@16 511
Chris@16 512 static BOOST_CONSTEXPR duration zero()
Chris@16 513 {
Chris@16 514 return duration(duration_values<rep>::zero());
Chris@16 515 }
Chris@16 516 static BOOST_CHRONO_LIB_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION ()
Chris@16 517 {
Chris@16 518 return duration((duration_values<rep>::min)());
Chris@16 519 }
Chris@16 520 static BOOST_CHRONO_LIB_CONSTEXPR duration max BOOST_PREVENT_MACRO_SUBSTITUTION ()
Chris@16 521 {
Chris@16 522 return duration((duration_values<rep>::max)());
Chris@16 523 }
Chris@16 524 };
Chris@16 525
Chris@16 526 //----------------------------------------------------------------------------//
Chris@16 527 // 20.9.3.5 duration non-member arithmetic [time.duration.nonmember] //
Chris@16 528 //----------------------------------------------------------------------------//
Chris@16 529
Chris@16 530 // Duration +
Chris@16 531
Chris@16 532 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 533 inline BOOST_CONSTEXPR
Chris@16 534 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
Chris@16 535 operator+(const duration<Rep1, Period1>& lhs,
Chris@16 536 const duration<Rep2, Period2>& rhs)
Chris@16 537 {
Chris@16 538 typedef typename common_type<duration<Rep1, Period1>,
Chris@16 539 duration<Rep2, Period2> >::type CD;
Chris@16 540 return CD(CD(lhs).count()+CD(rhs).count());
Chris@16 541 }
Chris@16 542
Chris@16 543 // Duration -
Chris@16 544
Chris@16 545 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 546 inline BOOST_CONSTEXPR
Chris@16 547 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
Chris@16 548 operator-(const duration<Rep1, Period1>& lhs,
Chris@16 549 const duration<Rep2, Period2>& rhs)
Chris@16 550 {
Chris@16 551 typedef typename common_type<duration<Rep1, Period1>,
Chris@16 552 duration<Rep2, Period2> >::type CD;
Chris@16 553 return CD(CD(lhs).count()-CD(rhs).count());
Chris@16 554 }
Chris@16 555
Chris@16 556 // Duration *
Chris@16 557
Chris@16 558 template <class Rep1, class Period, class Rep2>
Chris@16 559 inline BOOST_CONSTEXPR
Chris@16 560 typename boost::enable_if <
Chris@16 561 mpl::and_ <
Chris@16 562 boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>,
Chris@16 563 boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type>
Chris@16 564 >,
Chris@16 565 duration<typename common_type<Rep1, Rep2>::type, Period>
Chris@16 566 >::type
Chris@16 567 operator*(const duration<Rep1, Period>& d, const Rep2& s)
Chris@16 568 {
Chris@16 569 typedef typename common_type<Rep1, Rep2>::type CR;
Chris@16 570 typedef duration<CR, Period> CD;
Chris@16 571 return CD(CD(d).count()*static_cast<CR>(s));
Chris@16 572 }
Chris@16 573
Chris@16 574 template <class Rep1, class Period, class Rep2>
Chris@16 575 inline BOOST_CONSTEXPR
Chris@16 576 typename boost::enable_if <
Chris@16 577 mpl::and_ <
Chris@16 578 boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>,
Chris@16 579 boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type>
Chris@16 580 >,
Chris@16 581 duration<typename common_type<Rep1, Rep2>::type, Period>
Chris@16 582 >::type
Chris@16 583 operator*(const Rep1& s, const duration<Rep2, Period>& d)
Chris@16 584 {
Chris@16 585 return d * s;
Chris@16 586 }
Chris@16 587
Chris@16 588 // Duration /
Chris@16 589
Chris@16 590 template <class Rep1, class Period, class Rep2>
Chris@16 591 inline BOOST_CONSTEXPR
Chris@16 592 typename boost::disable_if <boost::chrono::detail::is_duration<Rep2>,
Chris@16 593 typename boost::chrono::detail::duration_divide_result<
Chris@16 594 duration<Rep1, Period>, Rep2>::type
Chris@16 595 >::type
Chris@16 596 operator/(const duration<Rep1, Period>& d, const Rep2& s)
Chris@16 597 {
Chris@16 598 typedef typename common_type<Rep1, Rep2>::type CR;
Chris@16 599 typedef duration<CR, Period> CD;
Chris@16 600
Chris@16 601 return CD(CD(d).count()/static_cast<CR>(s));
Chris@16 602 }
Chris@16 603
Chris@16 604 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 605 inline BOOST_CONSTEXPR
Chris@16 606 typename common_type<Rep1, Rep2>::type
Chris@16 607 operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
Chris@16 608 {
Chris@16 609 typedef typename common_type<duration<Rep1, Period1>,
Chris@16 610 duration<Rep2, Period2> >::type CD;
Chris@16 611 return CD(lhs).count() / CD(rhs).count();
Chris@16 612 }
Chris@16 613
Chris@16 614 #ifdef BOOST_CHRONO_EXTENSIONS
Chris@16 615 template <class Rep1, class Rep2, class Period>
Chris@16 616 inline BOOST_CONSTEXPR
Chris@16 617 typename boost::disable_if <boost::chrono::detail::is_duration<Rep1>,
Chris@16 618 typename boost::chrono::detail::duration_divide_result2<
Chris@16 619 Rep1, duration<Rep2, Period> >::type
Chris@16 620 >::type
Chris@16 621 operator/(const Rep1& s, const duration<Rep2, Period>& d)
Chris@16 622 {
Chris@16 623 typedef typename common_type<Rep1, Rep2>::type CR;
Chris@16 624 typedef duration<CR, Period> CD;
Chris@16 625
Chris@16 626 return static_cast<CR>(s)/CD(d).count();
Chris@16 627 }
Chris@16 628 #endif
Chris@16 629 // Duration %
Chris@16 630
Chris@16 631 template <class Rep1, class Period, class Rep2>
Chris@16 632 inline BOOST_CONSTEXPR
Chris@16 633 typename boost::disable_if <boost::chrono::detail::is_duration<Rep2>,
Chris@16 634 typename boost::chrono::detail::duration_modulo_result<
Chris@16 635 duration<Rep1, Period>, Rep2>::type
Chris@16 636 >::type
Chris@16 637 operator%(const duration<Rep1, Period>& d, const Rep2& s)
Chris@16 638 {
Chris@16 639 typedef typename common_type<Rep1, Rep2>::type CR;
Chris@16 640 typedef duration<CR, Period> CD;
Chris@16 641
Chris@16 642 return CD(CD(d).count()%static_cast<CR>(s));
Chris@16 643 }
Chris@16 644
Chris@16 645 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 646 inline BOOST_CONSTEXPR
Chris@16 647 typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
Chris@16 648 operator%(const duration<Rep1, Period1>& lhs,
Chris@16 649 const duration<Rep2, Period2>& rhs) {
Chris@16 650 typedef typename common_type<duration<Rep1, Period1>,
Chris@16 651 duration<Rep2, Period2> >::type CD;
Chris@16 652
Chris@16 653 return CD(CD(lhs).count()%CD(rhs).count());
Chris@16 654 }
Chris@16 655
Chris@16 656
Chris@16 657 //----------------------------------------------------------------------------//
Chris@16 658 // 20.9.3.6 duration comparisons [time.duration.comparisons] //
Chris@16 659 //----------------------------------------------------------------------------//
Chris@16 660
Chris@16 661 namespace detail
Chris@16 662 {
Chris@16 663 template <class LhsDuration, class RhsDuration>
Chris@16 664 struct duration_eq
Chris@16 665 {
Chris@16 666 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const
Chris@16 667 {
Chris@16 668 typedef typename common_type<LhsDuration, RhsDuration>::type CD;
Chris@16 669 return CD(lhs).count() == CD(rhs).count();
Chris@16 670 }
Chris@16 671 };
Chris@16 672
Chris@16 673 template <class LhsDuration>
Chris@16 674 struct duration_eq<LhsDuration, LhsDuration>
Chris@16 675 {
Chris@16 676 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const
Chris@16 677 {
Chris@16 678 return lhs.count() == rhs.count();
Chris@16 679 }
Chris@16 680 };
Chris@16 681
Chris@16 682 template <class LhsDuration, class RhsDuration>
Chris@16 683 struct duration_lt
Chris@16 684 {
Chris@16 685 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const
Chris@16 686 {
Chris@16 687 typedef typename common_type<LhsDuration, RhsDuration>::type CD;
Chris@16 688 return CD(lhs).count() < CD(rhs).count();
Chris@16 689 }
Chris@16 690 };
Chris@16 691
Chris@16 692 template <class LhsDuration>
Chris@16 693 struct duration_lt<LhsDuration, LhsDuration>
Chris@16 694 {
Chris@16 695 BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const
Chris@16 696 {
Chris@16 697 return lhs.count() < rhs.count();
Chris@16 698 }
Chris@16 699 };
Chris@16 700
Chris@16 701 } // namespace detail
Chris@16 702
Chris@16 703 // Duration ==
Chris@16 704
Chris@16 705 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 706 inline BOOST_CONSTEXPR
Chris@16 707 bool
Chris@16 708 operator==(const duration<Rep1, Period1>& lhs,
Chris@16 709 const duration<Rep2, Period2>& rhs)
Chris@16 710 {
Chris@16 711 return boost::chrono::detail::duration_eq<
Chris@16 712 duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs);
Chris@16 713 }
Chris@16 714
Chris@16 715 // Duration !=
Chris@16 716
Chris@16 717 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 718 inline BOOST_CONSTEXPR
Chris@16 719 bool
Chris@16 720 operator!=(const duration<Rep1, Period1>& lhs,
Chris@16 721 const duration<Rep2, Period2>& rhs)
Chris@16 722 {
Chris@16 723 return !(lhs == rhs);
Chris@16 724 }
Chris@16 725
Chris@16 726 // Duration <
Chris@16 727
Chris@16 728 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 729 inline BOOST_CONSTEXPR
Chris@16 730 bool
Chris@16 731 operator< (const duration<Rep1, Period1>& lhs,
Chris@16 732 const duration<Rep2, Period2>& rhs)
Chris@16 733 {
Chris@16 734 return boost::chrono::detail::duration_lt<
Chris@16 735 duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs);
Chris@16 736 }
Chris@16 737
Chris@16 738 // Duration >
Chris@16 739
Chris@16 740 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 741 inline BOOST_CONSTEXPR
Chris@16 742 bool
Chris@16 743 operator> (const duration<Rep1, Period1>& lhs,
Chris@16 744 const duration<Rep2, Period2>& rhs)
Chris@16 745 {
Chris@16 746 return rhs < lhs;
Chris@16 747 }
Chris@16 748
Chris@16 749 // Duration <=
Chris@16 750
Chris@16 751 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 752 inline BOOST_CONSTEXPR
Chris@16 753 bool
Chris@16 754 operator<=(const duration<Rep1, Period1>& lhs,
Chris@16 755 const duration<Rep2, Period2>& rhs)
Chris@16 756 {
Chris@16 757 return !(rhs < lhs);
Chris@16 758 }
Chris@16 759
Chris@16 760 // Duration >=
Chris@16 761
Chris@16 762 template <class Rep1, class Period1, class Rep2, class Period2>
Chris@16 763 inline BOOST_CONSTEXPR
Chris@16 764 bool
Chris@16 765 operator>=(const duration<Rep1, Period1>& lhs,
Chris@16 766 const duration<Rep2, Period2>& rhs)
Chris@16 767 {
Chris@16 768 return !(lhs < rhs);
Chris@16 769 }
Chris@16 770
Chris@16 771 //----------------------------------------------------------------------------//
Chris@16 772 // 20.9.3.7 duration_cast [time.duration.cast] //
Chris@16 773 //----------------------------------------------------------------------------//
Chris@16 774
Chris@16 775 // Compile-time select the most efficient algorithm for the conversion...
Chris@16 776 template <class ToDuration, class Rep, class Period>
Chris@16 777 inline BOOST_CONSTEXPR
Chris@16 778 typename boost::enable_if <
Chris@16 779 boost::chrono::detail::is_duration<ToDuration>, ToDuration>::type
Chris@16 780 duration_cast(const duration<Rep, Period>& fd)
Chris@16 781 {
Chris@16 782 return boost::chrono::detail::duration_cast<
Chris@16 783 duration<Rep, Period>, ToDuration>()(fd);
Chris@16 784 }
Chris@16 785
Chris@16 786 } // namespace chrono
Chris@16 787 } // namespace boost
Chris@16 788
Chris@16 789 #ifndef BOOST_CHRONO_HEADER_ONLY
Chris@16 790 // the suffix header occurs after all of our code:
Chris@16 791 #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
Chris@16 792 #endif
Chris@16 793
Chris@16 794 #endif // BOOST_CHRONO_DURATION_HPP