Manu343726 / Turbo

C++11 metaprogramming library
MIT License
111 stars 14 forks source link

Rewrite tml::eval #8

Open Manu343726 opened 9 years ago

Manu343726 commented 9 years ago

Template metaprograms have different categories of C++ types/constructions acting as different elements of the metaprogram syntax. The utility eval (Abbreviated to the macro $()) takes any metaprogram expression and evaluates it. To be able to get the correct value of the expression, eval should handle the different categories of constructions mentioned above, acting accordingly.

Here those categories are defined as concepts:

Value

Plain C++ type with any special characteristics (See concepts bellow). The result of evaluating a value is the value itself:

template<typename T>
using eval_value = T;

Metafunction

A metafunction is any C++ type with a type member type/alias. Nullary metafunctions are supported. An is_metafunction trait should be provided. Possible implementation:

template<typename T>
struct is_metafunction : std::false_type {};

template<typename T>
struct is_metafunction<void_t<typename T::type>> : std::true_type {};

To evaluate a metafunction means to get its type member, that is:

template<typename F>
using evaluate_metafunction = typename F::type;

//Example
using common = eval_metafunction<std::common_type<int,char>>;

Live example.

If the metafunction is not a nullary metafunction, its parameters should be evaluated first prior to metafunction evaluation,. This process is called _parameter expansion_. Metafunction parameter expansion could be explicitly disabled if needed by a noexpand type member on the metafunction.

Metafunction class

A metafunction class is any C++ type with a member apply metafunction. Nullary metafunction classes are supported (Note that means apply could be a type or a template). An is_metafunction_class should be provided. Possible implementation:

namespace detail
{
    template<typename...>
    using void_t = void;

    template<template<typename...> class...>
    using void_template = void;

    template<typename T, typename=void>
    struct has_apply_type : std::false_type {};

    template<typename T>
    struct has_apply_type<T, void_t<typename T::apply>> : std::true_type {};

    template<typename T, typename=void>
    struct has_apply_template : std::false_type {};

    template<typename T>
    struct has_apply_template<T, void_template<T::template apply>> : std::true_type {};
}

template<typename T>
using is_metafunction_class = std::integral_constant<bool, detail::has_apply_type<T>::value ||
                                                           detail::has_apply_template<T>::value>;

Live example.

To evaluate a metafunction class means to evaluate its internal apply metafunction. Possible implementation:

/* TODO */
Manu343726 commented 9 years ago

Check core_concepts.hpp and new_eval.hpp files at concepts-lite branch. The later is not working due to bugs on gcc-clite. The former also needed some workarounds against bugs.