N4115, Parameter Pack Searching

Doc No: | N4115
Date: | 2014-07-04
Reply to: | `stdbill.h@pobox.com`

## Searching for Types in Parameter Packs

### Bill Seymour
Stephan T. Lavavej
2014-07-04

### Abstract:

This paper proposes that a mechanism for finding types in parameter packs be added to the standard library.

### The basic idea:

This paper proposes three new class templates for `<type_traits>`. One is just a holder of a parameter pack; the other two report at compile time whether a parameter pack contains one or more types.

Possible implementations of the last two are shown as proof of concept. They both compile to either `std::true_type` or `std::false_type`.

And in the spirit of N3854, this paper also adds the “`_v`” values.

#### A class template that just holds a parameter pack:

        template <class... T> struct packer { };

This is inspired by `std::tuple`, but it lacks members, so it could serve as an empty base class, and an object of the ultimate type could always be instantiated (even if the parameter pack contains `void` or some type that lacks a default constructor).

#### Whether type T is in parameter pack P:

        template <class T, class... P> struct is_contained_in;

        template <class T, class... P>
          constexpr bool is_contained_in_v = is_contained_in<T,P>::value;

#### One possible implementation:

        template <class T> struct is_contained_in<T> : false_type { };

        template <class First, class... Rest>
          struct is_contained_in<First, First, Rest...> : true_type { };

        template <class T, class First, class... Rest>
          struct is_contained_in<T, First, Rest...>
            : is_contained_in<T, Rest...> { };

#### Whether a `packer`, T, has a parameter pack that’s a superset of the pack of some minimum `packer`, U:

        template <class T, class U> struct contains_types;

        template <class T, class U>
          constexpr bool contains_types_v = contains_types<T,U>::value;

#### One possible implementation:

        template <class... TPack>
          struct contains_types<packer<TPack...>, packer<>> : true_type { };

        template <class... TPack, class UFirst, class... URest>
          struct contains_types<packer<TPack...>, packer<UFirst, URest...>>
            : integral_constant<bool,
                is_contained_in<UFirst, TPack...>::value &&
                contains_types<packer<TPack...>, packer<URest...>>::value> { };

### Standardese relative to N3936:

In 20.10.2 Header `<type_traits>` synopsis [meta.type.synop]:

- Change “// 20.10.3, helper class:”

  - Make the heading plural:

    > // 20.10.3, helper classes:

  - Add at the end:

            template<class... T> struct packer;

- Add to “// 20.10.6, type relations:”

          template <class T, class... P> struct is_contained_in;
          template <class T, class U> struct contains_types;

          template <class T, class... P>
            constexpr bool is_contained_in_v = is_contained_in<T,P>::value;
          template <class T, class U>
            constexpr bool contains_types_v = contains_types<T,U>::value;

In 20.10.3 Helper classes [meta.help]:

- Add just before the closing brace of `namespace` `std`:

          template<class... T> struct packer { };

- Add a new paragraph after paragraph 1:

  > The class template `packer` simply holds a parameter pack.

In 20.10.6 Relationships between types [meta.rel], add to the end of Table 51:

> `template <class T, class... P> struct is_contained_in;` | Type `T` is contained in parameter pack `P` |
> `template <class T, class U> struct contains_types;` | `T`’s parameter pack contains at least one instance of each of the types in `U`’s parameter pack | `T` and `U` are `packer`s (20.10.3).

Reply to: `stdbill.h@pobox.com`