1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <tuple>
11
12// template <class... Types> class tuple;
13
14// template <class... Types>
15//   class tuple_size<tuple<Types...>>
16//     : public integral_constant<size_t, sizeof...(Types)> { };
17
18// UNSUPPORTED: c++98, c++03
19
20#include <tuple>
21#include <array>
22#include <type_traits>
23
24struct Dummy1 {};
25struct Dummy2 {};
26struct Dummy3 {};
27
28template <>
29class std::tuple_size<Dummy1> {
30public:
31  static size_t value;
32};
33
34template <>
35class std::tuple_size<Dummy2> {
36public:
37  static void value() {}
38};
39
40template <>
41class std::tuple_size<Dummy3> {};
42
43int main()
44{
45  // Test that tuple_size<const T> is not incomplete when tuple_size<T>::value
46  // is well-formed but not a constant expression.
47  {
48    // expected-error@__tuple:* 1 {{is not a constant expression}}
49    (void)std::tuple_size<const Dummy1>::value; // expected-note {{here}}
50  }
51  // Test that tuple_size<const T> is not incomplete when tuple_size<T>::value
52  // is well-formed but not convertible to size_t.
53  {
54    // expected-error@__tuple:* 1 {{value of type 'void ()' is not implicitly convertible to}}
55    (void)std::tuple_size<const Dummy2>::value; // expected-note {{here}}
56  }
57  // Test that tuple_size<const T> generates an error when tuple_size<T> is
58  // complete but ::value isn't a constant expression convertible to size_t.
59  {
60    // expected-error@__tuple:* 1 {{no member named 'value'}}
61    (void)std::tuple_size<const Dummy3>::value; // expected-note {{here}}
62  }
63}
64