Boost logo

Boost Users :

From: Eric Niebler (eric_at_[hidden])
Date: 2007-12-08 17:30:39


AJD wrote:
> "Eric Niebler" <eric_at_[hidden]> wrote in message
> news:475AEB69.9070304_at_boost-consulting.com...
>> I'm confused. So your vector2<> type is intended as a wrapper for any
>> kind of terminal, not arrays?
>
> vector2<> doesn't wrap terminals, it just wraps regular types to provide
> uniform access to them with a vector (math vector) interface. This way
> vector2<float[3]>, vector2<float(&)[3]>, and vector2<D3DXVECTOR> could all
> be used with expressions regardless of their underlying type, and additional
> types can be used just by specializing vector2<T> and providing the
> subscript operator as well as some traits.

OK...

>> So how is your example different than any
>> of the examples in proto's docs?
>
> I based it off of the lazyvector example, but the code does not optimize as
> expected. (In fact, all I really did was swap out the vector type.)

Your code doesn't optimize because you replaced the terminal type with
something that proto doesn't recognize as a terminal.

>> Have you tried using proto::extends<>
>> (or BOOST_PROTO_EXTENDS) to extend terminal<T>::type instead of
>> terminal<float[3]>::type ? You'll also need to patch up your grammar to
>> accept any kind of terminal.
>
> I'm not sure that's the correct approach... proto should not have to know
> about the internal type of vector2<> at all. I could do this with a helper
> type where vector2 extends vector2_internal which contains all the
> functionality, but then I'm faced with the problem that the many
> specializations of vector2_internal<> could have different constructors
> which would no longer be accessible through the vector2 interface.

Proto builds trees. Trees have terminals and non-terminals. Any type
which proto doesn't recognize is assumed to be a terminal and is
automatically wrapped. Types which proto recognizes are:

- proto::expr<>
- Anything that inherits from proto::extends<>
- Anything type that uses the BOOST_PROTO_EXTENDS macro

Your vector terminals must conform to one of those. Otherwise, proto
will make it conform by wrapping it, and that makes your optimizer's job
harder.

The code I sent has a specialization for vector2<float[3]>. Can't you
just add additional specializations to handle the terminals you're
interested in? Or define vector2 once as:

template< typename T, typename U = proto::is_proto_expr >
struct vector2
{
     BOOST_PROTO_EXTENDS(
         typename proto::terminal<T>::type
       , vector2<T>
       , VectorDomain
     )

     typedef typename vector_traits<T>::value_type value_type;

     value_type & operator [](std::size_t i)
     {
         return vector_traits<T>::index(proto::arg(*this), i);
     }

     value_type const & operator [](std::size_t i) const
     {
         return vector_traits<T>::index(proto::arg(*this), i);
     }
};

And then specialize vector_traits<>.

-- 
Eric Niebler
Boost Consulting
www.boost-consulting.com

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net