Index: libcxx/include/type_traits =================================================================== --- libcxx/include/type_traits +++ libcxx/include/type_traits @@ -4726,8 +4726,14 @@ #ifdef _LIBCPP_UNDERLYING_TYPE +template ::value> struct underlying_type; + + template -struct underlying_type +struct underlying_type<_Tp, false> {}; + +template +struct underlying_type<_Tp, true> { typedef _LIBCPP_UNDERLYING_TYPE(_Tp) type; }; Index: libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.fail.cpp =================================================================== --- /dev/null +++ libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++11, C++14, c++17 +// type_traits + +// underlying_type +// Mandates: enum must not be an incomplete enumeration type. + +#include +#include + +#include "test_macros.h" + +enum E1 { zero, one, two = sizeof(std::underlying_type::type) }; + +int main(int, char**) +{ + return 0; +} Index: libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp =================================================================== --- libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp +++ libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp @@ -15,6 +15,18 @@ #include "test_macros.h" +#if TEST_STD_VER > 17 +template > +struct has_type_member : std::false_type {}; + +template +struct has_type_member::type>> : std::true_type {}; + +struct S {}; +#endif + + enum E { V = INT_MIN }; #if !defined(_WIN32) || defined(__MINGW32__) @@ -50,5 +62,18 @@ #endif // TEST_STD_VER > 11 #endif // TEST_STD_VER >= 11 +#if TEST_STD_VER > 17 + static_assert( has_type_member::value, ""); + static_assert( has_type_member::value, ""); + static_assert( has_type_member::value, ""); + + static_assert(!has_type_member::value, ""); + static_assert(!has_type_member::value, ""); + static_assert(!has_type_member::value, ""); + static_assert(!has_type_member::value, ""); + static_assert(!has_type_member::value, ""); + static_assert(!has_type_member::value, ""); +#endif + return 0; }