Index: libstdc++-v3/include/Makefile.in =================================================================== --- libstdc++-v3/include/Makefile.in (revision 137251) +++ libstdc++-v3/include/Makefile.in (working copy) @@ -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 \ Index: libstdc++-v3/include/std/ratio =================================================================== --- libstdc++-v3/include/std/ratio (revision 0) +++ libstdc++-v3/include/std/ratio (revision 0) @@ -0,0 +1,248 @@ +// -*- 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 include/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 +#include + +namespace std +{ + template + struct __static_sign : + std::integral_constant + {}; + + template + struct __static_abs : + std::integral_constant::value> + {}; + + template + struct __static_gcd; + + template + struct __static_gcd : + __static_gcd<__M, (__N % __M)> + {}; + + template + struct __static_gcd<__N, 0> : + std::integral_constant::value> + {}; + + template + struct __static_gcd<0, __M> : + std::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 + { + static const uintmax_t __c = 1ul << (sizeof(intmax_t) * 4); + + static const uintmax_t __a0 = __static_abs<__N>::value % __c; + static const uintmax_t __a1 = __static_abs<__N>::value / __c; + static const uintmax_t __b0 = __static_abs<__M>::value % __c; + static const uintmax_t __b1 = __static_abs<__M>::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"); + + static const intmax_t value = __N * __M; + }; + + //helpers for __safe_add + template + struct __add_overflow_check_impl : + std::integral_constant + {}; + + template + struct __add_overflow_check_impl<__N, __M, false> : + std::integral_constant= -INTMAX_MAX - __M)> + {}; + + template + struct __add_overflow_check : + __add_overflow_check_impl<__N, __M, (__M >= 0)> + {}; + + template + struct __safe_add + { + static_assert(__add_overflow_check<__N, __M>::value != 0, + "overflow in addition"); + + static const intmax_t value = __N + __M; + }; + + template + struct ratio + { + static_assert(__D != 0, "denominator cannot be zero"); + static_assert(__N > INTMAX_MIN && __D > INTMAX_MIN, "out of range"); + + //Note: sign(N) * abs(N) == N + static const std::intmax_t num = + __N * __static_sign<__D>::value / __static_gcd<__N, __D>::value; + + static const std::intmax_t den = + __static_abs<__D>::value / __static_gcd<__N, __D>::value; + }; + + template + struct ratio_add + { + private: + static const std::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: + enum { + __gcd1 = __static_gcd<__R1::num, __R2::den>::value, + __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 : + std::conditional< + (__R1::num == __R2::num && __R1::den == __R2::den), + std::true_type, + std::false_type>::type + {}; + + template + struct ratio_less : + std::conditional< + (__safe_multiply<__R1::num, __R2::den>::value < + __safe_multiply<__R2::num, __R1::den>::value), + std::true_type, + std::false_type>::type + {}; + + template + struct ratio_not_equal : + std::integral_constant::value> + {}; + + template + struct ratio_less_equal : + std::integral_constant::value> + {}; + + template + struct ratio_greater : + std::integral_constant::value> + {}; + + template + struct ratio_greater_equal : + std::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 +#endif Index: libstdc++-v3/include/Makefile.am =================================================================== --- libstdc++-v3/include/Makefile.am (revision 137251) +++ libstdc++-v3/include/Makefile.am (working copy) @@ -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 \ Index: libstdc++-v3/testsuite/20_util/ratio/cons/cons.cc =================================================================== --- libstdc++-v3/testsuite/20_util/ratio/cons/cons.cc (revision 0) +++ libstdc++-v3/testsuite/20_util/ratio/cons/cons.cc (revision 0) @@ -0,0 +1,49 @@ +// { 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 + +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 ); +} + +int main() +{ + test01(); + return 0; +} Index: libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc =================================================================== --- libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc (revision 0) +++ libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc (revision 0) @@ -0,0 +1,49 @@ +// { dg-do compile } +// { 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 + +void +test01() +{ + std::ratio r1; + std::ratio<-INTMAX_MAX, INTMAX_MAX> r2; +} + +void +test02() +{ + std::ratio r1; +} + +void +test03() +{ + std::ratio<1,0> r1; +} + +// { dg-error "instantiated from here" "" { target *-*-* } 34 } +// { dg-error "instantiated from here" "" { target *-*-* } 40 } +// { dg-error "static assertion failed" "" { target *-*-* } 131 } +// { dg-error "static assertion failed" "" { target *-*-* } 132 } +// { dg-excess-errors "In instantiation of" } + + Index: libstdc++-v3/testsuite/20_util/ratio/operations/ops.cc =================================================================== --- libstdc++-v3/testsuite/20_util/ratio/operations/ops.cc (revision 0) +++ libstdc++-v3/testsuite/20_util/ratio/operations/ops.cc (revision 0) @@ -0,0 +1,73 @@ +// { 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 + +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); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + return 0; +} + Index: libstdc++-v3/testsuite/20_util/ratio/comparisons/1.cc =================================================================== --- libstdc++-v3/testsuite/20_util/ratio/comparisons/1.cc (revision 0) +++ libstdc++-v3/testsuite/20_util/ratio/comparisons/1.cc (revision 0) @@ -0,0 +1,51 @@ +// { 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 + +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,4>>::value == 0 )); +} + +int main() +{ + test01(); + test02(); + return 0; +} +