////
Copyright 2017 Peter Dimov

Distributed under the Boost Software License, Version 1.0.

See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
////

[#definitions]
# Definitions

A _list_ is a -- usually but not necessarily variadic -- template class whose parameters are all types,
for example `mp_list<char[], void>`, `mp_list<>`, `std::tuple<int, float, char>`, `std::pair<int, float>`, `std::shared_ptr<X>`.

A _metafunction_ is a class template or a template alias whose parameters are all types, for example `std::add_pointer_t`,
`std::is_const`, `mp_second`, `mp_push_front`, `mp_list`, `std::tuple`, `std::pair`, `std::shared_ptr`, or

```
template<class...> using F1 = void;

template<class T> using F2 = T*;

template<class... T> using F3 = std::integral_constant<std::size_t, sizeof...(T)>;
```

A _quoted metafunction_ is a class with a public metafunction member called `fn`, for example

```
struct Q1 { template<class...> using fn = void; };

struct Q2 { template<class T> using fn = T*; };

struct Q3 { template<class... T> using fn =
  std::integral_constant<std::size_t, sizeof...(T)>; };
```

An _integral constant type_ is a class with a public member `value` that is an integral constant in the C++ sense. For example,
`std::integral_constant<int, 7>`, or

  struct N { static int constexpr value = 2; };

A _set_ is a list whose elements are unique.

A _map_ is a list of lists, the inner lists having at least one element (the key.) The keys of the map must be unique. For example,

```
using M1 = std::tuple<std::pair<int, int*>, std::pair<float, float*>,
    std::pair<void, void*>>;

using M2 = mp_list<mp_list<int, int*>, mp_list<float>,
    mp_list<char, char[1], char[2]>>;
```

A _value list_ is a template class whose parameters are all values (non-type template parameters.) Value lists
match `template<auto...> class L`, and require {cpp}17 (because `auto` template parameters are a {cpp}17 feature.)

Value lists are only supported by a handful of the primitives. Mp11's primary focus is on type manipulation. For
working with lists of values, the usual approach is to convert the value list to a type list using `mp_rename`,
manipulate the type list, then convert back to a value list using `mp_rename_v`.
