Commit 1c9f675f by Ed Smith-Rowland Committed by Edward Smith-Rowland

Implement N3642 - User-defined Literals for Standard Library Types

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.

From-SVN: r199584
parent 38e55e5c
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.
2013-05-28 Jonathan Wakely <jwakely.gcc@gmail.com>
* src/c++11/compatibility-chrono.cc (steady_clock::now()): If
......
......@@ -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 \
......
......@@ -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 \
......
......@@ -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 */
......@@ -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
// { dg-options "-std=gnu++1y" }
// { dg-do compile }
// 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.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// NOTE: This makes use of the fact that we know how moveable
// is implemented on string (via swap). If the implementation changed
// this test may begin to fail.
#include <chrono>
#include <type_traits>
void
test03()
{
using namespace std::literals::chrono_literals;
static_assert(std::is_same<decltype(1h), std::chrono::hours>::value,
"1h is std::chrono::hours");
static_assert(std::is_same<decltype(1.0h),
std::chrono::duration<long double, std::ratio<3600L, 1L>>>::value,
"1.0h is std::chrono::duration<long double, std::ratio<3600L, 1L>>");
static_assert(std::is_same<decltype(1min), std::chrono::minutes>::value,
"1min is std::chrono::minutes");
static_assert(std::is_same<decltype(1.0min),
std::chrono::duration<long double, std::ratio<60L, 1L>>>::value,
"1.0min is std::chrono::duration<long double, std::ratio<60L, 1L>>");
static_assert(std::is_same<decltype(1s), std::chrono::seconds>::value,
"1s is std::chrono::seconds");
static_assert(std::is_same<decltype(1.0s),
std::chrono::duration<long double, std::ratio<1L, 1L>>>::value,
"1.0s is std::chrono::duration<long double, std::ratio<1L, 1L>>");
static_assert(std::is_same<decltype(1ms), std::chrono::milliseconds>::value,
"1ms is std::chrono::milliseconds");
static_assert(std::is_same<decltype(1.0ms),
std::chrono::duration<long double, std::ratio<1L, 1000L>>>::value,
"1.0ms is std::chrono::duration<long double, std::ratio<1L, 1000L>>");
static_assert(std::is_same<decltype(1us), std::chrono::microseconds>::value,
"1us is std::chrono::microseconds");
static_assert(std::is_same<decltype(1.0us),
std::chrono::duration<long double, std::ratio<1L, 1000000L>>>::value,
"1.0us is std::chrono::duration<long double, std::ratio<1L, 1000000L>>");
static_assert(std::is_same<decltype(1ns), std::chrono::nanoseconds>::value,
"1ns is std::chrono::nanoseconds");
static_assert(std::is_same<decltype(1.0ns),
std::chrono::duration<long double, std::ratio<1L, 1000000000L>>>::value,
"1.0ns is std::chrono::duration<long double, std::ratio<1L, 1000000000L>>");
}
// { dg-do run }
// { dg-options "-std=gnu++1y" }
// 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.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// NOTE: This makes use of the fact that we know how moveable
// is implemented on string (via swap). If the implementation changed
// this test may begin to fail.
#include <chrono>
#include <testsuite_hooks.h>
void
test03()
{
using namespace std::literals::chrono_literals;
auto jiffy = 23ns;
VERIFY( jiffy == std::chrono::nanoseconds(23) );
auto fjiffy = 23.0ns;
VERIFY( (fjiffy == std::chrono::duration<long double, std::nano>(23.0L)) );
auto blip = 14us;
VERIFY( blip == std::chrono::microseconds(14) );
auto fblip = 14.0us;
VERIFY( (fblip == std::chrono::duration<long double, std::micro>(14.0L)) );
auto bit = 77ms;
VERIFY( bit == std::chrono::milliseconds(77) );
auto fbit = 77.0ms;
VERIFY( (fbit == std::chrono::duration<long double, std::milli>(77.0L)) );
auto warmup = 33s;
VERIFY( warmup == std::chrono::seconds(33) );
auto fwarmup = 33.0s;
VERIFY( (fwarmup == std::chrono::duration<long double, std::ratio<1,1>>(33.0L)) );
auto classtime = 50min;
VERIFY( classtime == std::chrono::minutes(50) );
auto fclasstime = 50.0min;
VERIFY( (fclasstime == std::chrono::duration<long double, std::ratio<60,1>>(50.0L)) );
auto longtime = 1h + 30min;
VERIFY( longtime == std::chrono::minutes(90) );
auto flongtime = 1.0h + 30.0min;
VERIFY( (flongtime == std::chrono::duration<long double, std::ratio<3600,1>>(1.0L)
+ std::chrono::duration<long double, std::ratio<60,1>>(30.0L)) );
VERIFY( (flongtime == std::chrono::duration<long double, std::ratio<60,1>>(90.0L)) );
auto workday = 8h;
VERIFY( workday == std::chrono::hours(8) );
auto fworkday = 8.0h;
VERIFY( (fworkday == std::chrono::duration<long double, std::ratio<3600,1>>(8.0L)) );
}
int
main()
{
test03();
}
......@@ -31,5 +31,5 @@ void test01()
test_type d;
}
// { dg-error "rep cannot be a duration" "" { target *-*-* } 245 }
// { dg-error "rep cannot be a duration" "" { target *-*-* } 246 }
// { dg-error "required from here" "" { target *-*-* } 31 }
......@@ -32,5 +32,5 @@ void test01()
test_type d; // { dg-error "required from here" }
}
// { dg-error "must be a specialization of ratio" "" { target *-*-* } 246 }
// { dg-error "must be a specialization of ratio" "" { target *-*-* } 247 }
// { dg-prune-output "not a member" }
......@@ -33,5 +33,5 @@ void test01()
test_type d;
}
// { dg-error "period must be positive" "" { target *-*-* } 248 }
// { dg-error "period must be positive" "" { target *-*-* } 249 }
// { dg-error "required from here" "" { target *-*-* } 33 }
// { dg-options "-std=gnu++1y" }
// { dg-do compile }
// 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.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// NOTE: This makes use of the fact that we know how moveable
// is implemented on string (via swap). If the implementation changed
// this test may begin to fail.
#include <string>
#include <type_traits>
void
test01()
{
using namespace std::literals::string_literals;
static_assert(std::is_same<decltype("Hello"s), std::string>::value,
"\"Hello\"s is std::string");
static_assert(std::is_same<decltype(u8"Hello"s), std::string>::value,
"u8\"Hello\"s is std::string");
static_assert(std::is_same<decltype(L"Hello"s), std::wstring>::value,
"L\"Hello\"s is std::wstring");
static_assert(std::is_same<decltype(u"Hello"s), std::u16string>::value,
"u\"Hello\"s is std::u16string");
static_assert(std::is_same<decltype(U"Hello"s), std::u32string>::value,
"U\"Hello\"s is std::u32string");
}
// { dg-do run }
// { dg-options "-std=gnu++1y" }
// 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.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// NOTE: This makes use of the fact that we know how moveable
// is implemented on string (via swap). If the implementation changed
// this test may begin to fail.
#include <string>
#include <testsuite_hooks.h>
void
test01()
{
using namespace std::literals::string_literals;
std::string planet = "Mercury"s;
std::wstring wplanet = L"Venus"s;
std::string u8planet = u8"Mars"s;
std::u16string u16planet = u"Juiter"s;
std::u32string u32planet = U"Saturn"s;
VERIFY( planet == std::string("Mercury") );
VERIFY( wplanet == std::wstring(L"Venus") );
VERIFY( u8planet == std::string(u8"Mars") );
VERIFY( u16planet == std::u16string(u"Juiter") );
VERIFY( u32planet == std::u32string(U"Saturn") );
}
int
main()
{
test01();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment