TypePack.hpp

A set of types that can be manipulated at compile time (good for metaprogramming)

TypePacks are static structures that provide a large set of mechanisms to access and adjust the included types.

To create a TypePack, just pass in zero or more types into the TypePack template.

using my_pack = TypePack<int, std::string, double>;

After manipulations, you can apply a type pack using the apply<> member template. E.g.,

my_pack::resize<5,char>::reverse::apply<std::tuple> my_tuple;

…would create a variable of type std::tuple<char, char, double, std::string, int>.

Member functions include (all of which are constexpr): Has<T>() - Return true/false: Is T is part of the pack? Count<T>() - Return number of times T is in the pack. GetID<T>() - Return first position of T in the pack, (or -1 if none). GetSize() - Return total number of types in this pack. IsEmpty() - Return true/false: Is this pack empty? IsUnique() - Return true/false: are all types in pack are distinct?

Type accessors: get<POS> - Type at position POS in the pack. first_t - Type of first position in the pack. last_t - Type of last position in the pack. select<Ps…> - Create a new pack with types from selected positions.

Type manipulations: set<POS, T> - Change type at position POS to T. push_front<Ts…> - Add any number of types Ts to the front of the pack. push_back<Ts…> - Add any number of types Ts to the back of the pack. pop - Pack with first type missing. popN<N> - Pack with first N types missing. shrink<N> - Pack with ONLY first N types. resize<N,D> - Resize pack to N types; if N greater than current size, pad with D. merge

- Append all of pack P to the end of this pack. find_union

- Join this pack to P, keeping only one of each type. find_intersect

- Limit to only common types between this pack and P reverse - Reverse the order of types in this pack. rotate - Move the first type in pack to the end.

Applications: apply<T> - Take template T and apply these types as its arguments. to_function_t<T> - Convert to a function type, with return type T and arg types from pack. filter<FILTER> - Keep only those types, T, that can legally form FILTER<T> and does not have a FILTER<T>::value == false. filter_out<FILTER> - Remove those types, T, that can legally form FILTER<T> and do not have a FILTER<T>::value == false. find<FILTER> - Convert to first type, T, that can legally form FILTER<T> and does not have a FILTER<T>::value == false. remove_t<T> - Remove type T from anywhere in the pack. make_unique - Remove all type duplications. wrap<WRAPPER> - Convert to TypePack where all members are run through WRAPPER

Developer notes:

  • GetIDPack could return an ValPack of ALL ID’s for a type that appears more than once.

Typedefs

template<typename T, int N>
using TypePackFill = typename internal::tp_pad<TypePack<>, T, N>::type
struct null_t
#include <TypePack.hpp>
template<typename T1, typename ...Ts>
struct TypePack<T1, Ts...>
#include <TypePack.hpp>

Public Types

template<typename T>
using has_type = typename std::integral_constant<bool, Has<T>()>

Return a type indicating whether the specified type is present.

template<int POS>
using get = pack_id<POS, T1, Ts...>

Get the type associated with a specified position in the pack.

using this_t = TypePack<T1, Ts...>

What is the full type of this TypePack?

using first_t = T1

What is the first type in this TypePack?

using last_t = last_type<T1, Ts...>

What is the final type in this TypePack?

template<typename ...T>
using push_front = TypePack<T..., T1, Ts...>

Push a new type onto the front of this TypePack.

template<typename ...T>
using push_back = TypePack<T1, Ts..., T...>

Push a new type onto the back of this TypePack.

template<typename ...T>
using add = TypePack<T1, Ts..., T...>

Push a new type onto the back of this TypePack.

using pop = TypePack<Ts...>

Remove the first type from this TypePack and return the rest.

template<int N>
using popN = typename internal::tp_shift<N, TypePack<>, this_t>::type2
template<int N>
using shrink = typename internal::tp_shift<N, TypePack<>, this_t>::type1

Reduce the size of this TypePack down to N.

template<typename T, int N = 1>
using pad = typename internal::tp_pad<this_t, T, N>::type

Add N new entries onto TypePack, all of provided type T.

template<int N, typename DEFAULT = null_t>
using resize = typename pad<DEFAULT, (N > SIZE) ? (N - SIZE) : 0>::template shrink<N>

Make this TypePack the specified size, padding with provided type T.

template<typename IN>
using merge = typename internal::tp_shift<IN::SIZE, this_t, IN>::type1

Join this TypePack with another TypePack (append)

template<typename IN>
using find_union = typename internal::tp_shift<IN::SIZE, this_t, IN>::type1::make_unique

Join this TypePack with another, keeping only one of each type.

template<typename IN>
using find_intersect = typename internal::tp_filter_t<this_t, IN::template has_type>

