Skip to content

Instantly share code, notes, and snippets.

@rpavlik
Last active October 23, 2015 18:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rpavlik/97d7fbf318e7eb093a33 to your computer and use it in GitHub Desktop.
Save rpavlik/97d7fbf318e7eb093a33 to your computer and use it in GitHub Desktop.
Data structures in meta and typepack

(Based in part on https://ericniebler.github.io/meta/index.html, designed to be a printable quick reference.)

Quick reference examples

Using the C++14 standard library.

  • Trait: std::add_pointer
    • is a "template" (has template parameters) - not a type unless evaluated.
    • Evaluate: typename std::add_pointer<int>::type (aka typepack::t_<std::add_pointer<int>>) is int *
  • Alias (alias template): std::add_pointer_t
    • is a "template" (has template parameters) - not a type unless evaluated.
    • application: std::add_pointer_t<int> is int *
  • Alias class: meta::quote<std::add_pointer_t> or meta::quote_trait<std::add_pointer> or struct add_pointer_class { template<typename T> using apply = std::add_pointer_t; };
    • is a type (not a template) for easy passing to algorithms, with a nested alias template.
    • application: given one of the above with the name add_pointer_ac, typepack::apply<add_pointer_ac, int> is int *

Basic entities

Type aliases

Type aliases are these things:

using StringVec = std::vector<String>;

C++11, more consistent syntax for typedefs. (mirrors usage of auto, etc.)

Alias templates (aliases)

Alias templates are the above except with one or more free template arguments:

template<typename... Args>
using PointlessVecWrapper = std::vector<Args...>;

// As seen in C++14
template<typename... Args>
using enable_if_t = typename enable_if<Args>::type;

Importantly, naming them "returns" the "value" - no nested type required. Alias templates are the main "function" type in meta and typepack, unlike MPL where "metafunctions" aka "traits" primary. Unless otherwise specified, alias refers to alias template.

Traits

Traits are class templates that have a nested type alias called type, like this boring one that always "returns" void no matter the argument(s).

template <typename... Args>
struct t
{
    using type = void;
};

(These are what the MPL calls metafunctions, except they'd probably have a typedef void type instead of the newer type alias syntax using type = void.)

You can evaluate traits either with typename whatever<args>::type or the cleaner typepack::t_<whatever<args>>. (meta uses meta::_t to mimic the C++14 practice of providing aliases for all traits, ending in _t, but that's technically a not-permissible name. This is probably one of the largest porting differences between typepack and meta.)

Alias classes

Alias classes are for "higher-order" metaprogramming: since the primary function abstraction takes template args (that is, it's not a type), they can be a pain to pass around - not as easy as passing a type. Alias classes are (non-templated!) classes with a nested alias template named apply.

struct ac
{
    template <typename... Args>
    using apply = void;
};

They're a way to pass "functions" as arguments to algorithms (like transform, fold, etc.) To evaluate them, use the alias template typepack::apply like typepack::apply<ac, arg1, arg2>

Operations on entities

  • Evaluate:
    • Alias: name them with arguments.
    • Trait: typepack::t_<yourtrait<yourargs>>
    • Alias class: typepack::apply<ac, arg1, arg2>
  • Conversions:
    • Alias (alias template) to alias class: typepack::quote<youralias>
    • Trait (that is, nested type name) to alias class that handles evaluating the trait: typepack::quote_trait<yourtrait>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment