diff options
Diffstat (limited to 'src/boost/libs/ratio/example')
-rw-r--r-- | src/boost/libs/ratio/example/config.hpp | 123 | ||||
-rw-r--r-- | src/boost/libs/ratio/example/display_ex.cpp | 39 | ||||
-rw-r--r-- | src/boost/libs/ratio/example/duration.hpp | 799 | ||||
-rw-r--r-- | src/boost/libs/ratio/example/si_physics.cpp | 236 | ||||
-rw-r--r-- | src/boost/libs/ratio/example/static_assert.hpp | 30 | ||||
-rw-r--r-- | src/boost/libs/ratio/example/type_traits/add_rvalue_reference.hpp | 67 | ||||
-rw-r--r-- | src/boost/libs/ratio/example/type_traits/common_type.hpp | 151 | ||||
-rw-r--r-- | src/boost/libs/ratio/example/type_traits/declval.hpp | 44 | ||||
-rw-r--r-- | src/boost/libs/ratio/example/type_traits/detail/common_type.hpp | 316 |
9 files changed, 1805 insertions, 0 deletions
diff --git a/src/boost/libs/ratio/example/config.hpp b/src/boost/libs/ratio/example/config.hpp new file mode 100644 index 00000000..0965dc62 --- /dev/null +++ b/src/boost/libs/ratio/example/config.hpp @@ -0,0 +1,123 @@ +// boost/chrono/config.hpp -------------------------------------------------// + +// Copyright Beman Dawes 2003, 2006, 2008 +// Copyright 2009 Vicente J. Botet Escriba + +// 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) + +// See http://www.boost.org/libs/chrono for documentation. + +#ifndef BOOST_EX_CHRONO_CONFIG_HPP +#define BOOST_EX_CHRONO_CONFIG_HPP + +#include <boost/config.hpp> + +// BOOST_EX_CHRONO_POSIX_API, BOOST_EX_CHRONO_MAC_API, or BOOST_EX_CHRONO_WINDOWS_API +// can be defined by the user to specify which API should be used + +#if defined(BOOST_EX_CHRONO_WINDOWS_API) +# warning Boost.Chrono will use the Windows API +#elif defined(BOOST_EX_CHRONO_MAC_API) +# warning Boost.Chrono will use the Mac API +#elif defined(BOOST_EX_CHRONO_POSIX_API) +# warning Boost.Chrono will use the POSIX API +#endif + +# if defined( BOOST_EX_CHRONO_WINDOWS_API ) && defined( BOOST_EX_CHRONO_POSIX_API ) +# error both BOOST_EX_CHRONO_WINDOWS_API and BOOST_EX_CHRONO_POSIX_API are defined +# elif defined( BOOST_EX_CHRONO_WINDOWS_API ) && defined( BOOST_EX_CHRONO_MAC_API ) +# error both BOOST_EX_CHRONO_WINDOWS_API and BOOST_EX_CHRONO_MAC_API are defined +# elif defined( BOOST_EX_CHRONO_MAC_API ) && defined( BOOST_EX_CHRONO_POSIX_API ) +# error both BOOST_EX_CHRONO_MAC_API and BOOST_EX_CHRONO_POSIX_API are defined +# elif !defined( BOOST_EX_CHRONO_WINDOWS_API ) && !defined( BOOST_EX_CHRONO_MAC_API ) && !defined( BOOST_EX_CHRONO_POSIX_API ) +# if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) +# define BOOST_EX_CHRONO_WINDOWS_API +# define BOOST_EX_CHRONO_HAS_CLOCK_MONOTONIC +# define BOOST_EX_CHRONO_HAS_THREAD_CLOCK +# define BOOST_EX_CHRONO_THREAD_CLOCK_IS_MONOTONIC true +# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +# define BOOST_EX_CHRONO_MAC_API +# define BOOST_EX_CHRONO_HAS_CLOCK_MONOTONIC +# define BOOST_EX_CHRONO_THREAD_CLOCK_IS_MONOTONIC true +# else +# define BOOST_EX_CHRONO_POSIX_API +# endif +# endif + +# if defined( BOOST_EX_CHRONO_POSIX_API ) +# include <time.h> //to check for CLOCK_REALTIME and CLOCK_MONOTONIC and _POSIX_THREAD_CPUTIME +# if defined(CLOCK_REALTIME) +# if defined(CLOCK_MONOTONIC) +# define BOOST_EX_CHRONO_HAS_CLOCK_MONOTONIC +# endif +# else +# error <time.h> does not supply CLOCK_REALTIME +# endif +# if defined(_POSIX_THREAD_CPUTIME) +# define BOOST_EX_CHRONO_HAS_THREAD_CLOCK +# define BOOST_EX_CHRONO_THREAD_CLOCK_IS_MONOTONIC true +# endif +# endif + + + +// enable dynamic linking on Windows ---------------------------------------// + +//# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_EX_CHRONO_DYN_LINK)) && defined(__BORLANDC__) && defined(__WIN32__) +//# error Dynamic linking Boost.System does not work for Borland; use static linking instead +//# endif + +#ifdef BOOST_HAS_DECLSPEC // defined by boost.config +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_EX_CHRONO_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_EX_CHRONO_DYN_LINK) +// export if this is our own source, otherwise import: +#ifdef BOOST_EX_CHRONO_SOURCE +# define BOOST_EX_CHRONO_DECL __declspec(dllexport) +#else +# define BOOST_EX_CHRONO_DECL __declspec(dllimport) +#endif // BOOST_EX_CHRONO_SOURCE +#endif // DYN_LINK +#endif // BOOST_HAS_DECLSPEC +// +// if BOOST_EX_CHRONO_DECL isn't defined yet define it now: +#ifndef BOOST_EX_CHRONO_DECL +#define BOOST_EX_CHRONO_DECL +#endif + +// define constexpr related macros ------------------------------// + +//~ #include <boost/config.hpp> +#if defined(BOOST_NO_CXX11_CONSTEXPR) +#define BOOST_EX_CHRONO_CONSTEXPR +#define BOOST_EX_CHRONO_CONST_REF const& +#else +#define BOOST_EX_CHRONO_CONSTEXPR constexpr +#define BOOST_EX_CHRONO_CONST_REF +#endif + +// enable automatic library variant selection ------------------------------// + +#if !defined(BOOST_EX_CHRONO_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_EX_CHRONO_NO_LIB) +// +// Set the name of our library; this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_chrono +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_EX_CHRONO_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include <boost/config/auto_link.hpp> +#endif // auto-linking disabled + +#endif // BOOST_EX_CHRONO_CONFIG_HPP + diff --git a/src/boost/libs/ratio/example/display_ex.cpp b/src/boost/libs/ratio/example/display_ex.cpp new file mode 100644 index 00000000..7627371c --- /dev/null +++ b/src/boost/libs/ratio/example/display_ex.cpp @@ -0,0 +1,39 @@ +// io_ex2.cpp ----------------------------------------------------------// + +// Copyright 2010 Howard Hinnant +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +/* +This code was adapted by Vicente J. Botet Escriba from Hinnant's html documentation. +Many thanks to Howard for making his code available under the Boost license. +*/ + +#include <iostream> +#include <boost/ratio/ratio_io.hpp> + +int main() +{ + using namespace std; + using namespace boost; + + cout << "ratio_string<deca, char>::prefix() = " + << ratio_string<boost::deca, char>::prefix() << '\n'; + cout << "ratio_string<deca, char>::symbol() = " + << ratio_string<boost::deca, char>::symbol() << '\n'; + + cout << "ratio_string<giga, char>::prefix() = " + << ratio_string<boost::giga, char>::prefix() << '\n'; + cout << "ratio_string<giga, char>::symbol() = " + << ratio_string<boost::giga, char>::symbol() << '\n'; + + cout << "ratio_string<ratio<4, 6>, char>::prefix() = " + << ratio_string<boost::ratio<4, 6>, char>::prefix() << '\n'; + cout << "ratio_string<ratio<4, 6>, char>::symbol() = " + << ratio_string<boost::ratio<4, 6>, char>::symbol() << '\n'; + + return 0; +} + diff --git a/src/boost/libs/ratio/example/duration.hpp b/src/boost/libs/ratio/example/duration.hpp new file mode 100644 index 00000000..bede8081 --- /dev/null +++ b/src/boost/libs/ratio/example/duration.hpp @@ -0,0 +1,799 @@ +// duration.hpp --------------------------------------------------------------// + +// Copyright 2008 Howard Hinnant +// Copyright 2008 Beman Dawes +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +/* + +This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. +Many thanks to Howard for making his code available under the Boost license. +The original code was modified to conform to Boost conventions and to section +20.9 Time utilities [time] of the C++ committee's working paper N2798. +See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. + +time2_demo contained this comment: + + Much thanks to Andrei Alexandrescu, + Walter Brown, + Peter Dimov, + Jeff Garland, + Terry Golubiewski, + Daniel Krugler, + Anthony Williams. +*/ + + +#ifndef BOOST_EX_CHRONO_DURATION_HPP +#define BOOST_EX_CHRONO_DURATION_HPP + +#include "config.hpp" +#include "static_assert.hpp" + +//~ #include <iostream> + +#include <climits> +#include <limits> + + +#include <boost/mpl/logical.hpp> +#include <boost/ratio/ratio.hpp> +#include <boost/type_traits/common_type.hpp> +#include <boost/type_traits/is_convertible.hpp> +#include <boost/type_traits/is_floating_point.hpp> +#include <boost/type_traits/is_unsigned.hpp> +#include <boost/type_traits/is_arithmetic.hpp> + +#include <boost/cstdint.hpp> +#if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__) +#else +#include <boost/utility/enable_if.hpp> +#endif +#include <boost/detail/workaround.hpp> +#include <boost/integer_traits.hpp> + +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || !defined(BOOST_EX_CHRONO_USES_MPL_ASSERT) +#define BOOST_EX_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION "A duration representation can not be a duration" +#define BOOST_EX_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO "Second template parameter of duration must be a boost::ratio" +#define BOOST_EX_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE "duration period must be positive" +#define BOOST_EX_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_EX_CHRONO_DURATION "Second template parameter of time_point must be a boost_ex::chrono::duration" +#endif + + +//----------------------------------------------------------------------------// +// // +// 20.9 Time utilities [time] // +// synopsis // +// // +//----------------------------------------------------------------------------// + +namespace boost_ex { + using boost::ratio; + +namespace chrono { + + template <class Rep, class Period = ratio<1> > + class duration; + + namespace detail + { + template <class T> + struct is_duration + : boost::false_type {}; + + template <class Rep, class Period> + struct is_duration<duration<Rep, Period> > + : boost::true_type {}; + //template <class T> + // struct is_duration + // : is_duration<typename boost::remove_cv<T>::type> {}; + + template <class Duration, class Rep, bool = is_duration<Rep>::value> + struct duration_divide_result + { + }; + + template <class Duration, class Rep2, + bool = ( + (boost::is_convertible<typename Duration::rep, + typename boost::common_type<typename Duration::rep, Rep2>::type>::value) + && (boost::is_convertible<Rep2, + typename boost::common_type<typename Duration::rep, Rep2>::type>::value) + ) + > + struct duration_divide_imp + { + }; + + template <class Rep1, class Period, class Rep2> + struct duration_divide_imp<duration<Rep1, Period>, Rep2, true> + { + typedef duration<typename boost::common_type<Rep1, Rep2>::type, Period> type; + }; + + template <class Rep1, class Period, class Rep2> + struct duration_divide_result<duration<Rep1, Period>, Rep2, false> + : duration_divide_imp<duration<Rep1, Period>, Rep2> + { + }; + +/// + template <class Rep, class Duration, bool = is_duration<Rep>::value> + struct duration_divide_result2 + { + }; + + template <class Rep, class Duration, + bool = ( + (boost::is_convertible<typename Duration::rep, + typename boost::common_type<typename Duration::rep, Rep>::type>::value) + && (boost::is_convertible<Rep, + typename boost::common_type<typename Duration::rep, Rep>::type>::value) + ) + > + struct duration_divide_imp2 + { + }; + + template <class Rep1, class Rep2, class Period > + struct duration_divide_imp2<Rep1, duration<Rep2, Period>, true> + { + //typedef typename boost::common_type<Rep1, Rep2>::type type; + typedef double type; + }; + + template <class Rep1, class Rep2, class Period > + struct duration_divide_result2<Rep1, duration<Rep2, Period>, false> + : duration_divide_imp2<Rep1, duration<Rep2, Period> > + { + }; + +/// + template <class Duration, class Rep, bool = is_duration<Rep>::value> + struct duration_modulo_result + { + }; + + template <class Duration, class Rep2, + bool = ( + //boost::is_convertible<typename Duration::rep, + //typename boost::common_type<typename Duration::rep, Rep2>::type>::value + //&& + boost::is_convertible<Rep2, + typename boost::common_type<typename Duration::rep, Rep2>::type>::value + ) + > + struct duration_modulo_imp + { + }; + + template <class Rep1, class Period, class Rep2> + struct duration_modulo_imp<duration<Rep1, Period>, Rep2, true> + { + typedef duration<typename boost::common_type<Rep1, Rep2>::type, Period> type; + }; + + template <class Rep1, class Period, class Rep2> + struct duration_modulo_result<duration<Rep1, Period>, Rep2, false> + : duration_modulo_imp<duration<Rep1, Period>, Rep2> + { + }; + + } // namespace detail +} // namespace chrono +} + +namespace boost { +// common_type trait specializations + +template <class Rep1, class Period1, class Rep2, class Period2> + struct common_type<boost_ex::chrono::duration<Rep1, Period1>, + boost_ex::chrono::duration<Rep2, Period2> >; + +} +namespace boost_ex { + +namespace chrono { + + // customization traits + template <class Rep> struct treat_as_floating_point; + template <class Rep> struct duration_values; + + // duration arithmetic +// template <class Rep1, class Period1, class Rep2, class Period2> +// typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type +// operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); +// template <class Rep1, class Period1, class Rep2, class Period2> +// typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type +// operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); +// template <class Rep1, class Period, class Rep2> +// typename boost::enable_if_c +// < +// boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>::value +// && boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type>::value, +// duration<typename common_type<Rep1, Rep2>::type, Period> +// >::type +// operator*(const duration<Rep1, Period>& d, const Rep2& s); +// template <class Rep1, class Period, class Rep2> +// typename boost::enable_if_c +// < +// boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>::value +// && boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type>::value, +// duration<typename common_type<Rep1, Rep2>::type, Period> +// >::type +// operator*(const Rep1& s, const duration<Rep2, Period>& d); + +// template <class Rep1, class Period, class Rep2> +// typename boost::disable_if <detail::is_duration<Rep2>, +// typename detail::duration_divide_result<duration<Rep1, Period>, Rep2>::type +// >::type +// operator/(const duration<Rep1, Period>& d, const Rep2& s); + +// template <class Rep1, class Period1, class Rep2, class Period2> +// typename common_type<Rep1, Rep2>::type +// operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); + + // duration comparisons +// template <class Rep1, class Period1, class Rep2, class Period2> +// bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); +// template <class Rep1, class Period1, class Rep2, class Period2> +// bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); +// template <class Rep1, class Period1, class Rep2, class Period2> +// bool operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); +// template <class Rep1, class Period1, class Rep2, class Period2> +// bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); +// template <class Rep1, class Period1, class Rep2, class Period2> +// bool operator> (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); +// template <class Rep1, class Period1, class Rep2, class Period2> +// bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); + + // duration_cast + + //template <class ToDuration, class Rep, class Period> + // ToDuration duration_cast(const duration<Rep, Period>& d); + + // convenience typedefs + typedef duration<boost::int_least64_t, boost::nano> nanoseconds; // at least 64 bits needed + typedef duration<boost::int_least64_t, boost::micro> microseconds; // at least 55 bits needed + typedef duration<boost::int_least64_t, boost::milli> milliseconds; // at least 45 bits needed + typedef duration<boost::int_least64_t> seconds; // at least 35 bits needed + typedef duration<boost::int_least32_t, ratio< 60> > minutes; // at least 29 bits needed + typedef duration<boost::int_least32_t, ratio<3600> > hours; // at least 23 bits needed + +//----------------------------------------------------------------------------// +// duration helpers // +//----------------------------------------------------------------------------// + + namespace detail + { + + // duration_cast + + // duration_cast is the heart of this whole prototype. It can convert any + // duration to any other. It is also (implicitly) used in converting + // time_points. The conversion is always exact if possible. And it is + // always as efficient as hand written code. If different representations + // are involved, care is taken to never require implicit conversions. + // Instead static_cast is used explicitly for every required conversion. + // If there are a mixture of integral and floating point representations, + // the use of common_type ensures that the most logical "intermediate" + // representation is used. + template <class FromDuration, class ToDuration, + class Period = typename boost::ratio_divide<typename FromDuration::period, + typename ToDuration::period>::type, + bool = Period::num == 1, + bool = Period::den == 1> + struct duration_cast; + + // When the two periods are the same, all that is left to do is static_cast from + // the source representation to the target representation (which may be a no-op). + // This conversion is always exact as long as the static_cast from the source + // representation to the destination representation is exact. + template <class FromDuration, class ToDuration, class Period> + struct duration_cast<FromDuration, ToDuration, Period, true, true> + { + ToDuration operator()(const FromDuration& fd) const + { + return ToDuration(static_cast<typename ToDuration::rep>(fd.count())); + } + }; + + // When the numerator of FromPeriod / ToPeriod is 1, then all we need to do is + // divide by the denominator of FromPeriod / ToPeriod. The common_type of + // the two representations is used for the intermediate computation before + // static_cast'ing to the destination. + // This conversion is generally not exact because of the division (but could be + // if you get lucky on the run time value of fd.count()). + template <class FromDuration, class ToDuration, class Period> + struct duration_cast<FromDuration, ToDuration, Period, true, false> + { + ToDuration operator()(const FromDuration& fd) const + { + typedef typename boost::common_type< + typename ToDuration::rep, + typename FromDuration::rep, + boost::intmax_t>::type C; + return ToDuration(static_cast<typename ToDuration::rep>( + static_cast<C>(fd.count()) / static_cast<C>(Period::den))); + } + }; + + // When the denomenator of FromPeriod / ToPeriod is 1, then all we need to do is + // multiply by the numerator of FromPeriod / ToPeriod. The common_type of + // the two representations is used for the intermediate computation before + // static_cast'ing to the destination. + // This conversion is always exact as long as the static_cast's involved are exact. + template <class FromDuration, class ToDuration, class Period> + struct duration_cast<FromDuration, ToDuration, Period, false, true> + { + ToDuration operator()(const FromDuration& fd) const + { + typedef typename boost::common_type< + typename ToDuration::rep, + typename FromDuration::rep, + boost::intmax_t>::type C; + return ToDuration(static_cast<typename ToDuration::rep>( + static_cast<C>(fd.count()) * static_cast<C>(Period::num))); + } + }; + + // When neither the numerator or denominator of FromPeriod / ToPeriod is 1, then we need to + // multiply by the numerator and divide by the denominator of FromPeriod / ToPeriod. The + // common_type of the two representations is used for the intermediate computation before + // static_cast'ing to the destination. + // This conversion is generally not exact because of the division (but could be + // if you get lucky on the run time value of fd.count()). + template <class FromDuration, class ToDuration, class Period> + struct duration_cast<FromDuration, ToDuration, Period, false, false> + { + ToDuration operator()(const FromDuration& fd) const + { + typedef typename boost::common_type< + typename ToDuration::rep, + typename FromDuration::rep, + boost::intmax_t>::type C; + return ToDuration(static_cast<typename ToDuration::rep>( + static_cast<C>(fd.count()) * static_cast<C>(Period::num) + / static_cast<C>(Period::den))); + } + }; + + } // namespace detail + +//----------------------------------------------------------------------------// +// // +// 20.9.2 Time-related traits [time.traits] // +// // +//----------------------------------------------------------------------------// +//----------------------------------------------------------------------------// +// 20.9.2.1 treat_as_floating_point [time.traits.is_fp] // +// Probably should have been treat_as_floating_point. Editor notifed. // +//----------------------------------------------------------------------------// + + // Support bidirectional (non-exact) conversions for floating point rep types + // (or user defined rep types which specialize treat_as_floating_point). + template <class Rep> + struct treat_as_floating_point : boost::is_floating_point<Rep> {}; + +//----------------------------------------------------------------------------// +// 20.9.2.2 duration_values [time.traits.duration_values] // +//----------------------------------------------------------------------------// + + namespace detail { + template <class T, bool = boost::is_arithmetic<T>::value> + struct chrono_numeric_limits { + static T lowest() throw() {return (std::numeric_limits<T>::min) ();} + }; + + template <class T> + struct chrono_numeric_limits<T,true> { + static T lowest() throw() {return (std::numeric_limits<T>::min) ();} + }; + + template <> + struct chrono_numeric_limits<float,true> { + static float lowest() throw() {return -(std::numeric_limits<float>::max) ();} + }; + + template <> + struct chrono_numeric_limits<double,true> { + static double lowest() throw() {return -(std::numeric_limits<double>::max) ();} + }; + + template <> + struct chrono_numeric_limits<long double,true> { + static long double lowest() throw() {return -(std::numeric_limits<long double>::max)();} + }; + + template <class T> + struct numeric_limits : chrono_numeric_limits<typename boost::remove_cv<T>::type> {}; + + } + template <class Rep> + struct duration_values + { + static Rep zero() {return Rep(0);} + static Rep max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (std::numeric_limits<Rep>::max)();} + + static Rep min BOOST_PREVENT_MACRO_SUBSTITUTION () {return detail::numeric_limits<Rep>::lowest();} + }; + +} // namespace chrono +} +//----------------------------------------------------------------------------// +// 20.9.2.3 Specializations of common_type [time.traits.specializations] // +//----------------------------------------------------------------------------// +namespace boost { +template <class Rep1, class Period1, class Rep2, class Period2> +struct common_type<boost_ex::chrono::duration<Rep1, Period1>, + boost_ex::chrono::duration<Rep2, Period2> > +{ + typedef boost_ex::chrono::duration<typename common_type<Rep1, Rep2>::type, + typename boost::ratio_gcd<Period1, Period2>::type> type; +}; + +} +//----------------------------------------------------------------------------// +// // +// 20.9.3 Class template duration [time.duration] // +// // +//----------------------------------------------------------------------------// + +namespace boost_ex { + +namespace chrono { + + template <class Rep, class Period> + class duration + { + BOOST_EX_CHRONO_STATIC_ASSERT(!boost_ex::chrono::detail::is_duration<Rep>::value, BOOST_EX_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION, ()); + BOOST_EX_CHRONO_STATIC_ASSERT(boost::ratio_detail::is_ratio<Period>::value, BOOST_EX_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO, ()); + BOOST_EX_CHRONO_STATIC_ASSERT(Period::num>0, BOOST_EX_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE, ()); + public: + typedef Rep rep; + typedef Period period; + private: + rep rep_; + public: + + duration() { } // = default; + template <class Rep2> + explicit duration(const Rep2& r +#if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__) +#else + , typename boost::enable_if < + boost::mpl::and_ < + boost::is_convertible<Rep2, rep>, + boost::mpl::or_ < + treat_as_floating_point<rep>, + boost::mpl::and_ < + boost::mpl::not_ < treat_as_floating_point<rep> >, + boost::mpl::not_ < treat_as_floating_point<Rep2> > + > + > + > + >::type* = 0 +#endif + ) + : rep_(r) { } + ~duration() {} //= default; + duration(const duration& rhs) : rep_(rhs.rep_) {} // = default; + duration& operator=(const duration& rhs) // = default; + { + if (&rhs != this) rep_= rhs.rep_; + return *this; + } + + // conversions + template <class Rep2, class Period2> + duration(const duration<Rep2, Period2>& d +#if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__) +#else + , typename boost::enable_if < + boost::mpl::or_ < + treat_as_floating_point<rep>, + boost::mpl::and_ < + boost::mpl::bool_ < boost::ratio_divide<Period2, period>::type::den == 1>, + boost::mpl::not_ < treat_as_floating_point<Rep2> > + > + > + >::type* = 0 +#endif + ) +//~ #ifdef __GNUC__ + // GCC 4.2.4 refused to accept a definition at this point, + // yet both VC++ 9.0 SP1 and Intel ia32 11.0 accepted the definition + // without complaint. VC++ 9.0 SP1 refused to accept a later definition, + // although that was fine with GCC 4.2.4 and Intel ia32 11.0. Thus we + // have to support both approaches. + //~ ; +//~ #else + //~ : rep_(chrono::duration_cast<duration>(d).count()) {} + : rep_(chrono::detail::duration_cast<duration<Rep2, Period2>, duration>()(d).count()) {} +//~ #endif + + // observer + + rep count() const {return rep_;} + + // arithmetic + + duration operator+() const {return *this;} + duration operator-() const {return duration(-rep_);} + duration& operator++() {++rep_; return *this;} + duration operator++(int) {return duration(rep_++);} + duration& operator--() {--rep_; return *this;} + duration operator--(int) {return duration(rep_--);} + + duration& operator+=(const duration& d) {rep_ += d.count(); return *this;} + duration& operator-=(const duration& d) {rep_ -= d.count(); return *this;} + + duration& operator*=(const rep& rhs) {rep_ *= rhs; return *this;} + duration& operator/=(const rep& rhs) {rep_ /= rhs; return *this;} + duration& operator%=(const rep& rhs) {rep_ %= rhs; return *this;} + duration& operator%=(const duration& rhs) {rep_ %= rhs.count(); return *this;}; + // 20.9.3.4 duration special values [time.duration.special] + + static duration zero() {return duration(duration_values<rep>::zero());} + static duration min BOOST_PREVENT_MACRO_SUBSTITUTION () {return duration((duration_values<rep>::min)());} + static duration max BOOST_PREVENT_MACRO_SUBSTITUTION () {return duration((duration_values<rep>::max)());} + }; + +//----------------------------------------------------------------------------// +// 20.9.3.5 duration non-member arithmetic [time.duration.nonmember] // +//----------------------------------------------------------------------------// + + // Duration + + + template <class Rep1, class Period1, class Rep2, class Period2> + inline + typename boost::common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type + operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) + { + typename boost::common_type<duration<Rep1, Period1>, + duration<Rep2, Period2> >::type result = lhs; + result += rhs; + return result; + } + + // Duration - + + template <class Rep1, class Period1, class Rep2, class Period2> + inline + typename boost::common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type + operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) + { + typename boost::common_type<duration<Rep1, Period1>, + duration<Rep2, Period2> >::type result = lhs; + result -= rhs; + return result; + } + + // Duration * + + template <class Rep1, class Period, class Rep2> + inline +#if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__) + duration<typename boost::common_type<Rep1, Rep2>::type, Period> +#else +typename boost::enable_if < + boost::mpl::and_ < + boost::is_convertible<Rep1, typename boost::common_type<Rep1, Rep2>::type>, + boost::is_convertible<Rep2, typename boost::common_type<Rep1, Rep2>::type> + >, + duration<typename boost::common_type<Rep1, Rep2>::type, Period> + >::type +#endif + operator*(const duration<Rep1, Period>& d, const Rep2& s) + { + typedef typename boost::common_type<Rep1, Rep2>::type CR; + duration<CR, Period> r = d; + r *= static_cast<CR>(s); + return r; + } + + template <class Rep1, class Period, class Rep2> + inline +#if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__) + duration<typename boost::common_type<Rep1, Rep2>::type, Period> +#else + typename boost::enable_if < + boost::mpl::and_ < + boost::is_convertible<Rep1, typename boost::common_type<Rep1, Rep2>::type>, + boost::is_convertible<Rep2, typename boost::common_type<Rep1, Rep2>::type> + >, + duration<typename boost::common_type<Rep1, Rep2>::type, Period> + >::type +#endif + operator*(const Rep1& s, const duration<Rep2, Period>& d) + { + return d * s; + } + + // Duration / + + template <class Rep1, class Period, class Rep2> + inline + typename boost::disable_if <boost_ex::chrono::detail::is_duration<Rep2>, + typename boost_ex::chrono::detail::duration_divide_result<duration<Rep1, Period>, Rep2>::type + >::type + operator/(const duration<Rep1, Period>& d, const Rep2& s) + { + typedef typename boost::common_type<Rep1, Rep2>::type CR; + duration<CR, Period> r = d; + r /= static_cast<CR>(s); + return r; + } + + template <class Rep1, class Period1, class Rep2, class Period2> + inline + typename boost::common_type<Rep1, Rep2>::type + operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) + { + typedef typename boost::common_type<duration<Rep1, Period1>, + duration<Rep2, Period2> >::type CD; + return CD(lhs).count() / CD(rhs).count(); + } + + template <class Rep1, class Rep2, class Period> + inline + typename boost::disable_if <boost_ex::chrono::detail::is_duration<Rep1>, + typename boost_ex::chrono::detail::duration_divide_result2<Rep1, duration<Rep2, Period> >::type + >::type + operator/(const Rep1& s, const duration<Rep2, Period>& d) + { + typedef typename boost::common_type<Rep1, Rep2>::type CR; + duration<CR, Period> r = d; + //return static_cast<CR>(r.count()) / static_cast<CR>(s); + return static_cast<CR>(s)/r.count(); + } + + // Duration % + + template <class Rep1, class Period, class Rep2> + typename boost::disable_if <boost_ex::chrono::detail::is_duration<Rep2>, + typename boost_ex::chrono::detail::duration_modulo_result<duration<Rep1, Period>, Rep2>::type + >::type + operator%(const duration<Rep1, Period>& d, const Rep2& s) { + typedef typename boost::common_type<Rep1, Rep2>::type CR; + duration<CR, Period> r = d; + r %= static_cast<CR>(s); + return r; + } + + template <class Rep1, class Period1, class Rep2, class Period2> + typename boost::common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type + operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) { + typedef typename boost::common_type<duration<Rep1, Period1>, + duration<Rep2, Period2> >::type CD; + CD r(lhs); + r%=CD(rhs); + return r; + } + + +//----------------------------------------------------------------------------// +// 20.9.3.6 duration comparisons [time.duration.comparisons] // +//----------------------------------------------------------------------------// + + namespace detail + { + template <class LhsDuration, class RhsDuration> + struct duration_eq + { + bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) + { + typedef typename boost::common_type<LhsDuration, RhsDuration>::type CD; + return CD(lhs).count() == CD(rhs).count(); + } + }; + + template <class LhsDuration> + struct duration_eq<LhsDuration, LhsDuration> + { + bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) + {return lhs.count() == rhs.count();} + }; + + template <class LhsDuration, class RhsDuration> + struct duration_lt + { + bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) + { + typedef typename boost::common_type<LhsDuration, RhsDuration>::type CD; + return CD(lhs).count() < CD(rhs).count(); + } + }; + + template <class LhsDuration> + struct duration_lt<LhsDuration, LhsDuration> + { + bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) + {return lhs.count() < rhs.count();} + }; + + } // namespace detail + + // Duration == + + template <class Rep1, class Period1, class Rep2, class Period2> + inline + bool + operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) + { + return boost_ex::chrono::detail::duration_eq<duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs); + } + + // Duration != + + template <class Rep1, class Period1, class Rep2, class Period2> + inline + bool + operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) + { + return !(lhs == rhs); + } + + // Duration < + + template <class Rep1, class Period1, class Rep2, class Period2> + inline + bool + operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) + { + return boost_ex::chrono::detail::duration_lt<duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs); + } + + // Duration > + + template <class Rep1, class Period1, class Rep2, class Period2> + inline + bool + operator> (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) + { + return rhs < lhs; + } + + // Duration <= + + template <class Rep1, class Period1, class Rep2, class Period2> + inline + bool + operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) + { + return !(rhs < lhs); + } + + // Duration >= + + template <class Rep1, class Period1, class Rep2, class Period2> + inline + bool + operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) + { + return !(lhs < rhs); + } + +//----------------------------------------------------------------------------// +// 20.9.3.7 duration_cast [time.duration.cast] // +//----------------------------------------------------------------------------// + + // Compile-time select the most efficient algorithm for the conversion... + template <class ToDuration, class Rep, class Period> + inline +#if (defined(BOOST_MSVC) && (BOOST_MSVC == 1500)) || defined(__IBMCPP__) + ToDuration +#else + typename boost::enable_if <boost_ex::chrono::detail::is_duration<ToDuration>, ToDuration>::type +#endif + duration_cast(const duration<Rep, Period>& fd) + { + return boost_ex::chrono::detail::duration_cast<duration<Rep, Period>, ToDuration>()(fd); + } + +} +} +#endif // BOOST_EX_CHRONO_DURATION_HPP diff --git a/src/boost/libs/ratio/example/si_physics.cpp b/src/boost/libs/ratio/example/si_physics.cpp new file mode 100644 index 00000000..1e526b53 --- /dev/null +++ b/src/boost/libs/ratio/example/si_physics.cpp @@ -0,0 +1,236 @@ +// ratio_test.cpp ----------------------------------------------------------// + +// Copyright 2008 Howard Hinnant +// Copyright 2008 Beman Dawes + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include <iostream> +#include <boost/ratio/ratio.hpp> +#include "duration.hpp" + +namespace User1 +{ +// Example type-safe "physics" code interoperating with chrono::duration types +// and taking advantage of the std::ratio infrastructure and design philosophy. + +// length - mimics chrono::duration except restricts representation to double. +// Uses boost::ratio facilities for length units conversions. + +template <class Ratio> +class length +{ +public: + typedef Ratio ratio; +private: + double len_; +public: + + length() : len_(1) {} + length(const double& len) : len_(len) {} + + // conversions + template <class R> + length(const length<R>& d) + : len_(d.count() * boost::ratio_divide<Ratio, R>::type::den / + boost::ratio_divide<Ratio, R>::type::num) {} + + // observer + + double count() const {return len_;} + + // arithmetic + + length& operator+=(const length& d) {len_ += d.count(); return *this;} + length& operator-=(const length& d) {len_ -= d.count(); return *this;} + + length operator+() const {return *this;} + length operator-() const {return length(-len_);} + + length& operator*=(double rhs) {len_ *= rhs; return *this;} + length& operator/=(double rhs) {len_ /= rhs; return *this;} +}; + +// Sparse sampling of length units +typedef length<boost::ratio<1> > meter; // set meter as "unity" +typedef length<boost::centi> centimeter; // 1/100 meter +typedef length<boost::kilo> kilometer; // 1000 meters +typedef length<boost::ratio<254, 10000> > inch; // 254/10000 meters +// length takes ratio instead of two integral types so that definitions can be made like so: +typedef length<boost::ratio_multiply<boost::ratio<12>, inch::ratio>::type> foot; // 12 inchs +typedef length<boost::ratio_multiply<boost::ratio<5280>, foot::ratio>::type> mile; // 5280 feet + +// Need a floating point definition of seconds +typedef boost_ex::chrono::duration<double> seconds; // unity +// Demo of (scientific) support for sub-nanosecond resolutions +typedef boost_ex::chrono::duration<double, boost::pico> picosecond; // 10^-12 seconds +typedef boost_ex::chrono::duration<double, boost::femto> femtosecond; // 10^-15 seconds +typedef boost_ex::chrono::duration<double, boost::atto> attosecond; // 10^-18 seconds + +// A very brief proof-of-concept for SIUnits-like library +// Hard-wired to floating point seconds and meters, but accepts other units (shown in testUser1()) +template <class R1, class R2> +class quantity +{ + double q_; +public: + typedef R1 time_dim; + typedef R2 distance_dim; + quantity() : q_(1) {} + + double get() const {return q_;} + void set(double q) {q_ = q;} +}; + +template <> +class quantity<boost::ratio<1>, boost::ratio<0> > +{ + double q_; +public: + quantity() : q_(1) {} + quantity(seconds d) : q_(d.count()) {} // note: only User1::seconds needed here + + double get() const {return q_;} + void set(double q) {q_ = q;} +}; + +template <> +class quantity<boost::ratio<0>, boost::ratio<1> > +{ + double q_; +public: + quantity() : q_(1) {} + quantity(meter d) : q_(d.count()) {} // note: only User1::meter needed here + + double get() const {return q_;} + void set(double q) {q_ = q;} +}; + +template <> +class quantity<boost::ratio<0>, boost::ratio<0> > +{ + double q_; +public: + quantity() : q_(1) {} + quantity(double d) : q_(d) {} + + double get() const {return q_;} + void set(double q) {q_ = q;} +}; + +// Example SI-Units +typedef quantity<boost::ratio<0>, boost::ratio<0> > Scalar; +typedef quantity<boost::ratio<1>, boost::ratio<0> > Time; // second +typedef quantity<boost::ratio<0>, boost::ratio<1> > Distance; // meter +typedef quantity<boost::ratio<-1>, boost::ratio<1> > Speed; // meter/second +typedef quantity<boost::ratio<-2>, boost::ratio<1> > Acceleration; // meter/second^2 + +template <class R1, class R2, class R3, class R4> +quantity<typename boost::ratio_subtract<R1, R3>::type, typename boost::ratio_subtract<R2, R4>::type> +operator/(const quantity<R1, R2>& x, const quantity<R3, R4>& y) +{ + typedef quantity<typename boost::ratio_subtract<R1, R3>::type, typename boost::ratio_subtract<R2, R4>::type> R; + R r; + r.set(x.get() / y.get()); + return r; +} + +template <class R1, class R2, class R3, class R4> +quantity<typename boost::ratio_add<R1, R3>::type, typename boost::ratio_add<R2, R4>::type> +operator*(const quantity<R1, R2>& x, const quantity<R3, R4>& y) +{ + typedef quantity<typename boost::ratio_add<R1, R3>::type, typename boost::ratio_add<R2, R4>::type> R; + R r; + r.set(x.get() * y.get()); + return r; +} + +template <class R1, class R2> +quantity<R1, R2> +operator+(const quantity<R1, R2>& x, const quantity<R1, R2>& y) +{ + typedef quantity<R1, R2> R; + R r; + r.set(x.get() + y.get()); + return r; +} + +template <class R1, class R2> +quantity<R1, R2> +operator-(const quantity<R1, R2>& x, const quantity<R1, R2>& y) +{ + typedef quantity<R1, R2> R; + R r; + r.set(x.get() - y.get()); + return r; +} + +// Example type-safe physics function +Distance +compute_distance(Speed v0, Time t, Acceleration a) +{ + return v0 * t + Scalar(.5) * a * t * t; // if a units mistake is made here it won't compile +} + +} // User1 + +// Exercise example type-safe physics function and show interoperation +// of custom time durations (User1::seconds) and standard time durations (std::hours). +// Though input can be arbitrary (but type-safe) units, output is always in SI-units +// (a limitation of the simplified Units lib demoed here). + + + +int main() +{ + //~ typedef boost::ratio<8, BOOST_INTMAX_C(0x7FFFFFFFD)> R1; + //~ typedef boost::ratio<3, BOOST_INTMAX_C(0x7FFFFFFFD)> R2; + typedef User1::quantity<boost::ratio_subtract<boost::ratio<0>, boost::ratio<1> >::type, + boost::ratio_subtract<boost::ratio<1>, boost::ratio<0> >::type > RR; + //~ typedef boost::ratio_subtract<R1, R2>::type RS; + //~ std::cout << RS::num << '/' << RS::den << '\n'; + + + std::cout << "*************\n"; + std::cout << "* testUser1 *\n"; + std::cout << "*************\n"; + User1::Distance d(( User1::mile(110) )); + boost_ex::chrono::hours h((2)); + User1::Time t(( h )); + //~ boost_ex::chrono::seconds sss=boost_ex::chrono::duration_cast<boost_ex::chrono::seconds>(h); + //~ User1::seconds sss((120)); + //~ User1::Time t(( sss )); + + //typedef User1::quantity<boost::ratio_subtract<User1::Distance::time_dim, User1::Time::time_dim >::type, + // boost::ratio_subtract<User1::Distance::distance_dim, User1::Time::distance_dim >::type > R; + RR r=d / t; + //r.set(d.get() / t.get()); + + User1::Speed rc= r; + (void)rc; + User1::Speed s = d / t; + std::cout << "Speed = " << s.get() << " meters/sec\n"; + User1::Acceleration a = User1::Distance( User1::foot(32.2) ) / User1::Time() / User1::Time(); + std::cout << "Acceleration = " << a.get() << " meters/sec^2\n"; + User1::Distance df = compute_distance(s, User1::Time( User1::seconds(0.5) ), a); + std::cout << "Distance = " << df.get() << " meters\n"; + std::cout << "There are " << User1::mile::ratio::den << '/' << User1::mile::ratio::num << " miles/meter"; + User1::meter mt = 1; + User1::mile mi = mt; + std::cout << " which is approximately " << mi.count() << '\n'; + std::cout << "There are " << User1::mile::ratio::num << '/' << User1::mile::ratio::den << " meters/mile"; + mi = 1; + mt = mi; + std::cout << " which is approximately " << mt.count() << '\n'; + User1::attosecond as(1); + User1::seconds sec = as; + std::cout << "1 attosecond is " << sec.count() << " seconds\n"; + std::cout << "sec = as; // compiles\n"; + sec = User1::seconds(1); + as = sec; + std::cout << "1 second is " << as.count() << " attoseconds\n"; + std::cout << "as = sec; // compiles\n"; + std::cout << "\n"; + return 0; +} diff --git a/src/boost/libs/ratio/example/static_assert.hpp b/src/boost/libs/ratio/example/static_assert.hpp new file mode 100644 index 00000000..b2d912ee --- /dev/null +++ b/src/boost/libs/ratio/example/static_assert.hpp @@ -0,0 +1,30 @@ +// static_assert.hpp --------------------------------------------------------------// + +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + + +#ifndef BOOST_EX_CHRONO_DETAIL_STATIC_ASSERT_HPP +#define BOOST_EX_CHRONO_DETAIL_STATIC_ASSERT_HPP + +#include "config.hpp" + +#ifndef BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_EX_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG) +#elif defined(BOOST_CHRONO_USES_STATIC_ASSERT) +#include <boost/static_assert.hpp> +#define BOOST_EX_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) BOOST_STATIC_ASSERT(CND) +#elif defined(BOOST_CHRONO_USES_MPL_ASSERT) +#include <boost/mpl/assert.hpp> +#include <boost/mpl/bool.hpp> +#define BOOST_EX_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) \ + BOOST_MPL_ASSERT_MSG(boost::mpl::bool_< (CND) >::type::value, MSG, TYPES) +#else +//~ #elif defined(BOOST_CHRONO_USES_ARRAY_ASSERT) +#define BOOST_EX_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) static char BOOST_JOIN(boost_chrono_test_,__LINE__)[(CND)?1:-1] +//~ #define BOOST_EX_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) +#endif + +#endif // BOOST_EX_CHRONO_DETAIL_STATIC_ASSERT_HPP diff --git a/src/boost/libs/ratio/example/type_traits/add_rvalue_reference.hpp b/src/boost/libs/ratio/example/type_traits/add_rvalue_reference.hpp new file mode 100644 index 00000000..28258a01 --- /dev/null +++ b/src/boost/libs/ratio/example/type_traits/add_rvalue_reference.hpp @@ -0,0 +1,67 @@ +// add_rvalue_reference.hpp ---------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_EX_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP +#define BOOST_EX_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP + +#include <boost/config.hpp> + +//----------------------------------------------------------------------------// + +#include <boost/type_traits/is_void.hpp> +#include <boost/type_traits/is_reference.hpp> + +// should be the last #include +#include <boost/type_traits/detail/type_trait_def.hpp> + +//----------------------------------------------------------------------------// +// // +// C++03 implementation of // +// 20.7.6.2 Reference modifications [meta.trans.ref] // +// Written by Vicente J. Botet Escriba // +// // +// If T names an object or function type then the member typedef type +// shall name T&&; otherwise, type shall name T. [ Note: This rule reflects +// the semantics of reference collapsing. For example, when a type T names +// a type T1&, the type add_rvalue_reference<T>::type is not an rvalue +// reference. -end note ] +//----------------------------------------------------------------------------// + +namespace boost_ex { + +namespace type_traits_detail { + + template <typename T, bool b> + struct add_rvalue_reference_helper + { typedef T type; }; + + template <typename T> + struct add_rvalue_reference_helper<T, true> + { +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + typedef T&& type; +#else + typedef T type; +#endif + }; + + template <typename T> + struct add_rvalue_reference_imp + { + typedef typename boost_ex::type_traits_detail::add_rvalue_reference_helper + <T, (!boost::is_void<T>::value && !boost::is_reference<T>::value) >::type type; + }; + +} + +BOOST_TT_AUX_TYPE_TRAIT_DEF1(add_rvalue_reference,T,typename boost_ex::type_traits_detail::add_rvalue_reference_imp<T>::type) + +} // namespace boost_ex + +#include <boost/type_traits/detail/type_trait_undef.hpp> + +#endif // BOOST_EX_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP diff --git a/src/boost/libs/ratio/example/type_traits/common_type.hpp b/src/boost/libs/ratio/example/type_traits/common_type.hpp new file mode 100644 index 00000000..0e8cec28 --- /dev/null +++ b/src/boost/libs/ratio/example/type_traits/common_type.hpp @@ -0,0 +1,151 @@ +// common_type.hpp ---------------------------------------------------------// + +// Copyright 2008 Howard Hinnant +// Copyright 2008 Beman Dawes + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_EX_TYPE_TRAITS_EXT_COMMON_TYPE_HPP +#define BOOST_EX_TYPE_TRAITS_EXT_COMMON_TYPE_HPP + +#include <boost/config.hpp> + +//----------------------------------------------------------------------------// +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#define BOOST_EX_COMMON_TYPE_ARITY 3 +#endif + +//----------------------------------------------------------------------------// +#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_EX_COMMON_TYPE_DONT_USE_TYPEOF) +#define BOOST_TYPEOF_SILENT +#include <boost/typeof/typeof.hpp> // boost wonders never cease! +#endif + +//----------------------------------------------------------------------------// +#ifndef BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG) +#elif defined(BOOST_EX_COMMON_TYPE_USES_STATIC_ASSERT) +#include <boost/static_assert.hpp> +#define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) BOOST_STATIC_ASSERT(CND) +#elif defined(BOOST_EX_COMMON_TYPE_USES_MPL_ASSERT) +#include <boost/mpl/assert.hpp> +#include <boost/mpl/bool.hpp> +#define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) \ + BOOST_MPL_ASSERT_MSG(boost::mpl::bool_< (CND) >::type::value, MSG, TYPES) +#else +//~ #elif defined(BOOST_EX_COMMON_TYPE_USES_ARRAY_ASSERT) +#define BOOST_EX_COMMON_TYPE_CONCAT(A,B) A##B +#define BOOST_EX_COMMON_TYPE_NAME(A,B) BOOST_EX_COMMON_TYPE_CONCAT(A,B) +#define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) static char BOOST_EX_COMMON_TYPE_NAME(__boost_common_type_test_,__LINE__)[(CND)?1:-1] +//~ #define BOOST_EX_COMMON_TYPE_STATIC_ASSERT(CND, MSG, TYPES) +#endif + +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || !defined(BOOST_EX_COMMON_TYPE_USES_MPL_ASSERT) +#define BOOST_EX_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE "must be complete type" +#endif + +#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_EX_COMMON_TYPE_DONT_USE_TYPEOF) +#include "detail/common_type.hpp" +#include <boost/type_traits/remove_cv.hpp> +#endif +#include <boost/mpl/if.hpp> +#include "declval.hpp" + +//----------------------------------------------------------------------------// +// // +// C++03 implementation of // +// 20.6.7 Other transformations [meta.trans.other] // +// Written by Howard Hinnant // +// Adapted for Boost by Beman Dawes, Vicente Botet and Jeffrey Hellrung // +// // +//----------------------------------------------------------------------------// + +namespace boost_ex { + +// prototype +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template<typename... T> + struct common_type; +#else // or no specialization + template <class T, class U = void, class V = void> + struct common_type + { + public: + typedef typename common_type<typename common_type<T, U>::type, V>::type type; + }; +#endif + + +// 1 arg + template<typename T> +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + struct common_type<T> +#else + struct common_type<T, void, void> + +#endif + { + BOOST_EX_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_EX_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T)); + public: + typedef T type; + }; + +// 2 args +namespace type_traits_detail { + + template <class T, class U> + struct common_type_2 + { + private: + BOOST_EX_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_EX_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T)); + BOOST_EX_COMMON_TYPE_STATIC_ASSERT(sizeof(U) > 0, BOOST_EX_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (U)); + static bool declval_bool(); // workaround gcc bug; not required by std + static typename add_rvalue_reference<T>::type declval_T(); // workaround gcc bug; not required by std + static typename add_rvalue_reference<U>::type declval_U(); // workaround gcc bug; not required by std + +#if !defined(BOOST_NO_CXX11_DECLTYPE) + public: + typedef decltype(declval<bool>() ? declval<T>() : declval<U>()) type; +#elif defined(BOOST_EX_COMMON_TYPE_DONT_USE_TYPEOF) + public: + typedef typename detail_type_traits_common_type::common_type_impl< + typename remove_cv<T>::type, + typename remove_cv<U>::type + >::type type; +#else + public: + //~ typedef BOOST_TYPEOF_TPL(declval_bool() ? declval_T() : declval_U()) type; + typedef BOOST_TYPEOF_TPL(declval<bool>() ? declval<T>() : declval<U>()) type; +#endif + }; + + template <class T> + struct common_type_2<T, T> + { + typedef T type; + }; + } + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template <class T, class U> + struct common_type<T, U> +#else + template <class T, class U> + struct common_type<T, U, void> +#endif + : type_traits_detail::common_type_2<T,U> + { }; + + +// 3 or more args +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template<typename T, typename U, typename... V> + struct common_type<T, U, V...> { + public: + typedef typename common_type<typename common_type<T, U>::type, V...>::type type; + }; +#endif +} // namespace boost_ex + +#endif // BOOST_TYPE_TRAITS_EXT_COMMON_TYPE_HPP diff --git a/src/boost/libs/ratio/example/type_traits/declval.hpp b/src/boost/libs/ratio/example/type_traits/declval.hpp new file mode 100644 index 00000000..437e3450 --- /dev/null +++ b/src/boost/libs/ratio/example/type_traits/declval.hpp @@ -0,0 +1,44 @@ +// common_type.hpp ---------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_EX_TYPE_TRAITS_EXT_DECLVAL__HPP +#define BOOST_EX_TYPE_TRAITS_EXT_DECLVAL__HPP + +#include <boost/config.hpp> + +//----------------------------------------------------------------------------// + +#include "add_rvalue_reference.hpp" + +//----------------------------------------------------------------------------// +// // +// C++03 implementation of // +// Written by Vicente J. Botet Escriba // +//~ 20.3.4 Function template declval [declval] +//~ 1 The library provides the function template declval to simplify the definition of expressions which occur as +//~ unevaluated operands. +//~ 2 Remarks: If this function is used, the program is ill-formed. +//~ 3 Remarks: The template parameter T of declval may be an incomplete type. +//~ [ Example: + +//~ template <class To, class From> +//~ decltype(static_cast<To>(declval<From>())) convert(From&&); + +//~ declares a function template convert which only participats in overloading if the type From can be +//~ explicitly converted to type To. For another example see class template common_type (20.7.6.6). -end +//~ example ] +// // +//----------------------------------------------------------------------------// + +namespace boost_ex { + + template <typename T> + typename add_rvalue_reference<T>::type declval(); //noexcept; // as unevaluated operand + +} // namespace boost + +#endif // BOOST_EX_TYPE_TRAITS_EXT_DECLVAL__HPP diff --git a/src/boost/libs/ratio/example/type_traits/detail/common_type.hpp b/src/boost/libs/ratio/example/type_traits/detail/common_type.hpp new file mode 100644 index 00000000..ca7555de --- /dev/null +++ b/src/boost/libs/ratio/example/type_traits/detail/common_type.hpp @@ -0,0 +1,316 @@ +/******************************************************************************* + * boost/type_traits/detail/common_type.hpp + * + * Copyright 2010, Jeffrey Hellrung. + * 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) + * + * struct boost::common_type<T,U> + * + * common_type<T,U>::type is the type of the expression + * b() ? x() : y() + * where b() returns a bool, x() has return type T, and y() has return type U. + * See + * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm#common_type + * + * Note that this evaluates to void if one or both of T and U is void. + ******************************************************************************/ + +#ifndef BOOST_EX_TYPE_TRAITS_EXT_DETAIL_COMMON_TYPE_HPP +#define BOOST_EX_TYPE_TRAITS_EXT_DETAIL_COMMON_TYPE_HPP + +#include <cstddef> + +#include <boost/mpl/assert.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/begin_end.hpp> +#include <boost/mpl/contains.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/deref.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/inserter.hpp> +#include <boost/mpl/next.hpp> +#include <boost/mpl/or.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/push_back.hpp> +#include <boost/mpl/size.hpp> +#include <boost/mpl/vector/vector0.hpp> +#include <boost/mpl/vector/vector10.hpp> +#include <boost/type_traits/integral_constant.hpp> +#include <boost/type_traits/is_enum.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/make_signed.hpp> +#include <boost/type_traits/make_unsigned.hpp> +#include <boost/type_traits/remove_cv.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/type_traits/declval.hpp> + +namespace boost_ex +{ + +namespace detail_type_traits_common_type +{ + +/******************************************************************************* + * struct propagate_cv< From, To > + * + * This metafunction propagates cv-qualifiers on type From to type To. + ******************************************************************************/ + +template< class From, class To > +struct propagate_cv +{ typedef To type; }; +template< class From, class To > +struct propagate_cv< const From, To > +{ typedef To const type; }; +template< class From, class To > +struct propagate_cv< volatile From, To > +{ typedef To volatile type; }; +template< class From, class To > +struct propagate_cv< const volatile From, To > +{ typedef To const volatile type; }; + +/******************************************************************************* + * struct is_signable_integral<T> + * + * This metafunction determines if T is an integral type which can be made + * signed or unsigned. + ******************************************************************************/ + +template< class T > +struct is_signable_integral + : mpl::or_< is_integral<T>, is_enum<T> > +{ }; +template<> +struct is_signable_integral< bool > + : false_type +{ }; + +/******************************************************************************* + * struct sizeof_t<N> + * typedef ... yes_type + * typedef ... no_type + * + * These types are integral players in the use of the "sizeof trick", i.e., we + * can distinguish overload selection by inspecting the size of the return type + * of the overload. + ******************************************************************************/ + +template< std::size_t N > struct sizeof_t { char _dummy[N]; }; +typedef sizeof_t<1> yes_type; +typedef sizeof_t<2> no_type; +BOOST_MPL_ASSERT_RELATION( sizeof( yes_type ), ==, 1 ); +BOOST_MPL_ASSERT_RELATION( sizeof( no_type ), ==, 2 ); + +/******************************************************************************* + * rvalue_test(T&) -> no_type + * rvalue_test(...) -> yes_type + * + * These overloads are used to determine the rvalue-ness of an expression. + ******************************************************************************/ + +template< class T > no_type rvalue_test(T&); +yes_type rvalue_test(...); + +/******************************************************************************* + * struct conversion_test_overloads< Sequence > + * + * This struct has multiple overloads of the static member function apply, each + * one taking a single parameter of a type within the Boost.MPL sequence + * Sequence. Each such apply overload has a return type with sizeof equal to + * one plus the index of the parameter type within Sequence. Thus, we can + * deduce the type T of an expression as long as we can generate a finite set of + * candidate types containing T via these apply overloads and the "sizeof + * trick". + ******************************************************************************/ + +template< class First, class Last, std::size_t Index > +struct conversion_test_overloads_iterate + : conversion_test_overloads_iterate< + typename mpl::next< First >::type, Last, Index + 1 + > +{ + using conversion_test_overloads_iterate< + typename mpl::next< First >::type, Last, Index + 1 + >::apply; + static sizeof_t< Index + 1 > + apply(typename mpl::deref< First >::type); +}; + +template< class Last, std::size_t Index > +struct conversion_test_overloads_iterate< Last, Last, Index > +{ static sizeof_t< Index + 1 > apply(...); }; + +template< class Sequence > +struct conversion_test_overloads + : conversion_test_overloads_iterate< + typename mpl::begin< Sequence >::type, + typename mpl::end< Sequence >::type, + 0 + > +{ }; + +/******************************************************************************* + * struct select< Sequence, Index > + * + * select is synonymous with mpl::at_c unless Index equals the size of the + * Boost.MPL Sequence, in which case this evaluates to void. + ******************************************************************************/ + +template< + class Sequence, int Index, + int N = mpl::size< Sequence >::value +> +struct select + : mpl::at_c< Sequence, Index > +{ }; +template< class Sequence, int N > +struct select< Sequence, N, N > +{ typedef void type; }; + +/******************************************************************************* + * class deduce_common_type< T, U, NominalCandidates > + * struct nominal_candidates<T,U> + * struct common_type_dispatch_on_rvalueness<T,U> + * struct common_type_impl<T,U> + * + * These classes and structs implement the logic behind common_type, which goes + * roughly as follows. Let C be the type of the conditional expression + * declval< bool >() ? declval<T>() : declval<U>() + * if C is an rvalue, then: + * let T' and U' be T and U stripped of reference- and cv-qualifiers + * if T' and U' are pointer types, say, T' = V* and U' = W*, then: + * define the set of NominalCandidates to be + * { V*, W*, V'*, W'* } + * where V' is V with whatever cv-qualifiers are on W, and W' is W + * with whatever cv-qualifiers are on V + * else T' and U' are both "signable integral types" (integral and enum + * types excepting bool), then: + * define the set of NominalCandidates to be + * { unsigned(T'), unsigned(U'), signed(T'), signed(U') } + * where unsigned(X) is make_unsigned<X>::type and signed(X) is + * make_signed<X>::type + * else + * define the set of NominalCandidates to be + * { T', U' } + * else + * let V and W be T and U stripped of reference-qualifiers + * define the set of NominalCandidates to be + * { V&, W&, V'&, W'& } + * where V' is V with whatever cv-qualifiers are on W, and W' is W with + * whatever cv-qualifiers are on V + * define the set of Candidates to be equal to the set of NominalCandidates with + * duplicates removed, and use this set of Candidates to determine C using the + * conversion_test_overloads struct + ******************************************************************************/ + +template< class T, class U, class NominalCandidates > +class deduce_common_type +{ + typedef typename mpl::copy< + NominalCandidates, + mpl::inserter< + mpl::vector0<>, + mpl::if_< + mpl::contains< mpl::_1, mpl::_2 >, + mpl::_1, + mpl::push_back< mpl::_1, mpl::_2 > + > + > + >::type candidate_types; + static const int best_candidate_index = + sizeof( conversion_test_overloads< candidate_types >::apply( + declval< bool >() ? declval<T>() : declval<U>() + ) ) - 1; +public: + typedef typename select< candidate_types, best_candidate_index >::type type; +}; + +template< + class T, class U, + class V = typename remove_cv< typename remove_reference<T>::type >::type, + class W = typename remove_cv< typename remove_reference<U>::type >::type, + bool = is_signable_integral<V>::value && is_signable_integral<W>::value +> +struct nominal_candidates; + +template< class T, class U, class V, class W > +struct nominal_candidates< T, U, V, W, false > +{ typedef mpl::vector2<V,W> type; }; + +template< class T, class U, class V, class W > +struct nominal_candidates< T, U, V, W, true > +{ + typedef mpl::vector4< + typename make_unsigned<V>::type, + typename make_unsigned<W>::type, + typename make_signed<V>::type, + typename make_signed<W>::type + > type; +}; + +template< class T, class U, class V, class W > +struct nominal_candidates< T, U, V*, W*, false > +{ + typedef mpl::vector4< + V*, W*, + typename propagate_cv<W,V>::type *, + typename propagate_cv<V,W>::type * + > type; +}; + +template< + class T, class U, + bool = sizeof( ::boost::detail_type_traits_common_type::rvalue_test( + declval< bool >() ? declval<T>() : declval<U>() + ) ) == sizeof( yes_type ) +> +struct common_type_dispatch_on_rvalueness; + +template< class T, class U > +struct common_type_dispatch_on_rvalueness< T, U, true > + : deduce_common_type< T, U, typename nominal_candidates<T,U>::type > +{ }; + +template< class T, class U > +struct common_type_dispatch_on_rvalueness< T, U, false > +{ +private: + typedef typename remove_reference<T>::type unrefed_T_type; + typedef typename remove_reference<U>::type unrefed_U_type; +public: + typedef typename deduce_common_type< + T, U, + mpl::vector4< + unrefed_T_type &, + unrefed_U_type &, + typename propagate_cv< unrefed_U_type, unrefed_T_type >::type &, + typename propagate_cv< unrefed_T_type, unrefed_U_type >::type & + > + >::type type; +}; + +template< class T, class U > +struct common_type_impl + : common_type_dispatch_on_rvalueness<T,U> +{ }; + +template< class T > struct common_type_impl< T, void > { typedef void type; }; +template< class T > struct common_type_impl< void, T > { typedef void type; }; +template<> struct common_type_impl< void, void > { typedef void type; }; +template< > struct common_type_impl< char, short> { typedef int type; }; +template< > struct common_type_impl< short, char> { typedef int type; }; +template< > struct common_type_impl< unsigned char, short> { typedef int type; }; +template< > struct common_type_impl< short, unsigned char> { typedef int type; }; +template< > struct common_type_impl< unsigned char, unsigned short> { typedef int type; }; +template< > struct common_type_impl< unsigned short, unsigned char> { typedef int type; }; +template< > struct common_type_impl< char, unsigned short> { typedef int type; }; +template< > struct common_type_impl< unsigned short, char> { typedef int type; }; + +} // namespace detail_type_traits_common_type + + +} // namespace boost_ex + +#endif // BOOST_EX_TYPE_TRAITS_EXT_DETAIL_COMMON_TYPE_HPP |