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

Zoe Carver via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Wed Mar 6 20:49:09 PST 2019


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

Update tests (tentatively) & fix stylistic error.


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


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**)
 {
     static_assert((std::is_same<std::underlying_type<E>::type, int>::value),
@@ -52,6 +64,9 @@
     static_assert((std::is_same<std::underlying_type_t<G>, char>::value), "");
 #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,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// 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
@@ -4711,12 +4711,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.189648.patch
Type: text/x-patch
Size: 2695 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20190307/d8284b06/attachment.bin>


More information about the libcxx-commits mailing list