```
template<class T> struct tuple_size;
```

Remarks:
All specializations of tuple_size shall meet the
Cpp17UnaryTypeTrait requirements ([meta.rqmts]) with a
base characteristic of integral_constant<size_t, N>
for some N.

```
template<class... Types>
struct tuple_size<tuple<Types...>> : public integral_constant<size_t, sizeof...(Types)> { };
```

```
template<size_t I, class... Types>
struct tuple_element<I, tuple<Types...>> {
using type = TI;
};
```

```
template<class T> struct tuple_size<const T>;
template<class T> struct tuple_size<volatile T>;
template<class T> struct tuple_size<const volatile T>;
```

If the expression TS::value is well-formed
when treated as an unevaluated operand, then each
of the three templates shall meet the Cpp17UnaryTypeTrait requirements ([meta.rqmts])
with a base characteristic of

integral_constant<size_t, TS::value>

Otherwise, they shall have no member value.

Only the validity of the immediate context of the expression is considered.

[ Note

: *end note*

]The compilation of the expression can result in side effects
such as the instantiation of class template specializations and
function template specializations, the generation of implicitly-defined functions, and so on.

Such side effects are not in the โimmediate contextโ and
can result in the program being ill-formed.

โ In addition to being available via inclusion of the <tuple> header,
the three templates are available
when any of the headers
<array> ([array.syn]),
<ranges> ([ranges.syn]),
<span> ([span.syn]), or
<utility> ([utility.syn])
are included.

```
template<size_t I, class T> struct tuple_element<I, const T>;
template<size_t I, class T> struct tuple_element<I, volatile T>;
template<size_t I, class T> struct tuple_element<I, const volatile T>;
```

Then
each of the three templates shall meet the Cpp17TransformationTrait
requirements ([meta.rqmts]) with a member typedef type that names the following
type:

- for the first specialization, add_const_t<TE>,
- for the second specialization, add_volatile_t<TE>, and
- for the third specialization, add_cv_t<TE>.

In addition to being available via inclusion of the <tuple> header,
the three templates are available
when any of the headers
<array> ([array.syn]),
<ranges> ([ranges.syn]),
<span> ([span.syn]), or
<utility> ([utility.syn])
are included.