diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-08 16:18:49 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-08 16:18:49 +0000 |
commit | 71fd77c9b4b3398097c48d6c1d3be7296d670f89 (patch) | |
tree | ca77b69e8b4f032f1066c6a31847233f9db7f8e5 /libstdc++-v3/include/std | |
parent | 313793ac30b7208dfb273ab1823bed6b0c20deb4 (diff) | |
download | gcc-71fd77c9b4b3398097c48d6c1d3be7296d670f89.tar.gz |
2008-07-08 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r137620
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@137632 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/std')
-rw-r--r-- | libstdc++-v3/include/std/ratio | 288 | ||||
-rw-r--r-- | libstdc++-v3/include/std/system_error | 4 | ||||
-rw-r--r-- | libstdc++-v3/include/std/type_traits | 39 |
3 files changed, 327 insertions, 4 deletions
diff --git a/libstdc++-v3/include/std/ratio b/libstdc++-v3/include/std/ratio new file mode 100644 index 00000000000..9980571f160 --- /dev/null +++ b/libstdc++-v3/include/std/ratio @@ -0,0 +1,288 @@ +// <ratio> -*- 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 <c++0x_warning.h> +#else + +#include <type_traits> +#include <cstdint> + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +namespace std +{ + template<intmax_t _Pn> + struct __static_sign + : integral_constant<intmax_t, (_Pn < 0) ? -1 : 1> + { }; + + template<intmax_t _Pn> + struct __static_abs + : integral_constant<intmax_t, _Pn * __static_sign<_Pn>::value> + { }; + + template<intmax_t _Pn, intmax_t _Qn> + struct __static_gcd; + + template<intmax_t _Pn, intmax_t _Qn> + struct __static_gcd + : __static_gcd<_Qn, (_Pn % _Qn)> + { }; + + template<intmax_t _Pn> + struct __static_gcd<_Pn, 0> + : integral_constant<intmax_t, __static_abs<_Pn>::value> + { }; + + template<intmax_t _Qn> + struct __static_gcd<0, _Qn> + : integral_constant<intmax_t, __static_abs<_Qn>::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<intmax_t _Pn, intmax_t _Qn> + 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<intmax_t _Pn, intmax_t _Qn, bool> + struct __add_overflow_check_impl + : integral_constant<bool, (_Pn <= __INTMAX_MAX__ - _Qn)> + { }; + + template<intmax_t _Pn, intmax_t _Qn> + struct __add_overflow_check_impl<_Pn, _Qn, false> + : integral_constant<bool, (_Pn >= -__INTMAX_MAX__ - _Qn)> + { }; + + template<intmax_t _Pn, intmax_t _Qn> + struct __add_overflow_check + : __add_overflow_check_impl<_Pn, _Qn, (_Qn >= 0)> + { }; + + template<intmax_t _Pn, intmax_t _Qn> + struct __safe_add + { + static_assert(__add_overflow_check<_Pn, _Qn>::value != 0, + "overflow in addition"); + + static const intmax_t value = _Pn + _Qn; + }; + + /** + * @brief Provides compile-time rational arithmetic. + * + * This class template represents any finite rational number with a + * numerator and denominator representable by compile-time constants of + * type intmax_t. The ratio is simplified when instantiated. + * + * For example: + * @code + * std::ratio<7,-21>::num == -1; + * std::ratio<7,-21>::den == 3; + * @endcode + * + */ + template<intmax_t _Num, intmax_t _Den = 1> + struct ratio + { + static_assert(_Den != 0, "denominator cannot be zero"); + static_assert(_Num >= -__INTMAX_MAX__ && _Den >= -__INTMAX_MAX__, + "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<intmax_t _Num, intmax_t _Den> + const intmax_t ratio<_Num, _Den>::num; + + template<intmax_t _Num, intmax_t _Den> + const intmax_t ratio<_Num, _Den>::den; + + template<typename _R1, typename _R2> + 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<typename _R1, typename _R2> + struct ratio_subtract + { + typedef typename ratio_add< + _R1, + ratio<-_R2::num, _R2::den>>::type type; + }; + + template<typename _R1, typename _R2> + 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<typename _R1, typename _R2> + struct ratio_divide + { + static_assert(_R2::num != 0, "division by 0"); + + typedef typename ratio_multiply< + _R1, + ratio<_R2::den, _R2::num>>::type type; + }; + + template<typename _R1, typename _R2> + struct ratio_equal + : integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den> + { }; + + template<typename _R1, typename _R2> + struct ratio_not_equal + : integral_constant<bool, !ratio_equal<_R1, _R2>::value> + { }; + + template<typename _R1, typename _R2> + struct __ratio_less_simple_impl + : integral_constant<bool, + (__safe_multiply<_R1::num, _R2::den>::value + < __safe_multiply<_R2::num, _R1::den>::value)> + { }; + + // If the denominators are equal or the signs differ, we can just compare + // numerators, otherwise fallback to the simple cross-multiply method. + template<typename _R1, typename _R2> + struct __ratio_less_impl + : conditional<(_R1::den == _R2::den + || (__static_sign<_R1::num>::value + != __static_sign<_R2::num>::value)), + integral_constant<bool, (_R1::num < _R2::num)>, + __ratio_less_simple_impl<_R1, _R2>>::type + { }; + + template<typename _R1, typename _R2> + struct ratio_less + : __ratio_less_impl<_R1, _R2>::type + { }; + + template<typename _R1, typename _R2> + struct ratio_less_equal + : integral_constant<bool, !ratio_less<_R2, _R1>::value> + { }; + + template<typename _R1, typename _R2> + struct ratio_greater + : integral_constant<bool, ratio_less<_R2, _R1>::value> + { }; + + template<typename _R1, typename _R2> + struct ratio_greater_equal + : integral_constant<bool, !ratio_less<_R1, _R2>::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/include/std/system_error b/libstdc++-v3/include/std/system_error index 343eb6e83f7..b0585810663 100644 --- a/libstdc++-v3/include/std/system_error +++ b/libstdc++-v3/include/std/system_error @@ -53,7 +53,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) class system_error; /// is_error_code_enum - template<typename _T> + template<typename _Tp> struct is_error_code_enum : public false_type { }; template<> @@ -61,7 +61,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) : public true_type { }; /// is_error_condition_enum - template<typename _T> + template<typename _Tp> struct is_error_condition_enum : public false_type { }; template<> diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 5fdc95ecad9..1a759187955 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -203,13 +203,13 @@ namespace std : public integral_constant<bool, __has_trivial_destructor(_Tp)> { }; - /// has_nothrow_default_destructor + /// has_nothrow_default_constructor template<typename _Tp> struct has_nothrow_default_constructor : public integral_constant<bool, __has_nothrow_constructor(_Tp)> { }; - /// has_nothrow_copy_destructor + /// has_nothrow_copy_constructor template<typename _Tp> struct has_nothrow_copy_constructor : public integral_constant<bool, __has_nothrow_copy(_Tp)> @@ -551,6 +551,41 @@ namespace std // Integral, but don't define. template<> struct make_signed<bool>; + + template<typename... _Tp> + struct common_type; + + template<typename _Tp> + struct common_type<_Tp> + { + static_assert(sizeof(_Tp) > 0, "must be complete type"); + typedef _Tp type; + }; + + template<typename _Tp, typename _Up> + class common_type<_Tp, _Up> + { + static_assert(sizeof(_Tp) > 0, "must be complete type"); + static_assert(sizeof(_Up) > 0, "must be complete type"); + + static _Tp&& __t(); + static _Up&& __u(); + + // HACK: Prevents optimization of ?: in the decltype + // expression when the condition is the literal, "true". + // See, PR36628. + static bool __true_or_false(); + + public: + typedef decltype(__true_or_false() ? __t() : __u()) type; + }; + + template<typename _Tp, typename _Up, typename... _Vp> + struct common_type<_Tp, _Up, _Vp...> + { + typedef typename + common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type; + }; } #endif // __GXX_EXPERIMENTAL_CXX0X__ |