Limit to only common types between this TypePack and another.

using reverse = typename pop::reverse::template push_back<T1>

Rearrange types in TypePack into reverse order.

using rotate = typename pop::template push_back<T1>

Rotate types through TypePack by the specified number of steps.

template<int ID, typename T>
using set = typename shrink<ID>::template push_back<T>::template merge<popN<ID + 1>>

Set the type at the specified position to the new type provided. Return as new TypePack.

template<int... Ps>
using select = TypePack<get<Ps>...>

Choose a set of specific positions. Return as new TypePack.

template<typename RETURN_T>
using to_function_t = RETURN_T(T1, Ts...)

Convert to a function signature with a specified return type.

template<template<typename...> class TEMPLATE>
using apply = TEMPLATE<T1, Ts...>

Apply to a specified template with TypePack as template arguments.

template<template<typename...> class FILTER>
using filter = internal::tp_filter_t<this_t, FILTER>

Remove all types that cannot pass a filter. Return as new TypePack.

template<template<typename...> class FILTER>
using filter_out = internal::tp_filter_out_t<this_t, FILTER>

Remove all types that DO pass a filter. Return as new TypePack.

template<template<typename...> class FILTER>
using find_t = typename internal::tp_filter_t<this_t, FILTER>::first_t

Return the first type that satisfies a filter.

template<typename T>
using remove_t = internal::tp_filter_out_t<this_t, type_matcher<T>::template is_match>

Remove all instances of a given type.

using make_unique = typename remove_t<first_t>::make_unique::template push_front<first_t>

Remove all duplicates within a TypePack.

template<template<typename...> class WRAPPER>
using wrap = internal::tp_wrap_t<this_t, WRAPPER>

Wrap all types in a specified wrapper template.

template<size_t COMBO_SIZE>
using make_combos = typename internal::all_combos<COMBO_SIZE, this_t, this_t>::result_t

Figure out all of the combinations of types possible.

Public Static Functions

template<typename T>
static inline constexpr bool Has()

Return a bool indicating whether the specified type is present.

template<typename T>
static inline constexpr size_t Count()

Count the number of instances of the specified type.

template<typename T>
static inline constexpr int GetID()

Return the position of the specified type.

template<typename T>
static inline constexpr int GetID(const T&)

Return the position of the type of owner.

static inline constexpr int GetSize()

Return the number of types in this pack.

static inline constexpr bool IsEmpty()

Return bool indicating if there are any types in this pack.

static inline constexpr bool IsUnique()

Return bool indicating if all types in this pack are different from each other.

static inline constexpr int CountUnique()

Count how many distinct types are in this pack.

Public Static Attributes

static constexpr int SIZE = 1 + sizeof...(Ts)

Set to the number of types in this pack.

template<typename M1>
struct type_matcher
#include <TypePack.hpp>

Public Types

template<typename M2>
using is_match = std::is_same<M1, M2>
template<>
struct TypePack<>
#include <TypePack.hpp>

Public Types

using this_t = TypePack<>
using first_t = null_t
using last_t = null_t
template<typename ...T>
using push_front = TypePack<T...>
template<typename ...T>
using push_back = TypePack<T...>
template<typename ...T>
using add = TypePack<T...>
template<int N>
using popN = this_t
template<int N>
using shrink = this_t
template<typename T, int N = 1>
using pad = typename internal::tp_pad<this_t, T, N>::type
template<int N, typename DEFAULT = null_t>
using resize = pad<DEFAULT, N>
template<typename IN>
using merge = IN
using reverse = this_t
using rotate = this_t
template<typename RETURN_T>
using to_function_t = RETURN_T()
template<template<typename...> class TEMPLATE>
using apply = TEMPLATE<>
template<template<typename...> class FILTER>
using filter = this_t
template<template<typename...> class FILTER>
using filter_out = this_t
template<template<typename...> class FILTER>
using find_t = null_t
template<typename T>
using remove_t = this_t
using make_unique = this_t
template<template<typename...> class WRAPPER>
using wrap = this_t

Public Static Functions

template<typename T>
static inline constexpr bool Has()
template<typename T>
static inline constexpr size_t Count()
static inline constexpr int GetSize()
static inline constexpr bool IsEmpty()
static inline constexpr bool IsUnique()

Public Static Attributes

static constexpr int SIZE = 0
template<typename T>
struct is_TypePack : public std::false_type
#include <TypePack.hpp>

A type trait to determine if a template that we are looking at is some kind of type pack.

template<typename ...Ts>
struct is_TypePack<TypePack<Ts...>> : public std::true_type
#include <TypePack.hpp>