diff options
author | emsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-01 18:37:47 +0000 |
---|---|---|
committer | emsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-01 18:37:47 +0000 |
commit | 47269859a5bb1d55547b4dbc3213206706db5813 (patch) | |
tree | 097d9ec3dc554024a29227d76b6237d9cb0f1cdb /libstdc++-v3/include | |
parent | 4cd8ae4b844d51eb02d0a8da666209769b5a5c8a (diff) | |
download | gcc-47269859a5bb1d55547b4dbc3213206706db5813.tar.gz |
2013-05-30 Ed Smith-Rowland <3dw4rd@verizon.net>
Implement N3642 - User-defined Literals for Standard Library Types
* include/bits/parse_numbers.h: New.
* include/std/chrono: Add duration literal operators.
* include/bits/basic_string.h: Add string literal operators.
* include/Makefile.in: Add parse_numbers.h.
* include/Makefile.am: Ditto.
* testsuite/20_util/duration/literals/values.cc: New.
* testsuite/20_util/duration/literals/types.cc: New.
* testsuite/20_util/duration/requirements/typedefs_neg1.cc: Adjust.
* testsuite/20_util/duration/requirements/typedefs_neg2.cc: Adjust.
* testsuite/20_util/duration/requirements/typedefs_neg3.cc: Adjust.
* testsuite/21_strings/basic_string/literals/values.cc: New.
* testsuite/21_strings/basic_string/literals/types.cc: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199584 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r-- | libstdc++-v3/include/Makefile.am | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/Makefile.in | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/basic_string.h | 37 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/parse_numbers.h | 417 | ||||
-rw-r--r-- | libstdc++-v3/include/std/chrono | 133 |
5 files changed, 589 insertions, 0 deletions
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index e8ef7066bcd..f09300b8bee 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -117,6 +117,7 @@ bits_headers = \ ${bits_srcdir}/move.h \ ${bits_srcdir}/ostream.tcc \ ${bits_srcdir}/ostream_insert.h \ + ${bits_srcdir}/parse_numbers.h \ ${bits_srcdir}/postypes.h \ ${bits_srcdir}/ptr_traits.h \ ${bits_srcdir}/random.h \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 2ba9433bd7d..a090cad9fce 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -379,6 +379,7 @@ bits_headers = \ ${bits_srcdir}/move.h \ ${bits_srcdir}/ostream.tcc \ ${bits_srcdir}/ostream_insert.h \ + ${bits_srcdir}/parse_numbers.h \ ${bits_srcdir}/postypes.h \ ${bits_srcdir}/ptr_traits.h \ ${bits_srcdir}/random.h \ diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 23bd9b9c096..a249df23742 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -3106,6 +3106,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION } // namespace +#if __cplusplus > 201103L + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +inline namespace literals { +inline namespace string_literals { + + inline basic_string<char> + operator"" s(const char* __str, size_t __len) + { return basic_string<char>{__str, __len}; } + +#ifdef _GLIBCXX_USE_WCHAR_T + inline basic_string<wchar_t> + operator"" s(const wchar_t* __str, size_t __len) + { return basic_string<wchar_t>{__str, __len}; } +#endif + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + inline basic_string<char16_t> + operator"" s(const char16_t* __str, size_t __len) + { return basic_string<char16_t>{__str, __len}; } + + inline basic_string<char32_t> + operator"" s(const char32_t* __str, size_t __len) + { return basic_string<char32_t>{__str, __len}; } +#endif + +} // inline namespace string_literals +} // inline namespace literals + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif // __cplusplus > 201103L + #endif // C++11 #endif /* _BASIC_STRING_H */ diff --git a/libstdc++-v3/include/bits/parse_numbers.h b/libstdc++-v3/include/bits/parse_numbers.h new file mode 100644 index 00000000000..eaa3d27a18a --- /dev/null +++ b/libstdc++-v3/include/bits/parse_numbers.h @@ -0,0 +1,417 @@ +// Components for compile-time parsing of numbers -*- C++ -*- + +// Copyright (C) 2013 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file bits/parse_numbers.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{chrono} + */ + +#ifndef _PARSE_NUMBERS_H +#define _PARSE_NUMBERS_H 1 + +#pragma GCC system_header + +// From n3642.pdf except I added binary literals and digit separator '`'. + +#if __cplusplus > 201103L + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +namespace __parse_int { + + template<unsigned _Base, char _Dig> + struct _Digit; + + template<unsigned _Base> + struct _Digit<_Base, '0'> + { + static constexpr bool valid{true}; + static constexpr unsigned value{0}; + }; + + template<unsigned _Base> + struct _Digit<_Base, '1'> + { + static constexpr bool valid{true}; + static constexpr unsigned value{1}; + }; + + template<unsigned _Base> + struct _Digit<_Base, '2'> + { + static_assert(_Base > 2, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{2}; + }; + + template<unsigned _Base> + struct _Digit<_Base, '3'> + { + static_assert(_Base > 3, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{3}; + }; + + template<unsigned _Base> + struct _Digit<_Base, '4'> + { + static_assert(_Base > 4, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{4}; + }; + + template<unsigned _Base> + struct _Digit<_Base, '5'> + { + static_assert(_Base > 5, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{5}; + }; + + template<unsigned _Base> + struct _Digit<_Base, '6'> + { + static_assert(_Base > 6, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{6}; + }; + + template<unsigned _Base> + struct _Digit<_Base, '7'> + { + static_assert(_Base > 7, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{7}; + }; + + template<unsigned _Base> + struct _Digit<_Base, '8'> + { + static_assert(_Base > 8, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{8}; + }; + + template<unsigned _Base> + struct _Digit<_Base, '9'> + { + static_assert(_Base > 9, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{9}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'a'> + { + static_assert(_Base > 0xa, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xa}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'A'> + { + static_assert(_Base > 0xa, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xa}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'b'> + { + static_assert(_Base > 0xb, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xb}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'B'> + { + static_assert(_Base > 0xb, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xb}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'c'> + { + static_assert(_Base > 0xc, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xc}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'C'> + { + static_assert(_Base > 0xc, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xc}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'd'> + { + static_assert(_Base > 0xd, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xd}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'D'> + { + static_assert(_Base > 0xd, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xd}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'e'> + { + static_assert(_Base > 0xe, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xe}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'E'> + { + static_assert(_Base > 0xe, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xe}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'f'> + { + static_assert(_Base > 0xf, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xf}; + }; + + template<unsigned _Base> + struct _Digit<_Base, 'F'> + { + static_assert(_Base > 0xf, "invalid digit"); + static constexpr bool valid{true}; + static constexpr unsigned value{0xf}; + }; + + // Digit separator + template<unsigned _Base> + struct _Digit<_Base, '`'> + { + static constexpr bool valid{false}; + static constexpr unsigned value{0}; + }; + + +//------------------------------------------------------------------------------ + + template<unsigned _Base, char _Dig, char... _Digs> + struct _Digits_help + { + static constexpr unsigned + value{_Digit<_Base, _Dig>::valid ? + 1U + _Digits_help<_Base, _Digs...>::value : + _Digits_help<_Base, _Digs...>::value}; + }; + + template<unsigned _Base, char _Dig> + struct _Digits_help<_Base, _Dig> + { + static constexpr unsigned value{_Digit<_Base, _Dig>::valid ? 1U : 0U}; + }; + + template<unsigned _Base, char... _Digs> + struct _Digits + { + static constexpr unsigned value{_Digits_help<_Base, _Digs...>::value}; + }; + + template<unsigned _Base> + struct _Digits<_Base> + { + static constexpr unsigned value{0U}; + }; + +//------------------------------------------------------------------------------ + + template<unsigned _Base, char _Dig, char... _Digs> + struct _Power_help + { + static constexpr unsigned + value{_Digit<_Base, _Dig>::valid ? + _Base * _Power_help<_Base, _Digs...>::value : + _Power_help<_Base, _Digs...>::value}; + }; + + template<unsigned _Base, char _Dig> + struct _Power_help<_Base, _Dig> + { + static constexpr unsigned value{_Digit<_Base, _Dig>::valid ? 1U : 0U}; + }; + + template<unsigned _Base, char... _Digs> + struct _Power + { + static constexpr unsigned value{_Power_help<_Base, _Digs...>::value}; + }; + + template<unsigned _Base> + struct _Power<_Base> + { + static constexpr unsigned value{0U}; + }; + +//------------------------------------------------------------------------------ + + template<unsigned _Base, unsigned _Pow, char _Dig, char... _Digs> + 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}; + }; + + template<unsigned _Base, unsigned _Pow, char _Dig> + 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}; + }; + + template<unsigned _Base, char... _Digs> + struct _Number + { + static constexpr unsigned + value{_Number_help<_Base, _Power<_Base, _Digs...>::value, + _Digs...>::value}; + }; + + template<unsigned _Base> + struct _Number<_Base> + { + static constexpr unsigned value{0U}; + }; + +//------------------------------------------------------------------------------ +// This _Parse_int is the same 'level' as the old _Base_dispatch. + + template<char... _Digs> + struct _Parse_int; + + template<char... _Digs> + struct _Parse_int<'0', 'b', _Digs...> + { + static constexpr unsigned long long + value{_Number<2U, _Digs...>::value}; + }; + + template<char... _Digs> + struct _Parse_int<'0', 'B', _Digs...> + { + static constexpr unsigned long long + value{_Number<2U, _Digs...>::value}; + }; + + template<char... _Digs> + struct _Parse_int<'0', 'x', _Digs...> + { + static constexpr unsigned long long + value{_Number<16U, _Digs...>::value}; + }; + + template<char... _Digs> + struct _Parse_int<'0', 'X', _Digs...> + { + static constexpr unsigned long long + value{_Number<16U, _Digs...>::value}; + }; + + template<char... _Digs> + struct _Parse_int<'0', _Digs...> + { + static constexpr unsigned long long + value{_Number<8U, _Digs...>::value}; + }; + + template<char... _Digs> + struct _Parse_int + { + static constexpr unsigned long long + value{_Number<10U, _Digs...>::value}; + }; + +} // namespace __parse_int + + +namespace __select_int { + + template<unsigned long long _Val, typename... _Ints> + struct _Select_int_base; + + template<unsigned long long _Val, typename _IntType, typename... _Ints> + struct _Select_int_base<_Val, _IntType, _Ints...> + : integral_constant + < + typename conditional + < + _Val <= static_cast<unsigned long long> + (std::numeric_limits<_IntType>::max()), + _IntType, + typename _Select_int_base<_Val, _Ints...>::value_type + >::type, + _Val + > + { }; + + template<unsigned long long _Val> + struct _Select_int_base<_Val> : integral_constant<unsigned long long, _Val> + { }; + + template<char... _Digs> + struct _Select_int + : _Select_int_base< + __parse_int::_Parse_int<_Digs...>::value, + unsigned char, + unsigned short, + unsigned int, + unsigned long, + unsigned long long + > + { }; + +} // namespace __select_int + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif // __cplusplus > 201103L + +#endif // _PARSE_NUMBERS_H diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index 6d9df7d7dda..f4c4ef017e6 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -39,6 +39,7 @@ #include <type_traits> #include <limits> #include <ctime> +#include <bits/parse_numbers.h> // for literals support. #ifdef _GLIBCXX_USE_C99_STDINT_TR1 @@ -786,4 +787,136 @@ _GLIBCXX_END_NAMESPACE_VERSION #endif // C++11 +#if __cplusplus > 201103L + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +inline namespace literals { +inline namespace chrono_literals { + + namespace __detail { + + using namespace __parse_int; + + template<unsigned long long _Val, typename _Dur> + struct _Select_type + : conditional< + _Val <= static_cast<unsigned long long> + (numeric_limits<typename _Dur::rep>::max()), + _Dur, void> + { + static constexpr typename _Select_type::type + value{static_cast<typename _Select_type::type>(_Val)}; + }; + + template<unsigned long long _Val, typename _Dur> + constexpr typename _Select_type<_Val, _Dur>::type + _Select_type<_Val, _Dur>::value; + + } // __detail + + inline constexpr chrono::duration<long double, ratio<3600,1>> + operator"" h(long double __hours) + { return chrono::duration<long double, ratio<3600,1>>{__hours}; } + + template <char... _Digits> + inline constexpr typename + __detail::_Select_type<__select_int::_Select_int<_Digits...>::value, + chrono::hours>::type + operator"" h() + { + return __detail::_Select_type< + __select_int::_Select_int<_Digits...>::value, + chrono::hours>::value; + } + + inline constexpr chrono::duration<long double, ratio<60,1>> + operator"" min(long double __mins) + { return chrono::duration<long double, ratio<60,1>>{__mins}; } + + template <char... _Digits> + inline constexpr typename + __detail::_Select_type<__select_int::_Select_int<_Digits...>::value, + chrono::minutes>::type + operator"" min() + { + return __detail::_Select_type< + __select_int::_Select_int<_Digits...>::value, + chrono::minutes>::value; + } + + inline constexpr chrono::duration<long double> + operator"" s(long double __secs) + { return chrono::duration<long double>{__secs}; } + + template <char... _Digits> + inline constexpr typename + __detail::_Select_type<__select_int::_Select_int<_Digits...>::value, + chrono::seconds>::type + operator"" s() + { + return __detail::_Select_type< + __select_int::_Select_int<_Digits...>::value, + chrono::seconds>::value; + } + + inline constexpr chrono::duration<long double, milli> + operator"" ms(long double __msecs) + { return chrono::duration<long double, milli>{__msecs}; } + + template <char... _Digits> + inline constexpr typename + __detail::_Select_type<__select_int::_Select_int<_Digits...>::value, + chrono::milliseconds>::type + operator"" ms() + { + return __detail::_Select_type< + __select_int::_Select_int<_Digits...>::value, + chrono::milliseconds>::value; + } + + inline constexpr chrono::duration<long double, micro> + operator"" us(long double __usecs) + { return chrono::duration<long double, micro>{__usecs}; } + + template <char... _Digits> + inline constexpr typename + __detail::_Select_type<__select_int::_Select_int<_Digits...>::value, + chrono::microseconds>::type + operator"" us() + { + return __detail::_Select_type< + __select_int::_Select_int<_Digits...>::value, + chrono::microseconds>::value; + } + + inline constexpr chrono::duration<long double, nano> + operator"" ns(long double __nsecs) + { return chrono::duration<long double, nano>{__nsecs}; } + + template <char... _Digits> + inline constexpr typename + __detail::_Select_type<__select_int::_Select_int<_Digits...>::value, + chrono::nanoseconds>::type + operator"" ns() + { + return __detail::_Select_type< + __select_int::_Select_int<_Digits...>::value, + chrono::nanoseconds>::value; + } + +} // inline namespace chrono_literals +} // inline namespace literals + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif //_GLIBCXX_USE_C99_STDINT_TR1 + +#endif // __cplusplus > 201103L + #endif //_GLIBCXX_CHRONO |