A Metafunction
is a function that takes hana::type
s as inputs and returns a hana::type
as output.
A Metafunction
is an object satisfying the FunctionObject concept, but with additional requirements. First, it must be possible to apply a Metafunction
to arguments whose tag is type_tag
, and the result of such an application must be an object whose tag is also type_tag
. Note that hana::type
and hana::basic_type
are the only such types.
Secondly, a Metafunction
must provide a nested ::apply
template which allows performing the same type-level computation as is done by the call operator. In Boost.MPL parlance, a Metafunction
F
is hence a MetafunctionClass in addition to being a FunctionObject
. Rigorously, the following must be satisfied by any object f
of type F
which is a Metafunction
, and for arbitrary types T...
:
Thirdly, to ease the inter-operation of values and types, Metafunction
s must also allow being called with arguments that are not hana::type
s. In that case, the result is equivalent to calling the metafunction on the types of the arguments. Rigorously, this means that for arbitrary objects x...
,
The Metafunction
concept does not have a minimal complete definition in terms of tag-dispatched methods. Instead, the syntactic requirements documented above should be satisfied, and the Metafunction
struct should be specialized explicitly in Hana's namespace.
hana::metafunction
, hana::metafunction_class
, hana::template_
Metafunction
s Comparable
? When seeing hana::template_
, a question that naturally arises is whether Metafunction
s should be made Comparable
. Indeed, it would seem to make sense to compare two templates F
and G
with template_<F> == template_<G>
. However, in the case where F
and/or G
are alias templates, it makes sense to talk about two types of comparisons. The first one is shallow comparison, and it determines that two alias templates are equal if they are the same alias template. The second one is deep comparison, and it determines that two template aliases are equal if they alias the same type for any template argument. For example, given F
and G
defined as
shallow comparison would determine that F
and G
are different because they are two different template aliases, while deep comparison would determine that F
and G
are equal because they always expand to the same type, void
. Unfortunately, deep comparison is impossible to implement because one would have to check F
and G
on all possible types. On the other hand, shallow comparison is not satisfactory because Metafunction
s are nothing but functions on type
s, and the equality of two functions is normally defined with deep comparison. Hence, we adopt a conservative stance and avoid providing comparison for Metafunction
s.
Variables | |
template<template< typename ... > class F> | |
constexpr auto | boost::hana::template_ |
Lift a template to a Metafunction.Given a template class or template alias f , template_<f> is a Metafunction satisfying. More... | |
template<template< typename ... > class F> | |
constexpr auto | boost::hana::metafunction |
Lift a MPL-style metafunction to a Metafunction.Given a MPL-style metafunction, metafunction<f> is a Metafunction satisfying. More... | |
template<typename F > | |
constexpr auto | boost::hana::metafunction_class |
Lift a MPL-style metafunction class to a Metafunction.Given a MPL-style metafunction class, metafunction_class<f> is a Metafunction satisfying. More... | |
constexpr auto | boost::hana::integral |
Turn a Metafunction into a function taking type s and returning a default-constructed object.Given a Metafunction f , integral returns a new Metafunction that default-constructs an object of the type returned by f . More specifically, the following holds: More... | |
template<template< typename ... > class F> | |
constexpr auto | boost::hana::trait = hana::integral(hana::metafunction<F>) |
Alias to integral(metafunction<F>) , provided for convenience. More... | |
constexpr auto boost::hana::template_ |
#include <boost/hana/fwd/type.hpp>
Lift a template to a Metafunction.Given a template class or template alias f
, template_<f>
is a Metafunction
satisfying.
template_<f>(type_c<x>...)
is valid whenever the expression f<x...>
is valid.constexpr auto boost::hana::metafunction |
#include <boost/hana/fwd/type.hpp>
Lift a MPL-style metafunction to a Metafunction.Given a MPL-style metafunction, metafunction<f>
is a Metafunction
satisfying.
metafunction<f>(type_c<x>...)
is valid whenever the expression f<x...>::type
is valid.constexpr auto boost::hana::metafunction_class |
#include <boost/hana/fwd/type.hpp>
Lift a MPL-style metafunction class to a Metafunction.Given a MPL-style metafunction class, metafunction_class<f>
is a Metafunction
satisfying.
metafunction_class<f>(type_c<x>...)
is valid whenever the expression f::apply<x...>::type
is valid.constexpr auto boost::hana::integral |
#include <boost/hana/fwd/type.hpp>
Turn a Metafunction
into a function taking type
s and returning a default-constructed object.Given a Metafunction
f
, integral
returns a new Metafunction
that default-constructs an object of the type returned by f
. More specifically, the following holds:
The principal use case for integral
is to transform Metafunction
s returning a type that inherits from a meaningful base like std::integral_constant
into functions returning e.g. a hana::integral_constant
.
Metafunction
because it does not return a type
. As such, it would not make sense to make decltype(integral(f))
a MPL metafunction class like the usual Metafunction
s are.integral
with metafunctions returning std::integral_constant
s, don't forget to include the boost/hana/ext/std/integral_constant.hpp header to ensure Hana can interoperate with the result.integral(f)(t...)
is valid whenever the expression decltype(f(t...))::type
is valid.constexpr auto boost::hana::trait = hana::integral(hana::metafunction<F>) |
#include <boost/hana/fwd/type.hpp>
Alias to integral(metafunction<F>)
, provided for convenience.