[libcxx-commits] [PATCH] D58987: Make underlying_type SFINAE-friendly

Zoe Carver via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Apr 5 19:25:05 PDT 2019


zoecarver updated this revision to Diff 193997.
zoecarver added a comment.

Update status.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D58987/new/

https://reviews.llvm.org/D58987

Files:
  include/type_traits
  test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.fail.cpp
  test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp
  www/cxx2a_status.html


Index: www/cxx2a_status.html
===================================================================
--- www/cxx2a_status.html
+++ www/cxx2a_status.html
@@ -139,7 +139,7 @@
 
  	<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
 	<tr><td><a href="https://wg21.link/P0339R6">P0339R6</a></td><td>LWG</td><td>polymorphic_allocator<> as a vocabulary type</td><td>Kona</td><td></td><td></td></tr>
-	<tr><td><a href="https://wg21.link/P0340R3">P0340R3</a></td><td>LWG</td><td>Making std::underlying_type SFINAE-friendly</td><td>Kona</td><td></td><td></td></tr>
+	<tr><td><a href="https://wg21.link/P0340R3">P0340R3</a></td><td>LWG</td><td>Making std::underlying_type SFINAE-friendly</td><td>Kona</td><td>Complete</td><td></td></tr>
 	<tr><td><a href="https://wg21.link/P0738R2">P0738R2</a></td><td>LWG</td><td>I Stream, You Stream, We All Stream for istream_iterator</td><td>Kona</td><td></td><td></td></tr>
 	<tr><td><a href="https://wg21.link/P0811R3">P0811R3</a></td><td>LWG</td><td>Well-behaved interpolation for numbers and pointers</td><td>Kona</td><td></td><td></td></tr>
 	<tr><td><a href="https://wg21.link/P0920R2">P0920R2</a></td><td>LWG</td><td>Precalculated hash values in lookup</td><td>Kona</td><td></td><td></td></tr>
Index: test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp
===================================================================
--- test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp
+++ test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp
@@ -27,6 +27,18 @@
 enum F { W = UINT_MAX };
 #endif // TEST_UNSIGNED_UNDERLYING_TYPE
 
+template <class T, class = typename std::underlying_type<T>::type>
+std::true_type test_sfinae(int);
+
+template <class T>
+std::false_type test_sfinae(...);
+
+template <class T>
+constexpr bool test_sfinae_v() // This is a function so it is valid pre-c++14
+{
+	return decltype(test_sfinae<T>(0))::value;
+}
+
 int main(int, char**)
 {
     ASSERT_SAME_TYPE(int, std::underlying_type<E>::type);
@@ -49,6 +61,9 @@
     ASSERT_SAME_TYPE(char, std::underlying_type_t<G>);
 #endif // TEST_STD_VER > 11
 #endif // TEST_STD_VER >= 11
+	
+	static_assert(!test_sfinae_v<int>(), "Not an enum");
+	static_assert(test_sfinae_v<E>(), "Is an enum");
 
   return 0;
 }
Index: test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.fail.cpp
===================================================================
--- /dev/null
+++ test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.fail.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// type_traits
+
+// underlying_type
+
+#include <type_traits>
+
+int main(int, char**)
+{
+	// no `type` member indicates that `int` is not an enum
+	using t = std::underlying_type<int>::type; // expected-error {{no type named 'type' in 'std::__1::underlying_type<int>'}}
+	return 0;
+}
Index: include/type_traits
===================================================================
--- include/type_traits
+++ include/type_traits
@@ -4700,12 +4700,18 @@
 
 #ifdef _LIBCPP_UNDERLYING_TYPE
 
-template <class _Tp>
-struct underlying_type
+template <class _Tp, bool = is_enum<_Tp>::value>
+struct __impl_underlying_type
 {
     typedef _LIBCPP_UNDERLYING_TYPE(_Tp) type;
 };
 
+template <class _Tp>
+struct __impl_underlying_type<_Tp, false> { };
+
+template <class _Tp>
+struct underlying_type : __impl_underlying_type<_Tp> { };
+
 #if _LIBCPP_STD_VER > 11
 template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type;
 #endif


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D58987.193997.patch
Type: text/x-patch
Size: 3922 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20190406/0c2a719c/attachment.bin>


More information about the libcxx-commits mailing list