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
This commit is contained in:
parent
168126e598
commit
6ae2ae3b84
|
@ -1,5 +1,14 @@
|
||||||
2016-11-15 Jonathan Wakely <jwakely@redhat.com>
|
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
|
* testsuite/libstdc++-prettyprinters/cxx17.cc: Adjust test for
|
||||||
variant<T&>.
|
variant<T&>.
|
||||||
|
|
||||||
|
|
|
@ -503,14 +503,10 @@
|
||||||
<span class="emphasis"><em><code class="code">priority_queue</code> lacking comparator typedef
|
<span class="emphasis"><em><code class="code">priority_queue</code> lacking comparator typedef
|
||||||
</em></span>
|
</em></span>
|
||||||
</span></dt><dd><p>Define the <code class="code">value_compare</code> typedef.
|
</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>:
|
</p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2770" target="_top">2770</a>:
|
||||||
<span class="emphasis"><em>Inconsistent <code class="code">string</code> interface taking <code class="code">string_view</code>
|
<span class="emphasis"><em><code class="code">tuple_size<const T></code> specialization is not
|
||||||
|
SFINAE compatible and breaks decomposition declarations
|
||||||
</em></span>
|
</em></span>
|
||||||
</span></dt><dd><p>Add the new constructor and additionally constrain it
|
</span></dt><dd><p>Safely detect <code class="code">tuple_size<T>::value</code> and
|
||||||
to avoid ambiguities with non-const <code class="code">charT*</code>.
|
only use it if valid.
|
||||||
</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.
|
|
||||||
</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>
|
</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>
|
|
@ -1107,20 +1107,13 @@ requirements of the license of GCC.
|
||||||
<listitem><para>Define the <code>value_compare</code> typedef.
|
<listitem><para>Define the <code>value_compare</code> typedef.
|
||||||
</para></listitem></varlistentry>
|
</para></listitem></varlistentry>
|
||||||
|
|
||||||
<varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2742">2742</link>:
|
<varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2770">2770</link>:
|
||||||
<emphasis>Inconsistent <code>string</code> interface taking <code>string_view</code>
|
<emphasis><code>tuple_size<const T></code> specialization is not
|
||||||
|
SFINAE compatible and breaks decomposition declarations
|
||||||
</emphasis>
|
</emphasis>
|
||||||
</term>
|
</term>
|
||||||
<listitem><para>Add the new constructor and additionally constrain it
|
<listitem><para>Safely detect <code>tuple_size<T>::value</code> and
|
||||||
to avoid ambiguities with non-const <code>charT*</code>.
|
only use it if valid.
|
||||||
</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.
|
|
||||||
</para></listitem></varlistentry>
|
</para></listitem></varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
|
@ -87,19 +87,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct tuple_size;
|
struct tuple_size;
|
||||||
|
|
||||||
|
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||||
|
// 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_cv_impl<_Tp, __void_t<decltype(tuple_size<_Tp>::value)>>
|
||||||
|
: integral_constant<size_t, tuple_size<_Tp>::value> { };
|
||||||
|
|
||||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||||
// 2313. tuple_size should always derive from integral_constant<size_t, N>
|
// 2313. tuple_size should always derive from integral_constant<size_t, N>
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct tuple_size<const _Tp>
|
struct tuple_size<const _Tp> : __tuple_size_cv_impl<_Tp> { };
|
||||||
: integral_constant<size_t, tuple_size<_Tp>::value> { };
|
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct tuple_size<volatile _Tp>
|
struct tuple_size<volatile _Tp> : __tuple_size_cv_impl<_Tp> { };
|
||||||
: integral_constant<size_t, tuple_size<_Tp>::value> { };
|
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct tuple_size<const volatile _Tp>
|
struct tuple_size<const volatile _Tp> : __tuple_size_cv_impl<_Tp> { };
|
||||||
: integral_constant<size_t, tuple_size<_Tp>::value> { };
|
|
||||||
|
|
||||||
/// Gives the type of the ith element of a given tuple type.
|
/// Gives the type of the ith element of a given tuple type.
|
||||||
template<std::size_t __i, typename _Tp>
|
template<std::size_t __i, typename _Tp>
|
||||||
|
|
|
@ -42,3 +42,13 @@ int main()
|
||||||
test01();
|
test01();
|
||||||
return 0;
|
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, "" );
|
||||||
|
|
Loading…
Reference in New Issue