commit 87d26af2fc07f0c45a0a6676161ae1db1d7541b7 Author: Jonathan Wakely Date: Wed May 14 16:35:20 2014 +0100 2014-05-15 Ed Smith-Rowland <3dw4rd@verizon.net> Jonathan Wakely PR libstdc++/61166 * include/bits/parse_numbers.h: Use integral_constant to remove duplication and simplify. * testsuite/20_util/duration/literals/61166.cc: New. diff --git a/libstdc++-v3/include/bits/parse_numbers.h b/libstdc++-v3/include/bits/parse_numbers.h index 91a127c..0a42381a 100644 --- a/libstdc++-v3/include/bits/parse_numbers.h +++ b/libstdc++-v3/include/bits/parse_numbers.h @@ -27,8 +27,8 @@ * Do not attempt to use it directly. @headername{chrono} */ -#ifndef _PARSE_NUMBERS_H -#define _PARSE_NUMBERS_H 1 +#ifndef _GLIBCXX_PARSE_NUMBERS_H +#define _GLIBCXX_PARSE_NUMBERS_H 1 #pragma GCC system_header @@ -36,289 +36,181 @@ #if __cplusplus > 201103L +#include + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION -namespace __parse_int { - +namespace __parse_int +{ template struct _Digit; template - struct _Digit<_Base, '0'> + struct _Digit<_Base, '0'> : integral_constant { - static constexpr bool valid{true}; - static constexpr unsigned value{0}; + using __valid = true_type; }; template - struct _Digit<_Base, '1'> + struct _Digit<_Base, '1'> : integral_constant { - static constexpr bool valid{true}; - static constexpr unsigned value{1}; + using __valid = true_type; }; - template - struct _Digit<_Base, '2'> + template + struct _Digit_impl : integral_constant { - static_assert(_Base > 2, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{2}; + static_assert(_Base > _Val, "invalid digit"); + using __valid = true_type; }; template - struct _Digit<_Base, '3'> - { - static_assert(_Base > 3, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{3}; - }; + struct _Digit<_Base, '2'> : _Digit_impl<_Base, 2> + { }; template - struct _Digit<_Base, '4'> - { - static_assert(_Base > 4, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{4}; - }; + struct _Digit<_Base, '3'> : _Digit_impl<_Base, 3> + { }; template - struct _Digit<_Base, '5'> - { - static_assert(_Base > 5, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{5}; - }; + struct _Digit<_Base, '4'> : _Digit_impl<_Base, 4> + { }; template - struct _Digit<_Base, '6'> - { - static_assert(_Base > 6, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{6}; - }; + struct _Digit<_Base, '5'> : _Digit_impl<_Base, 5> + { }; template - struct _Digit<_Base, '7'> - { - static_assert(_Base > 7, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{7}; - }; + struct _Digit<_Base, '6'> : _Digit_impl<_Base, 6> + { }; template - struct _Digit<_Base, '8'> - { - static_assert(_Base > 8, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{8}; - }; + struct _Digit<_Base, '7'> : _Digit_impl<_Base, 7> + { }; template - struct _Digit<_Base, '9'> - { - static_assert(_Base > 9, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{9}; - }; + struct _Digit<_Base, '8'> : _Digit_impl<_Base, 8> + { }; template - struct _Digit<_Base, 'a'> - { - static_assert(_Base > 0xa, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xa}; - }; + struct _Digit<_Base, '9'> : _Digit_impl<_Base, 9> + { }; template - struct _Digit<_Base, 'A'> - { - static_assert(_Base > 0xa, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xa}; - }; + struct _Digit<_Base, 'a'> : _Digit_impl<_Base, 0xa> + { }; template - struct _Digit<_Base, 'b'> - { - static_assert(_Base > 0xb, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xb}; - }; + struct _Digit<_Base, 'A'> : _Digit_impl<_Base, 0xa> + { }; template - struct _Digit<_Base, 'B'> - { - static_assert(_Base > 0xb, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xb}; - }; + struct _Digit<_Base, 'b'> : _Digit_impl<_Base, 0xb> + { }; template - struct _Digit<_Base, 'c'> - { - static_assert(_Base > 0xc, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xc}; - }; + struct _Digit<_Base, 'B'> : _Digit_impl<_Base, 0xb> + { }; template - struct _Digit<_Base, 'C'> - { - static_assert(_Base > 0xc, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xc}; - }; + struct _Digit<_Base, 'c'> : _Digit_impl<_Base, 0xc> + { }; template - struct _Digit<_Base, 'd'> - { - static_assert(_Base > 0xd, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xd}; - }; + struct _Digit<_Base, 'C'> : _Digit_impl<_Base, 0xc> + { }; template - struct _Digit<_Base, 'D'> - { - static_assert(_Base > 0xd, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xd}; - }; + struct _Digit<_Base, 'd'> : _Digit_impl<_Base, 0xd> + { }; template - struct _Digit<_Base, 'e'> - { - static_assert(_Base > 0xe, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xe}; - }; + struct _Digit<_Base, 'D'> : _Digit_impl<_Base, 0xd> + { }; template - struct _Digit<_Base, 'E'> - { - static_assert(_Base > 0xe, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xe}; - }; + struct _Digit<_Base, 'e'> : _Digit_impl<_Base, 0xe> + { }; template - struct _Digit<_Base, 'f'> - { - static_assert(_Base > 0xf, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xf}; - }; + struct _Digit<_Base, 'E'> : _Digit_impl<_Base, 0xe> + { }; template - struct _Digit<_Base, 'F'> - { - static_assert(_Base > 0xf, "invalid digit"); - static constexpr bool valid{true}; - static constexpr unsigned value{0xf}; - }; + struct _Digit<_Base, 'f'> : _Digit_impl<_Base, 0xf> + { }; - // Digit separator template - struct _Digit<_Base, '\''> - { - static constexpr bool valid{false}; - static constexpr unsigned value{0}; - }; - - -//------------------------------------------------------------------------------ - - template - struct _Digits_help - { - static constexpr unsigned - value{_Digit<_Base, _Dig>::valid ? - 1U + _Digits_help<_Base, _Digs...>::value : - _Digits_help<_Base, _Digs...>::value}; - }; - - template - struct _Digits_help<_Base, _Dig> - { - static constexpr unsigned value{_Digit<_Base, _Dig>::valid ? 1U : 0U}; - }; - - template - struct _Digits - { - static constexpr unsigned value{_Digits_help<_Base, _Digs...>::value}; - }; + struct _Digit<_Base, 'F'> : _Digit_impl<_Base, 0xf> + { }; + // Digit separator template - struct _Digits<_Base> + struct _Digit<_Base, '\''> : integral_constant { - static constexpr unsigned value{0U}; + using __valid = false_type; }; //------------------------------------------------------------------------------ + template + using __ull_constant = integral_constant; + template struct _Power_help { - static constexpr unsigned - value{_Digit<_Base, _Dig>::valid ? - _Base * _Power_help<_Base, _Digs...>::value : - _Power_help<_Base, _Digs...>::value}; + using __next = typename _Power_help<_Base, _Digs...>::type; + using __valid_digit = typename _Digit<_Base, _Dig>::__valid; + using type + = __ull_constant<__next::value * (__valid_digit{} ? _Base : 1ULL)>; }; template struct _Power_help<_Base, _Dig> { - static constexpr unsigned value{_Digit<_Base, _Dig>::valid ? 1U : 0U}; + using __valid_digit = typename _Digit<_Base, _Dig>::__valid; + using type = __ull_constant<__valid_digit::value>; }; template - struct _Power - { - static constexpr unsigned value{_Power_help<_Base, _Digs...>::value}; - }; + struct _Power : _Power_help<_Base, _Digs...>::type + { }; template - struct _Power<_Base> - { - static constexpr unsigned value{0U}; - }; + struct _Power<_Base> : __ull_constant<0> + { }; //------------------------------------------------------------------------------ - template + template struct _Number_help { - static constexpr unsigned - value{_Digit<_Base, _Dig>::valid ? - _Pow * _Digit<_Base, _Dig>::value - + _Number_help<_Base, _Pow / _Base, _Digs...>::value : - _Number_help<_Base, _Pow, _Digs...>::value}; + using __digit = _Digit<_Base, _Dig>; + using __valid_digit = typename __digit::__valid; + using __next = _Number_help<_Base, + _Pow / (_Base * __valid_digit::value), + _Digs...>; + using type = __ull_constant<_Pow * __digit::value + __next::type::value>; }; - template + template struct _Number_help<_Base, _Pow, _Dig> { //static_assert(_Pow == 1U, "power should be one"); - static constexpr unsigned - value{_Digit<_Base, _Dig>::valid ? _Digit<_Base, _Dig>::value : 0U}; + using type = __ull_constant<_Digit<_Base, _Dig>::value>; }; template struct _Number - { - static constexpr unsigned - value{_Number_help<_Base, _Power<_Base, _Digs...>::value, - _Digs...>::value}; - }; + : _Number_help<_Base, _Power<_Base, _Digs...>::value, _Digs...>::type + { }; template struct _Number<_Base> - { - static constexpr unsigned value{0U}; - }; + : __ull_constant<0> + { }; //------------------------------------------------------------------------------ // This _Parse_int is the same 'level' as the old _Base_dispatch. @@ -328,84 +220,62 @@ namespace __parse_int { template struct _Parse_int<'0', 'b', _Digs...> - { - static constexpr unsigned long long - value{_Number<2U, _Digs...>::value}; - }; + : _Number<2U, _Digs...>::type + { }; template struct _Parse_int<'0', 'B', _Digs...> - { - static constexpr unsigned long long - value{_Number<2U, _Digs...>::value}; - }; + : _Number<2U, _Digs...>::type + { }; template struct _Parse_int<'0', 'x', _Digs...> - { - static constexpr unsigned long long - value{_Number<16U, _Digs...>::value}; - }; + : _Number<16U, _Digs...>::type + { }; template struct _Parse_int<'0', 'X', _Digs...> - { - static constexpr unsigned long long - value{_Number<16U, _Digs...>::value}; - }; + : _Number<16U, _Digs...>::type + { }; template struct _Parse_int<'0', _Digs...> - { - static constexpr unsigned long long - value{_Number<8U, _Digs...>::value}; - }; + : _Number<8U, _Digs...>::type + { }; template struct _Parse_int - { - static constexpr unsigned long long - value{_Number<10U, _Digs...>::value}; - }; + : _Number<10U, _Digs...>::type + { }; } // namespace __parse_int -namespace __select_int { - +namespace __select_int +{ template struct _Select_int_base; template struct _Select_int_base<_Val, _IntType, _Ints...> - : integral_constant - < - typename conditional - < - _Val <= static_cast - (std::numeric_limits<_IntType>::max()), - _IntType, - typename _Select_int_base<_Val, _Ints...>::value_type - >::type, - _Val - > + : conditional_t<(_Val <= std::numeric_limits<_IntType>::max()), + integral_constant<_IntType, _Val>, + _Select_int_base<_Val, _Ints...>> { }; template - struct _Select_int_base<_Val> : integral_constant + struct _Select_int_base<_Val> { }; template - struct _Select_int - : _Select_int_base< + using _Select_int = typename _Select_int_base< __parse_int::_Parse_int<_Digs...>::value, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long - > - { }; + >::type; } // namespace __select_int @@ -414,4 +284,4 @@ _GLIBCXX_END_NAMESPACE_VERSION #endif // __cplusplus > 201103L -#endif // _PARSE_NUMBERS_H +#endif // _GLIBCXX_PARSE_NUMBERS_H diff --git a/libstdc++-v3/testsuite/20_util/duration/literals/61166.cc b/libstdc++-v3/testsuite/20_util/duration/literals/61166.cc new file mode 100644 index 0000000..e06adf8 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/duration/literals/61166.cc @@ -0,0 +1,39 @@ +// { dg-do run } +// { dg-options "-std=gnu++1y" } + +// Copyright (C) 2014 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 3, 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 COPYING3. If not see +// . + +// libstdc++/61166 + +#include +#include + +void +test01() +{ + using namespace std::literals::chrono_literals; + + // std::numeric_limits::max() == 4294967295 + VERIFY( (429496729510h).count() == 429496729510 ); +} + +int +main() +{ + test01(); +}