From 6ae2ae3b84615e5e4504a1592af6a8d5579f17ca Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 15 Nov 2016 19:32:44 +0000 Subject: [PATCH] Make std::tuple_size SFINAE-friendly (LWG 2770) * doc/xml/manual/intro.xml: Document LWG 2770 status. Remove entries for 2742 and 2748. * doc/html/*: Regenerate. * include/std/utility (__tuple_size_cv_impl): New helper to safely detect tuple_size::value, as per LWG 2770. (tuple_size): Adjust partial specializations to derive from __tuple_size_cv_impl. * testsuite/20_util/tuple/cv_tuple_size.cc: Test SFINAE-friendliness. From-SVN: r242452 --- libstdc++-v3/ChangeLog | 9 +++++++++ libstdc++-v3/doc/html/manual/bugs.html | 14 +++++--------- libstdc++-v3/doc/xml/manual/intro.xml | 17 +++++------------ libstdc++-v3/include/std/utility | 18 ++++++++++++------ .../testsuite/20_util/tuple/cv_tuple_size.cc | 10 ++++++++++ 5 files changed, 41 insertions(+), 27 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 77669da173f..6bf1ecbcf0e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,14 @@ 2016-11-15 Jonathan Wakely + * doc/xml/manual/intro.xml: Document LWG 2770 status. Remove entries + for 2742 and 2748. + * doc/html/*: Regenerate. + * include/std/utility (__tuple_size_cv_impl): New helper to safely + detect tuple_size::value, as per LWG 2770. + (tuple_size): Adjust partial specializations to derive from + __tuple_size_cv_impl. + * testsuite/20_util/tuple/cv_tuple_size.cc: Test SFINAE-friendliness. + * testsuite/libstdc++-prettyprinters/cxx17.cc: Adjust test for variant. diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html index d4a39d82e89..ee39a954c5c 100644 --- a/libstdc++-v3/doc/html/manual/bugs.html +++ b/libstdc++-v3/doc/html/manual/bugs.html @@ -503,14 +503,10 @@ priority_queue lacking comparator typedef

Define the value_compare typedef. -

2742: - Inconsistent string interface taking string_view +

2770: + tuple_size<const T> specialization is not + SFINAE compatible and breaks decomposition declarations -

Add the new constructor and additionally constrain it - to avoid ambiguities with non-const charT*. -

2748: - swappable traits for optionals - -

Disable the non-member swap overload when - the contained object is not swappable. +

Safely detect tuple_size<T>::value and + only use it if valid.

\ No newline at end of file diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index 7f2586d8160..d23008ad332 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -1107,20 +1107,13 @@ requirements of the license of GCC. Define the value_compare typedef. - 2742: - Inconsistent string interface taking string_view + 2770: + tuple_size<const T> specialization is not + SFINAE compatible and breaks decomposition declarations - Add the new constructor and additionally constrain it - to avoid ambiguities with non-const charT*. - - - 2748: - swappable traits for optionals - - - Disable the non-member swap overload when - the contained object is not swappable. + Safely detect tuple_size<T>::value and + only use it if valid. diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index 2ca52fe699a..3982156d695 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -87,19 +87,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct tuple_size; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2770. tuple_size specialization is not SFINAE compatible + template + struct __tuple_size_cv_impl { }; + + template + struct __tuple_size_cv_impl<_Tp, __void_t::value)>> + : integral_constant::value> { }; + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2313. tuple_size should always derive from integral_constant template - struct tuple_size - : integral_constant::value> { }; + struct tuple_size : __tuple_size_cv_impl<_Tp> { }; template - struct tuple_size - : integral_constant::value> { }; + struct tuple_size : __tuple_size_cv_impl<_Tp> { }; template - struct tuple_size - : integral_constant::value> { }; + struct tuple_size : __tuple_size_cv_impl<_Tp> { }; /// Gives the type of the ith element of a given tuple type. template diff --git a/libstdc++-v3/testsuite/20_util/tuple/cv_tuple_size.cc b/libstdc++-v3/testsuite/20_util/tuple/cv_tuple_size.cc index df5e0e993d3..c4a1e02db87 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/cv_tuple_size.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/cv_tuple_size.cc @@ -42,3 +42,13 @@ int main() test01(); return 0; } + +// LWG DR 2770. tuple_size specialization is not SFINAE compatible +template +struct has_value : std::false_type { }; + +template +struct has_value> : std::true_type { }; + +static_assert( !has_value>::value, "" ); +static_assert( !has_value>::value, "" );