Front Page / Metafunctions / Concepts / Numeric Metafunction

# Numeric Metafunction

### Description

A Numeric Metafunction is a Tag Dispatched Metafunction that provides a built-in infrastructure for easy implementation of mixed-type operations.

### Expression requirements

In the following table and subsequent specifications, `op` is a placeholder token for the actual Numeric Metafunction's name, and `x`, `y` and x1,x2,... xn are arbitrary numeric types.

Expression | Type | Complexity
--- | --- | ---
`op_tag<x>::type` | Integral Constant | Amortized constant time.
    op_impl<
         op_tag<x>::type
       , op_tag<y>::type
       >::apply<x,y>::type
| Any type | Unspecified.
`op<`x1,x2,... xn`>::type` | Any type | Unspecified.

### Expression semantics

    typedef op_tag<x>::type tag;

Semantics: | `tag` is a tag type for `x` for `op`. `tag::value` is `x`'s conversion rank.

    typedef op_impl<
          op_tag<x>::type
        , op_tag<y>::type
        >::apply<x,y>::type r;

Semantics: | `r` is the result of `op` application on arguments `x` and `y`.

    typedef op<x1,x2,... xn>::type r;

Semantics: | `r` is the result of `op` application on arguments x1,x2,... xn.

### Example

    struct complex_tag : int_<10> {};

    template< typename Re, typename Im > struct complex
    {
        typedef complex_tag tag;
        typedef complex type;
        typedef Re real;
        typedef Im imag;
    };

    template< typename C > struct real : C::real {};
    template< typename C > struct imag : C::imag {};

    namespace boost { namespace mpl {

    template<>
    struct plus_impl< complex_tag,complex_tag >
    {
        template< typename N1, typename N2 > struct apply
            : complex<
                  plus< typename N1::real, typename N2::real >
                , plus< typename N1::imag, typename N2::imag >
                >
        {
        };
    };

    }}

    typedef complex< int_<5>, int_<-1> > c1;
    typedef complex< int_<-5>, int_<1> > c2;

    typedef plus<c1,c2> r1;
    BOOST_MPL_ASSERT_RELATION( real<r1>::value, ==, 0 );
    BOOST_MPL_ASSERT_RELATION( imag<r1>::value, ==, 0 );

    typedef plus<c1,c1> r2;
    BOOST_MPL_ASSERT_RELATION( real<r2>::value, ==, 10 );
    BOOST_MPL_ASSERT_RELATION( imag<r2>::value, ==, -2 );

    typedef plus<c2,c2> r3;
    BOOST_MPL_ASSERT_RELATION( real<r3>::value, ==, -10 );
    BOOST_MPL_ASSERT_RELATION( imag<r3>::value, ==, 2 );

### Models

- `plus`
- `minus`
- `times`
- `divides`

### See also

Tag Dispatched Metafunction, Metafunctions, `numeric_cast`