diff options
Diffstat (limited to '')
86 files changed, 7395 insertions, 0 deletions
diff --git a/src/boost/libs/ratio/CMakeLists.txt b/src/boost/libs/ratio/CMakeLists.txt new file mode 100644 index 00000000..386159a0 --- /dev/null +++ b/src/boost/libs/ratio/CMakeLists.txt @@ -0,0 +1,37 @@ +# Copyright 2019 Mike Dev +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt +# +# NOTE: CMake support for Boost.Ratio is currently experimental at best +# and the interface is likely to change in the future + +cmake_minimum_required( VERSION 3.5 ) +project( BoostRatio LANGUAGES CXX) +option( BOOST_RATIO_INCLUDE_TESTS "Add boost ratio tests" OFF ) + +add_library( boost_ratio INTERFACE ) +add_library( Boost::ratio ALIAS boost_ratio ) + +target_include_directories( boost_ratio INTERFACE include ) + +target_link_libraries( boost_ratio + INTERFACE + Boost::config + Boost::core + Boost::integer + Boost::mpl + Boost::static_assert + Boost::type_traits + +# NOTE: As of Boost 1.70, the dependency on rational is only +# necessary, if BOOST_RATIO_EXTENSIONS is defined. +# Maybe consuming libraries that do so should add +# Boost::rational as a dependency themselves, +# instead of doing it here for everyone? + Boost::rational +) + +if( BOOST_RATIO_INCLUDE_TESTS ) + enable_testing() + add_subdirectory( test ) +endif() diff --git a/src/boost/libs/ratio/README.md b/src/boost/libs/ratio/README.md new file mode 100644 index 00000000..28aae848 --- /dev/null +++ b/src/boost/libs/ratio/README.md @@ -0,0 +1,8 @@ +ratio +====== + +Compile time rational arithmetic. C++11. + +### License + +Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt). 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 diff --git a/src/boost/libs/ratio/index.html b/src/boost/libs/ratio/index.html new file mode 100644 index 00000000..938b8b82 --- /dev/null +++ b/src/boost/libs/ratio/index.html @@ -0,0 +1,15 @@ +<html> +<head> +<meta http-equiv="refresh" content="0; URL=../../doc/html/ratio.html"> +</head> +<body> +Automatic redirection failed, please go to +<a href="../../doc/html/ratio.html">../../doc/html/ratio.html</a> +<p>© Copyright 2009-2010 Vicente J. Botet Escribá. +Distributed under the Boost Software +License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt"> +LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> +http://www.boost.org/LICENSE_1_0.txt</a>) +</p> +</body> +</html> diff --git a/src/boost/libs/ratio/meta/libraries.json b/src/boost/libs/ratio/meta/libraries.json new file mode 100644 index 00000000..40ea0a70 --- /dev/null +++ b/src/boost/libs/ratio/meta/libraries.json @@ -0,0 +1,18 @@ +{ + "key": "ratio", + "name": "Ratio", + "authors": [ + "Howard Hinnant", + "Beman Dawes", + "Vicente J. Botet Escriba" + ], + "maintainers": [ + "Vicente J. Botet Escriba <vicente.botet -at- wanadoo.fr>" + ], + "description": + "Compile time rational arithmetic. C++11.", + "std": [ "proposal" ], + "category": [ + "Math" + ] +} diff --git a/src/boost/libs/ratio/test/CMakeLists.txt b/src/boost/libs/ratio/test/CMakeLists.txt new file mode 100644 index 00000000..0a49e9f7 --- /dev/null +++ b/src/boost/libs/ratio/test/CMakeLists.txt @@ -0,0 +1,49 @@ +# Copyright 2019 Mike Dev +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt +# +# NOTE: CMake support for Boost.Ratio is currently experimental at best +# and this file runs only a subset of the unit tests +# (in particular none of the fail tests) + + +## unit tests + +# list of tests that contain a main function +set( exec_test_files ratio_ext_pass;ratio_io_pass;ratio_pass ) +file( GLOB_RECURSE test_files *_pass.cpp ) +foreach( file IN LISTS test_files ) + + get_filename_component( core_name ${file} NAME_WE ) + set( test_name test_boost_ratio_${core_name} ) + + if( ${core_name} IN_LIST exec_test_files ) + add_executable( ${test_name} ${file} ) + add_test( NAME ${test_name} COMMAND ${test_name} ) + else() + # most tests are compile only, so we just need to create an object file + # in order to see, if it compiles + add_library( ${test_name} STATIC ${file}) + endif() + + target_link_libraries( ${test_name} PUBLIC + Boost::ratio + ) + +endforeach() + +## examples +file( GLOB_RECURSE test_files ../example/*.cpp ) +foreach( file IN LISTS test_files ) + + get_filename_component( core_name ${file} NAME_WE ) + set( test_name test_boost_ratio_${core_name} ) + + add_executable( ${test_name} ${file} ) + target_link_libraries( ${test_name} PUBLIC + Boost::ratio + ) + add_test( NAME ${test_name} COMMAND ${test_name} ) + +endforeach() + diff --git a/src/boost/libs/ratio/test/Jamfile.v2 b/src/boost/libs/ratio/test/Jamfile.v2 new file mode 100644 index 00000000..a79ff685 --- /dev/null +++ b/src/boost/libs/ratio/test/Jamfile.v2 @@ -0,0 +1,132 @@ +# Boost Ratio Library test Jamfile + +# Copyright Beman Dawes 2003, 2006, 2008 + +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt + +# See library home page at http://www.boost.org/libs/ratio + +# uncomment one if the above lines if you build outside the Boost release +#local BOOST_ROOT = /boost_1_41_0 ; +#local BOOST_ROOT = c:/cygwin/boost_1_41_0 ; + +if ! $(BOOST_ROOT) +{ + BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ; +} + +project + : requirements + #<os>LINUX:<threading>multi + # uncomment the line above if you build outside the Boost release + #<include>$(BOOST_ROOT) + # uncomment the line above if you build outside the Boost release + #<include>../../.. + <toolset>msvc:<asynch-exceptions>on + <define>BOOST_ENABLE_WARNINGS + <define>BOOST_RATIO_USES_MPL_ASSERT + <define>BOOST_RATIO_VERSION=2 + <define>BOOST_MPL_NEXT_PRIOR_EXT + #<toolset>sun:<define>BOOST_COMMON_TYPE_DONT_USE_TYPEOF + #<toolset>sun:<define>BOOST_TYPEOF_EMULATION + <toolset>sun:<define>__typeof__=__typeof__ + <warnings>all + <toolset>gcc:<cxxflags>-Wextra + <toolset>gcc:<cxxflags>-Wno-long-long + <toolset>gcc:<cxxflags>-pedantic + <toolset>darwin:<cxxflags>-Wextra + <toolset>darwin:<cxxflags>-Wno-long-long + <toolset>darwin:<cxxflags>-pedantic + #<toolset>pathscale:<cxxflags>-Wextra + <toolset>pathscale:<cxxflags>-Wno-long-long + <toolset>pathscale:<cxxflags>-pedantic + <toolset>clang:<cxxflags>-Wextra + <toolset>clang:<cxxflags>-pedantic + <toolset>clang:<cxxflags>-Wno-long-long + #<toolset>gcc-mingw-4.5.0:<cxxflags>-Wno-missing-field-initializers + #<toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option + #<toolset>gcc-mingw-4.6.0:<cxxflags>-fdiagnostics-show-option + <toolset>msvc:<cxxflags>/wd4127 +# Note: Some of the remarks from the Intel compiler are disabled +# remark #1418: external function definition with no prior declaration +# remark #304: access control not specified ("public" by default) + <toolset>intel:<cxxflags>-wd304,1418 + ; + + test-suite "ratio_ratio" + : + [ compile typedefs_pass.cpp ] + [ compile ratio_ratio/ratio_pass.cpp ] + [ compile-fail ratio_ratio/ratio1_fail.cpp ] + [ compile-fail ratio_ratio/ratio2_fail.cpp ] + [ compile-fail ratio_ratio/ratio3_fail.cpp ] + [ compile-fail ratio_ratio/ratio4_fail.cpp ] + ; + + test-suite "ratio_io" + : + [ compile-fail ratio_io/ratio_io_fail.cpp ] + [ run ratio_io/ratio_io_pass.cpp ] + ; + + test-suite "ratio_arithmetic" + : + [ compile ratio_arithmetic/ratio_add_pass.cpp ] + [ compile ratio_arithmetic/ratio_subtract_pass.cpp ] + [ compile ratio_arithmetic/ratio_multiply_pass.cpp ] + [ compile ratio_arithmetic/ratio_divide_pass.cpp ] + [ compile-fail ratio_arithmetic/ratio_add_fail.cpp ] + [ compile-fail ratio_arithmetic/ratio_add_2_fail.cpp ] + [ compile-fail ratio_arithmetic/ratio_add_3_fail.cpp ] + [ compile-fail ratio_arithmetic/ratio_subtract_fail.cpp ] + [ compile-fail ratio_arithmetic/ratio_multiply_fail.cpp ] + [ compile-fail ratio_arithmetic/ratio_divide_fail.cpp ] + [ compile ratio_arithmetic/ratio_negate_pass.cpp ] + [ compile ratio_arithmetic/ratio_sign_pass.cpp ] + [ compile ratio_arithmetic/ratio_abs_pass.cpp ] + [ compile ratio_arithmetic/ratio_power_pass.cpp ] + ; + + test-suite "ratio_comparison" + : + [ compile ratio_comparison/ratio_equal_pass.cpp ] + [ compile ratio_comparison/ratio_not_equal_pass.cpp ] + [ compile ratio_comparison/ratio_less_pass.cpp ] + [ compile ratio_comparison/ratio_less_equal_pass.cpp ] + [ compile ratio_comparison/ratio_greater_pass.cpp ] + [ compile ratio_comparison/ratio_greater_equal_pass.cpp ] + ; + + test-suite "examples" + : + [ run ../example/si_physics.cpp ] + [ run ../example/display_ex.cpp ] + ; + + test-suite "ratio_ext" + : + [ run ratio_extensions/ratio_ext_pass.cpp ] + [ compile ratio_extensions/mpl_plus_pass.cpp ] + [ compile ratio_extensions/mpl_minus_pass.cpp ] + [ compile ratio_extensions/mpl_times_pass.cpp ] + [ compile ratio_extensions/mpl_divides_pass.cpp ] + [ compile ratio_extensions/mpl_negate_pass.cpp ] + [ compile ratio_extensions/mpl_sign_pass.cpp ] + [ compile ratio_extensions/mpl_abs_pass.cpp ] + [ compile ratio_extensions/mpl_equal_to_pass.cpp ] + [ compile ratio_extensions/mpl_not_equal_to_pass.cpp ] + [ compile ratio_extensions/mpl_less_pass.cpp ] + [ compile ratio_extensions/mpl_less_equal_pass.cpp ] + [ compile ratio_extensions/mpl_greater_pass.cpp ] + [ compile ratio_extensions/mpl_greater_equal_pass.cpp ] + [ compile ratio_extensions/mpl_arithmetic_pass.cpp ] + [ compile ratio_extensions/mpl_comparison_pass.cpp ] + [ compile ratio_extensions/mpl_rational_constant_pass.cpp ] + + ; + + #test-suite "tickets" + # : + # [ run test_6498_pass.cpp ] + # ; diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_abs_pass.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_abs_pass.cpp new file mode 100644 index 00000000..4ff23677 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_abs_pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_abs + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + + { + typedef boost::ratio<0> R1; + typedef boost::ratio_abs<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 0 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio_abs<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio_abs<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio_abs<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio_abs<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_2_fail.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_2_fail.cpp new file mode 100644 index 00000000..3d6eb1b9 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_2_fail.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include <boost/ratio/ratio.hpp> + + +template <typename R> +struct numerator; + +template <boost::intmax_t N, boost::intmax_t D> +struct numerator<boost::ratio<N,D> > { + static const boost::intmax_t value = N; +}; + + +BOOST_RATIO_STATIC_ASSERT(( + numerator<boost::ratio_add<boost::ratio<1,2>,boost::ratio<1,3> > >::value == 1) + , NOTHING, ()); diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_3_fail.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_3_fail.cpp new file mode 100644 index 00000000..6a64668d --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_3_fail.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include <boost/ratio/ratio.hpp> + +template <typename T, typename R> +struct S { + T val; +}; + +boost::intmax_t func(S<int, boost::ratio<5,6> > const& s) { + return s.val*3; +} + + +boost::intmax_t test() { + return func( + S<int, boost::ratio_add< + boost::ratio<1,2>, + boost::ratio<1,3> + > + //~ ::type + >() + ); +} + diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_fail.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_fail.cpp new file mode 100644 index 00000000..57ec0d45 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include <boost/ratio/ratio.hpp> +#include <boost/integer_traits.hpp> + +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + + +typedef boost::ratio<boost::integer_traits<boost::intmax_t>::const_max, 1> R1; +typedef boost::ratio<1, 1> R2; +typedef boost::ratio_add<R1, R2>::type RT; + +BOOST_RATIO_STATIC_ASSERT(RT::num==boost::integer_traits<boost::intmax_t>::const_max+1, NOTHING, (RT)); +BOOST_RATIO_STATIC_ASSERT(RT::den==1, NOTHING, (RT)); diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_pass.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_pass.cpp new file mode 100644 index 00000000..e13c4579 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_add_pass.cpp @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_add + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<0> R1; + typedef boost::ratio<0> R2; + typedef boost::ratio_add<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 0 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_add<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 2 && R::den == 1, NOTHING, ()); + typedef boost::ratio_add<R, R2> RR; + BOOST_RATIO_STATIC_ASSERT(RR::num == 3 && RR::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_add<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 3 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_add<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_add<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<-1, 1> R2; + typedef boost::ratio_add<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, -1> R2; + typedef boost::ratio_add<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<56987354, 467584654> R1; + typedef boost::ratio<544668, 22145> R2; + typedef boost::ratio_add<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 127970191639601LL && R::den == 5177331081415LL, NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-1, 1> R2; + typedef boost::ratio_add<R1, R2>::type RT; + } + +} + +boost::intmax_t func(boost::ratio<5,6> s) { + return s.num; +} + + +boost::intmax_t test_conversion() { + return func( + boost::ratio_add< + boost::ratio<1,2>, + boost::ratio<1,3> + > + () + ); +} + diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_divide_fail.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_divide_fail.cpp new file mode 100644 index 00000000..1ac95512 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_divide_fail.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_divide + +#include <boost/ratio/ratio.hpp> + +typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; +typedef boost::ratio<1,2> R2; +typedef boost::ratio_divide<R1, R2>::type RT; diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_divide_pass.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_divide_pass.cpp new file mode 100644 index 00000000..5eedc4b9 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_divide_pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_divide + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_divide<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_divide<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_divide<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_divide<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<-1, 1> R2; + typedef boost::ratio_divide<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, -1> R2; + typedef boost::ratio_divide<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<56987354, 467584654> R1; + typedef boost::ratio<544668, 22145> R2; + typedef boost::ratio_divide<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 630992477165LL && R::den == 127339199162436LL, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_multiply_fail.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_multiply_fail.cpp new file mode 100644 index 00000000..61afafa3 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_multiply_fail.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_multiply + +#include <boost/ratio/ratio.hpp> + +typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; +typedef boost::ratio<2,1> R2; +typedef boost::ratio_multiply<R1, R2>::type RT; diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_multiply_pass.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_multiply_pass.cpp new file mode 100644 index 00000000..42083b81 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_multiply_pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_multiply + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_multiply<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_multiply<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_multiply<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_multiply<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<-1, 1> R2; + typedef boost::ratio_multiply<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, -1> R2; + typedef boost::ratio_multiply<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<56987354, 467584654> R1; + typedef boost::ratio<544668, 22145> R2; + typedef boost::ratio_multiply<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 15519594064236LL && R::den == 5177331081415LL, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_negate_pass.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_negate_pass.cpp new file mode 100644 index 00000000..9954fc27 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_negate_pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_negate + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + + { + typedef boost::ratio<0> R1; + typedef boost::ratio_negate<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 0 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio_negate<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio_negate<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio_negate<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio_negate<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_power_pass.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_power_pass.cpp new file mode 100644 index 00000000..8bfe41ae --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_power_pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_power + +#define BOOST_RATIO_EXTENSIONS +#include <boost/ratio/ratio.hpp> + +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio_power<R1, 1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio_power<R1, -1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 2 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio_power<R1, 0> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio_power<R1, 2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 4, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio_power<R1, 2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 4, NOTHING, ()); + } + { + typedef boost::ratio<2, 3> R1; + typedef boost::ratio_power<R1, 2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 4 && R::den == 9, NOTHING, ()); + } + { + typedef boost::ratio<2, 3> R1; + typedef boost::ratio_power<R1, -2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 9 && R::den == 4, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_sign_pass.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_sign_pass.cpp new file mode 100644 index 00000000..0cc09a11 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_sign_pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_sign + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + + { + typedef boost::ratio<0> R1; + typedef boost::ratio_sign<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::value == 0, NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio_sign<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::value == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio_sign<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::value == 1, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio_sign<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::value == -1, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio_sign<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::value == -1, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_subtract_fail.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_subtract_fail.cpp new file mode 100644 index 00000000..087d7b28 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_subtract_fail.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_subtract + +#include <boost/ratio/ratio.hpp> + +typedef boost::ratio<BOOST_RATIO_INTMAX_C(-0x7FFFFFFFFFFFFFFF), 1> R1; +typedef boost::ratio<1,1> R2; +typedef boost::ratio_subtract<R1, R2>::type RT; diff --git a/src/boost/libs/ratio/test/ratio_arithmetic/ratio_subtract_pass.cpp b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_subtract_pass.cpp new file mode 100644 index 00000000..7fa344e5 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_arithmetic/ratio_subtract_pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_subtract + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + + { + typedef boost::ratio<0> R1; + typedef boost::ratio<0> R2; + typedef boost::ratio_subtract<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 0 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_subtract<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 0 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_subtract<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_subtract<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -3 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::ratio_subtract<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -3 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<-1, 1> R2; + typedef boost::ratio_subtract<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 3 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, -1> R2; + typedef boost::ratio_subtract<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 3 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<56987354, 467584654> R1; + typedef boost::ratio<544668, 22145> R2; + typedef boost::ratio_subtract<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -126708206685271LL && R::den == 5177331081415LL, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_comparison/ratio_equal_pass.cpp b/src/boost/libs/ratio/test/ratio_comparison/ratio_equal_pass.cpp new file mode 100644 index 00000000..355cfa0d --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_comparison/ratio_equal_pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_equal + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_equal<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_comparison/ratio_greater_equal_pass.cpp b/src/boost/libs/ratio/test/ratio_comparison/ratio_greater_equal_pass.cpp new file mode 100644 index 00000000..dbe6a537 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_comparison/ratio_greater_equal_pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1,BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1,BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_greater_equal<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_comparison/ratio_greater_pass.cpp b/src/boost/libs/ratio/test/ratio_comparison/ratio_greater_pass.cpp new file mode 100644 index 00000000..cf34d2f7 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_comparison/ratio_greater_pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_greater<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_comparison/ratio_less_equal_pass.cpp b/src/boost/libs/ratio/test/ratio_comparison/ratio_less_equal_pass.cpp new file mode 100644 index 00000000..9310fd91 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_comparison/ratio_less_equal_pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less_equal<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_comparison/ratio_less_pass.cpp b/src/boost/libs/ratio/test/ratio_comparison/ratio_less_pass.cpp new file mode 100644 index 00000000..652a4743 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_comparison/ratio_less_pass.cpp @@ -0,0 +1,91 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 0x7FFFFFFFFFFFFFFELL> R1; + typedef boost::ratio<0x7FFFFFFFFFFFFFFDLL, 0x7FFFFFFFFFFFFFFCLL> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<0x7FFFFFFFFFFFFFFDLL, 0x7FFFFFFFFFFFFFFCLL> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 0x7FFFFFFFFFFFFFFELL> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-0x7FFFFFFFFFFFFFFDLL, 0x7FFFFFFFFFFFFFFCLL> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 0x7FFFFFFFFFFFFFFELL> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 0x7FFFFFFFFFFFFFFELL> R1; + typedef boost::ratio<0x7FFFFFFFFFFFFFFELL, 0x7FFFFFFFFFFFFFFDLL> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<641981, 1339063> R1; + typedef boost::ratio<1291640, 2694141LL> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1291640, 2694141LL> R1; + typedef boost::ratio<641981, 1339063> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_less<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_comparison/ratio_not_equal_pass.cpp b/src/boost/libs/ratio/test/ratio_comparison/ratio_not_equal_pass.cpp new file mode 100644 index 00000000..c1af8abd --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_comparison/ratio_not_equal_pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include <boost/ratio/ratio.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_not_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_not_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_not_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::ratio_not_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_not_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_not_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_not_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::ratio_not_equal<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_abs_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_abs_pass.cpp new file mode 100644 index 00000000..35d0cea9 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_abs_pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test mpl::abs + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/abs.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + + { + typedef boost::ratio<0> R1; + typedef boost::mpl::abs<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 0 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::mpl::abs<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::mpl::abs<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::mpl::abs<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::mpl::abs<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_arithmetic_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_arithmetic_pass.cpp new file mode 100644 index 00000000..c5e62b26 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_arithmetic_pass.cpp @@ -0,0 +1,13 @@ +//===----------------------------------------------------------------------===// +// Copyright 2011 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/arithmetic.hpp> + +void test() +{ + +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_comparison_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_comparison_pass.cpp new file mode 100644 index 00000000..57750a9c --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_comparison_pass.cpp @@ -0,0 +1,13 @@ +//===----------------------------------------------------------------------===// +// Copyright 2011 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/comparison.hpp> + +void test() +{ + +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_divides_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_divides_pass.cpp new file mode 100644 index 00000000..2afdf9e1 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_divides_pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test mpl::divides + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/divides.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::divides<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::divides<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::divides<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::divides<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<-1, 1> R2; + typedef boost::mpl::divides<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, -1> R2; + typedef boost::mpl::divides<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<56987354, 467584654> R1; + typedef boost::ratio<544668, 22145> R2; + typedef boost::mpl::divides<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 630992477165LL && R::den == 127339199162436LL, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_equal_to_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_equal_to_pass.cpp new file mode 100644 index 00000000..e86c31c7 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_equal_to_pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test mpl::equal_to + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/equal_to.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::equal_to<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_greater_equal_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_greater_equal_pass.cpp new file mode 100644 index 00000000..e9c33060 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_greater_equal_pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/greater_equal.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1,BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1,BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::greater_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::greater_equal<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_greater_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_greater_pass.cpp new file mode 100644 index 00000000..dd910831 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_greater_pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/greater.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::greater<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::greater<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_less_equal_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_less_equal_pass.cpp new file mode 100644 index 00000000..2443c258 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_less_equal_pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/less_equal.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::less_equal<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less_equal<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_less_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_less_pass.cpp new file mode 100644 index 00000000..89032e1c --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_less_pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/less.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 0x7FFFFFFFFFFFFFFELL> R1; + typedef boost::ratio<0x7FFFFFFFFFFFFFFDLL, 0x7FFFFFFFFFFFFFFCLL> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<0x7FFFFFFFFFFFFFFDLL, 0x7FFFFFFFFFFFFFFCLL> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 0x7FFFFFFFFFFFFFFELL> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-0x7FFFFFFFFFFFFFFDLL, 0x7FFFFFFFFFFFFFFCLL> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 0x7FFFFFFFFFFFFFFELL> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 0x7FFFFFFFFFFFFFFELL> R1; + typedef boost::ratio<0x7FFFFFFFFFFFFFFELL, 0x7FFFFFFFFFFFFFFDLL> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<641981, 1339063> R1; + typedef boost::ratio<1291640, 2694141LL> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::less<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1291640, 2694141LL> R1; + typedef boost::ratio<641981, 1339063> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::less<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_minus_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_minus_pass.cpp new file mode 100644 index 00000000..ca335716 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_minus_pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test mpl::minus + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/minus.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::minus<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 0 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::minus<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::minus<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -3 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::minus<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -3 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<-1, 1> R2; + typedef boost::mpl::minus<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 3 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, -1> R2; + typedef boost::mpl::minus<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 3 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<56987354, 467584654> R1; + typedef boost::ratio<544668, 22145> R2; + typedef boost::mpl::minus<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -126708206685271LL && R::den == 5177331081415LL, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_negate_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_negate_pass.cpp new file mode 100644 index 00000000..87f75f30 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_negate_pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test mpl::negate + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/negate.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + + { + typedef boost::ratio<0> R1; + typedef boost::mpl::negate<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 0 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::mpl::negate<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::mpl::negate<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::mpl::negate<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::mpl::negate<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_not_equal_to_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_not_equal_to_pass.cpp new file mode 100644 index 00000000..3e4c662d --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_not_equal_to_pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/not_equal_to.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::not_equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::not_equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::not_equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((!boost::mpl::not_equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, -1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::not_equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::not_equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<-BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::not_equal_to<R1, R2>::value), NOTHING, ()); + } + { + typedef boost::ratio<1, BOOST_RATIO_INTMAX_T_MAX> R1; + typedef boost::ratio<1, -BOOST_RATIO_INTMAX_T_MAX> R2; + BOOST_RATIO_STATIC_ASSERT((boost::mpl::not_equal_to<R1, R2>::value), NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_plus_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_plus_pass.cpp new file mode 100644 index 00000000..ccf03c38 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_plus_pass.cpp @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test mpl::plus + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/plus.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::mpl::int_<1> R2; + typedef boost::mpl::plus<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 2 && R::den == 1, NOTHING, ()); + typedef boost::mpl::plus<R, R2> RR; + BOOST_RATIO_STATIC_ASSERT(RR::num == 3 && RR::den == 1, NOTHING, ()); + } + { + typedef boost::mpl::int_<1> R1; + typedef boost::ratio<1, 2> R2; + typedef boost::mpl::plus<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 3 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::int_<0> R3; + typedef boost::mpl::plus<R1, R2, R3> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::int_<0> R3; + typedef boost::mpl::plus<R1, R2, R3> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<-1, 1> R2; + typedef boost::mpl::int_<0> R3; + typedef boost::mpl::plus<R1, R2, R3> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, -1> R2; + typedef boost::mpl::int_<0> R3; + typedef boost::mpl::plus<R1, R2, R3> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<56987354, 467584654> R1; + typedef boost::ratio<544668, 22145> R2; + typedef boost::mpl::int_<0> R3; + typedef boost::mpl::plus<R1, R2, R3> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 127970191639601LL && R::den == 5177331081415LL, NOTHING, ()); + } + { + typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, 1> R1; + typedef boost::ratio<-1, 1> R2; + typedef boost::mpl::int_<0> R3; + typedef boost::mpl::plus<R1, R2, R3>::type RT; + } + +} + +boost::intmax_t func(boost::ratio<5,6> s) { + return s.num; +} + + +boost::intmax_t test_conversion() { + return func( + boost::mpl::plus< + boost::ratio<1,2>, + boost::ratio<1,3> + > + () + ); +} + diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_rational_constant_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_rational_constant_pass.cpp new file mode 100644 index 00000000..57750a9c --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_rational_constant_pass.cpp @@ -0,0 +1,13 @@ +//===----------------------------------------------------------------------===// +// Copyright 2011 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/comparison.hpp> + +void test() +{ + +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_sign_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_sign_pass.cpp new file mode 100644 index 00000000..f78d2b4f --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_sign_pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test mpl::sign + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/sign.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + + { + typedef boost::ratio<0> R1; + typedef boost::mpl::sign<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::value == 0, NOTHING, ()); + } + { + typedef boost::ratio<1, 1> R1; + typedef boost::mpl::sign<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::value == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::mpl::sign<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::value == 1, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::mpl::sign<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::value == -1, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::mpl::sign<R1> R; + BOOST_RATIO_STATIC_ASSERT(R::value == -1, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/mpl_times_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/mpl_times_pass.cpp new file mode 100644 index 00000000..5f8a2a47 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/mpl_times_pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test mpl::times + +#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/mpl/times.hpp> +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +void test() +{ + { + typedef boost::ratio<1, 1> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::times<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 1, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::times<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<-1, 2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::times<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, -2> R1; + typedef boost::ratio<1, 1> R2; + typedef boost::mpl::times<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<-1, 1> R2; + typedef boost::mpl::times<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<1, 2> R1; + typedef boost::ratio<1, -1> R2; + typedef boost::mpl::times<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == -1 && R::den == 2, NOTHING, ()); + } + { + typedef boost::ratio<56987354, 467584654> R1; + typedef boost::ratio<544668, 22145> R2; + typedef boost::mpl::times<R1, R2> R; + BOOST_RATIO_STATIC_ASSERT(R::num == 15519594064236LL && R::den == 5177331081415LL, NOTHING, ()); + } +} diff --git a/src/boost/libs/ratio/test/ratio_extensions/ratio_ext_pass.cpp b/src/boost/libs/ratio/test/ratio_extensions/ratio_ext_pass.cpp new file mode 100644 index 00000000..a2fccff0 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_extensions/ratio_ext_pass.cpp @@ -0,0 +1,30 @@ +// Copyright 2011 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio: equivalent ratios convert with BOOST_RATIO_EXTENSIONS + +#define BOOST_RATIO_EXTENSIONS +#include <boost/ratio/ratio.hpp> +#include <boost/core/lightweight_test.hpp> + +boost::intmax_t func(boost::ratio<5,6> s); + +boost::intmax_t func(boost::ratio<5,6> s) { + return s.num; +} + +void test(); + +void test() { + boost::ratio<10,12> r; + BOOST_TEST(( + func(r)==5 + )); +} + +int main() +{ + test(); + return boost::report_errors(); +} diff --git a/src/boost/libs/ratio/test/ratio_io/ratio_io_fail.cpp b/src/boost/libs/ratio/test/ratio_io/ratio_io_fail.cpp new file mode 100644 index 00000000..86f37dc2 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_io/ratio_io_fail.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include <boost/ratio/ratio_io.hpp> + +//typedef boost::ratio_string<boost::ratio_add<boost::ratio<1,2>, boost::ratio<1,3> >, char> R1; +typedef boost::ratio_string<int, char> R1; + +void test() { + + std::string str = R1::symbol(); +} diff --git a/src/boost/libs/ratio/test/ratio_io/ratio_io_pass.cpp b/src/boost/libs/ratio/test/ratio_io/ratio_io_pass.cpp new file mode 100644 index 00000000..bcff57c4 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_io/ratio_io_pass.cpp @@ -0,0 +1,171 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio_add + +#define BOOST_RATIO_EXTENSIONS +#include <boost/ratio/ratio_io.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <climits> + +int main() +{ + + { + BOOST_TEST(( + boost::ratio_string<boost::atto, char>::prefix() == "atto" + )); + BOOST_TEST(( + boost::ratio_string<boost::atto, char>::symbol() == "a" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::femto, char>::prefix() == "femto" + )); + BOOST_TEST(( + boost::ratio_string<boost::femto, char>::symbol() == "f" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::pico, char>::prefix() == "pico" + )); + BOOST_TEST(( + boost::ratio_string<boost::pico, char>::symbol() == "p" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::nano, char>::prefix() == "nano" + )); + BOOST_TEST(( + boost::ratio_string<boost::nano, char>::symbol() == "n" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::micro, char>::prefix() == "micro" + )); + BOOST_TEST(( + boost::ratio_string<boost::micro, char>::symbol() == "\xC2\xB5" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::milli, char>::prefix() == "milli" + )); + BOOST_TEST(( + boost::ratio_string<boost::milli, char>::symbol() == "m" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::centi, char>::prefix() == "centi" + )); + BOOST_TEST(( + boost::ratio_string<boost::centi, char>::symbol() == "c" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::deci, char>::prefix() == "deci" + )); + BOOST_TEST(( + boost::ratio_string<boost::deci, char>::symbol() == "d" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::deca, char>::prefix() == "deca" + )); + BOOST_TEST(( + boost::ratio_string<boost::deca, char>::symbol() == "da" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::hecto, char>::prefix() == "hecto" + )); + BOOST_TEST(( + boost::ratio_string<boost::hecto, char>::symbol() == "h" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::kilo, char>::prefix() == "kilo" + )); + BOOST_TEST(( + boost::ratio_string<boost::kilo, char>::symbol() == "k" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::mega, char>::prefix() == "mega" + )); + BOOST_TEST(( + boost::ratio_string<boost::mega, char>::symbol() == "M" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::giga, char>::prefix() == "giga" + )); + BOOST_TEST(( + boost::ratio_string<boost::giga, char>::symbol() == "G" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::tera, char>::prefix() == "tera" + )); + BOOST_TEST(( + boost::ratio_string<boost::tera, char>::symbol() == "T" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::peta, char>::prefix() == "peta" + )); + BOOST_TEST(( + boost::ratio_string<boost::peta, char>::symbol() == "P" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::exa, char>::prefix() == "exa" + )); + BOOST_TEST(( + boost::ratio_string<boost::exa, char>::symbol() == "E" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::kibi, char>::prefix() == "kibi" + )); + BOOST_TEST(( + boost::ratio_string<boost::kibi, char>::symbol() == "Ki" + )); + } + { + BOOST_TEST(( + boost::ratio_string<boost::gibi, char>::prefix() == "gibi" + )); + BOOST_TEST(( + boost::ratio_string<boost::gibi, char>::symbol() == "Gi" + )); + } + return boost::report_errors(); +} + + diff --git a/src/boost/libs/ratio/test/ratio_ratio/ratio1_fail.cpp b/src/boost/libs/ratio/test/ratio_ratio/ratio1_fail.cpp new file mode 100644 index 00000000..17e6f4cd --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_ratio/ratio1_fail.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio: The template argument D mus not be zero + +#include <boost/ratio/ratio.hpp> +#include <boost/cstdint.hpp> + +void test() +{ + const boost::intmax_t t1 = boost::ratio<1, 0>::num; + (void)t1; +} diff --git a/src/boost/libs/ratio/test/ratio_ratio/ratio2_fail.cpp b/src/boost/libs/ratio/test/ratio_ratio/ratio2_fail.cpp new file mode 100644 index 00000000..8f77e644 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_ratio/ratio2_fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio: the absolute values of the template arguments N and D +// must be representable by type intmax_t. + +#include <boost/ratio/ratio.hpp> +#include <cstdint> + +void test() +{ + const boost::intmax_t t1 = boost::ratio<0x8000000000000000ULL, 1>::num; + (void)t1; +} diff --git a/src/boost/libs/ratio/test/ratio_ratio/ratio3_fail.cpp b/src/boost/libs/ratio/test/ratio_ratio/ratio3_fail.cpp new file mode 100644 index 00000000..86cd165f --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_ratio/ratio3_fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio: the absolute values of the template arguments N and D +// must be representable by type intmax_t. + +#include <boost/ratio/ratio.hpp> +#include <boost/cstdint.hpp> + +void test() +{ + const boost::intmax_t t1 = boost::ratio<1, 0x8000000000000000ULL>::num; + (void)t1; +} diff --git a/src/boost/libs/ratio/test/ratio_ratio/ratio4_fail.cpp b/src/boost/libs/ratio/test/ratio_ratio/ratio4_fail.cpp new file mode 100644 index 00000000..73af1799 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_ratio/ratio4_fail.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +//#define BOOST_RATIO_EXTENSIONS + +#include <boost/ratio/ratio.hpp> + +boost::intmax_t func(boost::ratio<5,6> const& s) { + return s.num; +} + +boost::intmax_t test() { + return func(boost::ratio<10,12>()); +} + diff --git a/src/boost/libs/ratio/test/ratio_ratio/ratio_pass.cpp b/src/boost/libs/ratio/test/ratio_ratio/ratio_pass.cpp new file mode 100644 index 00000000..fb52ac96 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_ratio/ratio_pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio: The static data members num and den shall have thcommon +// divisor of the absolute values of N and D: + +#include <boost/ratio/ratio.hpp> + +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +template <long long N, long long D, long long eN, long long eD> +void test() +{ + BOOST_RATIO_STATIC_ASSERT((boost::ratio<N, D>::num == eN), NOTHING, (boost::mpl::integral_c<boost::intmax_t,boost::ratio<N, D>::num>)); + BOOST_RATIO_STATIC_ASSERT((boost::ratio<N, D>::den == eD), NOTHING, (boost::mpl::integral_c<boost::intmax_t,boost::ratio<N, D>::den>)); +} + +int main() +{ + test<1, 1, 1, 1>(); + test<1, 10, 1, 10>(); + test<10, 10, 1, 1>(); + test<10, 1, 10, 1>(); + test<12, 4, 3, 1>(); + test<12, -4, -3, 1>(); + test<-12, 4, -3, 1>(); + test<-12, -4, 3, 1>(); + test<4, 12, 1, 3>(); + test<4, -12, -1, 3>(); + test<-4, 12, -1, 3>(); + test<-4, -12, 1, 3>(); + test<222, 333, 2, 3>(); + test<222, -333, -2, 3>(); + test<-222, 333, -2, 3>(); + test<-222, -333, 2, 3>(); + //test<BOOST_RATIO_INTMAX_T_MAX, 127, 72624976668147841LL, 1>(); + //test<-BOOST_RATIO_INTMAX_T_MAX, 127, -72624976668147841LL, 1>(); + //test<BOOST_RATIO_INTMAX_T_MAX, -127, -72624976668147841LL, 1>(); + //test<-BOOST_RATIO_INTMAX_T_MAX, -127, 72624976668147841LL, 1>(); + //~ test<BOOST_RATIO_INTMAX_T_MAX, 127, BOOST_RATIO_INTMAX_T_MAX, 127>(); + //~ test<-BOOST_RATIO_INTMAX_T_MAX, 127, -BOOST_RATIO_INTMAX_T_MAX, 127>(); + //~ test<BOOST_RATIO_INTMAX_T_MAX, -127, -BOOST_RATIO_INTMAX_T_MAX, 127>(); + //~ test<-BOOST_RATIO_INTMAX_T_MAX, -127, BOOST_RATIO_INTMAX_T_MAX, 127>(); +} diff --git a/src/boost/libs/ratio/test/ratio_test.cpp b/src/boost/libs/ratio/test/ratio_test.cpp new file mode 100644 index 00000000..380e1376 --- /dev/null +++ b/src/boost/libs/ratio/test/ratio_test.cpp @@ -0,0 +1,36 @@ +// 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 <boost/ratio/ratio.hpp> +#include <iostream> + +typedef boost::ratio<5, 3> five_thirds; // five_thirds::num == 5, five_thirds::den == 3 +typedef boost::ratio<25, 15> also_five_thirds; // also_five_thirds::num == 5, also_five_thirds::den == 3 +typedef boost::ratio_divide<five_thirds, also_five_thirds>::type one; // one::num == 1, one::den == 1 + + +typedef boost::ratio_multiply<boost::ratio<5>, boost::giga>::type _5giga; // _5giga::num == 5000000000, _5giga::den == 1 +typedef boost::ratio_multiply<boost::ratio<5>, boost::nano>::type _5nano; // _5nano::num == 1, _5nano::den == 200000000 + +// Test the case described in library working group issue 948. + +typedef boost::ratio<BOOST_RATIO_INTMAX_T_MAX, BOOST_RATIO_INTMAX_T_MAX-16> R1; +typedef boost::ratio<8, 7> R2; +typedef boost::ratio_multiply<R1, R2>::type RT; + + + +int main() +{ + typedef boost::ratio<8, BOOST_RATIO_INTMAX_C(0x7FFFFFFFD)> R1; + typedef boost::ratio<3, BOOST_RATIO_INTMAX_C(0x7FFFFFFFD)> R2; + typedef boost::ratio_subtract<R1, R2>::type RS; + std::cout << RS::num << '/' << RS::den << '\n'; + + return 0; +} diff --git a/src/boost/libs/ratio/test/test_cmake/CMakeLists.txt b/src/boost/libs/ratio/test/test_cmake/CMakeLists.txt new file mode 100644 index 00000000..c23df6b2 --- /dev/null +++ b/src/boost/libs/ratio/test/test_cmake/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright 2018 Mike Dev +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required(VERSION 3.5) +# NOTE: Individual boost cmake files might require a higher cmake version + +project(boost LANGUAGES CXX) + +#=== options === + +# Some libraries' cmake files don't work well with this cmake file, e.g. because +# - they are generally not designed to support the add_subdirectory workflow at all +# - they define targets with conflicting names (e.g. check) +# - require some additional (internal or external) dependencies +# +# Those libraries can be excluded here +set(BOOST_RATIO_IGNORE_LIBS callable_traits;hof;compute;gil;hana;yap;safe_numerics;beast CACHE STRING "List of libraries that will be excluded from cmake build") + + +#~~~ options ~~~ +message(STATUS "[Boost] Excluded libs (BOOST_RATIO_IGNORE_LIBS): ${BOOST_RATIO_IGNORE_LIBS}") + +# cmake doesn't require autolinking and currently most cmake files don't produce +# name mangled libraries anyway +add_definitions(-DBOOST_ALL_NO_LIB) +enable_testing() + +# Detect and process all CMakeLists files that reside in the root folder of a library +file(GLOB boost_libs_with_cmake_files ../../../../libs/*/CMakeLists.txt) + +foreach(cmake_file IN LISTS boost_libs_with_cmake_files) + + get_filename_component(dir ${cmake_file} DIRECTORY) + get_filename_component(lib_name ${dir} NAME) + if(NOT lib_name IN_LIST BOOST_RATIO_IGNORE_LIBS) + add_subdirectory(${dir} ${lib_name}) + endif() + +endforeach()
\ No newline at end of file diff --git a/src/boost/libs/ratio/test/typedefs_pass.cpp b/src/boost/libs/ratio/test/typedefs_pass.cpp new file mode 100644 index 00000000..da7c4ba2 --- /dev/null +++ b/src/boost/libs/ratio/test/typedefs_pass.cpp @@ -0,0 +1,29 @@ +// Copyright 2010 Vicente J. Botet Escriba +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// test ratio typedef's + +#include <boost/ratio/ratio.hpp> + +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) +#define NOTHING "" +#endif + +BOOST_RATIO_STATIC_ASSERT(boost::atto::num == 1 && boost::atto::den == 1000000000000000000ULL, NOTHING, (boost::mpl::integral_c<boost::intmax_t,boost::atto::den>)); +BOOST_RATIO_STATIC_ASSERT(boost::femto::num == 1 && boost::femto::den == 1000000000000000ULL, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::pico::num == 1 && boost::pico::den == 1000000000000ULL, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::nano::num == 1 && boost::nano::den == 1000000000ULL, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::micro::num == 1 && boost::micro::den == 1000000ULL, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::milli::num == 1 && boost::milli::den == 1000ULL, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::centi::num == 1 && boost::centi::den == 100ULL, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::deci::num == 1 && boost::deci::den == 10ULL, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::deca::num == 10ULL && boost::deca::den == 1, NOTHING, (boost::mpl::integral_c<boost::intmax_t,boost::deca::den>)); +BOOST_RATIO_STATIC_ASSERT(boost::hecto::num == 100ULL && boost::hecto::den == 1, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::kilo::num == 1000ULL && boost::kilo::den == 1, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::mega::num == 1000000ULL && boost::mega::den == 1, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::giga::num == 1000000000ULL && boost::giga::den == 1, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::tera::num == 1000000000000ULL && boost::tera::den == 1, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::peta::num == 1000000000000000ULL && boost::peta::den == 1, NOTHING, ()); +BOOST_RATIO_STATIC_ASSERT(boost::exa::num == 1000000000000000000ULL && boost::exa::den == 1, NOTHING, ()); + diff --git a/src/boost/libs/rational/CMakeLists.txt b/src/boost/libs/rational/CMakeLists.txt new file mode 100644 index 00000000..f4b66bd2 --- /dev/null +++ b/src/boost/libs/rational/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright 2019 Mike Dev +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt +# +# NOTE: CMake support for Boost.Rational is currently experimental at best +# and the interface is likely to change in the future + +cmake_minimum_required( VERSION 3.5 ) +project( BoostRational LANGUAGES CXX) +option( BOOST_RATIONAL_INCLUDE_TESTS "Add boost rational tests" OFF ) + +add_library( boost_rational INTERFACE ) +add_library( Boost::rational ALIAS boost_rational ) + +target_include_directories( boost_rational INTERFACE include ) + +target_link_libraries( boost_rational + INTERFACE + Boost::assert + Boost::config + Boost::core + Boost::integer + Boost::static_assert + Boost::throw_exception + Boost::type_traits + Boost::utility +) + +if( BOOST_RATIONAL_INCLUDE_TESTS ) + enable_testing() + add_subdirectory( test ) +endif() + diff --git a/src/boost/libs/rational/Jamfile b/src/boost/libs/rational/Jamfile new file mode 100644 index 00000000..facdaeec --- /dev/null +++ b/src/boost/libs/rational/Jamfile @@ -0,0 +1,10 @@ +# Boost.Rational Library Jamfile +# +# Copyright (c) 2018 James E. King III +# +# Use, modification, and distribution are subject to 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) + +# please order by name to ease maintenance +build-project test ; diff --git a/src/boost/libs/rational/LICENSE b/src/boost/libs/rational/LICENSE new file mode 100644 index 00000000..36b7cd93 --- /dev/null +++ b/src/boost/libs/rational/LICENSE @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/boost/libs/rational/README.md b/src/boost/libs/rational/README.md new file mode 100644 index 00000000..ed1608c2 --- /dev/null +++ b/src/boost/libs/rational/README.md @@ -0,0 +1,32 @@ +Rational, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), provides an implementation of rational numbers. + +### License + +Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). + +### Properties + +* C++03 +* Header-Only + +### Build Status + +Branch | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests | +:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- | +[`master`](https://github.com/boostorg/rational/tree/master) | [![Build Status](https://travis-ci.org/boostorg/rational.svg?branch=master)](https://travis-ci.org/boostorg/rational) | [![Build status](https://ci.appveyor.com/api/projects/status/8a2on7yb2xck80fa/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/rational-lqu73/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16002/badge.svg)](https://scan.coverity.com/projects/boostorg-rational) | [![codecov](https://codecov.io/gh/boostorg/rational/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/rational/branch/master)| [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/rational.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/rational.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/rational.html) +[`develop`](https://github.com/boostorg/rational/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/rational.svg?branch=develop)](https://travis-ci.org/boostorg/rational) | [![Build status](https://ci.appveyor.com/api/projects/status/8a2on7yb2xck80fa/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/rational-lqu73/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16002/badge.svg)](https://scan.coverity.com/projects/boostorg-rational) | [![codecov](https://codecov.io/gh/boostorg/rational/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/rational/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/rational.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/rational.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/rational.html) + +### Directories + +| Name | Purpose | +| ----------- | ------------------------------ | +| `include` | header | +| `test` | unit tests | + +### More information + +* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-rational) +* [Report bugs](https://github.com/boostorg/rational/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. +* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). +* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[rational]` tag at the beginning of the subject line. + diff --git a/src/boost/libs/rational/index.html b/src/boost/libs/rational/index.html new file mode 100644 index 00000000..3f3d676e --- /dev/null +++ b/src/boost/libs/rational/index.html @@ -0,0 +1,47 @@ +<html> + +<head> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +<title>Boost Rational Number Library</title> +</head> + +<body bgcolor="#FFFFFF" text="#000000"> + +<table border="1" bgcolor="#007F7F" cellpadding="2"> + <tr> + <td bgcolor="#FFFFFF"><img src="../../boost.png" alt="boost.png (6897 bytes)" WIDTH="277" HEIGHT="86"></td> + <td><a href="../../index.htm"><font face="Arial" color="#FFFFFF"><big>Home </big></font></a></td> + <td><a href="../libraries.htm"><font face="Arial" color="#FFFFFF"><big>Libraries </big></font></a></td> + <td><a href="http://www.boost.org/people/people.htm"><font face="Arial" color="#FFFFFF"><big>People </big></font></a></td> + <td><a href="http://www.boost.org/more/faq.htm"><font face="Arial" color="#FFFFFF"><big>FAQ </big></font></a></td> + <td><a href="../../more/index.htm"><font face="Arial" color="#FFFFFF"><big>More </big></font></a></td> + </tr> +</table> + +<h1>Rational Number library</h1> + +<p>The header rational.hpp provides an implementation of rational numbers. +The implementation is template-based, in a similar manner to the standard +complex number class.</p> + +<p>This implementation is intended for general use. If you are a number +theorist, or otherwise have very stringent requirements, you would be advised +to use one of the more specialist packages available.</p> + +<ul> + <li><a href="rational.html">Documentation</a> (HTML).</li> + <li>Header <a href="../../boost/rational.hpp">rational.hpp</a>.</li> + <li>See the <a href="rational.html">documentation</a> for links to sample programs.</li> + <li>Submitted by <a href="http://www.boost.org/people/paul_moore.htm"> Paul Moore</a>.</li> +</ul> + +<p>Revised December 14, 1999</p> + +<p>© Copyright Paul Moore 1999. Permission to copy, use, modify, sell +and distribute this document is granted provided this copyright notice +appears in all copies. This document is provided "as is" without +express or implied warranty, and with no claim as to its suitability for +any purpose.</p> +<!-- boostinspect:nolicense (can't find Paul Moore to change license) --> +</body> +</html> diff --git a/src/boost/libs/rational/meta/libraries.json b/src/boost/libs/rational/meta/libraries.json new file mode 100644 index 00000000..471b2429 --- /dev/null +++ b/src/boost/libs/rational/meta/libraries.json @@ -0,0 +1,14 @@ +{ + "key": "rational", + "name": "Rational", + "authors": [ + "Paul Moore" + ], + "description": "A rational number class.", + "category": [ + "Math" + ], + "maintainers": [ + "Jonathan Turkanis <turkanis -at- coderage.com>" + ] +} diff --git a/src/boost/libs/rational/rational.html b/src/boost/libs/rational/rational.html new file mode 100644 index 00000000..ebacab7f --- /dev/null +++ b/src/boost/libs/rational/rational.html @@ -0,0 +1,768 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +<title>Rational Number Library</title> +</head> +<body> +<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" + align="middle" width="277" height="86"> +Rational Numbers</h1> + +<h2><a name="Contents">Contents</a></h2> + +<ol> + <li><a href="#Class%20rational%20synopsis">Class rational synopsis</a></li> + <li><a href="#Rationale">Rationale</a></li> + <li><a href="#Background">Background</a></li> + <li><a href="#Integer%20Type%20Requirements">Integer Type Requirements</a></li> + <li><a href="#Interface">Interface</a> + <ul> + <li><a href="#Utility%20functions">Utility functions</a></li> + <li><a href="#Constructors">Constructors</a></li> + <li><a href="#Arithmetic%20operations">Arithmetic operations</a></li> + <li><a href="#Input%20and%20Output">Input and Output</a></li> + <li><a href="#In-place%20assignment">In-place assignment</a></li> + <li><a href="#Conversions">Conversions</a></li> + <li><a href="#Numerator%20and%20Denominator">Numerator and Denominator</a></li> + </ul></li> + <li><a href="#Performance">Performance</a></li> + <li><a href="#Exceptions">Exceptions</a></li> + <li><a href="#Internal%20representation">Internal representation</a></li> + <li><a href="#Design%20notes">Design notes</a> + <ul> + <li><a href="#Minimal%20Implementation">Minimal Implementation</a></li> + <li><a href="#Limited-range%20integer%20types">Limited-range integer types</a></li> + <li><a href="#Conversion%20from%20floating%20point">Conversion from floating point</a></li> + <li><a href="#Absolute%20Value">Absolute Value</a></li> + </ul></li> + <li><a href="#References">References</a></li> + <li><a href="#History%20and%20Acknowledgements">History and Acknowledgements</a></li> +</ol> + +<h2><a name="Class rational synopsis">Class rational synopsis</a></h2> +<pre> +#include <boost/rational.hpp> + +namespace boost { + +class bad_rational; + +template<typename I> class rational { + typedef <em>implementation-defined</em> bool_type; + +public: + typedef I int_type; + + // Constructors + rational(); // Zero; constexpr since C++11 + rational(I n); // Equal to n/1; constexpr since C++11 + rational(I n, I d); // General case (n/d); constexpr since C++14 + template<typename J> + explicit rational(const rational<J> &r); // Cross-instantiation; constexpr since C++11 + + // Normal copy constructors and assignment operators + + // Assignment from I + rational& operator=(I n); // constexpr since C++14 + + // Assign in place + rational& assign(I n, I d); // constexpr since C++14 + + // Representation + I numerator() const; // constexpr since C++11 + I denominator() const; // constexpr since C++11 + + // In addition to the following operators, all of the "obvious" derived + // operators are available - see <a href="../utility/operators.htm">operators.hpp</a> + + // Arithmetic operators + rational& operator+= (const rational& r); // constexpr since C++14 + rational& operator-= (const rational& r); // constexpr since C++14 + rational& operator*= (const rational& r); // constexpr since C++14 + rational& operator/= (const rational& r); // constexpr since C++14 + + // Arithmetic with integers + rational& operator+= (I i); // constexpr since C++14 + rational& operator-= (I i); // constexpr since C++14 + rational& operator*= (I i); // constexpr since C++14 + rational& operator/= (I i); // constexpr since C++14 + + // Increment and decrement + const rational& operator++(); // constexpr since C++14 + const rational& operator--(); // constexpr since C++14 + + // Operator not + bool operator!() const; // constexpr since C++11 + + // Boolean conversion + operator bool_type() const; // constexpr since C++11 + + // Comparison operators + bool operator< (const rational& r) const; // constexpr since C++14 + bool operator== (const rational& r) const; // constexpr since C++11 + + // Comparison with integers + bool operator< (I i) const; // constexpr since C++14 + bool operator> (I i) const; // constexpr since C++14 + bool operator== (I i) const; // constexpr since C++11 +}; + +// Unary operators +template <typename I> rational<I> operator+ (const rational<I>& r); // constexpr since C++11 +template <typename I> rational<I> operator- (const rational<I>& r); // constexpr since C++14 + +// Reversed order operators for - and / between (types convertible to) I and rational +template <typename I, typename II> inline rational<I> operator- (II i, const rational<I>& r); // constexpr since C++14 +template <typename I, typename II> inline rational<I> operator/ (II i, const rational<I>& r); // constexpr since C++14 + +// Absolute value +template <typename I> rational<I> abs (const rational<I>& r); // constexpr since C++14 + +// Input and output +template <typename I> std::istream& operator>> (std::istream& is, rational<I>& r); +template <typename I> std::ostream& operator<< (std::ostream& os, const rational<I>& r); + +// Type conversion +template <typename T, typename I> T rational_cast (const rational<I>& r); // constexpr since C++11 +</pre> + +<h2><a name="Rationale">Rationale</a></h2> + +Numbers come in many different forms. The most basic forms are natural numbers +(non-negative "whole" numbers), integers and real numbers. These types are +approximated by the C++ built-in types <b>unsigned int</b>, <b>int</b>, and +<b>float</b> (and their various equivalents in different sizes). + +<p>The C++ Standard Library extends the range of numeric types available by +providing the <b>complex</b> type. + +<p>This library provides a further numeric type, the <b>rational</b> numbers. + +<p>The <b>rational</b> class is actually a implemented as a template, in a +similar manner to the standard <b>complex</b> class. + +<h2><a name="Background">Background</a></h2> + +The mathematical concept of a rational number is what is commonly thought of +as a fraction - that is, a number which can be represented as the ratio of two +integers. This concept is distinct from that of a real number, which can take +on many more values (for example, the square root of 2, which cannot be +represented as a fraction). + +<p> +Computers cannot represent mathematical concepts exactly - there are always +compromises to be made. Machine integers have a limited range of values (often +32 bits), and machine approximations to reals are limited in precision. The +compromises have differing motivations - machine integers allow exact +calculation, but with a limited range, whereas machine reals allow a much +greater range, but at the expense of exactness. + +<p> +The rational number class provides an alternative compromise. Calculations +with rationals are exact, but there are limitations on the available range. To +be precise, rational numbers are exact as long as the numerator and +denominator (which are always held in normalized form, with no common factors) +are within the range of the underlying integer type. When values go outside +these bounds, overflow occurs and the results are undefined. + +<p> +The rational number class is a template to allow the programmer to control the +overflow behaviour somewhat. If an unlimited precision integer type is +available, rational numbers based on it will never overflow (modulo resource +limits) and will provide exact calculations in all circumstances. + +<h2><a name="Integer Type Requirements">Integer Type Requirements</a></h2> + +<p> The rational type takes a single template type parameter I. This is the +<em>underlying integer type</em> for the rational type. Any of the built-in +integer types provided by the C++ implementation are supported as values for +I. User-defined types may also be used, but users should be aware that the +performance characteristics of the rational class are highly dependent upon +the performance characteristics of the underlying integer type (often in +complex ways - for specific notes, see the <a href="#Performance">Performance</a> +section below). Note: Should the boost library support an unlimited-precision +integer type in the future, this type will be fully supported as the underlying +integer type for the rational class. +</p> + +<p> +A user-defined integer type which is to be used as the underlying integer type +for the rational type must be a model of the following concepts. +</p> + +<ul> +<li>Assignable +<li>Default Constructible +<li>Equality Comparable +<li>LessThan Comparable +</ul> + +<p> +Furthermore, I must be an <em>integer-like</em> type, that is the following +expressions must be valid for any two values n and m of type I, with the +"expected" semantics. + +<ul> +<li><code>n + m</code> +<li><code>n - m</code> +<li><code>n * m</code> +<li><code>n / m</code> (must truncate; must be nonnegative if <var>n</var> and + <var>m</var> are positive) +<li><code>n % m</code> (must be nonnegative if <var>n</var> and <var>m</var> + are positive) +<li>Assignment versions of the above +<li><code>+n</code>, <code>-n</code> +<li><code>!n</code> (must be <code>true</code> iff <var>n</var> is zero) +</ul> + +<p> +There must be <em>zero</em> and <em>one</em> values available for I. It should +be possible to generate these as <tt>I(0)</tt> and <tt>I(1)</tt>, +respectively. <em>Note:</em> This does not imply that I needs to have an +implicit conversion from integer - an <tt>explicit</tt> constructor is +adequate. + +<p> +It is valid for I to be an unsigned type. In that case, the derived rational +class will also be unsigned. Underflow behaviour of subtraction, where results +would otherwise be negative, is unpredictable in this case. + +<ul> +<li> +The implementation of rational_cast<T>(rational<I>) relies on the +ability to static_cast from type I to type T, and on the expression x/y being +valid for any two values of type T. +<li> +The input and output operators rely on the existence of corresponding input +and output operators for type I. +</ul> + +<p> +The <code>std::numeric_limits<I></code> specialization must exist (and be +visible before <code>boost::rational<I></code> needs to be specified). +The value of its <code>is_specialized</code> static data member must be +<var>true</var> and the value of its <code>is_signed</code> static data member +must be accurate. + +<h2><a name="Interface">Interface</a></h2> + +<h3><a name="Utility functions">Utility functions</a></h3> + +<p>Two utility function templates may be provided, that should work with <a +href="#Integer%20Type%20Requirements">any type that can be used</a> with the +<code>boost::rational<></code> class template.</p> + +<table summary="Common-factor utility functions"> +<tr> +<td width=5%></td> +<td><tt>gcd(n, m)</tt></td> +<td width=5%></td> +<td>The greatest common divisor of n and m</td> +</tr> +<tr> +<td width=5%></td> +<td><tt>lcm(n, m)</tt></td> +<td width=5%></td> +<td>The least common multiple of n and m</td> +</tr> +</table> + +<p>These function templates now forward calls to their equivalents in the <a +href="../integer/">Boost.Integer library</a>. Their presence can be controlled at +compile time with the <code>BOOST_CONTROL_RATIONAL_HAS_GCD</code> preprocessor +constant. + +<h3><a name="Constructors">Constructors</a></h3> +<p>Rationals can be constructed from zero, one, or two integer arguments; +representing default construction as zero, conversion from an integer posing as +the numerator with an implicit denominator of one, or a numerator and +denominator pair in that order, respectively. An integer argument should be of +the rational's integer type, or implicitly convertible to that type. (For the +two-argument constructor, any needed conversions are evaluated independently, +of course.) The components are stored in normalized form. + +<p>Rationals can also be constructed from another rational. When the source and +destination underlying integer types match, the automatically-defined copy- or +move-constructor is used. Otherwise, a converting constructor template is used. +The constructor does member-wise initialization of the numerator and denominator. +Component-level conversions that are marked <code>explicit</code> are fine. When +the conversion ends up value-preserving, it is already normalized; but a check +for normalization is performed in case value-preservation is violated. + +<p>These imply that the following statements are valid: + +<pre> + I n, d; + rational<I> zero; + rational<I> r1(n); + rational<I> r2(n, d); + rational<J> r3(r2); // assuming J(n) and J(d) are well-formed +</pre> + +<p>In C++11, the no-argument constructor, single-argument constructor, and +cross-version constructor template are marked as <code>constexpr</code>, making +them viable in constant-expressions when the initializers (if any) are also constant +expressions (and the necessary operations from the underlying integer type(s) +are <code>constexpr</code>-enabled). Since C++14, all constructors are +<code>constexpr</code>-enabled. + +<p>The single-argument constructor is <em>not</em> declared as explicit, so +there is an implicit conversion from the underlying integer type to the +rational type. The two-argument constructor can be considered an implicit +conversion with C++11's uniform initialization syntax, since it is also not +declared explicit. The cross-version constructor template is declared explicit, +so the direction of conversion between two rational instantiations must be +specified. + +<h3><a name="Arithmetic operations">Arithmetic operations</a></h3> +All of the standard numeric operators are defined for the <b>rational</b> +class. These include: +<br> + +<pre> + + += + - -= + * *= + / /= + ++ -- (both prefix and postfix) + == != + < > + <= >= + + Unary: + - ! +</pre> + +<p>Since C++14, all of these operations are <code>constexpr</code>-enabled. +In C++11, only <code>operator==</code>, <code>operator!=</code>, +unary <code>operator+</code>, and <code>operator!</code> are. + +<h3><a name="Input and Output">Input and Output</a></h3> +Input and output operators <tt><<</tt> and <tt>>></tt> +are provided. The external representation of a rational is +two integers, separated by a slash (<tt>/</tt>). On input, the format must be +exactly an integer, followed with no intervening whitespace by a slash, +followed (again with no intervening whitespace) by a second integer. The +external representation of an integer is defined by the underlying integer +type. + +<h3><a name="In-place assignment">In-place assignment</a></h3> +For any <tt>rational<I> r</tt>, <tt>r.assign(n, m)</tt> provides an +alternate to <tt>r = rational<I>(n, m);</tt>, without a user-specified +construction of a temporary. While this is probably unnecessary for rationals +based on machine integer types, it could offer a saving for rationals based on +unlimited-precision integers, for example. + +<p>The function will throw if the given components cannot be formed into a valid +rational number. Otherwise, it could throw only if the component-level move +assignment (in C++11; copy-assignment for earlier C++ versions) can throw. The +strong guarantee is kept if throwing happens in the first part, but there is a +risk of neither the strong nor basic guarantees happening if an exception is +thrown during the component assignments. + +<h3><a name="Conversions">Conversions</a></h3> +<p>There is a conversion operator to an unspecified Boolean type (most likely a +member pointer). This operator converts a rational to <code>false</code> if it +represents zero, and <code>true</code> otherwise. This conversion allows a +rational for use as the first argument of operator <code>?:</code>; as either +argument of operators <code>&&</code> or <code>||</code> without +forfeiting short-circuit evaluation; as a condition for a <code>do</code>, +<code>if</code>, <code>while</code>, or <code>for</code> statement; and as a +conditional declaration for <code>if</code>, <code>while</code>, or +<code>for</code> statements. The nature of the type used, and that any names +for that nature are kept private, should prevent any inappropriate non-Boolean +use like numeric or pointer operations or as a <code>switch</code> condition. + +<p>There are <em>no other</em> implicit conversions from a rational +type. Besides the explicit cross-version constructor template, there is an +explicit type-conversion function, <tt>rational_cast<T>(r)</tt>. This can +be used as follows: + +<pre> + rational<int> r(22,7); + double nearly_pi = boost::rational_cast<double>(r); +</pre> + +<p>The <tt>rational_cast<T></tt> function's behaviour is undefined if the +source rational's numerator or denominator cannot be safely cast to the +appropriate floating point type, or if the division of the numerator and +denominator (in the target floating point type) does not evaluate correctly. +Also, since this function has a custom name, it cannot be called in generic code +for trading between two instantiations of the same class template, unlike the +cross-version constructor. + +<p>In essence, all required conversions should be value-preserving, and all +operations should behave "sensibly". If these constraints cannot be met, a +separate user-defined conversion will be more appropriate. + +<p>Boolean conversion and <tt>rational_cast</tt> are <code>constexpr</code>-enabled. + +<p><em>Implementation note:</em> + +<p>The implementation of the rational_cast function was + +<pre> + template <typename Float, typename Int> + Float rational_cast(const rational<Int>& src) + { + return static_cast<Float>(src.numerator()) / src.denominator(); + } +</pre> + +Programs should not be written to depend upon this implementation, however, +especially since this implementation is now obsolete. (It required a mixed-mode +division between types <var>Float</var> and <var>Int</var>, contrary to the <a +href="#Integer%20Type%20Requirements">Integer Type Requirements</a>.) + +<h3><a name="Numerator and Denominator">Numerator and Denominator</a></h3> +Finally, access to the internal representation of rationals is provided by +the two member functions <tt>numerator()</tt> and <tt>denominator()</tt>. +These functions are <code>constexpr</code>-enabled. + +<p>These functions allow user code to implement any additional required +functionality. In particular, it should be noted that there may be cases where +the above rational_cast operation is inappropriate - particularly in cases +where the rational type is based on an unlimited-precision integer type. In +this case, a specially-written user-defined conversion to floating point will +be more appropriate. + +<h2><a name="Performance">Performance</a></h2> +The rational class has been designed with the implicit assumption that the +underlying integer type will act "like" the built in integer types. The +behavioural aspects of this assumption have been explicitly described above, +in the <a href="#Integer%20Type%20Requirements">Integer Type Requirements</a> +section. However, in addition to behavioural assumptions, there are implicit +performance assumptions. + +<p> No attempt will be made to provide detailed performance guarantees for the +operations available on the rational class. While it is possible for such +guarantees to be provided (in a similar manner to the performance +specifications of many of the standard library classes) it is by no means +clear that such guarantees will be of significant value to users of the +rational class. Instead, this section will provide a general discussion of the +performance characteristics of the rational class. + +<p>There now follows a list of the fundamental operations defined in the +<a href="../../boost/rational.hpp"> <boost/rational.hpp></a> header +and an informal description of their performance characteristics. Note that +these descriptions are based on the current implementation, and as such should +be considered subject to change. + +<ul> +<li>Construction of a rational is essentially just two constructions of the +underlying integer type, plus a normalization. + +<li>Increment and decrement operations are essentially as cheap as addition and +subtraction on the underlying integer type. + +<li>(In)equality comparison is essentially as cheap as two equality operations +on the underlying integer type. + +<li>I/O operations are not cheap, but their performance is essentially +dominated by the I/O time itself. + +<li>An (implicit) GCD routine call is essentially a repeated modulus operation. +Its other significant operations are construction, assignment, and comparison +against zero of IntType values. These latter operations are assumed to be +trivial in comparison with the modulus operation. + +<li>The (implicit) LCM operation is essentially a GCD plus a multiplication, +division, and comparison. + +<li>The addition and subtraction operations are complex. They will require +approximately two gcd operations, 3 divisions, 3 multiplications and an +addition on the underlying integer type. + +<li>The multiplication and division operations require two gcd operations, two +multiplications, and four divisions. + +<li>The compare-with-integer operation does a single integer division & +modulus pair, at most one extra integer addition and decrement, and at most +three integer comparisons. + +<li>The compare-with-rational operation does two double-sized GCD operations, +two extra additions and decrements, and three comparisons in the worst case. +(The GCD operations are double-sized because they are done in piecemeal and the +interim quotients are retained and compared, whereas a direct GCD function only +retains and compares the remainders.) + +<li>The final fundamental operation is normalizing a rational. This operation +is performed whenever a rational is constructed (and assigned in place). All +other operations are careful to maintain rationals in a normalized state. +Normalization costs the equivalent of one gcd and two divisions. +</ul> + +<p>Note that it is implicitly assumed that operations on IntType have the +"usual" performance characteristics - specifically, that the expensive +operations are multiplication, division, and modulo, with addition and +subtraction being significantly cheaper. It is assumed that construction (from +integer literals 0 and 1, and copy construction) and assignment are relatively +cheap, although some effort is taken to reduce unnecessary construction and +copying. It is also assumed that comparison (particularly against zero) is +cheap. + +<p>Integer types which do not conform to these assumptions will not be +particularly effective as the underlying integer type for the rational class. +Specifically, it is likely that performance will be severely sub-optimal. + +<h2><a name="Exceptions">Exceptions</a></h2> +Rationals can never have a denominator of zero. (This library does not support +representations for infinity or NaN). Should a rational result ever generate a +denominator of zero, or otherwise fail during normalization, the exception +<tt>boost::bad_rational</tt> (a subclass of <tt>std::domain_error</tt>) is +thrown. This should only occur if the user attempts to explicitly construct a +rational with a denominator of zero, to divide a rational by a zero value, or +generate a negative denominator too large to be normalized. The exception can +be thrown during a cross-instantiation conversion, when at least one of the +components ends up not being value-preserved and the new combination is not +considered normalized. + +<p>In addition, if operations on the underlying integer type can generate +exceptions, these will be propagated out of the operations on the rational +class. No particular assumptions should be made - it is only safe to assume +that any exceptions which can be thrown by the integer class could be thrown +by any rational operation. In particular, the rational constructor may throw +exceptions from the underlying integer type as a result of the normalization +step. The only exception to this rule is that the rational destructor will +only throw exceptions which can be thrown by the destructor of the underlying +integer type (usually none). + +<p>If the component-level assignment operator(s) can throw, then a rational +object's invariants may be violated if an exception happens during the second +component's assignment. (The <code>assign</code> member function counts here +too.) This violates both the strong and basic guarantees. + +<h2><a name="Internal representation">Internal representation</a></h2> +<em>Note:</em> This information is for information only. Programs should not +be written in such a way as to rely on these implementation details. + +<p>Internally, rational numbers are stored as a pair (numerator, denominator) +of integers (whose type is specified as the template parameter for the +rational type). Rationals are always stored in fully normalized form (ie, +gcd(numerator,denominator) = 1, and the denominator is always positive). + +<h2><a name="Design notes">Design notes</a></h2> +<h3><a name="Minimal Implementation">Minimal Implementation</a></h3> +The rational number class is designed to keep to the basics. The minimal +operations required of a numeric class are provided, along with access to the +underlying representation in the form of the numerator() and denominator() +member functions. With these building-blocks, it is possible to implement any +additional functionality required. + +<p>Areas where this minimality consideration has been relaxed are in providing +input/output operators, and rational_cast. The former is generally +uncontroversial. However, there are a number of cases where rational_cast is +not the best possible method for converting a rational to a floating point +value (notably where user-defined types are involved). In those cases, a +user-defined conversion can and should be implemented. There is no need +for such an operation to be named rational_cast, and so the rational_cast +function does <em>not</em> provide the necessary infrastructure to allow for +specialisation/overloading. + +<h3><a name="Limited-range integer types">Limited-range integer types</a></h3> +The rational number class is designed for use in conjunction with an +unlimited precision integer class. With such a class, rationals are always +exact, and no problems arise with precision loss, overflow or underflow. + +<p>Unfortunately, the C++ standard does not offer such a class <s>(and neither +does boost, at the present time)</s>. It is therefore likely that the rational +number class will in many cases be used with limited-precision integer types, +such as the built-in <tt>int</tt> type. + +<p>When used with a limited precision integer type, the rational class suffers +from many of the precision issues which cause difficulty with floating point +types. While it is likely that precision issues will not affect simple uses of +the rational class, users should be aware that such issues exist. + +<p>As a simple illustration of the issues associated with limited precision +integers, consider a case where the C++ <tt>int</tt> type is a 32-bit signed +representation. In this case, the smallest possible positive +rational<int> is <tt>1/0x7FFFFFFF</tt>. In other words, the +"granularity" of the rational<int> representation around zero is +approximately 4.66e-10. At the other end of the representable range, the +largest representable rational<int> is <tt>0x7FFFFFFF/1</tt>, and the +next lower representable rational<int> is <tt>0x7FFFFFFE/1</tt>. Thus, +at this end of the representable range, the granularity ia 1. This type of +magnitude-dependent granularity is typical of floating point representations. +However, it does not "feel" natural when using a rational number class. + +<p>Limited-precision integer types may raise issues with the range sizes of +their allowable negative values and positive values. If the negative range is +larger, then the extremely-negative numbers will not have an additive inverse in +the positive range, making them unusable as denominator values since they cannot +be normalized to positive values (unless the user is lucky enough that the input +components are not relatively prime pre-normalization). + +<p>It is up to the user of a rational type based on a limited-precision integer +type to be aware of, and code in anticipation of, such issues. + +<h3><a name="Conversion from floating point">Conversion from floating point</a></h3> +The library does not offer a conversion function from floating point to +rational. A number of requests were received for such a conversion, but +extensive discussions on the boost list reached the conclusion that there was +no "best solution" to the problem. As there is no reason why a user of the +library cannot write their own conversion function which suits their +particular requirements, the decision was taken not to pick any one algorithm +as "standard". + +<p>The key issue with any conversion function from a floating point value is +how to handle the loss of precision which is involved in floating point +operations. To provide a concrete example, consider the following code: + +<pre> + // These two values could in practice be obtained from user input, + // or from some form of measuring instrument. + double x = 1.0; + double y = 3.0; + + double z = x/y; + + rational<I> r = rational_from_double(z); +</pre> + +<p>The fundamental question is, precisely what rational should r be? A naive +answer is that r should be equal to 1/3. However, this ignores a multitude of +issues. + +<p>In the first instance, z is not exactly 1/3. Because of the limitations of +floating point representation, 1/3 is not exactly representable in any of the +common representations for the double type. Should r therefore not contain an +(exact) representation of the actual value represented by z? But will the user +be happy with a value of 33333333333333331/100000000000000000 for r? + +<p>Before even considering the above issue, we have to consider the accuracy +of the original values, x and y. If they came from an analog measuring +instrument, for example, they are not infinitely accurate in any case. In such +a case, a rational representation like the above promises far more accuracy +than there is any justification for. + +<p>All of this implies that we should be looking for some form of "nearest +simple fraction". Algorithms to determine this sort of value do exist. +However, not all applications want to work like this. In other cases, the +whole point of converting to rational is to obtain an exact representation, in +order to prevent accuracy loss during a series of calculations. In this case, +a completely precise representation is required, regardless of how "unnatural" +the fractions look. + +<p>With these conflicting requirements, there is clearly no single solution +which will satisfy all users. Furthermore, the algorithms involved are +relatively complex and specialised, and are best implemented with a good +understanding of the application requirements. All of these factors make such +a function unsuitable for a general-purpose library such as this. + +<h3><a name="Absolute Value">Absolute Value</a></h3> +In the first instance, it seems logical to implement +abs(rational<IntType>) in terms of abs(IntType). +However, there are a number of issues which arise with doing so. + +<p>The first issue is that, in order to locate the appropriate implementation +of abs(IntType) in the case where IntType is a user-defined type in a user +namespace, Koenig lookup is required. Not all compilers support Koenig lookup +for functions at the current time. For such compilers, clumsy workarounds, +which require cooperation from the user of the rational class, are required to +make things work. + +<p>The second, and potentially more serious, issue is that for non-standard +built-in integer types (for example, 64-bit integer types such as +<em>long long</em> or <em>__int64</em>), there is no guarantee that the vendor +has supplied a built in abs() function operating on such types. This is a +quality-of-implementation issue, but in practical terms, vendor support for +types such as <em>long long</em> is still very patchy. + +<p>As a consequence of these issues, it does not seem worth implementing +abs(rational<IntType>) in terms of abs(IntType). Instead, a simple +implementation with an inline implementation of abs() is used: + +<pre> + template <typename IntType> + inline rational<IntType> abs(const rational<IntType>& r) + { + if (r.numerator() >= IntType(0)) + return r; + + return rational<IntType>(-r.numerator(), r.denominator()); + } +</pre> + +<p>The same arguments imply that where the absolute value of an IntType is +required elsewhere, the calculation is performed inline. + +<h2><a name="References">References</a></h2> +<ul> +<li>The rational number header itself: <a href="../../boost/rational.hpp">rational.hpp</a> +<li>Some example code: <a href="test/rational_example.cpp">rational_example.cpp</a> +<li>The regression test: <a href="test/rational_test.cpp">rational_test.cpp</a> +</ul> + +<h2><a name="History and Acknowledgements">History and Acknowledgements</a></h2> + + <p> + In December, 1999, I implemented the initial version of the rational number + class, and submitted it to the <A HREF="http://www.boost.org/">boost.org</A> + mailing list. Some discussion of the implementation took place on the mailing + list. In particular, Andrew D. Jewell pointed out the importance of ensuring + that the risk of overflow was minimised, and provided overflow-free + implementations of most of the basic operations. The name rational_cast was + suggested by Kevlin Henney. Ed Brey provided invaluable comments - not least + in pointing out some fairly stupid typing errors in the original code!</p> + + <p>David Abrahams contributed helpful feedback on the documentation.</p> + + <p> + A long discussion of the merits of providing a conversion from floating + point to rational took place on the boost list in November 2000. Key + contributors included Reggie Seagraves, Lutz Kettner and Daniel Frey (although + most of the boost list seemed to get involved at one point or another!). Even + though the end result was a decision <em>not</em> to implement anything, the + discussion was very valuable in understanding the issues. + </p> + + <p> + Stephen Silver contributed useful experience on using the rational class + with a user-defined integer type. + </p> + + <p> + Nickolay Mladenov provided the current implementation of operator+= and + operator-=. + </p> + <p> + Discussion of the issues surrounding Koenig lookup and std::swap took place + on the boost list in January 2001. + </p> + <p> + Daryle Walker provided a Boolean conversion operator, so that a rational can + be used in the same Boolean contexts as the built-in numeric types, in December + 2005. He added the cross-instantiation constructor template in August 2013. + </p> + <p> + July 2014: Updated numerator/denominator accessors to return values by constant + reference: this gives a performance improvement when using with multiprecision (class) types. + </p> + <p> + July 2014: Updated to use BOOST_THROW_EXCEPTION uniformly throughout. + </p> + <p> + July 2014: Added support for C++11 constexpr constructors, plus tests to match. + </p> + <p> + Nov 2014: Added support for gcd and lcm of rational numbers. + </p> + <p> + Dec 2016: Reworked constructors and operators to prohibit narrowing implicit + conversions, in particular accidental conversion from floating point types. + </p> + <p> + Oct/Nov 2018: Add more constexpr. + </p> + +<p>Revised July 14, 2017</p> + +<p>© Copyright Paul Moore 1999-2001; © Daryle Walker 2005, 2013. +Permission to copy, use, modify, sell and distribute this document is granted +provided this copyright notice appears in all copies. This document is provided +"as is" without express or implied warranty, and with no claim as to +its suitability for any purpose.</p> +<!-- boostinspect:nolicense (can't find Paul Moore to change license) --> +</body> +</html> diff --git a/src/boost/libs/rational/test/CMakeLists.txt b/src/boost/libs/rational/test/CMakeLists.txt new file mode 100644 index 00000000..d6bd0299 --- /dev/null +++ b/src/boost/libs/rational/test/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright 2019 Mike Dev +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt +# +# NOTE: CMake support for Boost.Rational is currently experimental at best +# and the interface is likely to change in the future + +# NOTE: Boost::test not yet available, so we can't run the regular test +# add_executable( test_boost_rational_test rational_test.cpp ) +# target_link_libraries( test_boost_rational_test +# PUBLIC +# Boost::rational +# Boost::mpl +# Boost::test +# ) +# add_test( NAME test_boost_rational_test COMMAND test_boost_rational_test ) + +add_executable( test_boost_rational_constexpr_test constexpr_test.cpp ) +target_link_libraries( test_boost_rational_constexpr_test + PUBLIC + Boost::rational +) + +add_test( NAME test_boost_rational_constexpr_test COMMAND test_boost_rational_constexpr_test ) + diff --git a/src/boost/libs/rational/test/Jamfile.v2 b/src/boost/libs/rational/test/Jamfile.v2 new file mode 100644 index 00000000..aec0b53a --- /dev/null +++ b/src/boost/libs/rational/test/Jamfile.v2 @@ -0,0 +1,25 @@ +#~ Copyright Rene Rivera 2008 +#~ 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) + +import testing ; +import ../../config/checks/config : requires ; + +test-suite rational + : [ run rational_example.cpp ] + [ run rational_test.cpp + /boost/test//boost_unit_test_framework/<link>static ] + [ run constexpr_test.cpp : : : [ requires cxx11_constexpr ] ] + [ compile-fail expected_fail_01.cpp ] + [ compile-fail expected_fail_02.cpp ] + [ compile-fail expected_fail_03.cpp ] + [ compile-fail expected_fail_04.cpp ] + [ compile-fail expected_fail_05.cpp ] + [ compile-fail expected_fail_06.cpp ] + [ compile-fail expected_fail_07.cpp ] + [ compile-fail expected_fail_08.cpp ] + [ compile-fail expected_fail_09.cpp ] + [ compile-fail expected_fail_10.cpp ] + [ compile-fail expected_fail_11.cpp ] + [ compile expected_compile_12.cpp ] + ; diff --git a/src/boost/libs/rational/test/constexpr_test.cpp b/src/boost/libs/rational/test/constexpr_test.cpp new file mode 100644 index 00000000..22be172d --- /dev/null +++ b/src/boost/libs/rational/test/constexpr_test.cpp @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + + +int main() +{ +#ifndef BOOST_NO_CXX11_CONSTEXPR + constexpr boost::rational<int> i1; + constexpr boost::rational<int> i2(3); + constexpr boost::rational<long long> i3(i2); + constexpr boost::rational<short> i4(i2); + constexpr boost::rational<long long> i5(23u); // converting constructor + // constexpr boost::rational<short> i6(23u); // Not supported, needs an explicit typecast in constructor. + + static_assert(i1.numerator() == 0, "constexpr test"); + static_assert(i1.denominator() == 1, "constexpr test"); + static_assert(i2.numerator() == 3, "constexpr test"); + static_assert(i2.denominator() == 1, "constexpr test"); + static_assert(i3.numerator() == 3, "constexpr test"); + static_assert(i3.denominator() == 1, "constexpr test"); + static_assert(!i1, "constexpr test"); + static_assert(i2, "constexpr test"); +#endif + return 0; +} diff --git a/src/boost/libs/rational/test/expected_compile_12.cpp b/src/boost/libs/rational/test/expected_compile_12.cpp new file mode 100644 index 00000000..0cc9f61d --- /dev/null +++ b/src/boost/libs/rational/test/expected_compile_12.cpp @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2019. 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) + +// For more information read https://github.com/boostorg/rational/issues/26 + +#include <boost/rational.hpp> + +void test(const char* text) +{ + (void)text; +} + +void test(const boost::rational<int>& rational) +{ + (void)rational; +} + +int main() +{ + test("Some text"); + return 0; +} diff --git a/src/boost/libs/rational/test/expected_fail_01.cpp b/src/boost/libs/rational/test/expected_fail_01.cpp new file mode 100644 index 00000000..5c15433a --- /dev/null +++ b/src/boost/libs/rational/test/expected_fail_01.cpp @@ -0,0 +1,11 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + +int main() +{ + boost::rational<int> rat(3.14); +}
\ No newline at end of file diff --git a/src/boost/libs/rational/test/expected_fail_02.cpp b/src/boost/libs/rational/test/expected_fail_02.cpp new file mode 100644 index 00000000..03207000 --- /dev/null +++ b/src/boost/libs/rational/test/expected_fail_02.cpp @@ -0,0 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + +int main() +{ + boost::rational<int> rat(2); + rat = 0.5; +}
\ No newline at end of file diff --git a/src/boost/libs/rational/test/expected_fail_03.cpp b/src/boost/libs/rational/test/expected_fail_03.cpp new file mode 100644 index 00000000..4b5645c2 --- /dev/null +++ b/src/boost/libs/rational/test/expected_fail_03.cpp @@ -0,0 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + +int main() +{ + boost::rational<int> rat(2); + return rat == 0.5; +}
\ No newline at end of file diff --git a/src/boost/libs/rational/test/expected_fail_04.cpp b/src/boost/libs/rational/test/expected_fail_04.cpp new file mode 100644 index 00000000..62c764ae --- /dev/null +++ b/src/boost/libs/rational/test/expected_fail_04.cpp @@ -0,0 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + +int main() +{ + boost::rational<int> rat(2); + rat += 0.5; +}
\ No newline at end of file diff --git a/src/boost/libs/rational/test/expected_fail_05.cpp b/src/boost/libs/rational/test/expected_fail_05.cpp new file mode 100644 index 00000000..14c5ec4e --- /dev/null +++ b/src/boost/libs/rational/test/expected_fail_05.cpp @@ -0,0 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + +int main() +{ + boost::rational<int> rat(2); + rat -= 0.5; +}
\ No newline at end of file diff --git a/src/boost/libs/rational/test/expected_fail_06.cpp b/src/boost/libs/rational/test/expected_fail_06.cpp new file mode 100644 index 00000000..924e1930 --- /dev/null +++ b/src/boost/libs/rational/test/expected_fail_06.cpp @@ -0,0 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + +int main() +{ + boost::rational<int> rat(2); + rat *= 0.5; +}
\ No newline at end of file diff --git a/src/boost/libs/rational/test/expected_fail_07.cpp b/src/boost/libs/rational/test/expected_fail_07.cpp new file mode 100644 index 00000000..9c087afb --- /dev/null +++ b/src/boost/libs/rational/test/expected_fail_07.cpp @@ -0,0 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + +int main() +{ + boost::rational<int> rat(2); + rat /= 0.5; +}
\ No newline at end of file diff --git a/src/boost/libs/rational/test/expected_fail_08.cpp b/src/boost/libs/rational/test/expected_fail_08.cpp new file mode 100644 index 00000000..7efeb3b3 --- /dev/null +++ b/src/boost/libs/rational/test/expected_fail_08.cpp @@ -0,0 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + +int main() +{ + boost::rational<int> rat(2); + rat = rat + 0.5; +}
\ No newline at end of file diff --git a/src/boost/libs/rational/test/expected_fail_09.cpp b/src/boost/libs/rational/test/expected_fail_09.cpp new file mode 100644 index 00000000..c0cdb88d --- /dev/null +++ b/src/boost/libs/rational/test/expected_fail_09.cpp @@ -0,0 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + +int main() +{ + boost::rational<int> rat(2); + rat = rat - 0.5; +}
\ No newline at end of file diff --git a/src/boost/libs/rational/test/expected_fail_10.cpp b/src/boost/libs/rational/test/expected_fail_10.cpp new file mode 100644 index 00000000..126988fc --- /dev/null +++ b/src/boost/libs/rational/test/expected_fail_10.cpp @@ -0,0 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + +int main() +{ + boost::rational<int> rat(2); + rat = rat / 0.5; +}
\ No newline at end of file diff --git a/src/boost/libs/rational/test/expected_fail_11.cpp b/src/boost/libs/rational/test/expected_fail_11.cpp new file mode 100644 index 00000000..32d4232f --- /dev/null +++ b/src/boost/libs/rational/test/expected_fail_11.cpp @@ -0,0 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/rational.hpp> + +int main() +{ + boost::rational<int> rat(2); + rat = rat * 0.5; +}
\ No newline at end of file diff --git a/src/boost/libs/rational/test/rational_example.cpp b/src/boost/libs/rational/test/rational_example.cpp new file mode 100644 index 00000000..16c3fe63 --- /dev/null +++ b/src/boost/libs/rational/test/rational_example.cpp @@ -0,0 +1,108 @@ +// rational number example program ----------------------------------------// + +// (C) Copyright Paul Moore 1999. Permission to copy, use, modify, sell +// and distribute this software is granted provided this copyright notice +// appears in all copies. This software is provided "as is" without express or +// implied warranty, and with no claim as to its suitability for any purpose. + +// boostinspect:nolicense (don't complain about the lack of a Boost license) +// (Paul Moore hasn't been in contact for years, so there's no way to change the +// license.) + +// Revision History +// 14 Dec 99 Initial version + +#include <iostream> +#include <cassert> +#include <cstdlib> +#include <boost/config.hpp> +#ifndef BOOST_NO_LIMITS +#include <limits> +#else +#include <limits.h> +#endif +#include <exception> +#include <boost/rational.hpp> + +using std::cout; +using std::endl; +using boost::rational; + +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +// This is a nasty hack, required because MSVC does not implement "Koenig +// Lookup". Basically, if I call abs(r), the C++ standard says that the +// compiler should look for a definition of abs in the namespace which +// contains r's class (in this case boost) - among other places. + +// Koenig Lookup is a relatively recent feature, and other compilers may not +// implement it yet. If so, try including this line. + +using boost::abs; +#endif + +int main () +{ + rational<int> half(1,2); + rational<int> one(1); + rational<int> two(2); + + // Some basic checks + assert(half.numerator() == 1); + assert(half.denominator() == 2); + assert(boost::rational_cast<double>(half) == 0.5); + + // Arithmetic + assert(half + half == one); + assert(one - half == half); + assert(two * half == one); + assert(one / half == two); + + // With conversions to integer + assert(half+half == 1); + assert(2 * half == one); + assert(2 * half == 1); + assert(one / half == 2); + assert(1 / half == 2); + + // Sign handling + rational<int> minus_half(-1,2); + assert(-half == minus_half); + assert(abs(minus_half) == half); + + // Do we avoid overflow? +#ifndef BOOST_NO_LIMITS + int maxint = (std::numeric_limits<int>::max)(); +#else + int maxint = INT_MAX; +#endif + rational<int> big(maxint, 2); + assert(2 * big == maxint); + + // Print some of the above results + cout << half << "+" << half << "=" << one << endl; + cout << one << "-" << half << "=" << half << endl; + cout << two << "*" << half << "=" << one << endl; + cout << one << "/" << half << "=" << two << endl; + cout << "abs(" << minus_half << ")=" << half << endl; + cout << "2 * " << big << "=" << maxint + << " (rational: " << rational<int>(maxint) << ")" << endl; + + // Some extras + rational<int> pi(22,7); + cout << "pi = " << boost::rational_cast<double>(pi) << " (nearly)" << endl; + + // Exception handling + try { + rational<int> r; // Forgot to initialise - set to 0 + r = 1/r; // Boom! + } + catch (const boost::bad_rational &e) { + cout << "Bad rational, as expected: " << e.what() << endl; + } + catch (...) { + cout << "Wrong exception raised!" << endl; + } + + return 0; +} + diff --git a/src/boost/libs/rational/test/rational_test.cpp b/src/boost/libs/rational/test/rational_test.cpp new file mode 100644 index 00000000..ccd58ea5 --- /dev/null +++ b/src/boost/libs/rational/test/rational_test.cpp @@ -0,0 +1,1608 @@ +/* + * A test program for boost/rational.hpp. + * Change the typedef at the beginning of run_tests() to try out different + * integer types. (These tests are designed only for signed integer + * types. They should work for short, int and long.) + * + * (C) Copyright Stephen Silver, 2001. Permission to copy, use, modify, sell + * and distribute this software is granted provided this copyright notice + * appears in all copies. This software is provided "as is" without express or + * implied warranty, and with no claim as to its suitability for any purpose. + * + * Incorporated into the boost rational number library, and modified and + * extended, by Paul Moore, with permission. + */ + +// boostinspect:nolicense (don't complain about the lack of a Boost license) +// (Stephen Silver hasn't been contacted yet for permission to change the +// license. If Paul Moore's permission is also needed, then that's a problem +// since he hasn't been in contact for years.) + +// Revision History +// 30 Aug 13 Add bug-test of assignments holding the basic and/or strong +// guarantees (Daryle Walker) +// 27 Aug 13 Add test for cross-version constructor template (Daryle Walker) +// 23 Aug 13 Add bug-test of narrowing conversions during order comparison; +// spell logical-negation in it as "!" because MSVC won't accept +// "not" (Daryle Walker) +// 05 Nov 06 Add testing of zero-valued denominators & divisors; casting with +// types that are not implicitly convertible (Daryle Walker) +// 04 Nov 06 Resolve GCD issue with depreciation (Daryle Walker) +// 02 Nov 06 Add testing for operator<(int_type) w/ unsigneds (Daryle Walker) +// 31 Oct 06 Add testing for operator<(rational) overflow (Daryle Walker) +// 18 Oct 06 Various fixes for old compilers (JoaquÃn M López Muñoz) +// 27 Dec 05 Add testing for Boolean conversion operator (Daryle Walker) +// 24 Dec 05 Change code to use Boost.Test (Daryle Walker) +// 04 Mar 01 Patches for Intel C++ and GCC (David Abrahams) + +#define BOOST_TEST_MAIN "Boost::Rational unit tests" + +#include <boost/config.hpp> +#include <boost/limits.hpp> +#include <boost/mpl/list.hpp> +#include <boost/operators.hpp> +#include <boost/preprocessor/stringize.hpp> +#include <boost/integer/common_factor_rt.hpp> +#include <boost/cstdint.hpp> + +#include <boost/rational.hpp> + +#include <boost/test/unit_test.hpp> + +#include <climits> +#include <iomanip> +#include <ios> +#include <iostream> +#include <istream> +#include <ostream> +#include <sstream> +#include <stdexcept> +#include <string> + +#ifdef _MSC_VER +#pragma warning(disable:4146) +#endif + + +// We can override this on the compile, as -DINT_TYPE=short or whatever. +// The default test is against rational<long>. +#ifndef INT_TYPE +#define INT_TYPE long +#endif + +namespace { + +class MyOverflowingUnsigned; + +// This is a trivial user-defined wrapper around the built in int type. +// It can be used as a test type for rational<> +class MyInt : boost::operators<MyInt> +{ + friend class MyOverflowingUnsigned; + int val; +public: + MyInt(int n = 0) : val(n) {} + friend MyInt operator+ (const MyInt&); + friend MyInt operator- (const MyInt&); + MyInt& operator+= (const MyInt& rhs) { val += rhs.val; return *this; } + MyInt& operator-= (const MyInt& rhs) { val -= rhs.val; return *this; } + MyInt& operator*= (const MyInt& rhs) { val *= rhs.val; return *this; } + MyInt& operator/= (const MyInt& rhs) { val /= rhs.val; return *this; } + MyInt& operator%= (const MyInt& rhs) { val %= rhs.val; return *this; } + MyInt& operator|= (const MyInt& rhs) { val |= rhs.val; return *this; } + MyInt& operator&= (const MyInt& rhs) { val &= rhs.val; return *this; } + MyInt& operator^= (const MyInt& rhs) { val ^= rhs.val; return *this; } + const MyInt& operator++() { ++val; return *this; } + const MyInt& operator--() { --val; return *this; } + bool operator< (const MyInt& rhs) const { return val < rhs.val; } + bool operator== (const MyInt& rhs) const { return val == rhs.val; } + bool operator! () const { return !val; } + friend std::istream& operator>>(std::istream&, MyInt&); + friend std::ostream& operator<<(std::ostream&, const MyInt&); +}; + +inline MyInt operator+(const MyInt& rhs) { return rhs; } +inline MyInt operator-(const MyInt& rhs) { return MyInt(-rhs.val); } +inline std::istream& operator>>(std::istream& is, MyInt& i) { is >> i.val; return is; } +inline std::ostream& operator<<(std::ostream& os, const MyInt& i) { os << i.val; return os; } +inline MyInt abs(MyInt rhs) { if (rhs < MyInt()) rhs = -rhs; return rhs; } + +// This is an "unsigned" wrapper, that throws on overflow. It can be used to +// test rational<> when an operation goes out of bounds. +class MyOverflowingUnsigned + : private boost::unit_steppable<MyOverflowingUnsigned> + , private boost::ordered_euclidian_ring_operators1<MyOverflowingUnsigned> +{ + // Helper type-aliases + typedef MyOverflowingUnsigned self_type; + typedef unsigned self_type::* bool_type; + + // Member data + unsigned v_; + +public: + // Exception base class + class exception_base { protected: virtual ~exception_base() throw() {} }; + + // Divide-by-zero exception class + class divide_by_0_error + : public virtual exception_base + , public std::domain_error + { + public: + explicit divide_by_0_error( std::string const &w ) + : std::domain_error( w ) {} + + virtual ~divide_by_0_error() throw() {} + }; + + // Overflow exception class + class overflowing_error + : public virtual exception_base + , public std::overflow_error + { + public: + explicit overflowing_error( std::string const &w ) + : std::overflow_error( w ) {} + + virtual ~overflowing_error() throw() {} + }; + + // Lifetime management (use automatic dtr & copy-ctr) + MyOverflowingUnsigned( unsigned v = 0 ) : v_( v ) {} + explicit MyOverflowingUnsigned( MyInt const &m ) : v_( m.val ) {} + + // Operators (use automatic copy-assignment); arithmetic & comparison only + self_type & operator ++() + { + if ( this->v_ == UINT_MAX ) throw overflowing_error( "increment" ); + else ++this->v_; + return *this; + } + self_type & operator --() + { + if ( !this->v_ ) throw overflowing_error( "decrement" ); + else --this->v_; + return *this; + } + + operator bool_type() const { return this->v_ ? &self_type::v_ : 0; } + + bool operator !() const { return !this->v_; } + self_type operator +() const { return self_type( +this->v_ ); } + self_type operator -() const { return self_type( -this->v_ ); } + + bool operator <(self_type const &r) const { return this->v_ < r.v_; } + bool operator ==(self_type const &r) const { return this->v_ == r.v_; } + + self_type & operator *=( self_type const &r ) + { + if ( r.v_ && this->v_ > UINT_MAX / r.v_ ) + { + throw overflowing_error( "oversized factors" ); + } + this->v_ *= r.v_; + return *this; + } + self_type & operator /=( self_type const &r ) + { + if ( !r.v_ ) throw divide_by_0_error( "division" ); + this->v_ /= r.v_; + return *this; + } + self_type & operator %=( self_type const &r ) + { + if ( !r.v_ ) throw divide_by_0_error( "modulus" ); + this->v_ %= r.v_; + return *this; + } + self_type & operator +=( self_type const &r ) + { + if ( this->v_ > UINT_MAX - r.v_ ) + { + throw overflowing_error( "oversized addends" ); + } + this->v_ += r.v_; + return *this; + } + self_type & operator -=( self_type const &r ) + { + if ( this->v_ < r.v_ ) + { + throw overflowing_error( "oversized subtrahend" ); + } + this->v_ -= r.v_; + return *this; + } + + // Input & output + template < typename Ch, class Tr > + friend std::basic_istream<Ch, Tr> & + operator >>( std::basic_istream<Ch, Tr> &i, self_type &x ) + { return i >> x.v_; } + + template < typename Ch, class Tr > + friend std::basic_ostream<Ch, Tr> & + operator <<( std::basic_ostream<Ch, Tr> &o, self_type const &x ) + { return o << x.v_; } + +}; // MyOverflowingUnsigned + +inline MyOverflowingUnsigned abs( MyOverflowingUnsigned const &x ) { return x; } + +} // namespace + + +// Specialize numeric_limits for the custom types +namespace std +{ + +template < > +class numeric_limits< MyInt > +{ + typedef numeric_limits<int> limits_type; + +public: + static const bool is_specialized = limits_type::is_specialized; + + static MyInt min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return + limits_type::min BOOST_PREVENT_MACRO_SUBSTITUTION (); } + static MyInt max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return + limits_type::max BOOST_PREVENT_MACRO_SUBSTITUTION (); } + static MyInt lowest() throw() { return min BOOST_PREVENT_MACRO_SUBSTITUTION + (); } // C++11 + + static const int digits = limits_type::digits; + static const int digits10 = limits_type::digits10; + static const int max_digits10 = 0; // C++11 + static const bool is_signed = limits_type::is_signed; + static const bool is_integer = limits_type::is_integer; + static const bool is_exact = limits_type::is_exact; + static const int radix = limits_type::radix; + static MyInt epsilon() throw() { return limits_type::epsilon(); } + static MyInt round_error() throw() { return limits_type::round_error(); } + + static const int min_exponent = limits_type::min_exponent; + static const int min_exponent10 = limits_type::min_exponent10; + static const int max_exponent = limits_type::max_exponent; + static const int max_exponent10 = limits_type::max_exponent10; + + static const bool has_infinity = limits_type::has_infinity; + static const bool has_quiet_NaN = limits_type::has_quiet_NaN; + static const bool has_signaling_NaN = limits_type::has_signaling_NaN; + static const float_denorm_style has_denorm = limits_type::has_denorm; + static const bool has_denorm_loss = limits_type::has_denorm_loss; + + static MyInt infinity() throw() { return limits_type::infinity(); } + static MyInt quiet_NaN() throw() { return limits_type::quiet_NaN(); } + static MyInt signaling_NaN() throw() {return limits_type::signaling_NaN();} + static MyInt denorm_min() throw() { return limits_type::denorm_min(); } + + static const bool is_iec559 = limits_type::is_iec559; + static const bool is_bounded = limits_type::is_bounded; + static const bool is_modulo = limits_type::is_modulo; + + static const bool traps = limits_type::traps; + static const bool tinyness_before = limits_type::tinyness_before; + static const float_round_style round_style = limits_type::round_style; + +}; // std::numeric_limits<MyInt> + +template < > +class numeric_limits< MyOverflowingUnsigned > +{ + typedef numeric_limits<unsigned> limits_type; + +public: + static const bool is_specialized = limits_type::is_specialized; + + static MyOverflowingUnsigned min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() + { return limits_type::min BOOST_PREVENT_MACRO_SUBSTITUTION (); } + static MyOverflowingUnsigned max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() + { return limits_type::max BOOST_PREVENT_MACRO_SUBSTITUTION (); } + static MyOverflowingUnsigned lowest() throw() + { return min BOOST_PREVENT_MACRO_SUBSTITUTION (); } // C++11 + + static const int digits = limits_type::digits; + static const int digits10 = limits_type::digits10; + static const int max_digits10 = 0; // C++11 + static const bool is_signed = limits_type::is_signed; + static const bool is_integer = limits_type::is_integer; + static const bool is_exact = limits_type::is_exact; + static const int radix = limits_type::radix; + static MyOverflowingUnsigned epsilon() throw() + { return limits_type::epsilon(); } + static MyOverflowingUnsigned round_error() throw() + {return limits_type::round_error();} + + static const int min_exponent = limits_type::min_exponent; + static const int min_exponent10 = limits_type::min_exponent10; + static const int max_exponent = limits_type::max_exponent; + static const int max_exponent10 = limits_type::max_exponent10; + + static const bool has_infinity = limits_type::has_infinity; + static const bool has_quiet_NaN = limits_type::has_quiet_NaN; + static const bool has_signaling_NaN = limits_type::has_signaling_NaN; + static const float_denorm_style has_denorm = limits_type::has_denorm; + static const bool has_denorm_loss = limits_type::has_denorm_loss; + + static MyOverflowingUnsigned infinity() throw() + { return limits_type::infinity(); } + static MyOverflowingUnsigned quiet_NaN() throw() + { return limits_type::quiet_NaN(); } + static MyOverflowingUnsigned signaling_NaN() throw() + { return limits_type::signaling_NaN(); } + static MyOverflowingUnsigned denorm_min() throw() + { return limits_type::denorm_min(); } + + static const bool is_iec559 = limits_type::is_iec559; + static const bool is_bounded = limits_type::is_bounded; + static const bool is_modulo = limits_type::is_modulo; + + static const bool traps = limits_type::traps; + static const bool tinyness_before = limits_type::tinyness_before; + static const float_round_style round_style = limits_type::round_style; + +}; // std::numeric_limits<MyOverflowingUnsigned> + +} // namespace std + + +namespace { + +// This fixture replaces the check of rational's packing at the start of main. +class rational_size_check +{ + typedef INT_TYPE int_type; + typedef ::boost::rational<int_type> rational_type; + +public: + rational_size_check() + { + using ::std::cout; + + char const * const int_name = BOOST_PP_STRINGIZE( INT_TYPE ); + + cout << "Running tests for boost::rational<" << int_name << ">\n\n"; + + cout << "Implementation issue: the minimal size for a rational\n" + << "is twice the size of the underlying integer type.\n\n"; + + cout << "Checking to see if space is being wasted.\n" + << "\tsizeof(" << int_name << ") == " << sizeof( int_type ) + << "\n"; + cout << "\tsizeof(boost::rational<" << int_name << ">) == " + << sizeof( rational_type ) << "\n\n"; + + cout << "Implementation has " + << ( + (sizeof( rational_type ) > 2u * sizeof( int_type )) + ? "included padding bytes" + : "minimal size" + ) + << "\n\n"; + } +}; + +// This fixture groups all the common settings. +class my_configuration +{ +public: + template < typename T > + class hook + { + public: + typedef ::boost::rational<T> rational_type; + + private: + struct parts { rational_type parts_[ 9 ]; }; + + static parts generate_rationals() + { + rational_type r1, r2( 0 ), r3( 1 ), r4( -3 ), r5( 7, 2 ), + r6( 5, 15 ), r7( 14, -21 ), r8( -4, 6 ), + r9( -14, -70 ); + parts result; + result.parts_[0] = r1; + result.parts_[1] = r2; + result.parts_[2] = r3; + result.parts_[3] = r4; + result.parts_[4] = r5; + result.parts_[5] = r6; + result.parts_[6] = r7; + result.parts_[7] = r8; + result.parts_[8] = r9; + + return result; + } + + parts p_; // Order Dependency + + public: + rational_type ( &r_ )[ 9 ]; // Order Dependency + + hook() : p_( generate_rationals() ), r_( p_.parts_ ) {} + }; +}; + +// Instead of controlling the integer type needed with a #define, use a list of +// all available types. Since the headers #included don't change because of the +// integer #define, only the built-in types and MyInt are available. (Any other +// arbitrary integer type introduced by the #define would get compiler errors +// because its header can't be #included.) +typedef ::boost::mpl::list<short, int, long> builtin_signed_test_types; +typedef ::boost::mpl::list<short, int, long, MyInt> all_signed_test_types; + +// Without these explicit instantiations, MSVC++ 6.5/7.0 does not find +// some friend operators in certain contexts. +::boost::rational<short> dummy1; +::boost::rational<int> dummy2; +::boost::rational<long> dummy3; +::boost::rational<MyInt> dummy4; +::boost::rational<MyOverflowingUnsigned> dummy5; +::boost::rational<unsigned> dummy6; + +// Should there be regular tests with unsigned integer types? + +} // namespace + + +// Check if rational is the smallest size possible +BOOST_GLOBAL_FIXTURE( rational_size_check ); + + +#if BOOST_CONTROL_RATIONAL_HAS_GCD +// The factoring function template suite +BOOST_AUTO_TEST_SUITE( factoring_suite ) + +// GCD tests +BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_test, T, all_signed_test_types ) +{ + BOOST_CHECK_EQUAL( boost::gcd<T>( 1, -1), static_cast<T>( 1) ); + BOOST_CHECK_EQUAL( boost::gcd<T>( -1, 1), static_cast<T>( 1) ); + BOOST_CHECK_EQUAL( boost::gcd<T>( 1, 1), static_cast<T>( 1) ); + BOOST_CHECK_EQUAL( boost::gcd<T>( -1, -1), static_cast<T>( 1) ); + BOOST_CHECK_EQUAL( boost::gcd<T>( 0, 0), static_cast<T>( 0) ); + BOOST_CHECK_EQUAL( boost::gcd<T>( 7, 0), static_cast<T>( 7) ); + BOOST_CHECK_EQUAL( boost::gcd<T>( 0, 9), static_cast<T>( 9) ); + BOOST_CHECK_EQUAL( boost::gcd<T>( -7, 0), static_cast<T>( 7) ); + BOOST_CHECK_EQUAL( boost::gcd<T>( 0, -9), static_cast<T>( 9) ); + BOOST_CHECK_EQUAL( boost::gcd<T>( 42, 30), static_cast<T>( 6) ); + BOOST_CHECK_EQUAL( boost::gcd<T>( 6, -9), static_cast<T>( 3) ); + BOOST_CHECK_EQUAL( boost::gcd<T>(-10, -10), static_cast<T>(10) ); + BOOST_CHECK_EQUAL( boost::gcd<T>(-25, -10), static_cast<T>( 5) ); +} + +// LCM tests +BOOST_AUTO_TEST_CASE_TEMPLATE( lcm_test, T, all_signed_test_types ) +{ + BOOST_CHECK_EQUAL( boost::lcm<T>( 1, -1), static_cast<T>( 1) ); + BOOST_CHECK_EQUAL( boost::lcm<T>( -1, 1), static_cast<T>( 1) ); + BOOST_CHECK_EQUAL( boost::lcm<T>( 1, 1), static_cast<T>( 1) ); + BOOST_CHECK_EQUAL( boost::lcm<T>( -1, -1), static_cast<T>( 1) ); + BOOST_CHECK_EQUAL( boost::lcm<T>( 0, 0), static_cast<T>( 0) ); + BOOST_CHECK_EQUAL( boost::lcm<T>( 6, 0), static_cast<T>( 0) ); + BOOST_CHECK_EQUAL( boost::lcm<T>( 0, 7), static_cast<T>( 0) ); + BOOST_CHECK_EQUAL( boost::lcm<T>( -5, 0), static_cast<T>( 0) ); + BOOST_CHECK_EQUAL( boost::lcm<T>( 0, -4), static_cast<T>( 0) ); + BOOST_CHECK_EQUAL( boost::lcm<T>( 18, 30), static_cast<T>(90) ); + BOOST_CHECK_EQUAL( boost::lcm<T>( -6, 9), static_cast<T>(18) ); + BOOST_CHECK_EQUAL( boost::lcm<T>(-10, -10), static_cast<T>(10) ); + BOOST_CHECK_EQUAL( boost::lcm<T>( 25, -10), static_cast<T>(50) ); +} + +BOOST_AUTO_TEST_SUITE_END() +#endif // BOOST_CONTROL_RATIONAL_HAS_GCD + + +// The basic test suite +BOOST_FIXTURE_TEST_SUITE( basic_rational_suite, my_configuration ) + +// Initialization tests +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_initialization_test, T, + all_signed_test_types ) +{ + my_configuration::hook<T> h; + boost::rational<T> &r1 = h.r_[ 0 ], &r2 = h.r_[ 1 ], &r3 = h.r_[ 2 ], + &r4 = h.r_[ 3 ], &r5 = h.r_[ 4 ], &r6 = h.r_[ 5 ], + &r7 = h.r_[ 6 ], &r8 = h.r_[ 7 ], &r9 = h.r_[ 8 ]; + + BOOST_CHECK_EQUAL( r1.numerator(), static_cast<T>( 0) ); + BOOST_CHECK_EQUAL( r2.numerator(), static_cast<T>( 0) ); + BOOST_CHECK_EQUAL( r3.numerator(), static_cast<T>( 1) ); + BOOST_CHECK_EQUAL( r4.numerator(), static_cast<T>(-3) ); + BOOST_CHECK_EQUAL( r5.numerator(), static_cast<T>( 7) ); + BOOST_CHECK_EQUAL( r6.numerator(), static_cast<T>( 1) ); + BOOST_CHECK_EQUAL( r7.numerator(), static_cast<T>(-2) ); + BOOST_CHECK_EQUAL( r8.numerator(), static_cast<T>(-2) ); + BOOST_CHECK_EQUAL( r9.numerator(), static_cast<T>( 1) ); + + BOOST_CHECK_EQUAL( r1.denominator(), static_cast<T>(1) ); + BOOST_CHECK_EQUAL( r2.denominator(), static_cast<T>(1) ); + BOOST_CHECK_EQUAL( r3.denominator(), static_cast<T>(1) ); + BOOST_CHECK_EQUAL( r4.denominator(), static_cast<T>(1) ); + BOOST_CHECK_EQUAL( r5.denominator(), static_cast<T>(2) ); + BOOST_CHECK_EQUAL( r6.denominator(), static_cast<T>(3) ); + BOOST_CHECK_EQUAL( r7.denominator(), static_cast<T>(3) ); + BOOST_CHECK_EQUAL( r8.denominator(), static_cast<T>(3) ); + BOOST_CHECK_EQUAL( r9.denominator(), static_cast<T>(5) ); + + BOOST_CHECK_THROW( boost::rational<T>( 3, 0), boost::bad_rational ); + BOOST_CHECK_THROW( boost::rational<T>(-2, 0), boost::bad_rational ); + BOOST_CHECK_THROW( boost::rational<T>( 0, 0), boost::bad_rational ); +} + +// Assignment (non-operator) tests +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_assign_test, T, all_signed_test_types ) +{ + my_configuration::hook<T> h; + boost::rational<T> & r = h.r_[ 0 ]; + + r.assign( 6, 8 ); + BOOST_CHECK_EQUAL( r.numerator(), static_cast<T>(3) ); + BOOST_CHECK_EQUAL( r.denominator(), static_cast<T>(4) ); + + r.assign( 0, -7 ); + BOOST_CHECK_EQUAL( r.numerator(), static_cast<T>(0) ); + BOOST_CHECK_EQUAL( r.denominator(), static_cast<T>(1) ); + + BOOST_CHECK_THROW( r.assign( 4, 0), boost::bad_rational ); + BOOST_CHECK_THROW( r.assign( 0, 0), boost::bad_rational ); + BOOST_CHECK_THROW( r.assign(-7, 0), boost::bad_rational ); +} + +// Comparison tests +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_comparison_test, T, + all_signed_test_types ) +{ + my_configuration::hook<T> h; + const boost::rational<T> &r1 = h.r_[ 0 ], &r2 = h.r_[ 1 ], &r3 = h.r_[ 2 ], + &r4 = h.r_[ 3 ], &r5 = h.r_[ 4 ], &r6 = h.r_[ 5 ], + &r7 = h.r_[ 6 ], &r8 = h.r_[ 7 ], &r9 = h.r_[ 8 ]; + + BOOST_CHECK( r1 == r2 ); + BOOST_CHECK( r2 != r3 ); + BOOST_CHECK( r4 < r3 ); + BOOST_CHECK( r4 <= r5 ); + BOOST_CHECK( r1 <= r2 ); + BOOST_CHECK( r5 > r6 ); + BOOST_CHECK( r5 >= r6 ); + BOOST_CHECK( r7 >= r8 ); + + BOOST_CHECK( !(r3 == r2) ); + BOOST_CHECK( !(r1 != r2) ); + BOOST_CHECK( !(r1 < r2) ); + BOOST_CHECK( !(r5 < r6) ); + BOOST_CHECK( !(r9 <= r2) ); + BOOST_CHECK( !(r8 > r7) ); + BOOST_CHECK( !(r8 > r2) ); + BOOST_CHECK( !(r4 >= r6) ); + + BOOST_CHECK( r1 == static_cast<T>( 0) ); + BOOST_CHECK( r2 != static_cast<T>(-1) ); + BOOST_CHECK( r3 < static_cast<T>( 2) ); + BOOST_CHECK( r4 <= static_cast<T>(-3) ); + BOOST_CHECK( r5 > static_cast<T>( 3) ); + BOOST_CHECK( r6 >= static_cast<T>( 0) ); + + BOOST_CHECK( static_cast<T>( 0) == r2 ); + BOOST_CHECK( static_cast<T>( 0) != r7 ); + BOOST_CHECK( static_cast<T>(-1) < r8 ); + BOOST_CHECK( static_cast<T>(-2) <= r9 ); + BOOST_CHECK( static_cast<T>( 1) > r1 ); + BOOST_CHECK( static_cast<T>( 1) >= r3 ); + + // Extra tests with values close in continued-fraction notation + boost::rational<T> const x1( static_cast<T>(9), static_cast<T>(4) ); + boost::rational<T> const x2( static_cast<T>(61), static_cast<T>(27) ); + boost::rational<T> const x3( static_cast<T>(52), static_cast<T>(23) ); + boost::rational<T> const x4( static_cast<T>(70), static_cast<T>(31) ); + + BOOST_CHECK( x1 < x2 ); + BOOST_CHECK( !(x1 < x1) ); + BOOST_CHECK( !(x2 < x2) ); + BOOST_CHECK( !(x2 < x1) ); + BOOST_CHECK( x2 < x3 ); + BOOST_CHECK( x4 < x2 ); + BOOST_CHECK( !(x3 < x4) ); + BOOST_CHECK( r7 < x1 ); // not actually close; wanted -ve v. +ve instead + BOOST_CHECK( !(x2 < r7) ); +} + +// Increment & decrement tests +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_1step_test, T, all_signed_test_types ) +{ + my_configuration::hook<T> h; + boost::rational<T> &r1 = h.r_[ 0 ], &r2 = h.r_[ 1 ], &r3 = h.r_[ 2 ], + &r7 = h.r_[ 6 ], &r8 = h.r_[ 7 ]; + + BOOST_CHECK( r1++ == r2 ); + BOOST_CHECK( r1 != r2 ); + BOOST_CHECK( r1 == r3 ); + BOOST_CHECK( --r1 == r2 ); + BOOST_CHECK( r8-- == r7 ); + BOOST_CHECK( r8 != r7 ); + BOOST_CHECK( ++r8 == r7 ); +} + +// Absolute value tests +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_abs_test, T, all_signed_test_types ) +{ + typedef my_configuration::hook<T> hook_type; + typedef typename hook_type::rational_type rational_type; + + hook_type h; + rational_type &r2 = h.r_[ 1 ], &r5 = h.r_[ 4 ], &r8 = h.r_[ 7 ]; + +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + // This is a nasty hack, required because some compilers do not implement + // "Koenig Lookup." Basically, if I call abs(r), the C++ standard says that + // the compiler should look for a definition of abs in the namespace which + // contains r's class (in this case boost)--among other places. + + using boost::abs; +#endif + + BOOST_CHECK_EQUAL( abs(r2), r2 ); + BOOST_CHECK_EQUAL( abs(r5), r5 ); + BOOST_CHECK_EQUAL( abs(r8), rational_type(2, 3) ); +} + +// Unary operator tests +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_unary_test, T, all_signed_test_types ) +{ + my_configuration::hook<T> h; + boost::rational<T> &r2 = h.r_[ 1 ], &r3 = h.r_[ 2 ], + &r4 = h.r_[ 3 ], &r5 = h.r_[ 4 ]; + + BOOST_CHECK_EQUAL( +r5, r5 ); + + BOOST_CHECK( -r3 != r3 ); + BOOST_CHECK_EQUAL( -(-r3), r3 ); + BOOST_CHECK_EQUAL( -r4, static_cast<T>(3) ); + + BOOST_CHECK( !r2 ); + BOOST_CHECK( !!r3 ); + + BOOST_CHECK( ! static_cast<bool>(r2) ); + BOOST_CHECK( r3 ); +} + +BOOST_AUTO_TEST_SUITE_END() + + +// The rational arithmetic operations suite +BOOST_AUTO_TEST_SUITE( rational_arithmetic_suite ) + +// Addition & subtraction tests +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_additive_test, T, + all_signed_test_types ) +{ + typedef boost::rational<T> rational_type; + + BOOST_CHECK_EQUAL( rational_type( 1, 2) + rational_type(1, 2), + static_cast<T>(1) ); + BOOST_CHECK_EQUAL( rational_type(11, 3) + rational_type(1, 2), + rational_type( 25, 6) ); + BOOST_CHECK_EQUAL( rational_type(-8, 3) + rational_type(1, 5), + rational_type(-37, 15) ); + BOOST_CHECK_EQUAL( rational_type(-7, 6) + rational_type(1, 7), + rational_type( 1, 7) - rational_type(7, 6) ); + BOOST_CHECK_EQUAL( rational_type(13, 5) - rational_type(1, 2), + rational_type( 21, 10) ); + BOOST_CHECK_EQUAL( rational_type(22, 3) + static_cast<T>(1), + rational_type( 25, 3) ); + BOOST_CHECK_EQUAL( rational_type(12, 7) - static_cast<T>(2), + rational_type( -2, 7) ); + BOOST_CHECK_EQUAL( static_cast<T>(3) + rational_type(4, 5), + rational_type( 19, 5) ); + BOOST_CHECK_EQUAL( static_cast<T>(4) - rational_type(9, 2), + rational_type( -1, 2) ); + + rational_type r( 11 ); + + r -= rational_type( 20, 3 ); + BOOST_CHECK_EQUAL( r, rational_type(13, 3) ); + + r += rational_type( 1, 2 ); + BOOST_CHECK_EQUAL( r, rational_type(29, 6) ); + + r -= static_cast<T>( 5 ); + BOOST_CHECK_EQUAL( r, rational_type( 1, -6) ); + + r += rational_type( 1, 5 ); + BOOST_CHECK_EQUAL( r, rational_type( 1, 30) ); + + r += static_cast<T>( 2 ); + BOOST_CHECK_EQUAL( r, rational_type(61, 30) ); +} + +// Assignment tests +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_assignment_test, T, + all_signed_test_types ) +{ + typedef boost::rational<T> rational_type; + + rational_type r; + + r = rational_type( 1, 10 ); + BOOST_CHECK_EQUAL( r, rational_type( 1, 10) ); + + r = static_cast<T>( -9 ); + BOOST_CHECK_EQUAL( r, rational_type(-9, 1) ); +} + +// Multiplication tests +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_multiplication_test, T, + all_signed_test_types ) +{ + typedef boost::rational<T> rational_type; + + BOOST_CHECK_EQUAL( rational_type(1, 3) * rational_type(-3, 4), + rational_type(-1, 4) ); + BOOST_CHECK_EQUAL( rational_type(2, 5) * static_cast<T>(7), + rational_type(14, 5) ); + BOOST_CHECK_EQUAL( static_cast<T>(-2) * rational_type(1, 6), + rational_type(-1, 3) ); + + rational_type r = rational_type( 3, 7 ); + + r *= static_cast<T>( 14 ); + BOOST_CHECK_EQUAL( r, static_cast<T>(6) ); + + r *= rational_type( 3, 8 ); + BOOST_CHECK_EQUAL( r, rational_type(9, 4) ); +} + +// Division tests +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_division_test, T, + all_signed_test_types ) +{ + typedef boost::rational<T> rational_type; + + BOOST_CHECK_EQUAL( rational_type(-1, 20) / rational_type(4, 5), + rational_type(-1, 16) ); + BOOST_CHECK_EQUAL( rational_type( 5, 6) / static_cast<T>(7), + rational_type( 5, 42) ); + BOOST_CHECK_EQUAL( static_cast<T>(8) / rational_type(2, 7), + static_cast<T>(28) ); + + BOOST_CHECK_THROW( rational_type(23, 17) / rational_type(), + boost::bad_rational ); + BOOST_CHECK_THROW( rational_type( 4, 15) / static_cast<T>(0), + boost::bad_rational ); + + rational_type r = rational_type( 4, 3 ); + + r /= rational_type( 5, 4 ); + BOOST_CHECK_EQUAL( r, rational_type(16, 15) ); + + r /= static_cast<T>( 4 ); + BOOST_CHECK_EQUAL( r, rational_type( 4, 15) ); + + BOOST_CHECK_THROW( r /= rational_type(), boost::bad_rational ); + BOOST_CHECK_THROW( r /= static_cast<T>(0), boost::bad_rational ); + + BOOST_CHECK_EQUAL( rational_type(-1) / rational_type(-3), + rational_type(1, 3) ); +} + +// Tests for operations on self +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_self_operations_test, T, + all_signed_test_types ) +{ + typedef boost::rational<T> rational_type; + + rational_type r = rational_type( 4, 3 ); + + r += r; + BOOST_CHECK_EQUAL( r, rational_type( 8, 3) ); + + r *= r; + BOOST_CHECK_EQUAL( r, rational_type(64, 9) ); + + r /= r; + BOOST_CHECK_EQUAL( r, rational_type( 1, 1) ); + + r -= r; + BOOST_CHECK_EQUAL( r, rational_type( 0, 1) ); + + BOOST_CHECK_THROW( r /= r, boost::bad_rational ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_and_lcm_on_rationals, T, all_signed_test_types ) +{ + typedef boost::rational<T> rational; + BOOST_CHECK_EQUAL(boost::integer::gcd(rational(1, 4), rational(1, 3)), + rational(1, 12)); + BOOST_CHECK_EQUAL(boost::integer::lcm(rational(1, 4), rational(1, 3)), + rational(1)); +} + +// Assignment tests +BOOST_AUTO_TEST_CASE_TEMPLATE(rational_mixed_test, T, + /*all_signed_test_types*/ builtin_signed_test_types) +{ + { + typedef boost::rational<boost::intmax_t> rational_type; + T val1 = 20; + boost::intmax_t val2 = 30; + + rational_type r(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, 30)); + + r.assign(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, 30)); + } + { + typedef boost::rational<boost::uintmax_t> rational_type2; + + T val1 = 20; + boost::uintmax_t val3 = 30; + + rational_type2 r2(val1, val3); + BOOST_CHECK_EQUAL(r2, rational_type2(20, 30)); + + r2.assign(val1, val3); + BOOST_CHECK_EQUAL(r2, rational_type2(20, 30)); + } + { + typedef boost::rational<short> rational_type; + T val1 = 20; + short val2 = 30; + + rational_type r(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, 30)); + + r.assign(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, 30)); + } + { + typedef boost::rational<unsigned short> rational_type; + T val1 = 20; + unsigned short val2 = 30; + + rational_type r(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, 30)); + + r.assign(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, 30)); + } + { + typedef boost::rational<long> rational_type; + T val1 = 20; + long val2 = 30; + + rational_type r(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, 30)); + + r.assign(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, 30)); + } + { + typedef boost::rational<unsigned long> rational_type; + T val1 = 20; + unsigned long val2 = 30; + + rational_type r(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, 30)); + + r.assign(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, 30)); + } + { + typedef boost::rational<boost::intmax_t> rational_type; + T val1 = 20; + boost::intmax_t val2 = -30; + + rational_type r(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, -30)); + + r.assign(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(20, -30)); + } + { + typedef boost::rational<short> rational_type; + T val1 = -20; + short val2 = -30; + + rational_type r(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(-20, -30)); + + r.assign(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(-20, -30)); + } + { + typedef boost::rational<long> rational_type; + T val1 = -20; + long val2 = 30; + + rational_type r(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(-20, 30)); + + r.assign(val1, val2); + BOOST_CHECK_EQUAL(r, rational_type(-20, 30)); + } +} + +BOOST_AUTO_TEST_CASE(conversions) +{ + typedef boost::rational<boost::int32_t> signed_rat; + + boost::int32_t signed_max = (std::numeric_limits<boost::int32_t>::max)(); + boost::int32_t signed_min = (std::numeric_limits<boost::int32_t>::min)(); + boost::int32_t signed_min_num = signed_min + 1; + + BOOST_CHECK_EQUAL(signed_rat(signed_max).numerator(), signed_max); + BOOST_CHECK_EQUAL(signed_rat(signed_min).numerator(), signed_min); + BOOST_CHECK_EQUAL(signed_rat(signed_max, 1).numerator(), signed_max); + BOOST_CHECK_EQUAL(signed_rat(signed_min, 1).numerator(), signed_min); + BOOST_CHECK_EQUAL(signed_rat(1, signed_max).denominator(), signed_max); + BOOST_CHECK_EQUAL(signed_rat(1, signed_min_num).denominator(), -signed_min_num); + // This throws because we can't negate signed_min: + BOOST_CHECK_THROW(signed_rat(1, signed_min).denominator(), std::domain_error); + + signed_rat sr; + BOOST_CHECK_EQUAL(sr.assign(signed_max, 1).numerator(), signed_max); + BOOST_CHECK_EQUAL(sr.assign(1, signed_max).denominator(), signed_max); + BOOST_CHECK_EQUAL(sr.assign(signed_min, 1).numerator(), signed_min); + BOOST_CHECK_EQUAL(sr.assign(1, signed_min_num).denominator(), -signed_min_num); + BOOST_CHECK_THROW(sr.assign(1, signed_min), std::domain_error); + + BOOST_CHECK_EQUAL((sr = signed_max).numerator(), signed_max); + BOOST_CHECK_EQUAL((sr = signed_min).numerator(), signed_min); + + boost::int64_t big_signed_max = (std::numeric_limits<boost::int32_t>::max)(); + boost::int64_t big_signed_min = (std::numeric_limits<boost::int32_t>::min)(); + boost::int64_t big_signed_min_num = signed_min + 1; + + BOOST_CHECK_EQUAL(signed_rat(big_signed_max).numerator(), big_signed_max); + BOOST_CHECK_EQUAL(signed_rat(big_signed_min).numerator(), big_signed_min); + BOOST_CHECK_EQUAL(signed_rat(big_signed_max, 1).numerator(), big_signed_max); + BOOST_CHECK_EQUAL(signed_rat(big_signed_min, 1).numerator(), big_signed_min); + BOOST_CHECK_EQUAL(signed_rat(1, big_signed_max).denominator(), big_signed_max); + BOOST_CHECK_EQUAL(signed_rat(1, big_signed_min_num).denominator(), -big_signed_min_num); + // This throws because we can't negate big_signed_min: + BOOST_CHECK_THROW(signed_rat(1, big_signed_min).denominator(), std::domain_error); + + BOOST_CHECK_EQUAL(sr.assign(big_signed_max, 1).numerator(), big_signed_max); + BOOST_CHECK_EQUAL(sr.assign(1, big_signed_max).denominator(), big_signed_max); + BOOST_CHECK_EQUAL(sr.assign(big_signed_min, 1).numerator(), big_signed_min); + BOOST_CHECK_EQUAL(sr.assign(1, big_signed_min_num).denominator(), -big_signed_min_num); + BOOST_CHECK_THROW(sr.assign(1, big_signed_min), std::domain_error); + + BOOST_CHECK_EQUAL((sr = big_signed_max).numerator(), big_signed_max); + BOOST_CHECK_EQUAL((sr = big_signed_min).numerator(), big_signed_min); + + ++big_signed_max; + --big_signed_min; + BOOST_CHECK_THROW(signed_rat(big_signed_max).numerator(), std::domain_error); + BOOST_CHECK_THROW(signed_rat(big_signed_min).numerator(), std::domain_error); + BOOST_CHECK_THROW(signed_rat(big_signed_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(signed_rat(big_signed_min, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(signed_rat(1, big_signed_max).denominator(), std::domain_error); + + BOOST_CHECK_THROW(sr.assign(big_signed_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(sr.assign(1, big_signed_max).denominator(), std::domain_error); + BOOST_CHECK_THROW(sr.assign(big_signed_min, 1).numerator(), std::domain_error); + + BOOST_CHECK_THROW((sr = big_signed_max).numerator(), std::domain_error); + BOOST_CHECK_THROW((sr = big_signed_min).numerator(), std::domain_error); + + boost::int16_t small_signed_max = (std::numeric_limits<boost::int16_t>::max)(); + boost::int16_t small_signed_min = (std::numeric_limits<boost::int16_t>::min)(); + + BOOST_CHECK_EQUAL(signed_rat(small_signed_max).numerator(), small_signed_max); + BOOST_CHECK_EQUAL(signed_rat(small_signed_min).numerator(), small_signed_min); + BOOST_CHECK_EQUAL(signed_rat(small_signed_max, 1).numerator(), small_signed_max); + BOOST_CHECK_EQUAL(signed_rat(small_signed_min, 1).numerator(), small_signed_min); + BOOST_CHECK_EQUAL(signed_rat(1, small_signed_max).denominator(), small_signed_max); + BOOST_CHECK_EQUAL(signed_rat(1, small_signed_min).denominator(), -static_cast<boost::int32_t>(small_signed_min)); + + BOOST_CHECK_EQUAL(sr.assign(small_signed_max, 1).numerator(), small_signed_max); + BOOST_CHECK_EQUAL(sr.assign(1, small_signed_max).denominator(), small_signed_max); + BOOST_CHECK_EQUAL(sr.assign(small_signed_min, 1).numerator(), small_signed_min); + BOOST_CHECK_EQUAL(sr.assign(1, small_signed_min).denominator(), -static_cast<boost::int32_t>(small_signed_min)); + + BOOST_CHECK_EQUAL((sr = small_signed_max).numerator(), small_signed_max); + BOOST_CHECK_EQUAL((sr = small_signed_min).numerator(), small_signed_min); + + boost::uint32_t unsigned_max = signed_max; + BOOST_CHECK_EQUAL(signed_rat(unsigned_max).numerator(), signed_max); + BOOST_CHECK_EQUAL(signed_rat(unsigned_max, 1).numerator(), signed_max); + BOOST_CHECK_EQUAL(signed_rat(1, unsigned_max).denominator(), signed_max); + + BOOST_CHECK_EQUAL(sr.assign(unsigned_max, 1).numerator(), signed_max); + BOOST_CHECK_EQUAL(sr.assign(1, unsigned_max).denominator(), signed_max); + BOOST_CHECK_EQUAL((sr = unsigned_max).numerator(), signed_max); + ++unsigned_max; + BOOST_CHECK_THROW(signed_rat(unsigned_max).numerator(), std::domain_error); + BOOST_CHECK_THROW(signed_rat(unsigned_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(signed_rat(1, unsigned_max).denominator(), std::domain_error); + + BOOST_CHECK_THROW(sr.assign(unsigned_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(sr.assign(1, unsigned_max).denominator(), std::domain_error); + BOOST_CHECK_THROW((sr = unsigned_max).numerator(), std::domain_error); + + boost::uint64_t big_unsigned_max = signed_max; + BOOST_CHECK_EQUAL(signed_rat(big_unsigned_max).numerator(), signed_max); + BOOST_CHECK_EQUAL(signed_rat(big_unsigned_max, 1).numerator(), signed_max); + BOOST_CHECK_EQUAL(signed_rat(1, big_unsigned_max).denominator(), signed_max); + + BOOST_CHECK_EQUAL(sr.assign(big_unsigned_max, 1).numerator(), signed_max); + BOOST_CHECK_EQUAL(sr.assign(1, big_unsigned_max).denominator(), signed_max); + BOOST_CHECK_EQUAL((sr = big_unsigned_max).numerator(), signed_max); + ++big_unsigned_max; + BOOST_CHECK_THROW(signed_rat(big_unsigned_max).numerator(), std::domain_error); + BOOST_CHECK_THROW(signed_rat(big_unsigned_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(signed_rat(1, big_unsigned_max).denominator(), std::domain_error); + + BOOST_CHECK_THROW(sr.assign(big_unsigned_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(sr.assign(1, big_unsigned_max).denominator(), std::domain_error); + BOOST_CHECK_THROW((sr = big_unsigned_max).numerator(), std::domain_error); + + boost::uint16_t small_unsigned_max = signed_max; + BOOST_CHECK_EQUAL(signed_rat(small_unsigned_max).numerator(), small_unsigned_max); + BOOST_CHECK_EQUAL(signed_rat(small_unsigned_max, 1).numerator(), small_unsigned_max); + BOOST_CHECK_EQUAL(signed_rat(1, small_unsigned_max).denominator(), small_unsigned_max); + + BOOST_CHECK_EQUAL(sr.assign(small_unsigned_max, 1).numerator(), small_unsigned_max); + BOOST_CHECK_EQUAL(sr.assign(1, small_unsigned_max).denominator(), small_unsigned_max); + BOOST_CHECK_EQUAL((sr = small_unsigned_max).numerator(), small_unsigned_max); + + // Over again with unsigned rational type: + typedef boost::rational<boost::uint32_t> unsigned_rat; + + unsigned_max = (std::numeric_limits<boost::uint32_t>::max)(); + + BOOST_CHECK_EQUAL(unsigned_rat(unsigned_max).numerator(), unsigned_max); + BOOST_CHECK_EQUAL(unsigned_rat(unsigned_max, 1).numerator(), unsigned_max); + BOOST_CHECK_EQUAL(unsigned_rat(1, unsigned_max).denominator(), unsigned_max); + + unsigned_rat ur; + BOOST_CHECK_EQUAL((ur = unsigned_max).numerator(), unsigned_max); + BOOST_CHECK_EQUAL(ur.assign(unsigned_max, 1).numerator(), unsigned_max); + BOOST_CHECK_EQUAL(ur.assign(1, unsigned_max).denominator(), unsigned_max); + + big_unsigned_max = unsigned_max; + BOOST_CHECK_EQUAL(unsigned_rat(big_unsigned_max).numerator(), big_unsigned_max); + BOOST_CHECK_EQUAL(unsigned_rat(big_unsigned_max, 1).numerator(), big_unsigned_max); + BOOST_CHECK_EQUAL(unsigned_rat(1, big_unsigned_max).denominator(), big_unsigned_max); + BOOST_CHECK_EQUAL((ur = big_unsigned_max).numerator(), big_unsigned_max); + BOOST_CHECK_EQUAL(ur.assign(big_unsigned_max, 1).numerator(), big_unsigned_max); + BOOST_CHECK_EQUAL(ur.assign(1, big_unsigned_max).denominator(), big_unsigned_max); + ++big_unsigned_max; + BOOST_CHECK_THROW(unsigned_rat(big_unsigned_max).numerator(), std::domain_error); + BOOST_CHECK_THROW(unsigned_rat(big_unsigned_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(unsigned_rat(1, big_unsigned_max).denominator(), std::domain_error); + BOOST_CHECK_THROW((ur = big_unsigned_max).numerator(), std::domain_error); + BOOST_CHECK_THROW(ur.assign(big_unsigned_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(ur.assign(1, big_unsigned_max).denominator(), std::domain_error); + + BOOST_CHECK_EQUAL(unsigned_rat(small_unsigned_max).numerator(), small_unsigned_max); + BOOST_CHECK_EQUAL(unsigned_rat(small_unsigned_max, 1).numerator(), small_unsigned_max); + BOOST_CHECK_EQUAL(unsigned_rat(1, small_unsigned_max).denominator(), small_unsigned_max); + BOOST_CHECK_EQUAL((ur = small_unsigned_max).numerator(), small_unsigned_max); + BOOST_CHECK_EQUAL(ur.assign(small_unsigned_max, 1).numerator(), small_unsigned_max); + BOOST_CHECK_EQUAL(ur.assign(1, small_unsigned_max).denominator(), small_unsigned_max); + + BOOST_CHECK_EQUAL(unsigned_rat(signed_max).numerator(), signed_max); + BOOST_CHECK_EQUAL(unsigned_rat(signed_max, 1).numerator(), signed_max); + BOOST_CHECK_EQUAL(unsigned_rat(1, signed_max).denominator(), signed_max); + BOOST_CHECK_EQUAL((ur = signed_max).numerator(), signed_max); + BOOST_CHECK_EQUAL(ur.assign(signed_max, 1).numerator(), signed_max); + BOOST_CHECK_EQUAL(ur.assign(1, signed_max).denominator(), signed_max); + BOOST_CHECK_THROW(unsigned_rat(signed_min).numerator(), std::domain_error); + BOOST_CHECK_THROW(unsigned_rat(signed_min, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(unsigned_rat(1, signed_min).denominator(), std::domain_error); + BOOST_CHECK_THROW((ur = signed_min).numerator(), std::domain_error); + BOOST_CHECK_THROW(ur.assign(signed_min, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(ur.assign(1, signed_min).denominator(), std::domain_error); + + big_signed_max = unsigned_max; + BOOST_CHECK_EQUAL(unsigned_rat(big_signed_max).numerator(), unsigned_max); + BOOST_CHECK_EQUAL(unsigned_rat(big_signed_max, 1).numerator(), unsigned_max); + BOOST_CHECK_EQUAL(unsigned_rat(1, big_signed_max).denominator(), unsigned_max); + BOOST_CHECK_EQUAL((ur = big_signed_max).numerator(), unsigned_max); + BOOST_CHECK_EQUAL(ur.assign(big_signed_max, 1).numerator(), unsigned_max); + BOOST_CHECK_EQUAL(ur.assign(1, big_signed_max).denominator(), unsigned_max); + ++big_signed_max; + BOOST_CHECK_THROW(unsigned_rat(big_signed_max).numerator(), std::domain_error); + BOOST_CHECK_THROW(unsigned_rat(big_signed_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(unsigned_rat(1, big_signed_max).denominator(), std::domain_error); + BOOST_CHECK_THROW((ur = big_signed_max).numerator(), std::domain_error); + BOOST_CHECK_THROW(ur.assign(big_signed_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(ur.assign(1, big_signed_max).denominator(), std::domain_error); + big_signed_max = -1; + BOOST_CHECK_THROW(unsigned_rat(big_signed_max).numerator(), std::domain_error); + BOOST_CHECK_THROW(unsigned_rat(big_signed_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(unsigned_rat(1, big_signed_max).denominator(), std::domain_error); + BOOST_CHECK_THROW((ur = big_signed_max).numerator(), std::domain_error); + BOOST_CHECK_THROW(ur.assign(big_signed_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(ur.assign(1, big_signed_max).denominator(), std::domain_error); + + BOOST_CHECK_EQUAL(unsigned_rat(small_signed_max).numerator(), small_signed_max); + BOOST_CHECK_EQUAL(unsigned_rat(small_signed_max, 1).numerator(), small_signed_max); + BOOST_CHECK_EQUAL(unsigned_rat(1, small_signed_max).denominator(), small_signed_max); + BOOST_CHECK_EQUAL((ur = small_signed_max).numerator(), small_signed_max); + BOOST_CHECK_EQUAL(ur.assign(small_signed_max, 1).numerator(), small_signed_max); + BOOST_CHECK_EQUAL(ur.assign(1, small_signed_max).denominator(), small_signed_max); + small_signed_max = -1; + BOOST_CHECK_THROW(unsigned_rat(small_signed_max).numerator(), std::domain_error); + BOOST_CHECK_THROW(unsigned_rat(small_signed_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(unsigned_rat(1, small_signed_max).denominator(), std::domain_error); + BOOST_CHECK_THROW((ur = small_signed_max).numerator(), std::domain_error); + BOOST_CHECK_THROW(ur.assign(small_signed_max, 1).numerator(), std::domain_error); + BOOST_CHECK_THROW(ur.assign(1, small_signed_max).denominator(), std::domain_error); +} + +BOOST_AUTO_TEST_SUITE_END() + + +// The non-basic rational operations suite +BOOST_AUTO_TEST_SUITE( rational_extras_suite ) + +#ifndef BOOST_NO_IOSTREAM +// Output test +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_output_test, T, all_signed_test_types ) +{ + using namespace std; + typedef boost::rational<T> rational_type; + + // Basic test + ostringstream oss; + + oss << rational_type( 44, 14 ); + BOOST_CHECK_EQUAL( oss.str(), "22/7" ); + + // Width + oss.clear(); oss.str( "" ); + oss << setw( 5 ) << setfill('*') << rational_type( 1, 2 ) << 'r'; + BOOST_CHECK_EQUAL( oss.str(), "**1/2r" ); // not "****1/2r" + + // Positive-sign + oss.clear(); oss.str( "" ); + oss << showpos << rational_type( 2, 3 ) << noshowpos; + BOOST_CHECK_EQUAL( oss.str(), "+2/3" ); // not "+2/+3" + + // Internal padding + oss.clear(); oss.str( "" ); + oss << setw( 8 ) << internal << rational_type( 36, -15 ) << right << 'r'; + BOOST_CHECK_EQUAL( oss.str(), "-***12/5r" ); // not "-*****12/5r" + + // Showbase prefix + oss.clear(); oss.str( "" ); + oss << showbase << hex << rational_type( 34, 987 ) << noshowbase << dec; + BOOST_CHECK_EQUAL( oss.str(), "0x22/3db" ); // not "0x22/0x3db" +} + +// Input test, failing +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_input_failing_test, T, + all_signed_test_types ) +{ + std::istringstream iss( "" ); + boost::rational<T> r; + + iss >> r; + BOOST_CHECK( !iss ); + BOOST_CHECK( !iss.bad() ); + + iss.clear(); + iss.str( "42" ); + iss >> r; + BOOST_CHECK( !iss ); + + iss.clear(); + iss.str( "57A" ); + iss >> r; + BOOST_CHECK( !iss ); + + iss.clear(); + iss.str( "20-20" ); + iss >> r; + BOOST_CHECK( !iss ); + + iss.clear(); + iss.str( "1/" ); + iss >> r; + BOOST_CHECK( !iss ); + + iss.clear(); + iss.str( "1/ 2" ); + iss >> r; + BOOST_CHECK( !iss ); + + iss.clear(); + iss.str( "1 /2" ); + iss >> r; + BOOST_CHECK( !iss ); + + // Illegal value check(s) + typedef std::numeric_limits<T> limits_type; + + iss.clear(); + iss.str( "3/0" ); + iss >> r; + BOOST_CHECK( !iss ); + + if ( limits_type::is_signed && limits_type::is_bounded && + limits_type::min BOOST_PREVENT_MACRO_SUBSTITUTION () + + limits_type::max BOOST_PREVENT_MACRO_SUBSTITUTION () < T(0) ) + { + std::ostringstream oss; + + oss << 1 << '/' << limits_type::min BOOST_PREVENT_MACRO_SUBSTITUTION (); + iss.clear(); + iss.str( oss.str() ); + iss.exceptions( std::ios::failbit ); + BOOST_CHECK( iss.good() ); + BOOST_CHECK_THROW( iss >> r, boost::bad_rational ); + BOOST_CHECK( iss.fail() && !iss.bad() ); + iss.exceptions( std::ios::goodbit ); + } +} + +// Input test, passing +BOOST_AUTO_TEST_CASE_TEMPLATE( rational_input_passing_test, T, + all_signed_test_types ) +{ + typedef boost::rational<T> rational_type; + + std::istringstream iss( "1/2 12" ); + rational_type r; + int n = 0; + + BOOST_CHECK( iss >> r >> n ); + BOOST_CHECK_EQUAL( r, rational_type(1, 2) ); + BOOST_CHECK_EQUAL( n, 12 ); + + iss.clear(); + iss.str( "34/67" ); + BOOST_CHECK( iss >> r ); + BOOST_CHECK_EQUAL( r, rational_type(34, 67) ); + + iss.clear(); + iss.str( "-3/-6" ); + BOOST_CHECK( iss >> r ); + BOOST_CHECK_EQUAL( r, rational_type(1, 2) ); +} +#endif // BOOST_NO_IOSTREAM + +// Conversion test +BOOST_AUTO_TEST_CASE( rational_cast_test ) +{ + // Note that these are not generic. The problem is that rational_cast<T> + // requires a conversion from IntType to T. However, for a user-defined + // IntType, it is not possible to define such a conversion except as an + // "operator T()". This causes problems with overloading resolution. + boost::rational<int> const half( 1, 2 ); + + BOOST_CHECK_CLOSE( boost::rational_cast<double>(half), 0.5, 0.01 ); + BOOST_CHECK_EQUAL( boost::rational_cast<int>(half), 0 ); + BOOST_CHECK_EQUAL( boost::rational_cast<MyInt>(half), MyInt() ); + BOOST_CHECK_EQUAL( boost::rational_cast<boost::rational<MyInt> >(half), + boost::rational<MyInt>(1, 2) ); + + // Conversions via explicit-marked constructors + // (Note that the "explicit" mark prevents conversion to + // boost::rational<MyOverflowingUnsigned>.) + boost::rational<MyInt> const threehalves( 3, 2 ); + + BOOST_CHECK_EQUAL( boost::rational_cast<MyOverflowingUnsigned>(threehalves), + MyOverflowingUnsigned(1u) ); + // + // Converting constructor should throw if a bad rational number results: + // + BOOST_CHECK_THROW(boost::rational<short>(boost::rational<long>(1, 1 << sizeof(short) * CHAR_BIT)), boost::bad_rational); + // + // New tests from checked narrowing conversions: + // + BOOST_CHECK_THROW(boost::rational<unsigned>(-1), boost::bad_rational); + BOOST_CHECK_THROW(boost::rational<unsigned>(-1, 1), boost::bad_rational); + BOOST_CHECK_THROW(boost::rational<unsigned>(1, -1), boost::bad_rational); + unsigned ui_max = (std::numeric_limits<unsigned>::max)(); + BOOST_CHECK_THROW(boost::rational<int>(static_cast<unsigned>(ui_max)), boost::bad_rational); + BOOST_CHECK_THROW(boost::rational<int>(ui_max, 1u), boost::bad_rational); + BOOST_CHECK_THROW(boost::rational<int>(1u, ui_max), boost::bad_rational); + // + // Check assignments that should succeed from both wider and narrower types: + // + boost::rational<boost::int32_t> rat; +#ifndef BOOST_NO_INT64_T + boost::int64_t ll, ll1(1); + boost::uint64_t ull, ull1(1); + boost::int32_t imax = (std::numeric_limits<boost::int32_t>::max)(); + boost::int32_t imin = (std::numeric_limits<boost::int32_t>::min)(); + ll = imax; + rat.assign(ll, ll1); + BOOST_CHECK_EQUAL(rat.numerator(), imax); + BOOST_CHECK_EQUAL(rat.denominator(), 1); + ++ll; + BOOST_CHECK_THROW(rat.assign(ll, ll1), boost::bad_rational); + ll = imin; + rat.assign(ll, ll1); + BOOST_CHECK_EQUAL(rat.numerator(), imin); + BOOST_CHECK_EQUAL(rat.denominator(), 1); + --ll; + BOOST_CHECK_THROW(rat.assign(ll, ll1), boost::bad_rational); + ull = imax; + rat.assign(ull, ull1); + BOOST_CHECK_EQUAL(rat.numerator(), imax); + BOOST_CHECK_EQUAL(rat.denominator(), 1); + ++ull; + BOOST_CHECK_THROW(rat.assign(ull, ull1), boost::bad_rational); + ull = 0; + rat.assign(ull, ull1); + BOOST_CHECK_EQUAL(rat.numerator(), 0); + BOOST_CHECK_EQUAL(rat.denominator(), 1); +#endif + boost::int16_t smax = (std::numeric_limits<boost::int16_t>::max)(); + boost::int16_t smin = (std::numeric_limits<boost::int16_t>::min)(); + boost::int16_t s1 = 1; + rat.assign(smax, s1); + BOOST_CHECK_EQUAL(rat.numerator(), smax); + BOOST_CHECK_EQUAL(rat.denominator(), 1); + rat.assign(smin, s1); + BOOST_CHECK_EQUAL(rat.numerator(), smin); + BOOST_CHECK_EQUAL(rat.denominator(), 1); + boost::uint16_t usmax = (std::numeric_limits<boost::uint16_t>::max)(); + boost::uint16_t usmin = (std::numeric_limits<boost::uint16_t>::min)(); + boost::uint16_t us1 = 1; + rat.assign(usmax, us1); + BOOST_CHECK_EQUAL(rat.numerator(), usmax); + BOOST_CHECK_EQUAL(rat.denominator(), 1); + rat.assign(usmin, us1); + BOOST_CHECK_EQUAL(rat.numerator(), usmin); + BOOST_CHECK_EQUAL(rat.denominator(), 1); + // + // Over again with unsigned rational: + // + boost::rational<boost::uint32_t> urat; + unsigned uimax = (std::numeric_limits<boost::uint32_t>::max)(); + unsigned uimin = (std::numeric_limits<boost::uint32_t>::min)(); +#ifndef BOOST_NO_INT64_T + ll = uimax; + urat.assign(ll, ll1); + BOOST_CHECK_EQUAL(urat.numerator(), uimax); + BOOST_CHECK_EQUAL(urat.denominator(), 1); + ++ll; + BOOST_CHECK_THROW(urat.assign(ll, ll1), boost::bad_rational); + ll = uimin; + urat.assign(ll, ll1); + BOOST_CHECK_EQUAL(urat.numerator(), uimin); + BOOST_CHECK_EQUAL(urat.denominator(), 1); + --ll; + BOOST_CHECK_THROW(urat.assign(ll, ll1), boost::bad_rational); + ull = uimax; + urat.assign(ull, ull1); + BOOST_CHECK_EQUAL(urat.numerator(), uimax); + BOOST_CHECK_EQUAL(urat.denominator(), 1); + ++ull; + BOOST_CHECK_THROW(urat.assign(ull, ull1), boost::bad_rational); + ull = 0; + urat.assign(ull, ull1); + BOOST_CHECK_EQUAL(urat.numerator(), 0); + BOOST_CHECK_EQUAL(urat.denominator(), 1); +#endif + smin = 0; + s1 = 1; + urat.assign(smax, s1); + BOOST_CHECK_EQUAL(urat.numerator(), smax); + BOOST_CHECK_EQUAL(urat.denominator(), 1); + urat.assign(smin, s1); + BOOST_CHECK_EQUAL(urat.numerator(), smin); + BOOST_CHECK_EQUAL(urat.denominator(), 1); + urat.assign(usmax, us1); + BOOST_CHECK_EQUAL(urat.numerator(), usmax); + BOOST_CHECK_EQUAL(urat.denominator(), 1); + urat.assign(usmin, us1); + BOOST_CHECK_EQUAL(urat.numerator(), usmin); + BOOST_CHECK_EQUAL(urat.denominator(), 1); + // + // Conversions that must not be allowed: + // + BOOST_STATIC_ASSERT(!boost::is_convertible<float, boost::rational<int> >::value); + BOOST_STATIC_ASSERT(!boost::is_convertible<double, boost::rational<int> >::value); + BOOST_STATIC_ASSERT(!boost::is_convertible<long double, boost::rational<int> >::value); + // And ones that should: + BOOST_STATIC_ASSERT(boost::is_convertible<char, boost::rational<int> >::value); + BOOST_STATIC_ASSERT(boost::is_convertible<signed char, boost::rational<int> >::value); + BOOST_STATIC_ASSERT(boost::is_convertible<unsigned char, boost::rational<int> >::value); + BOOST_STATIC_ASSERT(boost::is_convertible<short, boost::rational<int> >::value); + BOOST_STATIC_ASSERT(boost::is_convertible<unsigned short, boost::rational<int> >::value); + BOOST_STATIC_ASSERT(boost::is_convertible<int, boost::rational<int> >::value); + BOOST_STATIC_ASSERT(boost::is_convertible<unsigned int, boost::rational<int> >::value); + BOOST_STATIC_ASSERT(boost::is_convertible<long, boost::rational<int> >::value); + BOOST_STATIC_ASSERT(boost::is_convertible<unsigned long, boost::rational<int> >::value); +} + +#ifndef BOOST_NO_MEMBER_TEMPLATES +// Cross-conversion constructor test +BOOST_AUTO_TEST_CASE( rational_cross_constructor_test ) +{ + // This template will be repeated a lot. + using boost::rational; + + // Create a bunch of explicit conversions. + rational<int> const half_i( 2, 4 ); + rational<unsigned> const half_u( half_i ); + rational<MyInt> const half_mi( half_i ); + rational<MyOverflowingUnsigned> const half_mu1(half_u), half_mu2(half_mi); + + BOOST_CHECK_EQUAL( half_u.numerator(), 1u ); + BOOST_CHECK_EQUAL( half_u.denominator(), 2u ); + BOOST_CHECK_EQUAL( half_mi.numerator(), MyInt(1) ); + BOOST_CHECK_EQUAL( half_mi.denominator(), MyInt(2) ); + BOOST_CHECK_EQUAL( half_mu1.numerator(), MyOverflowingUnsigned(1u) ); + BOOST_CHECK_EQUAL( half_mu1.denominator(), MyOverflowingUnsigned(2u) ); + BOOST_CHECK_EQUAL( half_mu2.numerator(), MyOverflowingUnsigned(1u) ); + BOOST_CHECK_EQUAL( half_mu2.denominator(), MyOverflowingUnsigned(2u) ); + +#if 0 + // This will fail since it needs an implicit conversion. + // (Try it if your compiler supports C++11 lambdas.) + BOOST_CHECK( [](rational<unsigned> x){return !!x;}(half_i) ); +#endif + + // Translation from a built-in unsigned type to a signed one is + // implementation-defined, so hopefully we won't get a trap value. + // (We're counting on static_cast<int>(UINT_MAX) being negative.) + rational<unsigned> const too_small( 1u, UINT_MAX ); + rational<int> receiver; + + BOOST_CHECK_THROW( receiver=rational<int>(too_small), boost::bad_rational ); +} +#endif // BOOST_NO_MEMBER_TEMPLATES + +// Dice tests (a non-main test) +BOOST_AUTO_TEST_CASE_TEMPLATE( dice_roll_test, T, all_signed_test_types ) +{ + typedef boost::rational<T> rational_type; + + // Determine the mean number of times a fair six-sided die + // must be thrown until each side has appeared at least once. + rational_type r = T( 0 ); + + for ( int i = 1 ; i <= 6 ; ++i ) + { + r += rational_type( 1, i ); + } + r *= static_cast<T>( 6 ); + + BOOST_CHECK_EQUAL( r, rational_type(147, 10) ); +} + +BOOST_AUTO_TEST_SUITE_END() + + +// The bugs, patches, and requests checking suite +BOOST_AUTO_TEST_SUITE( bug_patch_request_suite ) + +// "rational operator< can overflow" +BOOST_AUTO_TEST_CASE( bug_798357_test ) +{ + // Choose values such that rational-number comparisons will overflow if + // the multiplication method (n1/d1 ? n2/d2 == n1*d2 ? n2*d1) is used. + // (And make sure that the large components are relatively prime, so they + // won't partially cancel to make smaller, more reasonable, values.) + unsigned const n1 = UINT_MAX - 2u, d1 = UINT_MAX - 1u; + unsigned const n2 = d1, d2 = UINT_MAX; + boost::rational<MyOverflowingUnsigned> const r1( n1, d1 ), r2( n2, d2 ); + + BOOST_REQUIRE_EQUAL( boost::integer::gcd(n1, d1), 1u ); + BOOST_REQUIRE_EQUAL( boost::integer::gcd(n2, d2), 1u ); + BOOST_REQUIRE( n1 > UINT_MAX / d2 ); + BOOST_REQUIRE( n2 > UINT_MAX / d1 ); + BOOST_CHECK( r1 < r2 ); + BOOST_CHECK( !(r1 < r1) ); + BOOST_CHECK( !(r2 < r1) ); +} + +// "rational::operator< fails for unsigned value types" +BOOST_AUTO_TEST_CASE( patch_1434821_test ) +{ + // If a zero-rational v. positive-integer comparison involves negation, then + // it may fail with unsigned types, which wrap around (for built-ins) or + // throw/be-undefined (for user-defined types). + boost::rational<unsigned> const r( 0u ); + + BOOST_CHECK( r < 1u ); +} + +// "rational.hpp::gcd returns a negative value sometimes" +BOOST_AUTO_TEST_CASE( patch_1438626_test ) +{ + // The issue only manifests with 2's-complement integers that use their + // entire range of bits. [This means that ln(-INT_MIN)/ln(2) is an integer + // and INT_MAX + INT_MIN == -1.] The common computer platforms match this. +#if (INT_MAX + INT_MIN == -1) && ((INT_MAX ^ INT_MIN) == -1) + // If a GCD routine takes the absolute value of an argument only before + // processing, it won't realize that -INT_MIN -> INT_MIN (i.e. no change + // from negation) and will propagate a negative sign to its result. + BOOST_REQUIRE_EQUAL( boost::integer::gcd(INT_MIN, 6), 2 ); + + // That is bad if the rational number type does not check for that + // possibility during normalization. + boost::rational<int> const r1( INT_MIN / 2 + 3, 6 ), + r2( INT_MIN / 2 - 3, 6 ), r3 = r1 + r2; + + // If the error happens, the signs of the components will be switched. + // (The numerators' sum is INT_MIN, and its GCD with 6 would be negated.) + BOOST_CHECK_EQUAL( r3.numerator(), INT_MIN / 2 ); + BOOST_CHECK_EQUAL( r3.denominator(), 3 ); +#endif +} + +// The bug/patch numbers for the above 3 tests are from our SourceForge repo +// before we moved to our own SVN & Trac server. At the time this note is +// written, it seems that SourceForge has reset their tracking numbers at least +// once, so I don't know how to recover those old tickets. The ticket numbers +// for the following tests are from our SVN/Trac repo. + +//"narrowing conversion error with -std=c++0x in operator< with int_type != int" +BOOST_AUTO_TEST_CASE( ticket_5855_test ) +{ + // The internals of operator< currently store a structure of two int_type + // (where int_type is the component type of a boost::rational template + // class) and two computed types. These computed types, results of + // arithmetic operations among int_type values, are either int_type + // themselves or a larger type that can implicitly convert to int_type. + // Those conversions aren't usually a problem. But when an arithmetic + // operation involving two values of a built-in scalar type smaller than int + // are involved, the result is an int. But the resulting int-to-shorter + // conversion is considered narrowing, resulting in a warning or error on + // some compilers. Notably, C++11 compilers are supposed to consider it an + // error. + // + // The solution is to force an explicit conversion, although it's otherwise + // not needed. (The compiler can rescind the narrowing warning if the + // results of the larger type still fit in the smaller one, and that proof + // can be generated at constexpr time.) + typedef short shorter_than_int_type; + typedef boost::rational<shorter_than_int_type> rational_type; + + bool const dummy = rational_type() < rational_type(); + + BOOST_REQUIRE( !dummy ); +} + +// "rational::assign" doesn't even have the basic guarantee +BOOST_AUTO_TEST_CASE( ticket_9067_test ) +{ + using boost::rational; + using boost::integer::gcd; + + rational<int> a( 6, -8 ); + + // Normalize to maintain invariants + BOOST_CHECK_EQUAL( a.numerator(), -3 ); + BOOST_CHECK_EQUAL( a.denominator(), 4 ); + BOOST_CHECK( a.denominator() > 0 ); + BOOST_CHECK_EQUAL( gcd(a.numerator(), a.denominator()), 1 ); + + // Do we maintain the basic guarantee after a failed component-assign? + BOOST_CHECK_THROW( a.assign(1, 0), boost::bad_rational ); + BOOST_CHECK_NE( a.denominator(), 0 ); + BOOST_CHECK( a.denominator() > 0 ); + BOOST_CHECK_EQUAL( gcd(a.numerator(), a.denominator()), 1 ); + + // Do we get the strong guarantee? + BOOST_CHECK_EQUAL( a.numerator(), -3 ); + BOOST_CHECK_EQUAL( a.denominator(), 4 ); + +#if INT_MIN + INT_MAX < 0 + // Try an example without a zero-denominator + a = rational<int>( -9, 12 ); + BOOST_CHECK_EQUAL( a.numerator(), -3 ); + BOOST_CHECK_EQUAL( a.denominator(), 4 ); + BOOST_CHECK( a.denominator() > 0 ); + BOOST_CHECK_EQUAL( gcd(a.numerator(), a.denominator()), 1 ); + BOOST_CHECK_THROW( a.assign(-(INT_MIN + 1), INT_MIN), boost::bad_rational ); + BOOST_CHECK( a.denominator() > 0 ); + BOOST_CHECK_EQUAL( gcd(a.numerator(), a.denominator()), 1 ); + BOOST_CHECK_EQUAL( a.numerator(), -3 ); + BOOST_CHECK_EQUAL( a.denominator(), 4 ); +#endif +} + +BOOST_AUTO_TEST_SUITE_END() |