| Home | Libraries | People | FAQ | More

#### Adapting Existing Types to Proto

The preceding discussions of defining Proto front ends have all made a big assumption: that you have the luxury of defining everything from scratch. What happens if you have existing types, say a matrix type and a vector type, that you would like to treat as if they were Proto terminals? Proto usually trades only in its own expression types, but with ``BOOST_PROTO_DEFINE_OPERATORS`()`, it can accomodate your custom terminal types, too.

Let's say, for instance, that you have the following types and that you can't modify then to make them “native” Proto terminal types.

    namespace math
    {
        // A matrix type ...
        struct matrix { /*...*/ };

        // A vector type ...
        struct vector { /*...*/ };
    }

You can non-intrusively make objects of these types Proto terminals by defining the proper operator overloads using ``BOOST_PROTO_DEFINE_OPERATORS`()`. The basic procedure is as follows:

1. Define a trait that returns true for your types and false for all others.
2. Reopen the namespace of your types and use ``BOOST_PROTO_DEFINE_OPERATORS`()` to define a set of operator overloads, passing the name of the trait as the first macro parameter, and the name of a Proto domain (e.g., `proto::default_domain`) as the second.

The following code demonstrates how it works.

    namespace math
    {
        template<typename T>
        struct is_terminal
          : mpl::false_
        {};

        // OK, "matrix" is a custom terminal type
        template<>
        struct is_terminal<matrix>
          : mpl::true_
        {};

        // OK, "vector" is a custom terminal type
        template<>
        struct is_terminal<vector>
          : mpl::true_
        {};

        // Define all the operator overloads to construct Proto
        // expression templates, treating "matrix" and "vector"
        // objects as if they were Proto terminals.
        BOOST_PROTO_DEFINE_OPERATORS(is_terminal, proto::default_domain)
    }

The invocation of the ``BOOST_PROTO_DEFINE_OPERATORS`()` macro defines a complete set of operator overloads that treat `matrix` and `vector` objects as if they were Proto terminals. And since the operators are defined in the same namespace as the `matrix` and `vector` types, the operators will be found by argument-dependent lookup. With the code above, we can now construct expression templates with matrices and vectors, as shown below.

    math::matrix m1;
    math::vector v1;
    proto::literal<int> i(0);

    m1 * 1;  // custom terminal and literals are OK
    m1 * i;  // custom terminal and Proto expressions are OK
    m1 * v1; // two custom terminals are OK, too.