diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2016-11-15 19:32:44 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2016-11-15 19:32:44 +0000 |
commit | 6ae2ae3b84615e5e4504a1592af6a8d5579f17ca (patch) | |
tree | ebab8a077030dde507ddca02199aad37580caa05 | |
parent | 168126e59828b8d2cc8cbb7e03fbe8341177f58f (diff) | |
download | gcc-6ae2ae3b84615e5e4504a1592af6a8d5579f17ca.zip gcc-6ae2ae3b84615e5e4504a1592af6a8d5579f17ca.tar.gz gcc-6ae2ae3b84615e5e4504a1592af6a8d5579f17ca.tar.bz2 |
Make std::tuple_size<cv T> 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<T>::value, as per LWG 2770.
(tuple_size<cv T>): Adjust partial specializations to derive from
__tuple_size_cv_impl.
* testsuite/20_util/tuple/cv_tuple_size.cc: Test SFINAE-friendliness.
From-SVN: r242452
-rw-r--r-- | libstdc++-v3/ChangeLog | 9 | ||||
-rw-r--r-- | libstdc++-v3/doc/html/manual/bugs.html | 14 | ||||
-rw-r--r-- | libstdc++-v3/doc/xml/manual/intro.xml | 17 | ||||
-rw-r--r-- | libstdc++-v3/include/std/utility | 18 | ||||
-rw-r--r-- | libstdc++-v3/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 77669da..6bf1ecb 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,14 @@ 2016-11-15 Jonathan Wakely <jwakely@redhat.com> + * 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<T>::value, as per LWG 2770. + (tuple_size<cv T>): 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<T&>. diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html index d4a39d8..ee39a95 100644 --- a/libstdc++-v3/doc/html/manual/bugs.html +++ b/libstdc++-v3/doc/html/manual/bugs.html @@ -503,14 +503,10 @@ <span class="emphasis"><em><code class="code">priority_queue</code> lacking comparator typedef </em></span> </span></dt><dd><p>Define the <code class="code">value_compare</code> typedef. - </p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2742" target="_top">2742</a>: - <span class="emphasis"><em>Inconsistent <code class="code">string</code> interface taking <code class="code">string_view</code> + </p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2770" target="_top">2770</a>: + <span class="emphasis"><em><code class="code">tuple_size<const T></code> specialization is not + SFINAE compatible and breaks decomposition declarations </em></span> - </span></dt><dd><p>Add the new constructor and additionally constrain it - to avoid ambiguities with non-const <code class="code">charT*</code>. - </p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2748" target="_top">2748</a>: - <span class="emphasis"><em>swappable traits for optionals - </em></span> - </span></dt><dd><p>Disable the non-member <code class="code">swap</code> overload when - the contained object is not swappable. + </span></dt><dd><p>Safely detect <code class="code">tuple_size<T>::value</code> and + only use it if valid. </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="license.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="status.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="setup.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">License </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 2. Setup</td></tr></table></div></body></html>
\ 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 7f2586d..d23008a 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. <listitem><para>Define the <code>value_compare</code> typedef. </para></listitem></varlistentry> - <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2742">2742</link>: - <emphasis>Inconsistent <code>string</code> interface taking <code>string_view</code> + <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2770">2770</link>: + <emphasis><code>tuple_size<const T></code> specialization is not + SFINAE compatible and breaks decomposition declarations </emphasis> </term> - <listitem><para>Add the new constructor and additionally constrain it - to avoid ambiguities with non-const <code>charT*</code>. - </para></listitem></varlistentry> - - <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2748">2748</link>: - <emphasis>swappable traits for optionals - </emphasis> - </term> - <listitem><para>Disable the non-member <code>swap</code> overload when - the contained object is not swappable. + <listitem><para>Safely detect <code>tuple_size<T>::value</code> and + only use it if valid. </para></listitem></varlistentry> </variablelist> diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index 2ca52fe..3982156 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -88,18 +88,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct tuple_size; // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 2313. tuple_size should always derive from integral_constant<size_t, N> + // 2770. tuple_size<const T> specialization is not SFINAE compatible + template<typename _Tp, typename = void> + struct __tuple_size_cv_impl { }; + template<typename _Tp> - struct tuple_size<const _Tp> + struct __tuple_size_cv_impl<_Tp, __void_t<decltype(tuple_size<_Tp>::value)>> : integral_constant<size_t, tuple_size<_Tp>::value> { }; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2313. tuple_size should always derive from integral_constant<size_t, N> + template<typename _Tp> + struct tuple_size<const _Tp> : __tuple_size_cv_impl<_Tp> { }; + template<typename _Tp> - struct tuple_size<volatile _Tp> - : integral_constant<size_t, tuple_size<_Tp>::value> { }; + struct tuple_size<volatile _Tp> : __tuple_size_cv_impl<_Tp> { }; template<typename _Tp> - struct tuple_size<const volatile _Tp> - : integral_constant<size_t, tuple_size<_Tp>::value> { }; + struct tuple_size<const volatile _Tp> : __tuple_size_cv_impl<_Tp> { }; /// Gives the type of the ith element of a given tuple type. template<std::size_t __i, typename _Tp> 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 df5e0e9..c4a1e02 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<const T> specialization is not SFINAE compatible +template<typename T, typename = void> +struct has_value : std::false_type { }; + +template<typename T> +struct has_value<T, std::__void_t<decltype(T::value)>> : std::true_type { }; + +static_assert( !has_value<std::tuple_size<int>>::value, "" ); +static_assert( !has_value<std::tuple_size<const int>>::value, "" ); |