MPLLIBS_DATA

Synopsis

#define MPLLIBS_DATA(name, type_arity, constructors) \
  // unspecified

Description

Macro for defining a Haskell-like algebraic data type for template metaprograms. constructors is the list of constructors, represented as a sequence of two element tuples. Each tuple describes one constructor. The first element of the tuple is the name, the second element is the arity of the constructor. The values can be compared using boost::mpl::equal_to.

The ::tag of the values is algebraic_data_type_tag indicating that the values belong to an algebraic data-type. A custom tag (name_tag) is defined for each algebraic data-type.

type_arity is the number of type arguments. When there are one or more type arguments, the tag of the data type becomes a template class with type_arity arguments. The arguments are also algebraic data type tags. When a tag is not specified, it is boost::mpl::void_. The tag of the data type has this as default values for all template arguments.

When a constructor is evaluated, it instantiates itself with the evaluated results of the original constructor arguments. When the constructor is instantiated with template metaprogramming values, it is a template metaprogramming value itself as well.

The constructors support currying. For example when a constructor expecting 3 arguments is called with 2, it returns a constructor expecting 1 argument.

The values have a public static ::get_value() method taking no argument and returning the string representation of the constructor. The values also have a public static ::value string constant holding the same value. The string representation of the values created using the constructor contain the name of the constructor and the values of the arguments.

The number of constructor arguments should not be greater than the value of MPLLIBS_LIMIT_DATA_SIZE. It has the value 10 by default.

#include <mpllibs/metamonad/data.hpp>

Expression semantics

The following

MPLLIBS_DATA(name, 0, ((c1, 2))((c2, 0)));

is equivalent to

struct name_tag : mpl_tag<name_tag> {};

MPLLIBS_LAZY_METAFUNCTION(c1, (T0)(T1))
((tmp_value<c1<T0, T1>>, algebraic_data_type_tag));

struct c2 : tmp_value<c2, algebraic_data_type_tag> {};

For any n > 0 the following

MPLLIBS_DATA(name, n, ((c1, 2))((c2, 0)));

is equivalent to

template <class T1 = mpl::void_, ..., class Tn = mpl::void_>
struct name_tag : mpl_tag<name_tag<T0, ..., Tn>> {};

MPLLIBS_LAZY_METAFUNCTION(c1, (T0)(T1))
((tmp_value<c1<T0, T1>>, algebraic_data_type_tag));

struct c2 : tmp_value<c2, algebraic_data_type_tag> {};

Example

MPLLIBS_DATA(maybe, 1, ((nothing, 0))((just, 1)));

[up]