$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Eric Niebler (eric_at_[hidden])
Date: 2008-03-28 03:56:10
Noah Stein wrote:
> Fernando Cacciola wrote:
> 
>> 5) There is a reason why CGAL doesn't provide a distance function at all
> but
>> only a squared_distance, and I agree with that reason: sqrt() kills
>> robustness and distances are usually used for comparisons, so you seldom
>> need that.
> 
> This is one of the things I think proto can help with. I'm playing around
> with a simple vector/point/matrix library just to get a feel for it. proto
> should be able to transform expressions of the sort "length(a) > length(b)"
> into "dot(a,a) > dot(b,b)". I think proper use of proto can lead to high
> levels of expressivity combined with good optimization.
Indeed, see below.
     #include <iostream>
     #include <boost/xpressive/proto/proto.hpp>
     #include <boost/xpressive/proto/debug.hpp>
     #include <boost/xpressive/proto/transform.hpp>
     using namespace boost;
     using namespace proto;
     struct length_impl
     {
         friend std::ostream &operator<<(std::ostream &sout, length_impl)
         {
             return sout << "length_impl";
         }
     };
     struct dot_impl
     {
         // dot implementation here
         friend std::ostream &operator<<(std::ostream &sout, dot_impl)
         {
             return sout << "dot_impl";
         }
     };
     terminal<length_impl>::type const length = {{}};
     terminal<dot_impl>::type const dot = {{}};
     // work around msvc bugs...
     #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
     #define dot_impl() make<dot_impl>
     #define _arg1(a) call<_arg1(a)>
     #define _make_function(a,b,c) call<_make_function(a,b,c)>
     #define _make_terminal(a) call<_make_terminal(a)>
     #endif
     // convert length(a) < length(b) to dot(a,a) < dot(b,b)
     struct Convert
       : when<
             less<
                 function<terminal<length_impl>, _>
               , function<terminal<length_impl>, _>
             >
           , _make_less(
                 _make_function(
                     _make_terminal(dot_impl())
                   , _arg1(_arg0)
                   , _arg1(_arg0)
                 )
               , _make_function(
                     _make_terminal(dot_impl())
                   , _arg1(_arg1)
                   , _arg1(_arg1)
                 )
             )
         >
     {};
     int main()
     {
         int i = 0;
         display_expr(length(1) < length(2));
         display_expr(Convert()(length(1) < length(2), i, i));
     }
This program prints:
     less(
         function(
             terminal(length_impl)
           , terminal(1)
         )
       , function(
             terminal(length_impl)
           , terminal(2)
         )
     )
     less(
         function(
             terminal(dot_impl)
           , terminal(1)
           , terminal(1)
         )
       , function(
             terminal(dot_impl)
           , terminal(2)
           , terminal(2)
         )
     )
In addition to demonstrating how to transform expressions, it's also a 
neat demonstration of how buggy msvc is wrt function types. :-/
-- Eric Niebler Boost Consulting www.boost-consulting.com