From 4acedca122b595670e54d836ccc4b96801e8bb99 Mon Sep 17 00:00:00 2001 From: Chris Fairles Date: Fri, 4 Jul 2008 18:45:09 +0000 Subject: [PATCH] ratio: New, per N2661. 2008-07-04 Chris Fairles * include/std/ratio: New, per N2661. * include/Makefile.am: Update. * include/Makefile.in: Regenerate. * testsuite/20_util/ratio/cons/cons1.cc: New. * testsuite/20_util/ratio/cons/cons_overflow.cc: Likewise. * testsuite/20_util/ratio/operations/ops1.cc: Likewise. * testsuite/20_util/ratio/operations/ops2.cc: Likewise. * testsuite/20_util/ratio/operations/ops3.cc: Likewise. * testsuite/20_util/ratio/operations/ops_overflow.cc: Likewise. * testsuite/20_util/ratio/comparisons/comp1.cc: Likewise. From-SVN: r137482 --- libstdc++-v3/ChangeLog | 13 + libstdc++-v3/include/Makefile.am | 1 + libstdc++-v3/include/Makefile.in | 1 + libstdc++-v3/include/std/ratio | 257 ++++++++++++++++++ .../20_util/ratio/comparisons/comp1.cc | 87 ++++++ .../testsuite/20_util/ratio/cons/cons1.cc | 57 ++++ .../20_util/ratio/cons/cons_overflow.cc | 58 ++++ .../20_util/ratio/operations/ops1.cc | 80 ++++++ .../20_util/ratio/operations/ops2.cc | 78 ++++++ .../20_util/ratio/operations/ops3.cc | 77 ++++++ .../20_util/ratio/operations/ops_overflow.cc | 51 ++++ 11 files changed, 760 insertions(+) create mode 100644 libstdc++-v3/include/std/ratio create mode 100644 libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc create mode 100644 libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc create mode 100644 libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc create mode 100644 libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc create mode 100644 libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc create mode 100644 libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc create mode 100644 libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1f47acdf2d3..cae60608575 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2008-07-04 Chris Fairles + + * include/std/ratio: New, per N2661. + * include/Makefile.am: Update. + * include/Makefile.in: Regenerate. + * testsuite/20_util/ratio/cons/cons1.cc: New. + * testsuite/20_util/ratio/cons/cons_overflow.cc: Likewise. + * testsuite/20_util/ratio/operations/ops1.cc: Likewise. + * testsuite/20_util/ratio/operations/ops2.cc: Likewise. + * testsuite/20_util/ratio/operations/ops3.cc: Likewise. + * testsuite/20_util/ratio/operations/ops_overflow.cc: Likewise. + * testsuite/20_util/ratio/comparisons/comp1.cc: Likewise. + 2008-07-04 Paolo Carlini PR libstdc++/36616 diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index a8f48c7d282..7e82b8034b4 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -55,6 +55,7 @@ std_headers = \ ${std_srcdir}/queue \ ${std_srcdir}/random \ ${std_srcdir}/regex \ + ${std_srcdir}/ratio \ ${std_srcdir}/set \ ${std_srcdir}/sstream \ ${std_srcdir}/stack \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 8c1e626934f..c85c8bd233f 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -307,6 +307,7 @@ std_headers = \ ${std_srcdir}/ostream \ ${std_srcdir}/queue \ ${std_srcdir}/random \ + ${std_srcdir}/ratio \ ${std_srcdir}/regex \ ${std_srcdir}/set \ ${std_srcdir}/sstream \ diff --git a/libstdc++-v3/include/std/ratio b/libstdc++-v3/include/std/ratio new file mode 100644 index 00000000000..6dcefa5b931 --- /dev/null +++ b/libstdc++-v3/include/std/ratio @@ -0,0 +1,257 @@ +// -*- C++ -*- + +// Copyright (C) 2008 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ratio + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_RATIO +#define _GLIBCXX_RATIO 1 + +#pragma GCC system_header + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ +# include +#else + +#include +#include + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +namespace std +{ + template + struct __static_sign + : integral_constant + { }; + + template + struct __static_abs + : integral_constant::value> + { }; + + template + struct __static_gcd; + + template + struct __static_gcd + : __static_gcd<_Qn, (_Pn % _Qn)> + { }; + + template + struct __static_gcd<_Pn, 0> + : integral_constant::value> + { }; + + template + struct __static_gcd<0, _Qn> + : integral_constant::value> + { }; + + // Let c = 2^(half # of bits in an intmax_t) + // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0 + // The multiplication of N and M becomes, + // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0 + // Multiplication is safe if each term and the sum of the terms + // is representable by intmax_t. + template + struct __safe_multiply + { + private: + static const uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); + + static const uintmax_t __a0 = __static_abs<_Pn>::value % __c; + static const uintmax_t __a1 = __static_abs<_Pn>::value / __c; + static const uintmax_t __b0 = __static_abs<_Qn>::value % __c; + static const uintmax_t __b1 = __static_abs<_Qn>::value / __c; + + static_assert(__a1 == 0 || __b1 == 0, + "overflow in multiplication"); + static_assert(__a0 * __b1 + __b0 * __a1 < (__c >> 1), + "overflow in multiplication"); + static_assert(__b0 * __a0 <= INTMAX_MAX, + "overflow in multiplication"); + static_assert((__a0 * __b1 + __b0 * __a1) * __c <= + INTMAX_MAX - __b0 * __a0, "overflow in multiplication"); + + public: + static const intmax_t value = _Pn * _Qn; + }; + + // Helpers for __safe_add + template + struct __add_overflow_check_impl + : integral_constant + { }; + + template + struct __add_overflow_check_impl<_Pn, _Qn, false> + : integral_constant= -INTMAX_MAX - _Qn)> + { }; + + template + struct __add_overflow_check + : __add_overflow_check_impl<_Pn, _Qn, (_Qn >= 0)> + { }; + + template + struct __safe_add + { + static_assert(__add_overflow_check<_Pn, _Qn>::value != 0, + "overflow in addition"); + + static const intmax_t value = _Pn + _Qn; + }; + + template + struct ratio + { + static_assert(_Den != 0, "denominator cannot be zero"); + static_assert(_Num > INTMAX_MIN && _Den > INTMAX_MIN, "out of range"); + + // Note: sign(N) * abs(N) == N + static const intmax_t num = + _Num * __static_sign<_Den>::value / __static_gcd<_Num, _Den>::value; + + static const intmax_t den = + __static_abs<_Den>::value / __static_gcd<_Num, _Den>::value; + }; + + template + const intmax_t ratio<_Num, _Den>::num; + + template + const intmax_t ratio<_Num, _Den>::den; + + template + struct ratio_add + { + private: + static const intmax_t __gcd = + __static_gcd<_R1::den, _R2::den>::value; + + public: + typedef ratio< + __safe_add< + __safe_multiply<_R1::num, (_R2::den / __gcd)>::value, + __safe_multiply<_R2::num, (_R1::den / __gcd)>::value>::value, + __safe_multiply<_R1::den, (_R2::den / __gcd)>::value> type; + }; + + template + struct ratio_subtract + { + typedef typename ratio_add< + _R1, + ratio<-_R2::num, _R2::den>>::type type; + }; + + template + struct ratio_multiply + { + private: + static const intmax_t __gcd1 = + __static_gcd<_R1::num, _R2::den>::value; + static const intmax_t __gcd2 = + __static_gcd<_R2::num, _R1::den>::value; + + public: + typedef ratio< + __safe_multiply<(_R1::num / __gcd1), + (_R2::num / __gcd2)>::value, + __safe_multiply<(_R1::den / __gcd2), + (_R2::den / __gcd1)>::value> type; + }; + + template + struct ratio_divide + { + static_assert(_R2::num != 0, "division by 0"); + + typedef typename ratio_multiply< + _R1, + ratio<_R2::den, _R2::num>>::type type; + }; + + template + struct ratio_equal + : integral_constant + { }; + + template + struct ratio_not_equal + : integral_constant::value> + { }; + + template + struct ratio_less + : integral_constant::value < + __safe_multiply<_R2::num, _R1::den>::value)> + { }; + + template + struct ratio_less_equal + : integral_constant::value> + { }; + + template + struct ratio_greater + : integral_constant::value> + { }; + + template + struct ratio_greater_equal + : integral_constant::value> + { }; + + typedef ratio<1, 1000000000000000000> atto; + typedef ratio<1, 1000000000000000> femto; + typedef ratio<1, 1000000000000> pico; + typedef ratio<1, 1000000000> nano; + typedef ratio<1, 1000000> micro; + typedef ratio<1, 1000> milli; + typedef ratio<1, 100> centi; + typedef ratio<1, 10> deci; + typedef ratio< 10, 1> deca; + typedef ratio< 100, 1> hecto; + typedef ratio< 1000, 1> kilo; + typedef ratio< 1000000, 1> mega; + typedef ratio< 1000000000, 1> giga; + typedef ratio< 1000000000000, 1> tera; + typedef ratio< 1000000000000000, 1> peta; + typedef ratio< 1000000000000000000, 1> exa; +} + +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + +#endif //__GXX_EXPERIMENTAL_CXX0X__ + +#endif //_GLIBCXX_RATIO diff --git a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc new file mode 100644 index 00000000000..73064c70919 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc @@ -0,0 +1,87 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2008 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include +#include + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +void +test01() +{ + bool test __attribute__((unused)) = true; + + VERIFY(( std::ratio_equal, std::ratio<1,3>>::value == 1 )); + VERIFY(( std::ratio_equal, std::ratio<1,4>>::value == 0 )); + + VERIFY(( std::ratio_not_equal, + std::ratio<1,3>>::value == 0 )); + VERIFY(( std::ratio_not_equal, + std::ratio<1,4>>::value == 1 )); +} + +void +test02() +{ + bool test __attribute__((unused)) = true; + + VERIFY(( std::ratio_less, std::ratio<1,3>>::value == 1 )); + VERIFY(( std::ratio_less, std::ratio<1,3>>::value == 1 )); + + VERIFY(( std::ratio_less, std::ratio<1,4>>::value == 0 )); + VERIFY(( std::ratio_less, std::ratio<-1,3>>::value == 0 )); + + VERIFY(( std::ratio_less_equal, + std::ratio<-1,3>>::value == 1 )); + VERIFY(( std::ratio_less_equal, + std::ratio<1,3>>::value == 1 )); + + VERIFY(( std::ratio_less_equal, + std::ratio<-1,3>>::value == 0 )); + VERIFY(( std::ratio_less_equal, + std::ratio<-1,3>>::value == 0 )); + + VERIFY(( std::ratio_greater, std::ratio<1,4>>::value == 1 )); + VERIFY(( std::ratio_greater, std::ratio<-1,3>>::value == 1 )); + + VERIFY(( std::ratio_greater, std::ratio<1,3>>::value == 0 )); + VERIFY(( std::ratio_greater, std::ratio<1,3>>::value == 0 )); + + VERIFY(( std::ratio_greater_equal, + std::ratio<1,3>>::value == 1 )); + VERIFY(( std::ratio_greater_equal, + std::ratio<-1,3>>::value == 1 )); + + VERIFY(( std::ratio_greater_equal, + std::ratio<1,3>>::value == 0 )); + VERIFY(( std::ratio_greater_equal, + std::ratio<1,3>>::value == 0 )); +} + +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + +int main() +{ +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + test01(); + test02(); +#endif + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc b/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc new file mode 100644 index 00000000000..dc2f0dabd70 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc @@ -0,0 +1,57 @@ +// { dg-options "-std=gnu++0x" } + +// 2008-07-03 Chris Fairles + +// Copyright (C) 2008 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include +#include + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::ratio<1,3> r0; + std::ratio<2,6> r1; + std::ratio<2,-6> r2; + std::ratio<-2,6> r3; + + VERIFY( r0.num == 1 ); + VERIFY( r0.den == 3 ); + + VERIFY( r1.num == r0.num ); + VERIFY( r1.den == r0.den ); + VERIFY( r2.num == -r0.num ); + VERIFY( r2.den == r0.den ); + VERIFY( r3.num == -r0.num ); + VERIFY( r3.den == r0.den ); +} + +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + +int main() +{ +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + test01(); +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc new file mode 100644 index 00000000000..26bbfcdec53 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc @@ -0,0 +1,58 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2008 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +void +test01() +{ + std::ratio r1; + std::ratio<-INTMAX_MAX, INTMAX_MAX> r2; +} + +void +test02() +{ + std::ratio r1; +} + +void +test03() +{ + std::ratio<1, INTMAX_MIN> r1; +} + +void +test04() +{ + std::ratio<1,0> r1; +} + +// { dg-error "instantiated from here" "" { target *-*-* } 36 } +// { dg-error "instantiated from here" "" { target *-*-* } 42 } +// { dg-error "instantiated from here" "" { target *-*-* } 48 } +// { dg-error "denominator cannot be zero" "" { target *-*-* } 136 } +// { dg-error "out of range" "" { target *-*-* } 137 } +// { dg-excess-errors "In instantiation of" } + +#endif //_GLIBCXX_USE_C99_STDINT_TR1 diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc new file mode 100644 index 00000000000..3f6a91d2180 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc @@ -0,0 +1,80 @@ +// { dg-options "-std=gnu++0x" } + +// 2008-07-03 Chris Fairles + +// Copyright (C) 2008 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include +#include + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::ratio_add, std::ratio<5,12>>::type r; + + VERIFY( r.num == 19); + VERIFY( r.den == 24); +} + +void +test02() +{ + bool test __attribute__((unused)) = true; + std::ratio_subtract, std::ratio<5,12>>::type r; + + VERIFY( r.num == -1); + VERIFY( r.den == 24); +} + +void +test03() +{ + bool test __attribute__((unused)) = true; + std::ratio_multiply, std::ratio<5,12>>::type r; + + VERIFY( r.num == 5); + VERIFY( r.den == 32); +} + +void +test04() +{ + bool test __attribute__((unused)) = true; + std::ratio_divide, std::ratio<5,12>>::type r; + + VERIFY( r.num == 9); + VERIFY( r.den == 10); +} + +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + +int main() +{ +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + test01(); + test02(); + test03(); + test04(); +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc new file mode 100644 index 00000000000..2dc2be6b6d8 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc @@ -0,0 +1,78 @@ +// { dg-options "-std=gnu++0x" } + +// 2008-07-03 Chris Fairles + +// Copyright (C) 2008 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include +#include + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +typedef std::ratio<1, INTMAX_MAX> one_over_max; +typedef std::ratio<2, INTMAX_MAX> two_over_max; +typedef std::ratio max_over_one; +typedef std::ratio max_over_two; + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::ratio_add::type r1; + + VERIFY( r1.num == two_over_max::num); + VERIFY( r1.den == two_over_max::den); + + std::ratio_add< + std::ratio, + std::ratio>::type r2; + + VERIFY( r2.num == INTMAX_MAX); + VERIFY( r2.den == (INTMAX_MAX / 2) + 1); +} + +void +test02() +{ + bool test __attribute__((unused)) = true; + + std::ratio_subtract::type r1; + + VERIFY( r1.num == 0); + VERIFY( r1.den == 1); + + std::ratio_subtract< + std::ratio, + std::ratio>::type r2; + + VERIFY( r2.num == 1); + VERIFY( r2.den == (INTMAX_MAX / 2) + 1); +} + +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + +int main() +{ +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + test01(); + test02(); +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc new file mode 100644 index 00000000000..d66c37cf383 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc @@ -0,0 +1,77 @@ +// { dg-options "-std=gnu++0x" } + +// 2008-07-03 Chris Fairles + +// Copyright (C) 2008 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include +#include + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::ratio_multiply< + std::ratio<2, INTMAX_MAX>, + std::ratio>::type r1; + + VERIFY( r1.num == 1); + VERIFY( r1.den == 1); + + std::ratio_multiply< + std::ratio, + std::ratio<2 , INTMAX_MAX - 1>>::type r2; + + VERIFY( r2.num == INTMAX_MAX); + VERIFY( r2.den == INTMAX_MAX - 1); +} + +void +test02() +{ + bool test __attribute__((unused)) = true; + + std::ratio_divide< + std::ratio, + std::ratio>::type r1; + + VERIFY( r1.num == 1); + VERIFY( r1.den == 1); + + std::ratio_divide< + std::ratio, + std::ratio>::type r2; + + VERIFY( r2.num == INTMAX_MAX - 1); + VERIFY( r2.den == INTMAX_MAX); +} + +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + +int main() +{ +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + test01(); + test02(); +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc new file mode 100644 index 00000000000..7dffda39da2 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc @@ -0,0 +1,51 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// 2008-07-03 Chris Fairles + +// Copyright (C) 2008 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +void +test01() +{ + std::ratio_add, std::ratio<1>>::type r1; +} + +void +test02() +{ + std::ratio_multiply, std::ratio<3, 2>>::type r1; + std::ratio_multiply, std::ratio>::type r2; +} + +// { dg-error "instantiated from here" "" { target *-*-* } 31 } +// { dg-error "instantiated from here" "" { target *-*-* } 37 } +// { dg-error "instantiated from here" "" { target *-*-* } 38 } +// { dg-error "overflow in addition" "" { target *-*-* } 127 } +// { dg-error "overflow in multiplication" "" { target *-*-* } 95 } +// { dg-error "overflow in multiplication" "" { target *-*-* } 97 } +// { dg-error "overflow in multiplication" "" { target *-*-* } 99 } +// { dg-excess-errors "In instantiation of" } +// { dg-excess-errors "out of range" } + +#endif //_GLIBCXX_USE_C99_STDINT_TR1