Implement LWG 2770 - Make tuple_size<T> defined for all T
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@286779 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
|
template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size {};
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
class _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp>
|
class _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp>
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ template <class T, class Tuple>
|
|||||||
constexpr T make_from_tuple(Tuple&& t); // C++17
|
constexpr T make_from_tuple(Tuple&& t); // C++17
|
||||||
|
|
||||||
// 20.4.1.4, tuple helper classes:
|
// 20.4.1.4, tuple helper classes:
|
||||||
template <class T> class tuple_size; // undefined
|
template <class T> class tuple_size;
|
||||||
template <class... T> class tuple_size<tuple<T...>>;
|
template <class... T> class tuple_size<tuple<T...>>;
|
||||||
template <class T>
|
template <class T>
|
||||||
constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
|
constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
(void)std::tuple_size<std::tuple<> &>::value; // expected-error {{implicit instantiation of undefined template}}
|
(void)std::tuple_size<std::tuple<> &>::value; // expected-error {{no member named 'value'}}
|
||||||
(void)std::tuple_size<int>::value; // expected-error {{implicit instantiation of undefined template}}
|
(void)std::tuple_size<int>::value; // expected-error {{no member named 'value'}}
|
||||||
(void)std::tuple_size<std::tuple<>*>::value; // expected-error {{implicit instantiation of undefined template}}
|
(void)std::tuple_size<std::tuple<>*>::value; // expected-error {{no member named 'value'}}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,19 +18,36 @@
|
|||||||
// UNSUPPORTED: c++98, c++03
|
// UNSUPPORTED: c++98, c++03
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <utility>
|
||||||
|
#include <array>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
template <class T, class = decltype(std::tuple_size<T>::value)>
|
||||||
|
constexpr bool has_value(int) { return true; }
|
||||||
|
template <class> constexpr bool has_value(long) { return false; }
|
||||||
|
template <class T> constexpr bool has_value() { return has_value<T>(0); }
|
||||||
|
|
||||||
|
|
||||||
template <class T, std::size_t N>
|
template <class T, std::size_t N>
|
||||||
void test()
|
void test()
|
||||||
{
|
{
|
||||||
|
static_assert(has_value<T>(), "");
|
||||||
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
|
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
|
||||||
std::tuple_size<T> >::value), "");
|
std::tuple_size<T> >::value), "");
|
||||||
|
static_assert(has_value<const T>(), "");
|
||||||
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
|
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
|
||||||
std::tuple_size<const T> >::value), "");
|
std::tuple_size<const T> >::value), "");
|
||||||
|
static_assert(has_value<volatile T>(), "");
|
||||||
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
|
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
|
||||||
std::tuple_size<volatile T> >::value), "");
|
std::tuple_size<volatile T> >::value), "");
|
||||||
|
|
||||||
|
static_assert(has_value<const volatile T>(), "");
|
||||||
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
|
static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
|
||||||
std::tuple_size<const volatile T> >::value), "");
|
std::tuple_size<const volatile T> >::value), "");
|
||||||
|
{
|
||||||
|
static_assert(!has_value<T &>(), "");
|
||||||
|
static_assert(!has_value<T *>(), "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@@ -39,4 +56,13 @@ int main()
|
|||||||
test<std::tuple<int>, 1>();
|
test<std::tuple<int>, 1>();
|
||||||
test<std::tuple<char, int>, 2>();
|
test<std::tuple<char, int>, 2>();
|
||||||
test<std::tuple<char, char*, int>, 3>();
|
test<std::tuple<char, char*, int>, 3>();
|
||||||
|
test<std::pair<int, void*>, 2>();
|
||||||
|
test<std::array<int, 42>, 42>();
|
||||||
|
{
|
||||||
|
static_assert(!has_value<void>(), "");
|
||||||
|
static_assert(!has_value<void*>(), "");
|
||||||
|
static_assert(!has_value<int>(), "");
|
||||||
|
static_assert(!has_value<std::pair<int, int>*>(), "");
|
||||||
|
static_assert(!has_value<std::array<int, 42>&>(), "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,5 +22,5 @@ int main()
|
|||||||
(void)std::tuple_size_v<std::tuple<> &>; // expected-note {{requested here}}
|
(void)std::tuple_size_v<std::tuple<> &>; // expected-note {{requested here}}
|
||||||
(void)std::tuple_size_v<int>; // expected-note {{requested here}}
|
(void)std::tuple_size_v<int>; // expected-note {{requested here}}
|
||||||
(void)std::tuple_size_v<std::tuple<>*>; // expected-note {{requested here}}
|
(void)std::tuple_size_v<std::tuple<>*>; // expected-note {{requested here}}
|
||||||
// expected-error@tuple:* 3 {{implicit instantiation of undefined template}}
|
// expected-error@tuple:* 3 {{no member named 'value'}}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user