|
Boost : |
From: Eric Niebler (eric_at_[hidden])
Date: 2007-04-07 10:49:33
Andreas Pokorny wrote:
> Hi,
>
> I have looked at the examples and they all look very readable. I am now
> missing a facility to make more extended checks.
>
> I am not sure if I completly understood the syntax of the proto dsl.
> Here is a small matrix-vector example:
>
> struct RowVector
> : proto::or_<
> proto::terminal< row_vector<_> >
> , proto::terminal< dyn_row_vector >
> >{};
>
> struct ColumnVector
> : proto::or_<
> proto::terminal< col_vector<_> >
> , proto::terminal< dyn_col_vector >
> >{};
>
> struct MatrixExpr
> : proto::or_<
> proto::multiply<ColumnVector,RowVector>
> >{};
>
> struct ScalarExpr
> : proto::or_<
> proto::terminal< float>
> , proto::multiply<RowVector,ColumnVector>
> >{};
>
> In this case col_vector and row_vector could be like boost_array, with
> a compile time dimension, while dyn_col_vector and dyn_row_vector behave
> more like std::vector.
>
> Now I would like to forbid the mulitplication operator at compile time
> if both dimensions are compile time ones, and do not match. In all other
> cases the check has to be executed during runtime.
>
> How can I do that with proto?
I would create a predicate like dim_equal_to, like this:
template<typename A, typename B>
struct dim_equal_to
: mpl::or_<
mpl::equal_to<A,B>
, mpl::equal_to<A,long_<-1> >
, mpl::equal_to<B,long_<-1> >
>
{};
template<typename T>
struct dim_of;
template<typename Dim> // Assumes Dim is mpl::long_<N>
struct dim_of<row_vector<Dim> >
: Dim
{};
template<typename Dim> // Assumes Dim is mpl::long_<N>
struct dim_of<col_vector<Dim> >
: Dim
{};
template<typename T>
struct dim_of<dyn_row_vector>
: long_<-1>
{};
template<typename T>
struct dim_of<dyn_col_vector>
: long_<-1>
{};
And I would change MatrixExpr to look something like (untested!):
struct MatrixExpr
: proto::and_<
proto::multiply<ColumnVector,RowVector>
, proto::if_<
dim_equal_to<
dim_of<
proto::result_of::arg<proto::result_of::left<mpl::_> >
>
, dim_of<
proto::result_of::arg<proto::result_of::right<mpl::_> >
>
>
>
>
{};
ScalarExpr would get a similar treatment.
Some observations. In your code, you have:
> struct MatrixExpr
> : proto::or_<
> proto::multiply<ColumnVector,RowVector>
> >{};
In this case, the proto::or_ is superfluous, and can just be removed.
And in this expression:
> proto::terminal< row_vector<_> >
note that the _ is proto::_, not mpl::_, and that it will only match
types, not integers. Hence the comment above about assuming that Dim is
mpl::long_<N>.
HTH,
(I'm leaving today for a week-long vacation. I'll be on email only off
and on. Sorry 'bout that.)
-- Eric Niebler Boost Consulting www.boost-consulting.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk